{"cells":[{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"!pip install stegano","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# PRELIMINARIES\nimport os\nfrom stegano import lsb #USED FOR PNG IMAGE\nimport skimage.io as sk\nimport matplotlib.pyplot as plt\nfrom scipy import spatial\nfrom tqdm import tqdm\n\nfrom PIL import Image\nfrom random import shuffle\n\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image = sk.imread(\"../input/alaska2-image-steganalysis/JMiPOD/00005.jpg\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"secret = lsb.hide(\"../input/alaska2-image-steganalysis/JMiPOD/00005.jpg\", \"I will be there but you can't find me even if I'm a very very very long sentence\")\nsecret.save(\"encoded.png\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img1 = sk.imread(\"../input/alaska2-image-steganalysis/JMiPOD/00005.jpg\")\nimg2 = sk.imread(\"/kaggle/working/encoded.png\")\n\nfig,ax = plt.subplots(1,2,figsize=(18,8))\n    \nax[0].imshow(img1)\nax[1].imshow(img2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(lsb.reveal(\"/kaggle/working/encoded.png\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img2.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"vec1 = np.reshape(img1,(512*512*3))\nvec2 = np.reshape(img2,(512*512*3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(1 - spatial.distance.cosine(vec1,vec2)) #Cosine Similarity","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(spatial.distance.cosine(vec2,vec1)) #Cosine Dissimilarity","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"BASE_PATH = \"/kaggle/input/alaska2-image-steganalysis\"\ntrain_imageids = pd.Series(os.listdir(BASE_PATH + '/Cover')).sort_values(ascending=True).reset_index(drop=True)\ntest_imageids = pd.Series(os.listdir(BASE_PATH + '/Test')).sort_values(ascending=True).reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cover_images_path = pd.Series(BASE_PATH + '/Cover/' + train_imageids ).sort_values(ascending=True)\nJMIPOD_images_path = pd.Series(BASE_PATH + '/JMiPOD/'+train_imageids).sort_values(ascending=True)\nJUNIWARD_images_path = pd.Series(BASE_PATH + '/JUNIWARD/'+train_imageids).sort_values(ascending=True)\nUERD_images_path = pd.Series(BASE_PATH + '/UERD/'+train_imageids).sort_values(ascending=True)\ntest_images_path = pd.Series(BASE_PATH + '/Test/'+test_imageids).sort_values(ascending=True)\nss = pd.read_csv(f'{BASE_PATH}/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#VISUALIZING SOME IMAGES FROM COVER SECTION\nfig, ax = plt.subplots(nrows=2, ncols=2, figsize=(30, 15))\nk=0\nfor i, row in enumerate(ax):\n    for j, col in enumerate(row):\n        img = sk.imread(cover_images_path[k])\n        col.imshow(img)\n        col.set_title(cover_images_path[k])\n        k=k+1\nplt.suptitle('Samples from Cover Images', fontsize=14)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(nrows=3, ncols=4, figsize=(30, 15))\nfor i in range(3):\n    '''\n    If you want to print more images just change the values in range and ncols in subplot\n    \n    '''\n    cvimg = sk.imread(cover_images_path[i])\n    uniimg = sk.imread(JUNIWARD_images_path[i])\n    jpodimg = sk.imread(JMIPOD_images_path[i])\n    uerdimg = sk.imread(UERD_images_path[i])\n    \n    ax[i,0].imshow(cvimg)\n    ax[i,0].set_title('Cover_IMG'+train_imageids[i])\n    ax[i,1].imshow(uniimg)\n    ax[i,1].set_title('JNIWARD_IMG'+train_imageids[i])\n    ax[i,2].imshow(jpodimg)\n    ax[i,2].set_title('JMiPOD_IMG'+train_imageids[i])\n    ax[i,3].imshow(uerdimg)\n    ax[i,3].set_title('UERD_IMG'+train_imageids[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_cover = sk.imread(cover_images_path[0])\nimg_jmipod = sk.imread(JMIPOD_images_path[0])\nimg_juniward = sk.imread(JUNIWARD_images_path[0])\nimg_uerd = sk.imread(UERD_images_path[0])\n\n\nfig, ax = plt.subplots(nrows=3, ncols=4, figsize=(16, 12))\nax[0,0].imshow(img_jmipod)\nax[0,1].imshow((img_cover == img_jmipod).astype(int)[:,:,0])\nax[0,1].set_title(f'{train_imageids[k]} Channel 0')\n\nax[0,2].imshow((img_cover == img_jmipod).astype(int)[:,:,1])\nax[0,2].set_title(f'{train_imageids[k]} Channel 1')\nax[0,3].imshow((img_cover == img_jmipod).astype(int)[:,:,2])\nax[0,3].set_title(f'{train_imageids[k]} Channel 2')\nax[0,0].set_ylabel('JMiPOD', rotation=90, size='large', fontsize=14)\n\n\nax[1,0].imshow(img_juniward)\nax[1,1].imshow((img_cover == img_juniward).astype(int)[:,:,0])\nax[1,2].imshow((img_cover == img_juniward).astype(int)[:,:,1])\nax[1,3].imshow((img_cover == img_juniward).astype(int)[:,:,2])\nax[1,0].set_ylabel('JUNIWARD', rotation=90, size='large', fontsize=14)\n\nax[2,0].imshow(img_uerd)\nax[2,1].imshow((img_cover == img_uerd).astype(int)[:,:,0])\nax[2,2].imshow((img_cover == img_uerd).astype(int)[:,:,1])\nax[2,3].imshow((img_cover == img_uerd).astype(int)[:,:,2])\nax[2,0].set_ylabel('UERD', rotation=90, size='large', fontsize=14)\n\nplt.suptitle('Pixel Deviation from Cover Image', fontsize=14)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"\n![image.png](attachment:image.png)","attachments":{"image.png":{"image/png":"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"}}},{"metadata":{},"cell_type":"markdown","source":"* Firstly the image is converted into YCbCr from RGB channels. YCbCr and RGB are both colorspaces having different channels where YCbCr consists three channels as Luminance(Y) , Cb(Cb is blue minus luma (B-Y)) ,  Cr(Cr is red minus luma (R-Y)). \n\n* Then DCT is applied on the pixels of these channels , using DCT coeff ,\n\n* The image encoded using JPEG algorithm stays in YCbCr colorspace untill it is decoded by an Image viewer software. When a JPEG is read it is decoded and converted back to RGB colorspace to be rendered on screen "},{"metadata":{"trusted":true},"cell_type":"code","source":"fig,ax = plt.subplots(3,4,figsize=(20,12))\n\nfor i,paths in enumerate(cover_images_path[:3]):\n    image = Image.open(paths)\n    ycbcr = image.convert('YCbCr')\n    (y, cb, cr) = ycbcr.split()\n\n    ax[i,0].imshow(image)\n    ax[i,0].set_title('Cover'+train_imageids[i])\n    ax[i,1].imshow(y)\n    ax[i,1].set_title('Luminance')\n    ax[i,2].imshow(cb)\n    ax[i,2].set_title('Cb:Chroma Blue')\n    ax[i,3].imshow(cr)\n    ax[i,3].set_title('Cr:Chroma Red')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig,ax = plt.subplots(4,4,figsize=(20,16))\nplt.tight_layout()\n\n\nim1 = Image.open(cover_images_path[0])\nim2 = Image.open(JUNIWARD_images_path[0])\nim3 = Image.open(JMIPOD_images_path[0])\nim4 = Image.open(UERD_images_path[0])\n\nfor i,image in enumerate([im1,im2,im3,im4]):\n    ycbcr = image.convert('YCbCr')\n    (y, cb, cr) = ycbcr.split()\n\n    ax[i,0].imshow(image)\n    ax[i,0].set_title('Image')\n    ax[i,1].imshow(y)\n    ax[i,1].set_title('Luminance')\n    ax[i,2].imshow(cb)\n    ax[i,2].set_title('Cb:Chroma Blue')\n    ax[i,3].imshow(cr)\n    ax[i,3].set_title('Cr:Chroma Red')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! git clone https://github.com/dwgoon/jpegio","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install jpegio/.\nimport jpegio as jio","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig,ax = plt.subplots(4,4,figsize=(20,16))\nplt.tight_layout()\n\nfor i,path in enumerate([cover_images_path[0],JUNIWARD_images_path[0],JMIPOD_images_path[0],UERD_images_path[0]]):\n    \n    image = Image.open(path)\n    jpeg = jio.read(path)\n    DCT_Y = jpeg.coef_arrays[0]\n    DCT_Cr = jpeg.coef_arrays[1]\n    DCT_Cb = jpeg.coef_arrays[2]\n    \n    \n    ax[i,0].imshow(image)\n    ax[i,0].set_title('Image')\n    ax[i,1].imshow(DCT_Y)\n    ax[i,1].set_title('Luminance')\n    ax[i,2].imshow(DCT_Cb)\n    ax[i,2].set_title('Cb:Chroma Blue')\n    ax[i,3].imshow(DCT_Cr)\n    ax[i,3].set_title('Cr:Chroma Red')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"coverDCT = np.zeros([512,512,3])\nstegoDCT = np.zeros([512,512,3])\njpeg = jio.read(cover_images_path[0])\nstego_juni = jio.read(JUNIWARD_images_path[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"coverDCT[:,:,0] = jpeg.coef_arrays[0] ; coverDCT[:,:,1] = jpeg.coef_arrays[1] ; coverDCT[:,:,2] = jpeg.coef_arrays[2]\nstegoDCT[:,:,0] = stego_juni.coef_arrays[0] ; stegoDCT[:,:,1] = stego_juni.coef_arrays[1] ; stegoDCT[:,:,2] = stego_juni.coef_arrays[2]\n\nDCT_diff = coverDCT - stegoDCT\n# So since they are not the same Images the DCT_diff would not be zero\nprint(len(DCT_diff[np.where(DCT_diff!=0)]))\nprint(np.unique(DCT_diff))\nplt.figure(figsize=(16,10))\nplt.imshow( abs(DCT_diff) )\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"coverPixels = np.array(Image.open(cover_images_path[0])).astype('float')\nstegoPixels = np.array(Image.open(JUNIWARD_images_path[0])).astype('float')\n\npixelsDiff = coverPixels - stegoPixels\n\n# So since they are not the same Images the pixels_diff would not be zero\nprint(len(pixelsDiff[np.where(pixelsDiff!=0)]))\nprint(np.unique(pixelsDiff))\nplt.figure(figsize=(16,10))\nplt.imshow( abs(pixelsDiff) )\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig,ax = plt.subplots(1,2,figsize=(16,12))\nax[0].imshow(abs(DCT_diff))\nax[1].imshow(abs(pixelsDiff))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}