{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":113558,"databundleVersionId":14174843,"sourceType":"competition"}],"dockerImageVersionId":31153,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nimport os\nfrom PIL import Image\nimport random\nfrom skimage import measure\n\nimport cv2\nfrom shapely.geometry import Polygon\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-10-27T18:29:09.762010Z","iopub.execute_input":"2025-10-27T18:29:09.762330Z","iopub.status.idle":"2025-10-27T18:29:10.075462Z","shell.execute_reply.started":"2025-10-27T18:29:09.762307Z","shell.execute_reply":"2025-10-27T18:29:10.074491Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Read images from dir","metadata":{}},{"cell_type":"code","source":"authentic_images_dir = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/authentic\"\nforged_images_dir = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/forged\"\nforged_images_mask_dir = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_masks\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-27T16:34:39.808333Z","iopub.execute_input":"2025-10-27T16:34:39.808574Z","iopub.status.idle":"2025-10-27T16:34:39.824340Z","shell.execute_reply.started":"2025-10-27T16:34:39.808555Z","shell.execute_reply":"2025-10-27T16:34:39.823263Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"authentic_images_files = sorted(os.listdir(authentic_images_dir))\nforged_images_files = sorted(os.listdir(forged_images_dir))\nforged_images_mask_files = sorted(os.listdir(forged_images_mask_dir))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-27T16:34:39.825469Z","iopub.execute_input":"2025-10-27T16:34:39.825793Z","iopub.status.idle":"2025-10-27T16:34:39.854194Z","shell.execute_reply.started":"2025-10-27T16:34:39.825764Z","shell.execute_reply":"2025-10-27T16:34:39.853194Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Length of Authentic files: {len(authentic_images_files)}\")\nprint(f\"Length of Forged files: {len(forged_images_files)}\")\nprint(f\"Length of Forged mask files: {len(forged_images_mask_files)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-27T16:34:39.855894Z","iopub.execute_input":"2025-10-27T16:34:39.856421Z","iopub.status.idle":"2025-10-27T16:34:39.861530Z","shell.execute_reply.started":"2025-10-27T16:34:39.856395Z","shell.execute_reply":"2025-10-27T16:34:39.860733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_sample(n=1, i=None):\n    if i is None:\n        i = random.randint(0, len(authentic_images_files) - n)\n\n    mask_path = os.path.join(forged_images_mask_dir, forged_images_mask_files[i])\n    authentic_path = os.path.join(authentic_images_dir, f\"{forged_images_mask_files[i].split('.')[0]}.png\")\n    forged_path = os.path.join(forged_images_dir, f\"{forged_images_mask_files[i].split('.')[0]}.png\")\n\n    # Read images\n    authentic_img = np.array(Image.open(authentic_path))\n    forged_img = np.array(Image.open(forged_path))\n    mask_img = np.load(mask_path)\n\n    print(authentic_img.shape, forged_img.shape, mask_img.shape)\n\n    # assume mask_img[0] is the binary mask\n    mask = mask_img[0] if mask_img.ndim > 2 else mask_img\n    mask = (mask > 0.5).astype(np.uint8)\n\n    # find contours (boundaries) of forged areas\n    contours = measure.find_contours(mask, level=0.5)\n\n    # Plot side-by-side\n    plt.figure(figsize=(12, 4))\n\n    plt.subplot(1, 3, 1)\n    plt.imshow(authentic_img)\n    plt.title(\"Authentic Image\")\n    plt.axis('off')\n\n    plt.subplot(1, 3, 2)\n    plt.imshow(forged_img)\n    plt.title(\"Forged Image (Highlighted)\")\n    plt.axis('off')\n\n    # draw contours over forged image\n    for contour in contours:\n        poly = Polygon(contour[:, ::-1]) \n        buffer_distance = 7  # pixels or coordinate units\n        buffered_poly = poly.buffer(buffer_distance)\n        \n        # Convert back to array for plotting\n        buffered_contour = np.array(buffered_poly.exterior.coords)\n        # plt.plot(contour[:, 1], contour[:, 0], color='red', linewidth=1)\n        plt.plot(buffered_contour[:, 0], buffered_contour[:, 1], color='red', linestyle='--')\n\n    plt.subplot(1, 3, 3)\n    plt.imshow(mask, cmap='gray')\n    plt.title(\"Forged Mask\")\n    plt.axis('off')\n\n    plt.tight_layout()\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-27T17:30:40.801134Z","iopub.execute_input":"2025-10-27T17:30:40.801434Z","iopub.status.idle":"2025-10-27T17:30:40.812314Z","shell.execute_reply.started":"2025-10-27T17:30:40.801415Z","shell.execute_reply":"2025-10-27T17:30:40.811160Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_sample(i=11)\nplot_sample(i=51)\nplot_sample(i=101)\nplot_sample(i=501)\nplot_sample(i=1001)\nplot_sample(i=1502)\nplot_sample(i=2001)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-27T17:35:03.333657Z","iopub.execute_input":"2025-10-27T17:35:03.333996Z","iopub.status.idle":"2025-10-27T17:35:07.841626Z","shell.execute_reply.started":"2025-10-27T17:35:03.333968Z","shell.execute_reply":"2025-10-27T17:35:07.840790Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# First Impression\n\n1. The forged images from training dataset are mostly following Copy & Move technique to create a forgerd images.\n2. The copied part / entity from the image rotated at random angles.\n3. Majority of the images are from microscopic slides.\n4. Multiple entities are copied & moved in the same forged image.\n5. Mistake in corn forged images, When multiple entites are copied & moved but only one entity alone is masked.\n\n\n## Simply we can put like\nIn the image, if some enitiy is repeated then its forged ","metadata":{}},{"cell_type":"markdown","source":"---","metadata":{}}]}