{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Steganography\n\n*Steganography is an ancient practice of hiding secret message in non-secret medium. When spies in the Revolutionary War wrote in invisible ink or when Da Vinci embedded secret meaning in a painting that was steganography. This works in the digital world, too, where a file like an image can be stealthily encoded with information. For example, pixel values, brightness, and filter settings for an image are normally changed to affect the image's aesthetic look. But hackers can also manipulate them based on a secret code with no regard for how the inputs make the image look visually. This technique can be used for ethical reasons, such as to evade censorship or embed messages in Facebook photos. But these methods can also be used nefariously. For security defenders the question is how to tell the difference between an image that’s been modified for legitimate reasons and one that’s been changed to secretly contain malicious information.*\n\n**Cover:** The image which is used for hiding the secret information.\n\n**Stego:** The image after embedding a secret message.\n\n[Source](http://https://www.wired.com/story/steganography-hacker-lexicon/)\n\n\n<img  width=\"500\" height=\"500\" src=\"https://ars.els-cdn.com/content/image/1-s2.0-S1742287605000046-gr1.jpg\">\n\n\n### Steganography Techniques:\n<img  width=\"700\" height=\"700\" src=\"https://www.researchgate.net/profile/Ayman_El-Sayed2/publication/308663229/figure/fig2/AS:412394917515264@1475334018187/Classification-of-image-steganography-techniques.png\">\n\n**Spatial Domain Steganography Technique:**\n\n<img  width=\"700\" height=\"700\" src=\"https://ars.els-cdn.com/content/image/1-s2.0-S092359651830256X-gr5.jpg\">\n\nThese schemes support the\ngeneration of a hidden channel in the portions of the cover image, where variations\nare likely slightly restricted once related to the HVS. \n\n**Various steganography techniques under this domain:**\n\n<span style=\"color:blue\">LSB (Least significant Bit) Steganography:</span>\n\nThis is a simplest and straightforward steganographic technique that embeds the bits of secret message directly into the least significant bit (LSB) plane of the cover image  since human eye can't differentiate between two shades separated only by one bit.\n\n<img  width=\"700\" height=\"700\" src=\"https://img.wonderhowto.com/img/02/61/63645877844452/0/use-steganography-hide-data-images-with-steghide.w1456.jpg\">\n\n\n<span style=\"color:blue\">Gray Level Modification (GLM) Steganography:</span>\n\nIt maps data (not embed or hide it) by modifying the gray level values of\nthe image pixels. GLM Steganography uses the concept of odd and even numbers to map data within an image. It is a one-to-one mapping between the binary data and the selected pixels in an image. From a given image a set of pixels are selected\nbased on a mathematical function. The gray level values of those pixels are examined and compared with the bit stream that\nis to be mapped in the image.\n\n<img  width=\"700\" height=\"700\" src=\"https://snipboard.io/f4d2ZS.jpg\">\n\n\n<span style=\"color:blue\">PVD Method for Gray-Level Image:</span>\n\nIt segments the cover image into non overlapping blocks containing two connecting pixels and modifies the pixel difference in each block (pair) for data\nembedding. A larger difference in the original pixel values allows a greater modification.\n\n<img  width=\"700\" height=\"700\" src=\"https://www.researchgate.net/profile/Ki-Hyun_Jung/publication/324069876/figure/fig1/AS:610788930760705@1522634837468/General-pixel-values-differencing-embedding-scheme-Balasubramanian-et-al-57-proposed.png\">\n\n\n\n**Frequency Domain Steganography Technique:**\n\nThe basic idea to hide information in the frequency domain is to alter the magnitude of all of the DCT coefficients of cover image.\nThis mainly includes DCT(Discrete Cosine Transform) and Wavelet Transform.\n\n<img  width=\"700\" height=\"700\" src=\"https://lh3.googleusercontent.com/proxy/SwGQIF-PKfUGJG8ICkbzyYbB0IrOv1gLXVdS49uanNctMzO0I6YTKjXiozYirolKb3hC7arRczvR5a7RV7aLMQTOTyF2dZeapmBGZ3fUtx9ijPcy6fWb3-c\">\n\n**Spread Spectrum Image Steganography (SSIS) Technique:**\n\nSpread spectrum communication describes the process of spreading the bandwidth of a narrowband signal across a\nwide band of frequencies. This can be accomplished by modulating the narrowband waveform with a wideband waveform,\nsuch as white noise. After spreading, the energy of the narrowband signal in any one frequency band is low and therefore\ndifficult to detect. SSIS works by storing a message as Gaussian noise in an image. At low noise power levels, the image\ndegradation is undetectable by the human eye, while at higher levels the noise appears as speckles or “snow.”\n\n\n# Steganalysis\n\nIt is the process of detecting the trace of hidden message in the given image. \n**It can be classified into two types:**\n\n**1) Blind Steganalysis: **\n\nIt detects the embedding in the image without knowing the steganographic algorithm used for embedding.\n\n**2) Targeted Steganalysis:**\n\nIt utilizes the knowledge of the steganographic scheme used for embedding.\n"},{"metadata":{},"cell_type":"markdown","source":"<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/xepNoHgNj0w\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Importing the modules\nimport cv2\nimport numpy as np\nimport matplotlib.image as mpimg\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nfrom pathlib import Path\nimport os\nimport ipywidgets as widgets\nfrom IPython.display import display\nfrom IPython.html.widgets import interactive\nimport log\nfrom numpy import r_\nimport scipy\nfrom scipy.fftpack import dct, idct\nfrom numpy import pi\nfrom numpy import sin\nfrom numpy import zeros\n\nimport warnings\nwarnings.filterwarnings(\"ignore\", category=FutureWarning)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# EDA"},{"metadata":{},"cell_type":"markdown","source":"# Comparison in Spatial Domain"},{"metadata":{},"cell_type":"markdown","source":"### Hitsogram Analysis"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"path = Path('/kaggle/input/alaska2-image-steganalysis')\nfolders = ['Cover', 'JMiPOD', 'JUNIWARD', 'UERD']\n\n# Let us plot image histogram for cover and stego images in Gray scale:\nimg_num = 5\n\nfig, ax = plt.subplots(figsize=(20, 10))\n\ngray_img_cov = cv2.imread(f\"{path}/{folders[0]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\ngray_img_jmi = cv2.imread(f\"{path}/{folders[1]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\ngray_img_juni = cv2.imread(f\"{path}/{folders[2]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\ngray_img_uerd = cv2.imread(f\"{path}/{folders[3]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\n\n\n#################################\nplt.subplot(141)\nplt.title(\"Cover\")\nplt.imshow(gray_img_cov, cmap=\"gray\")\n\nplt.subplot(142)\nplt.title(\"JMiPOD\")\nplt.imshow(gray_img_jmi, cmap=\"gray\")\n\nplt.subplot(143)\nplt.title(\"JUNIWARD\")\nplt.imshow(gray_img_juni, cmap=\"gray\")\n\nplt.subplot(144)\nplt.title(\"UERD\")\nplt.imshow(gray_img_uerd, cmap=\"gray\")\n\nplt.show()\n#################################\n\nhist_cov = cv2.calcHist([gray_img_cov],[0],None,[256],[0,256])\nhist_jmi = cv2.calcHist([gray_img_jmi],[0],None,[256],[0,256])\nhist_juni = cv2.calcHist([gray_img_juni],[0],None,[256],[0,256])\nhist_uerd = cv2.calcHist([gray_img_uerd],[0],None,[256],[0,256])\n\n#################################\nfig, ax = plt.subplots(figsize=(20, 5))\n\nplt.subplot(141)\nplt.hist(gray_img_cov.ravel(),256,[0,256])\nplt.title('Histogram for Cover')\n\nplt.subplot(142)\nplt.hist(gray_img_jmi.ravel(),256,[0,256])\nplt.title('Histogram for JMiPOD')\n\nplt.subplot(143)\nplt.hist(gray_img_juni.ravel(),256,[0,256])\nplt.title('Histogram for JUNIWARD')\n\nplt.subplot(144)\nplt.hist(gray_img_uerd.ravel(),256,[0,256])\nplt.title('Histogram for UERD')\n\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"You can see slight difference in the histogram plots of cover and stego images"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Let us plot image histogram for cover and stego images in RGB scale:\nimg_num = 5\n\nfig, ax = plt.subplots(figsize=(20, 10))\n\nimg_cov = cv2.imread(f\"{path}/{folders[0]}/0000{img_num}.jpg\", -1)\nimg_jmi = cv2.imread(f\"{path}/{folders[1]}/0000{img_num}.jpg\", -1)\nimg_juni = cv2.imread(f\"{path}/{folders[2]}/0000{img_num}.jpg\", -1)\nimg_uerd = cv2.imread(f\"{path}/{folders[3]}/0000{img_num}.jpg\", -1)\n\n\n#################################\nplt.subplot(141)\nplt.title(\"Cover\")\nplt.imshow(img_cov)\n\nplt.subplot(142)\nplt.title(\"JMiPOD\")\nplt.imshow(img_jmi)\n\nplt.subplot(143)\nplt.title(\"JUNIWARD\")\nplt.imshow(img_juni)\n\nplt.subplot(144)\nplt.title(\"UERD\")\nplt.imshow(img_uerd)\n\nplt.show()\n#################################\n\nhistb_cov = cv2.calcHist([img_cov],[0],None,[256],[0,256])\nhistg_cov = cv2.calcHist([img_cov],[1],None,[256],[0,256])\nhistr_cov = cv2.calcHist([img_cov],[2],None,[256],[0,256])\n\nhistb_jmi = cv2.calcHist([img_jmi],[0],None,[256],[0,256])\nhistg_jmi = cv2.calcHist([img_jmi],[1],None,[256],[0,256])\nhistr_jmi = cv2.calcHist([img_jmi],[2],None,[256],[0,256])\n\nhistb_juni = cv2.calcHist([img_juni],[0],None,[256],[0,256])\nhistg_juni = cv2.calcHist([img_juni],[1],None,[256],[0,256])\nhistr_juni = cv2.calcHist([img_juni],[2],None,[256],[0,256])\n\nhistb_uerd = cv2.calcHist([img_uerd],[0],None,[256],[0,256])\nhistg_uerd = cv2.calcHist([img_uerd],[1],None,[256],[0,256])\nhistr_uerd = cv2.calcHist([img_uerd],[2],None,[256],[0,256])\n\n#################################\nfig, ax = plt.subplots(figsize=(20, 5))\n\nplt.subplot(341)\nplt.plot(histb_cov,color = 'b')\nplt.title('Histogram for Cover channel-0 (B)')\n\nplt.subplot(342)\nplt.plot(histb_jmi,color = 'b')\nplt.title('Histogram for JMiPOD channel-0 (B)')\n\nplt.subplot(343)\nplt.plot(histb_juni,color = 'b')\nplt.title('Histogram for JUNIWARD channel-0 (B)')\n\nplt.subplot(344)\nplt.plot(histb_uerd,color = 'b')\nplt.title('Histogram for UERD channel-0 (B)')\n\n\nplt.subplot(345)\nplt.plot(histg_cov,color = 'g')\nplt.title('Histogram for Cover channel-1 (G)')\n\nplt.subplot(346)\nplt.plot(histg_jmi,color = 'g')\nplt.title('Histogram for JMiPOD channel-1 (G)')\n\nplt.subplot(347)\nplt.plot(histg_juni,color = 'g')\nplt.title('Histogram for JUNIWARD channel-1 (G)')\n\nplt.subplot(348)\nplt.plot(histg_uerd,color = 'g')\nplt.title('Histogram for UERD channel-1 (G)')\n\n\nplt.subplot(349)\nplt.plot(histr_cov,color = 'r')\nplt.title('Histogram for Cover channel-2 (R)')\n\nplt.subplot(3,4,10)\nplt.plot(histr_jmi,color = 'r')\nplt.title('Histogram for JMiPOD channel-2 (R)')\n\nplt.subplot(3,4,11)\nplt.plot(histr_juni,color = 'r')\nplt.title('Histogram for JUNIWARD channel-2 (R)')\n\nplt.subplot(3,4,12)\nplt.plot(histr_uerd,color = 'r')\nplt.title('Histogram for UERD channel-2 (R)')\n\nplt.tight_layout()\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"(histr_jmi == histr_cov).all()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Inferencing using rgb seems to be difficult. They all look same but are different. "},{"metadata":{},"cell_type":"markdown","source":"**Ipython widget:**"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# Ipython widget will allow you to select images from the list.\n# Will consider only 100 images out of 75k\nimg_files = [f\"0000{i}.jpg\" if i<10 else f\"000{i}.jpg\"  for i in range(1,100)] \ndef show_hist_gray(img_file):\n    # Let us plot image histogram for cover and stego images in Gray scale:\n    fig, ax = plt.subplots(figsize=(20, 10))\n    print(f\"{path}/{folders[0]}/{img_file}\")\n    gray_img_cov = cv2.imread(f\"{path}/{folders[0]}/{img_file}\", cv2.IMREAD_GRAYSCALE)\n    gray_img_jmi = cv2.imread(f\"{path}/{folders[1]}/{img_file}\", cv2.IMREAD_GRAYSCALE)\n    gray_img_juni = cv2.imread(f\"{path}/{folders[2]}/{img_file}\", cv2.IMREAD_GRAYSCALE)\n    gray_img_uerd = cv2.imread(f\"{path}/{folders[3]}/{img_file}\", cv2.IMREAD_GRAYSCALE)\n\n\n    #################################\n    plt.subplot(141)\n    plt.title(\"Cover\")\n    plt.imshow(gray_img_cov, cmap=\"gray\")\n\n    plt.subplot(142)\n    plt.title(\"JMiPOD\")\n    plt.imshow(gray_img_jmi, cmap=\"gray\")\n\n    plt.subplot(143)\n    plt.title(\"JUNIWARD\")\n    plt.imshow(gray_img_juni, cmap=\"gray\")\n\n    plt.subplot(144)\n    plt.title(\"UERD\")\n    plt.imshow(gray_img_uerd, cmap=\"gray\")\n\n    plt.show()\n    #################################\n\n    hist_cov = cv2.calcHist([gray_img_cov],[0],None,[256],[0,256])\n    hist_jmi = cv2.calcHist([gray_img_jmi],[0],None,[256],[0,256])\n    hist_juni = cv2.calcHist([gray_img_juni],[0],None,[256],[0,256])\n    hist_uerd = cv2.calcHist([gray_img_uerd],[0],None,[256],[0,256])\n\n    #################################\n    fig, ax = plt.subplots(figsize=(20, 5))\n\n    plt.subplot(141)\n    plt.hist(gray_img_cov.ravel(),256,[0,256])\n    plt.title('Histogram for Cover')\n\n    plt.subplot(142)\n    plt.hist(gray_img_jmi.ravel(),256,[0,256])\n    plt.title('Histogram for JMiPOD')\n\n    plt.subplot(143)\n    plt.hist(gray_img_juni.ravel(),256,[0,256])\n    plt.title('Histogram for JUNIWARD')\n\n    plt.subplot(144)\n    plt.hist(gray_img_uerd.ravel(),256,[0,256])\n    plt.title('Histogram for UERD')\n\n#     plt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"opt = widgets.Select(options=img_files)\ninteractive(show_hist_gray, img_file=opt)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def show_hist_rgb(img_file):\n    # Let us plot image histogram for cover and stego images in RGB scale:\n\n    fig, ax = plt.subplots(figsize=(20, 10))\n\n    img_cov = cv2.imread(f\"{path}/{folders[0]}/{img_file}\", -1)\n    img_jmi = cv2.imread(f\"{path}/{folders[1]}/{img_file}\", -1)\n    img_juni = cv2.imread(f\"{path}/{folders[2]}/{img_file}\", -1)\n    img_uerd = cv2.imread(f\"{path}/{folders[3]}/{img_file}\", -1)\n\n\n    #################################\n    plt.subplot(141)\n    plt.title(\"Cover\")\n    plt.imshow(img_cov)\n\n    plt.subplot(142)\n    plt.title(\"JMiPOD\")\n    plt.imshow(img_jmi)\n\n    plt.subplot(143)\n    plt.title(\"JUNIWARD\")\n    plt.imshow(img_juni)\n\n    plt.subplot(144)\n    plt.title(\"UERD\")\n    plt.imshow(img_uerd)\n\n    plt.show()\n    #################################\n\n    histb_cov = cv2.calcHist([img_cov],[0],None,[256],[0,256])\n    histg_cov = cv2.calcHist([img_cov],[1],None,[256],[0,256])\n    histr_cov = cv2.calcHist([img_cov],[2],None,[256],[0,256])\n\n    histb_jmi = cv2.calcHist([img_jmi],[0],None,[256],[0,256])\n    histg_jmi = cv2.calcHist([img_jmi],[1],None,[256],[0,256])\n    histr_jmi = cv2.calcHist([img_jmi],[2],None,[256],[0,256])\n\n    histb_juni = cv2.calcHist([img_juni],[0],None,[256],[0,256])\n    histg_juni = cv2.calcHist([img_juni],[1],None,[256],[0,256])\n    histr_juni = cv2.calcHist([img_juni],[2],None,[256],[0,256])\n\n    histb_uerd = cv2.calcHist([img_uerd],[0],None,[256],[0,256])\n    histg_uerd = cv2.calcHist([img_uerd],[1],None,[256],[0,256])\n    histr_uerd = cv2.calcHist([img_uerd],[2],None,[256],[0,256])\n\n    #################################\n    fig, ax = plt.subplots(figsize=(20, 5))\n\n    plt.subplot(341)\n    plt.plot(histb_cov,color = 'b')\n    plt.title('Histogram for Cover channel-0 (B)')\n\n    plt.subplot(342)\n    plt.plot(histb_jmi,color = 'b')\n    plt.title('Histogram for JMiPOD channel-0 (B)')\n\n    plt.subplot(343)\n    plt.plot(histb_juni,color = 'b')\n    plt.title('Histogram for JUNIWARD channel-0 (B)')\n\n    plt.subplot(344)\n    plt.plot(histb_uerd,color = 'b')\n    plt.title('Histogram for UERD channel-0 (B)')\n\n\n    plt.subplot(345)\n    plt.plot(histg_cov,color = 'g')\n    plt.title('Histogram for Cover channel-1 (G)')\n\n    plt.subplot(346)\n    plt.plot(histg_jmi,color = 'g')\n    plt.title('Histogram for JMiPOD channel-1 (G)')\n\n    plt.subplot(347)\n    plt.plot(histg_juni,color = 'g')\n    plt.title('Histogram for JUNIWARD channel-1 (G)')\n\n    plt.subplot(348)\n    plt.plot(histg_uerd,color = 'g')\n    plt.title('Histogram for UERD channel-1 (G)')\n\n\n    plt.subplot(349)\n    plt.plot(histr_cov,color = 'r')\n    plt.title('Histogram for Cover channel-2 (R)')\n\n    plt.subplot(3,4,10)\n    plt.plot(histr_jmi,color = 'r')\n    plt.title('Histogram for JMiPOD channel-2 (R)')\n\n    plt.subplot(3,4,11)\n    plt.plot(histr_juni,color = 'r')\n    plt.title('Histogram for JUNIWARD channel-2 (R)')\n\n    plt.subplot(3,4,12)\n    plt.plot(histr_uerd,color = 'r')\n    plt.title('Histogram for UERD channel-2 (R)')\n\n    plt.tight_layout()\n#     plt.show()\n\n    ","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"opt = widgets.Select(options=img_files)\ninteractive(show_hist_rgb, img_file=opt)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"### LSB Analysis\n\nA simple way to detect tampering with least significant bits of images is based on the observation above \n– regions within tampered images will have the average of LSBs around 0.5, because the LSBs contain encrypted data, \nwhich is similar in structure with random data. So in order to analyse an image, we split it into blocks, \nand for each block calculate the average of LSBs.\n\n\n<sup>[Source](https://github.com/livz/cloacked-pixel/blob/master/lsb.py)</sup>\n\n<sup>[More details](https://github.com/FlorianPicca/Linked-Pixel-Steganography)</sup>"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# Statistical analysis of an image to detect LSB steganography\ndef analyse(in_file):\n\t'''\n\t- Split the image into blocks.\n\t- Compute the average value of the LSBs for each block.\n\t- The plot of the averages should be around 0.5 for zones that contain\n\t  hidden encrypted messages (random data).\n\t'''\n\tBS = 100\t# Block size \n\timg = Image.open(in_file)\n\t(width, height) = img.size\n\tprint(\"[+] Image size: %dx%d pixels.\" % (width, height))\n\tconv = img.convert(\"RGBA\").getdata()\n\n\t# Extract LSBs\n\tvr = []\t# Red LSBs\n\tvg = []\t# Green LSBs\n\tvb = []\t# LSBs\n\tfor h in range(height):\n\t\tfor w in range(width):\n\t\t\t(r, g, b, a) = conv.getpixel((w, h))\n\t\t\tvr.append(r & 1)\n\t\t\tvg.append(g & 1)\n\t\t\tvb.append(b & 1)\n\n\t# Average colours' LSB per each block\n\tavgR = []\n\tavgG = []\n\tavgB = []\n\tfor i in range(0, len(vr), BS):\n\t\tavgR.append(np.mean(vr[i:i + BS]))\n\t\tavgG.append(np.mean(vg[i:i + BS]))\n\t\tavgB.append(np.mean(vb[i:i + BS]))\n\n\t# Nice plot \n\tnumBlocks = len(avgR)\n\tblocks = [i for i in range(0, numBlocks)]\n\tplt.axis([0, len(avgR), 0, 1])\n\tplt.ylabel('Average LSB per block')\n\tplt.xlabel('Block number')\n\n#\tplt.plot(blocks, avgR, 'r.')\n#\tplt.plot(blocks, avgG, 'g')\n\tplt.plot(blocks, avgB, 'bo')\n\t\n# \tplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"img_num = 1\nfig, ax = plt.subplots(figsize=(20, 10))\n\nplt.subplot(141)\nplt.title(\"Cover\")\nanalyse(f\"{path}/{folders[0]}/0000{img_num}.jpg\")\n\nplt.subplot(142)\nplt.title(\"JMiPOD\")\nanalyse(f\"{path}/{folders[1]}/0000{img_num}.jpg\")\n\nplt.subplot(143)\nplt.title(\"JUNIWARD\")\nanalyse(f\"{path}/{folders[2]}/0000{img_num}.jpg\")\n\nplt.subplot(144)\nplt.title(\"UERD\")\nanalyse(f\"{path}/{folders[3]}/0000{img_num}.jpg\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Differencing"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# source: https://github.com/qll/shit/blob/master/shit/analyse.py\ndef match_imgs(img1_path, img2_path):\n    \"\"\"Match images together and check properties like mode and dimension.\"\"\"\n    img1 = Image.open(img1_path)\n    img2 = Image.open(img2_path)\n    if img1.mode != img2.mode:\n        log.warning('Unequal image modes (%s vs %s) - converting %s to %s',\n                    img1.mode, img2.mode, img1.mode, img2.mode)\n        img1 = img1.convert(img2.mode)\n    if img1.width != img2.width or img1.height != img2.height:\n        log.warning('Dimensions do not match ([%d, %d] vs [%d, %d])',\n                    img1.width, img1.height, img2.width, img2.height)\n    return img1, img2\n\ndef diffed_imgs(img1, img2):\n    \"\"\"Generator over all Pillow Image object pixel differences.\n    Will run in the boundaries of min{width, height} of both images. It is the\n    caller's responsibility to match image modes (RGB <-> RGBA).\n    \"\"\"\n    for y in range(min(img1.height, img2.height)):\n        for x in range(min(img1.width, img2.width)):\n            img1_pixel = img1.getpixel((x, y))\n            img2_pixel = img2.getpixel((x, y))\n            if img1_pixel != img2_pixel:\n                yield (x, y), img1_pixel, img2_pixel\n\n\ndef find_diffs(orig_path, stego_path, out_path=None):\n    \"\"\"Find differences in pixel values of the original and stego image.\"\"\"\n    orig, stego = match_imgs(orig_path, stego_path)\n    out = Image.new('RGB', orig.size, (0, 0, 0)) if out_path else None\n    for pos, orig_pixel, stego_pixel in diffed_imgs(orig, stego):\n#         log.info('Mismatched pixels at %s: %s vs %s', pos, orig_pixel,\n#                  stego_pixel)\n        if out:\n            out.putpixel(pos, (255, 255, 255))\n\n    if out:\n        out.save(out_path)\n        \n    im = plt.imread('/kaggle/working/output.jpg')\n    plt.imshow(im)    \n","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def show_diff_img(img_num):\n    fig, ax = plt.subplots(figsize=(20, 20))\n\n    img_cov = cv2.imread(f\"{path}/{folders[0]}/0000{img_num}.jpg\", -1)\n    img_jmi = cv2.imread(f\"{path}/{folders[1]}/0000{img_num}.jpg\", -1)\n    img_juni = cv2.imread(f\"{path}/{folders[2]}/0000{img_num}.jpg\", -1)\n    img_uerd = cv2.imread(f\"{path}/{folders[3]}/0000{img_num}.jpg\", -1)\n\n    plt.subplot(331)\n    plt.title(\"Cover\")\n    plt.imshow(img_cov)\n\n    plt.subplot(332)\n    plt.title(\"JMiPOD\")\n    plt.imshow(img_jmi)\n\n    plt.subplot(333)\n    plt.title(\"Cover-JMiPOD\")\n    find_diffs(f\"{path}/{folders[0]}/0000{img_num}.jpg\", f\"{path}/{folders[1]}/0000{img_num}.jpg\", \"output.jpg\")\n\n\n    plt.subplot(334)\n    plt.title(\"Cover\")\n    plt.imshow(img_cov)\n\n    plt.subplot(335)\n    plt.title(\"JUNIWARD\")\n    plt.imshow(img_juni)\n\n    plt.subplot(336)\n    plt.title(\"Cover-JUNIWARD\")\n    find_diffs(f\"{path}/{folders[0]}/0000{img_num}.jpg\", f\"{path}/{folders[2]}/0000{img_num}.jpg\", \"output.jpg\")\n\n\n    plt.subplot(337)\n    plt.title(\"Cover\")\n    plt.imshow(img_cov)\n\n    plt.subplot(338)\n    plt.title(\"JUERD\")\n    plt.imshow(img_juni)\n\n    plt.subplot(339)\n    plt.title(\"Cover-UERD\")\n    find_diffs(f\"{path}/{folders[0]}/0000{img_num}.jpg\", f\"{path}/{folders[3]}/0000{img_num}.jpg\", \"output.jpg\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_diff_img(8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_diff_img(5)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Comparison in Frequency Domain\n\ncredit->[Frank Ong](https://inst.eecs.berkeley.edu/~ee123/sp16/Sections/JPEG_DCT_Demo.html)"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"img_cov = cv2.imread(f\"{path}/{folders[0]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\nimg_jmi = cv2.imread(f\"{path}/{folders[1]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\nimg_juni = cv2.imread(f\"{path}/{folders[2]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\nimg_uerd = cv2.imread(f\"{path}/{folders[3]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def dct2(a):\n    return scipy.fftpack.dct( scipy.fftpack.dct( a, axis=0, norm='ortho' ), axis=1, norm='ortho' )\n\ndef idct2(a):\n    return scipy.fftpack.idct( scipy.fftpack.idct( a, axis=0 , norm='ortho'), axis=1 , norm='ortho')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"imsize = img_cov.shape\ndct = np.zeros(imsize)\n\n# Do 8x8 DCT on image (in-place)\nfor i in r_[:imsize[0]:8]:\n    for j in r_[:imsize[1]:8]:\n        dct[i:(i+8),j:(j+8)] = dct2( img_cov[i:(i+8),j:(j+8)] )","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"\npos = 128\n\n# Extract a block from image\nplt.figure()\nplt.imshow(img_cov[pos:pos+8,pos:pos+8],cmap='gray')\nplt.title( \"An 8x8 Image block\")\n\n# Display the dct of that block\nplt.figure()\nplt.imshow(dct[pos:pos+8,pos:pos+8],cmap='gray',vmax= np.max(dct)*0.01,vmin = 0, extent=[0,pi,pi,0])\nplt.title( \"An 8x8 DCT block\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"# Display entire DCT\nplt.figure()\nplt.imshow(img_cov)\nplt.title( \"orig image\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"# Display entire DCT\nplt.figure()\nplt.imshow(dct,cmap='gray',vmax = np.max(dct)*0.01,vmin = 0)\nplt.title( \"DCTs of the image\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### DCT coeff difference in gray images"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def show_dct_gray(img_num):\n    # Let us plot image histogram for cover and stego images in Gray scale:\n    fig, ax = plt.subplots(figsize=(20, 10))\n    print(f\"{path}/{folders[0]}/0000{img_num}.jpg\")\n    gray_img_cov = cv2.imread(f\"{path}/{folders[0]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\n    gray_img_jmi = cv2.imread(f\"{path}/{folders[1]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\n    gray_img_juni = cv2.imread(f\"{path}/{folders[2]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\n    gray_img_uerd = cv2.imread(f\"{path}/{folders[3]}/0000{img_num}.jpg\", cv2.IMREAD_GRAYSCALE)\n    \n    imsize = gray_img_cov.shape\n    dct_cov = np.zeros(imsize)\n    dct_jmi = np.zeros(imsize)\n    dct_juni = np.zeros(imsize)\n    dct_uerd = np.zeros(imsize)\n    \n    # Do 8x8 DCT on image (in-place)\n    for i in r_[:imsize[0]:8]:\n        for j in r_[:imsize[1]:8]:\n            dct_cov[i:(i+8),j:(j+8)] = dct2( gray_img_cov[i:(i+8),j:(j+8)] )\n            dct_jmi[i:(i+8),j:(j+8)] = dct2( gray_img_jmi[i:(i+8),j:(j+8)] )\n            dct_juni[i:(i+8),j:(j+8)] = dct2( gray_img_juni[i:(i+8),j:(j+8)] )\n            dct_uerd[i:(i+8),j:(j+8)] = dct2( gray_img_uerd[i:(i+8),j:(j+8)] )\n    \n \n   #################################\n    \n#     plt.suptitle('DCT on gray images')       fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"Cover\")\n    plt.imshow(gray_img_cov, cmap=\"gray\")\n\n    plt.subplot(142)\n    plt.title(\"JMiPOD\")\n    plt.imshow(gray_img_jmi, cmap=\"gray\")\n\n    plt.subplot(143)\n    plt.title(\"JUNIWARD\")\n    plt.imshow(gray_img_juni, cmap=\"gray\")\n\n    plt.subplot(144)\n    plt.title(\"UERD\")\n    plt.imshow(gray_img_uerd, cmap=\"gray\")\n\n    plt.show()    \n  \n\n    #################################\n#     plt.suptitle('Original gray images')\n    fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"DCT on Cover\")\n    plt.imshow(dct_cov, cmap=\"gray\", vmax = np.max(dct_cov)*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT on JMiPOD\")\n    plt.imshow(dct_jmi, cmap=\"gray\", vmax = np.max(dct_jmi)*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT on JUNIWARD\")\n    plt.imshow(dct_juni, cmap=\"gray\", vmax = np.max(dct_juni)*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT on UERD\")\n    plt.imshow(dct_uerd, cmap=\"gray\", vmax = np.max(dct_uerd)*0.01,vmin = 0)\n\n    plt.show()\n \n    #########################################\n    diff_cov_jmi = dct_cov - dct_jmi\n    diff_cov_juni = dct_cov - dct_juni\n    diff_cov_uerd = dct_cov - dct_uerd\n    ########################################\n    \n    fig, ax = plt.subplots(figsize=(20, 10))\n#     plt.suptitle('Difference in DCT coeff')\n    plt.subplot(141)\n    plt.title(\"DCT Cover\")#.axis('off')\n    plt.imshow(dct_cov, cmap=\"gray\", vmax = np.max(dct_cov)*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT Cover - DCT JMiPOD\")\n    plt.imshow(diff_cov_jmi, cmap=\"gray\", vmax = np.max(diff_cov_jmi)*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT Cover - DCT JUNIWARD\")\n    plt.imshow(diff_cov_juni, cmap=\"gray\", vmax = np.max(diff_cov_juni)*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT Cover - DCT UERD\")\n    plt.imshow(diff_cov_uerd, cmap=\"gray\", vmax = np.max(diff_cov_uerd)*0.01,vmin = 0)\n\n    plt.show()\n    \n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_dct_gray(1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_dct_gray(5)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### DCT coeff difference Channel wise"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def show_dct_channel_wise(img_num):\n    # Let us plot image histogram for cover and stego images in Gray scale:\n    fig, ax = plt.subplots(figsize=(20, 10))\n    print(f\"{path}/{folders[0]}/0000{img_num}.jpg\")\n    img_cov = cv2.imread(f\"{path}/{folders[0]}/0000{img_num}.jpg\", -1)\n    img_jmi = cv2.imread(f\"{path}/{folders[1]}/0000{img_num}.jpg\", -1)\n    img_juni = cv2.imread(f\"{path}/{folders[2]}/0000{img_num}.jpg\", -1)\n    img_uerd = cv2.imread(f\"{path}/{folders[3]}/0000{img_num}.jpg\", -1)\n    \n    imsize = img_cov.shape\n    \n    dct_cov = np.zeros(imsize)\n    dct_jmi = np.zeros(imsize)\n    dct_juni = np.zeros(imsize)\n    dct_uerd = np.zeros(imsize) \n    \n    diff_cov_jmi = np.zeros(imsize)\n    diff_cov_juni = np.zeros(imsize)\n    diff_cov_uerd = np.zeros(imsize) \n    \n    \n    # Do 8x8 DCT on image (in-place)\n    for i in r_[:imsize[0]:8]:\n        for j in r_[:imsize[1]:8]:\n            dct_cov[:,:,0][i:(i+8),j:(j+8)] = dct2( img_cov[:,:,0][i:(i+8),j:(j+8)] )\n            dct_jmi[:,:,0][i:(i+8),j:(j+8)] = dct2( img_jmi[:,:,0][i:(i+8),j:(j+8)] )\n            dct_juni[:,:,0][i:(i+8),j:(j+8)] = dct2( img_juni[:,:,0][i:(i+8),j:(j+8)] )\n            dct_uerd[:,:,0][i:(i+8),j:(j+8)] = dct2( img_uerd[:,:,0][i:(i+8),j:(j+8)] )\n\n            dct_cov[:,:,1][i:(i+8),j:(j+8)] = dct2( img_cov[:,:,1][i:(i+8),j:(j+8)] )\n            dct_jmi[:,:,1][i:(i+8),j:(j+8)] = dct2( img_jmi[:,:,1][i:(i+8),j:(j+8)] )\n            dct_juni[:,:,1][i:(i+8),j:(j+8)] = dct2( img_juni[:,:,1][i:(i+8),j:(j+8)] )\n            dct_uerd[:,:,1][i:(i+8),j:(j+8)] = dct2( img_uerd[:,:,1][i:(i+8),j:(j+8)] )\n            \n            dct_cov[:,:,2][i:(i+8),j:(j+8)] = dct2( img_cov[:,:,2][i:(i+8),j:(j+8)] )\n            dct_jmi[:,:,2][i:(i+8),j:(j+8)] = dct2( img_jmi[:,:,2][i:(i+8),j:(j+8)] )\n            dct_juni[:,:,2][i:(i+8),j:(j+8)] = dct2( img_juni[:,:,2][i:(i+8),j:(j+8)] )\n            dct_uerd[:,:,2][i:(i+8),j:(j+8)] = dct2( img_uerd[:,:,2][i:(i+8),j:(j+8)] )\n \n   #################################\n    \n#     plt.suptitle('DCT on gray images')       fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"Cover\")\n    plt.imshow(img_cov)\n\n    plt.subplot(142)\n    plt.title(\"JMiPOD\")\n    plt.imshow(img_jmi)\n\n    plt.subplot(143)\n    plt.title(\"JUNIWARD\")\n    plt.imshow(img_juni)\n\n    plt.subplot(144)\n    plt.title(\"UERD\")\n    plt.imshow(img_uerd)\n\n    plt.show()    \n  \n\n    #################################\n#     plt.suptitle('Original gray images')\n    fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"DCT on Cover=>channel 0\")\n    plt.imshow(dct_cov[:,:,0], cmap=\"gray\", vmax = np.max(dct_cov[:,:,0])*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT on JMiPOD=>channel 0\")\n    plt.imshow(dct_jmi[:,:,0], cmap=\"gray\", vmax = np.max(dct_jmi[:,:,0])*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT on JUNIWARD=>channel 0\")\n    plt.imshow(dct_juni[:,:,0], cmap=\"gray\", vmax = np.max(dct_juni[:,:,0])*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT on UERD=>channel 0\")\n    plt.imshow(dct_uerd[:,:,0], cmap=\"gray\", vmax = np.max(dct_uerd[:,:,0])*0.01,vmin = 0)\n\n    plt.show()\n \n    #########################################\n    diff_cov_jmi[:,:,0] = dct_cov[:,:,0] - dct_jmi[:,:,0]\n    diff_cov_juni[:,:,0] = dct_cov[:,:,0] - dct_juni[:,:,0]\n    diff_cov_uerd[:,:,0] = dct_cov[:,:,0] - dct_uerd[:,:,0]\n    ########################################\n    \n    fig, ax = plt.subplots(figsize=(20, 10))\n#     plt.suptitle('Difference in DCT coeff')\n    plt.subplot(141)\n    plt.title(\"DCT Cover=>channel 0\")#.axis('off')\n    plt.imshow(dct_cov[:,:,0], cmap=\"gray\", vmax = np.max(dct_cov[:,:,0])*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT Cover - DCT JMiPOD : Channel 0\")\n    plt.imshow(diff_cov_jmi[:,:,0], cmap=\"gray\", vmax = np.max(diff_cov_jmi[:,:,0])*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT Cover - DCT JUNIWARD : Channel 0\")\n    plt.imshow(diff_cov_juni[:,:,0], cmap=\"gray\", vmax = np.max(diff_cov_juni[:,:,0])*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT Cover - DCT UERD : Channel 0\")\n    plt.imshow(diff_cov_uerd[:,:,0], cmap=\"gray\", vmax = np.max(diff_cov_uerd[:,:,0])*0.01,vmin = 0)\n\n    plt.show()\n    \n    \n\n    #################################\n    fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"DCT on Cover=>channel 1\")\n    plt.imshow(dct_cov[:,:,1], cmap=\"gray\", vmax = np.max(dct_cov[:,:,1])*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT on JMiPOD=>channel 1\")\n    plt.imshow(dct_jmi[:,:,1], cmap=\"gray\", vmax = np.max(dct_jmi[:,:,1])*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT on JUNIWARD=>channel 1\")\n    plt.imshow(dct_juni[:,:,1], cmap=\"gray\", vmax = np.max(dct_juni[:,:,1])*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT on UERD=>channel 1\")\n    plt.imshow(dct_uerd[:,:,1], cmap=\"gray\", vmax = np.max(dct_uerd[:,:,1])*0.01,vmin = 0)\n\n    plt.show()\n \n    #########################################\n    diff_cov_jmi[:,:,1] = dct_cov[:,:,1] - dct_jmi[:,:,1]\n    diff_cov_juni[:,:,1] = dct_cov[:,:,1] - dct_juni[:,:,1]\n    diff_cov_uerd[:,:,1] = dct_cov[:,:,1] - dct_uerd[:,:,1]\n    ########################################\n    \n    fig, ax = plt.subplots(figsize=(20, 10))\n#     plt.suptitle('Difference in DCT coeff')\n    plt.subplot(141)\n    plt.title(\"DCT Cover=>channel 1\")#.axis('off')\n    plt.imshow(dct_cov[:,:,1], cmap=\"gray\", vmax = np.max(dct_cov[:,:,1])*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT Cover - DCT JMiPOD : Channel 1\")\n    plt.imshow(diff_cov_jmi[:,:,1], cmap=\"gray\", vmax = np.max(diff_cov_jmi[:,:,1])*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT Cover - DCT JUNIWARD : Channel 1\")\n    plt.imshow(diff_cov_juni[:,:,1], cmap=\"gray\", vmax = np.max(diff_cov_juni[:,:,1])*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT Cover - DCT UERD : Channel 1\")\n    plt.imshow(diff_cov_uerd[:,:,1], cmap=\"gray\", vmax = np.max(diff_cov_uerd[:,:,1])*0.01,vmin = 0)\n\n    plt.show()  \n    \n    #################################\n    fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"DCT on Cover=>channel 2\")\n    plt.imshow(dct_cov[:,:,2], cmap=\"gray\", vmax = np.max(dct_cov[:,:,2])*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT on JMiPOD=>channel 2\")\n    plt.imshow(dct_jmi[:,:,2], cmap=\"gray\", vmax = np.max(dct_jmi[:,:,2])*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT on JUNIWARD=>channel 2\")\n    plt.imshow(dct_juni[:,:,2], cmap=\"gray\", vmax = np.max(dct_juni[:,:,2])*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT on UERD=>channel 2\")\n    plt.imshow(dct_uerd[:,:,2], cmap=\"gray\", vmax = np.max(dct_uerd[:,:,2])*0.01,vmin = 0)\n\n    plt.show()\n \n    #########################################\n    diff_cov_jmi[:,:,2] = dct_cov[:,:,2] - dct_jmi[:,:,2]\n    diff_cov_juni[:,:,2] = dct_cov[:,:,2] - dct_juni[:,:,2]\n    diff_cov_uerd[:,:,2] = dct_cov[:,:,2] - dct_uerd[:,:,2]\n    ########################################\n    \n    fig, ax = plt.subplots(figsize=(20, 10))\n#     plt.suptitle('Difference in DCT coeff')\n    plt.subplot(141)\n    plt.title(\"DCT Cover=>channel 2\")#.axis('off')\n    plt.imshow(dct_cov[:,:,2], cmap=\"gray\", vmax = np.max(dct_cov[:,:,2])*0.01,vmin = 0)\n\n    plt.subplot(142)\n    plt.title(\"DCT Cover - DCT JMiPOD : Channel 2\")\n    plt.imshow(diff_cov_jmi[:,:,2], cmap=\"gray\", vmax = np.max(diff_cov_jmi[:,:,2])*0.01,vmin = 0)\n\n    plt.subplot(143)\n    plt.title(\"DCT Cover - DCT JUNIWARD : Channel 2\")\n    plt.imshow(diff_cov_juni[:,:,2], cmap=\"gray\", vmax = np.max(diff_cov_juni[:,:,2])*0.01,vmin = 0)\n\n    plt.subplot(144)\n    plt.title(\"DCT Cover - DCT UERD : Channel 2\")\n    plt.imshow(diff_cov_uerd[:,:,2], cmap=\"gray\", vmax = np.max(diff_cov_uerd[:,:,2])*0.01,vmin = 0)\n\n    plt.show()  \n        \n    \n    \n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_dct_channel_wise(1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_dct_channel_wise(2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### DCT coeff difference in bgr images"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def show_dct_bgr(img_num):\n    # Let us plot image histogram for cover and stego images in Gray scale:\n    fig, ax = plt.subplots(figsize=(20, 10))\n    print(f\"{path}/{folders[0]}/0000{img_num}.jpg\")\n    img_cov = cv2.imread(f\"{path}/{folders[0]}/0000{img_num}.jpg\", -1)\n    img_jmi = cv2.imread(f\"{path}/{folders[1]}/0000{img_num}.jpg\", -1)\n    img_juni = cv2.imread(f\"{path}/{folders[2]}/0000{img_num}.jpg\", -1)\n    img_uerd = cv2.imread(f\"{path}/{folders[3]}/0000{img_num}.jpg\", -1)\n    \n    imsize = img_cov.shape\n    \n    dct_cov = np.zeros(imsize)\n    dct_jmi = np.zeros(imsize)\n    dct_juni = np.zeros(imsize)\n    dct_uerd = np.zeros(imsize) \n    \n    \n    # Do 8x8 DCT on image (in-place)\n    for i in r_[:imsize[0]:8]:\n        for j in r_[:imsize[1]:8]:\n            dct_cov[:,:,0][i:(i+8),j:(j+8)] = dct2( img_cov[:,:,0][i:(i+8),j:(j+8)] )\n            dct_jmi[:,:,0][i:(i+8),j:(j+8)] = dct2( img_jmi[:,:,0][i:(i+8),j:(j+8)] )\n            dct_juni[:,:,0][i:(i+8),j:(j+8)] = dct2( img_juni[:,:,0][i:(i+8),j:(j+8)] )\n            dct_uerd[:,:,0][i:(i+8),j:(j+8)] = dct2( img_uerd[:,:,0][i:(i+8),j:(j+8)] )\n\n            dct_cov[:,:,1][i:(i+8),j:(j+8)] = dct2( img_cov[:,:,1][i:(i+8),j:(j+8)] )\n            dct_jmi[:,:,1][i:(i+8),j:(j+8)] = dct2( img_jmi[:,:,1][i:(i+8),j:(j+8)] )\n            dct_juni[:,:,1][i:(i+8),j:(j+8)] = dct2( img_juni[:,:,1][i:(i+8),j:(j+8)] )\n            dct_uerd[:,:,1][i:(i+8),j:(j+8)] = dct2( img_uerd[:,:,1][i:(i+8),j:(j+8)] )\n            \n            dct_cov[:,:,2][i:(i+8),j:(j+8)] = dct2( img_cov[:,:,2][i:(i+8),j:(j+8)] )\n            dct_jmi[:,:,2][i:(i+8),j:(j+8)] = dct2( img_jmi[:,:,2][i:(i+8),j:(j+8)] )\n            dct_juni[:,:,2][i:(i+8),j:(j+8)] = dct2( img_juni[:,:,2][i:(i+8),j:(j+8)] )\n            dct_uerd[:,:,2][i:(i+8),j:(j+8)] = dct2( img_uerd[:,:,2][i:(i+8),j:(j+8)] )\n \n   #################################\n    \n#     plt.suptitle('DCT on gray images')       fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"Cover\")\n    plt.imshow(img_cov)\n\n    plt.subplot(142)\n    plt.title(\"JMiPOD\")\n    plt.imshow(img_jmi)\n\n    plt.subplot(143)\n    plt.title(\"JUNIWARD\")\n    plt.imshow(img_juni)\n\n    plt.subplot(144)\n    plt.title(\"UERD\")\n    plt.imshow(img_uerd)\n\n    plt.show()    \n  \n\n    #################################\n#     plt.suptitle('Original gray images')\n    fig, ax = plt.subplots(figsize=(20, 10))\n    plt.subplot(141)\n    plt.title(\"DCT on Cover\")\n    plt.imshow(dct_cov)\n\n    plt.subplot(142)\n    plt.title(\"DCT on JMiPOD\")\n    plt.imshow(dct_jmi)\n\n    plt.subplot(143)\n    plt.title(\"DCT on JUNIWARD\")\n    plt.imshow(dct_juni)\n\n    plt.subplot(144)\n    plt.title(\"DCT on UERD\")\n    plt.imshow(dct_uerd)\n\n    plt.show()\n \n    #########################################\n    \n    diff_cov_jmi = dct_cov - dct_jmi\n    diff_cov_juni = dct_cov - dct_juni\n    diff_cov_uerd = dct_cov - dct_uerd\n    ########################################\n    \n    fig, ax = plt.subplots(figsize=(20, 10))\n#     plt.suptitle('Difference in DCT coeff')\n    plt.subplot(141)\n    plt.title(\"DCT Cover\")#.axis('off')\n    plt.imshow(dct_cov)\n\n    plt.subplot(142)\n    plt.title(\"DCT Cover - DCT JMiPOD\")\n    plt.imshow(diff_cov_jmi)\n\n    plt.subplot(143)\n    plt.title(\"DCT Cover - DCT JUNIWARD\")\n    plt.imshow(diff_cov_juni)\n\n    plt.subplot(144)\n    plt.title(\"DCT Cover - DCT UERD\")\n    plt.imshow(diff_cov_uerd)\n\n    plt.show()\n    \n    \n    \n    \n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_dct_bgr(1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_dct_bgr(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"<span style=\"color:red\"><b>Will be updating the kernel with more analysis so stay tuned.<b></span>\n"}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}