{"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":"gpu","dataSources":[{"sourceId":113558,"databundleVersionId":14878066,"sourceType":"competition"}],"dockerImageVersionId":31240,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\n\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\nfrom torchvision.models.segmentation import deeplabv3_resnet50","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:04.542115Z","iopub.execute_input":"2026-01-01T18:03:04.542925Z","iopub.status.idle":"2026-01-01T18:03:04.547099Z","shell.execute_reply.started":"2026-01-01T18:03:04.542899Z","shell.execute_reply":"2026-01-01T18:03:04.546173Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TRAIN_FORGED = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/forged\"\nTRAIN_MASKS  = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_masks\"\n\nTEST_IMAGES  = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/test_images\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:04.548326Z","iopub.execute_input":"2026-01-01T18:03:04.548607Z","iopub.status.idle":"2026-01-01T18:03:04.562229Z","shell.execute_reply.started":"2026-01-01T18:03:04.548590Z","shell.execute_reply":"2026-01-01T18:03:04.561667Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nimg_name = os.listdir(TRAIN_FORGED)[0]\n\nimage = cv2.imread(os.path.join(TRAIN_FORGED, img_name))\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\nraw_mask = np.load(os.path.join(TRAIN_MASKS, img_name.replace(\".png\", \".npy\")))\nmask = (raw_mask.sum(axis=0) > 0).astype(np.uint8)\n\nplt.figure(figsize=(12,4))\n\nplt.subplot(1,3,1)\nplt.title(\"Image\")\nplt.imshow(image)\nplt.axis(\"off\")\n\nplt.subplot(1,3,2)\nplt.title(\"Mask\")\nplt.imshow(mask, cmap=\"gray\")\nplt.axis(\"off\")\n\nplt.subplot(1,3,3)\nplt.title(\"Overlay\")\nplt.imshow(image)\nplt.imshow(mask, cmap=\"Reds\", alpha=0.4)\nplt.axis(\"off\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:04.562892Z","iopub.execute_input":"2026-01-01T18:03:04.563066Z","iopub.status.idle":"2026-01-01T18:03:04.894055Z","shell.execute_reply.started":"2026-01-01T18:03:04.563052Z","shell.execute_reply":"2026-01-01T18:03:04.893480Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfor i in range(1):\n    img_name = os.listdir(TRAIN_FORGED)[i]\n    \n    image = cv2.imread(os.path.join(TRAIN_FORGED, img_name))\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    \n    raw_mask = np.load(os.path.join(TRAIN_MASKS, img_name.replace(\".png\", \".npy\")))\n    mask = (raw_mask.sum(axis=0) > 0).astype(np.uint8)\n    \n    plt.figure(figsize=(12,4))\n    \n    plt.subplot(1,3,1)\n    plt.title(\"Image\")\n    plt.imshow(image)\n    plt.axis(\"off\")\n    \n    plt.subplot(1,3,2)\n    plt.title(\"Mask\")\n    plt.imshow(mask, cmap=\"gray\")\n    plt.axis(\"off\")\n    \n    plt.subplot(1,3,3)\n    plt.title(\"Overlay\")\n    plt.imshow(image)\n    plt.imshow(mask, cmap=\"Reds\", alpha=0.4)\n    plt.axis(\"off\")\n    \n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:04.895053Z","iopub.execute_input":"2026-01-01T18:03:04.895295Z","iopub.status.idle":"2026-01-01T18:03:05.217657Z","shell.execute_reply.started":"2026-01-01T18:03:04.895271Z","shell.execute_reply":"2026-01-01T18:03:05.216990Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":" img_name = os.listdir(TRAIN_FORGED)[1]\n    \nimg = cv2.imread(os.path.join(TRAIN_FORGED, img_name))\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:05.219171Z","iopub.execute_input":"2026-01-01T18:03:05.219435Z","iopub.status.idle":"2026-01-01T18:03:05.240996Z","shell.execute_reply.started":"2026-01-01T18:03:05.219418Z","shell.execute_reply":"2026-01-01T18:03:05.240318Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.imshow(img, cmap='gray')                       # original image\nplt.imshow(mask, cmap='jet', alpha=0.5)            # overlay mask in color\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:05.241771Z","iopub.execute_input":"2026-01-01T18:03:05.242018Z","iopub.status.idle":"2026-01-01T18:03:05.607844Z","shell.execute_reply.started":"2026-01-01T18:03:05.241997Z","shell.execute_reply":"2026-01-01T18:03:05.607023Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as mpatches\n\nfrom skimage.filters import threshold_otsu\nfrom skimage.segmentation import clear_border\nfrom skimage.measure import label, regionprops\nfrom skimage.morphology import closing, footprint_rectangle\nfrom skimage.color import label2rgb\n\n# -----------------------------\n# 1. Load image properly\n# -----------------------------\nimg_name = os.listdir(TRAIN_FORGED)[0]\nimg_path = os.path.join(TRAIN_FORGED, img_name)\n\nimage = cv2.imread(img_path)\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n# Convert to grayscale\ngray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)\n\n# -----------------------------\n# 2. Otsu Thresholding\n# -----------------------------\nthresh = threshold_otsu(gray)\nbw = closing(gray > thresh, footprint_rectangle((3, 3)))\n\n# -----------------------------\n# 3. Remove border artifacts\n# -----------------------------\ncleared = clear_border(bw)\n\n# -----------------------------\n# 4. Label regions\n# -----------------------------\nlabel_image = label(cleared)\nimage_label_overlay = label2rgb(label_image, image=image, bg_label=0)\n\n# -----------------------------\n# 5. Plot results\n# -----------------------------\nfig, ax = plt.subplots(figsize=(10, 6))\nax.imshow(image_label_overlay)\n\nfor region in regionprops(label_image):\n    if region.area >= 100:\n        minr, minc, maxr, maxc = region.bbox\n        rect = mpatches.Rectangle(\n            (minc, minr),\n            maxc - minc,\n            maxr - minr,\n            fill=False,\n            edgecolor=\"red\",\n            linewidth=2,\n        )\n        ax.add_patch(rect)\n\nax.set_axis_off()\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:05.608588Z","iopub.execute_input":"2026-01-01T18:03:05.608842Z","iopub.status.idle":"2026-01-01T18:03:06.268780Z","shell.execute_reply.started":"2026-01-01T18:03:05.608815Z","shell.execute_reply":"2026-01-01T18:03:06.268020Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom PIL import Image\n\ndef show_image_mask_overlay(img_path, mask_path, cmap='jet', alpha=0.5):\n    \"\"\"\n    Load image and binary mask (as files) and display:\n      [Original | Mask | Overlay]\n    in one row of subplots.\n    \"\"\"\n    # Load image (convert to RGB or grayscale array)\n    img = np.array(Image.open(img_path).convert('RGB'))\n    # Load mask (binary): convert to grayscale (0-255)\n    mask = np.array(Image.open(mask_path).convert('L')) \n    mask = (mask > 0).astype(np.uint8)  # ensure binary {0,1}\n    \n    # Prepare figure\n    fig, axes = plt.subplots(1, 3, figsize=(12,4))\n    \n    # Column 1: Original image\n    axes[0].imshow(img, cmap='gray' if img.ndim==2 else None)\n    axes[0].set_title(\"Original\")\n    \n    # Column 2: Mask\n    axes[1].imshow(mask, cmap='gray')\n    axes[1].set_title(\"Mask\")\n    \n    # Column 3: Overlay (original + colored mask on top)\n    axes[2].imshow(img, cmap='gray' if img.ndim==2 else None)\n    axes[2].imshow(mask, cmap=cmap, alpha=alpha)\n    axes[2].set_title(\"Overlay\")\n    \n    # Turn off axis ticks\n    for ax in axes:\n        ax.axis('off')\n    plt.tight_layout()\n    plt.show()\n    plt.close(fig)\n\n# Example usage (replace with your file paths):\n# show_image_mask_overlay('path/to/image.png', 'path/to/mask.png')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:06.269611Z","iopub.execute_input":"2026-01-01T18:03:06.269927Z","iopub.status.idle":"2026-01-01T18:03:06.276313Z","shell.execute_reply.started":"2026-01-01T18:03:06.269908Z","shell.execute_reply":"2026-01-01T18:03:06.275617Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_image_mask_overlay(img_path, mask_path, cmap='Reds', alpha=0.4):\n\n    img = np.array(Image.open(img_path).convert('RGB'))\n    mask = np.array(Image.open(mask_path).convert('L'))\n    mask = (mask > 0).astype(np.uint8)\n\n    # Ensure same size\n    if mask.shape[:2] != img.shape[:2]:\n        mask = np.array(\n            Image.fromarray(mask).resize(\n                (img.shape[1], img.shape[0]),\n                resample=Image.NEAREST\n            )\n        )\n\n    fig, axes = plt.subplots(1, 3, figsize=(12, 4))\n    fig.suptitle(img_path.split(\"/\")[-1], fontsize=12)\n\n    axes[0].imshow(img)\n    axes[0].set_title(\"Original\")\n\n    axes[1].imshow(mask, cmap='gray')\n    axes[1].set_title(\"Mask\")\n\n    axes[2].imshow(img)\n    axes[2].imshow(mask, cmap=cmap, alpha=alpha)\n    axes[2].set_title(\"Overlay\")\n\n    for ax in axes:\n        ax.axis('off')\n\n    plt.tight_layout()\n    plt.show()\n    plt.close(fig)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:06.277074Z","iopub.execute_input":"2026-01-01T18:03:06.277397Z","iopub.status.idle":"2026-01-01T18:03:06.296427Z","shell.execute_reply.started":"2026-01-01T18:03:06.277381Z","shell.execute_reply":"2026-01-01T18:03:06.295828Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TRAIN_FORGED = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/forged\"\nTRAIN_MASKS  = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_masks\"\n\nTEST_IMAGES  = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/test_images\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:06.297034Z","iopub.execute_input":"2026-01-01T18:03:06.297307Z","iopub.status.idle":"2026-01-01T18:03:06.314439Z","shell.execute_reply.started":"2026-01-01T18:03:06.297285Z","shell.execute_reply":"2026-01-01T18:03:06.313775Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img_names = sorted(os.listdir(TRAIN_FORGED))\n\nfor img_name in img_names:\n    img_path = os.path.join(TRAIN_FORGED, img_name)\n    mask_path = os.path.join(TRAIN_MASKS, img_name)\n\n    if not os.path.exists(mask_path):\n        continue\n\n    show_image_mask_overlay(img_path, mask_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:06.315090Z","iopub.execute_input":"2026-01-01T18:03:06.315396Z","iopub.status.idle":"2026-01-01T18:03:06.345711Z","shell.execute_reply.started":"2026-01-01T18:03:06.315380Z","shell.execute_reply":"2026-01-01T18:03:06.345170Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_test_image(img_path):\n    img = np.array(Image.open(img_path).convert('RGB'))\n    plt.figure(figsize=(4,4))\n    plt.imshow(img)\n    plt.title(os.path.basename(img_path))\n    plt.axis('off')\n    plt.show()\n\nfor img_name in os.listdir(TEST_IMAGES):\n    show_test_image(os.path.join(TEST_IMAGES, img_name))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-01T18:03:06.346392Z","iopub.execute_input":"2026-01-01T18:03:06.346630Z","iopub.status.idle":"2026-01-01T18:03:06.682950Z","shell.execute_reply.started":"2026-01-01T18:03:06.346610Z","shell.execute_reply":"2026-01-01T18:03:06.682196Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}