{"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":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 🧭 Dataset Overview\n\nThe dataset contains three folders for training and one for testing:\n```\ntrain_images/\n ├── authentic/   → Genuine (unaltered) images in png format  \n ├── forged/      → Manipulated (forged) images in png format  \ntrain_masks/      → Binary masks highlighting forged regions in npy format  \n\ntest_images/      → Images for which predictions must be made\n```\n","metadata":{}},{"cell_type":"markdown","source":"# 🎯 Task Objective\nFor each image in `test_images/`, your goal is to:\n\n1. Classify whether the image is authentic or forged.\n\n2. If the image is forged, predict the corresponding mask and put into the submission file as run length encoded masks.\n\nHere's what the sample submission file looks like:","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\nsample_submission = pd.read_csv(\"/kaggle/input/recodai-luc-scientific-image-forgery-detection/sample_submission.csv\")\nsample_submission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:35:56.849093Z","iopub.execute_input":"2025-11-09T12:35:56.849724Z","iopub.status.idle":"2025-11-09T12:35:56.880368Z","shell.execute_reply.started":"2025-11-09T12:35:56.849697Z","shell.execute_reply":"2025-11-09T12:35:56.879488Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# A Few Samples from Dataset","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport PIL\nfrom PIL import Image\nimport seaborn as sns\nimport os\nimport numpy as np\n\ndef show_images(i):\n    path_a = f\"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/authentic/{i}.png\"\n    path_b = f\"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/forged/{i}.png\"\n    path_c = f\"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_masks/{i}.npy\"\n    \n    # Open images using PIL\n    img_a = Image.open(path_a).convert(\"RGB\")\n    img_b = Image.open(path_b).convert(\"RGB\")\n    \n    # Load mask (assuming shape like [1, H, W] or [H, W])\n    mask_array = np.load(path_c)\n    if mask_array.ndim == 3:\n        mask_array = mask_array[0]\n    mask_array = (mask_array * 255).astype(np.uint8)\n\n    # Convert mask to red RGBA\n    red_mask = np.zeros((*mask_array.shape, 4), dtype=np.uint8)\n    red_mask[..., 0] = 255                         # Red channel\n    red_mask[..., 3] = (mask_array > 0) * 66      # Alpha (transparency)\n\n    red_mask_img = Image.fromarray(red_mask)\n\n    # Overlay red mask on forged image\n    img_overlay = Image.alpha_composite(img_b.convert(\"RGBA\"), red_mask_img)\n\n    # Create a figure with 1 row and 4 columns\n    fig, axes = plt.subplots(1, 4, figsize=(16, 4))\n\n    # Define titles and images\n    titles = ['Authentic', 'Forged', 'Mask', 'Overlay']\n    images = [img_a, img_b, Image.fromarray(mask_array), img_overlay]\n\n    # Display each image with its title\n    for ax, img, title in zip(axes, images, titles):\n        ax.imshow(img)\n        ax.set_title(title, fontsize=14)\n        ax.axis('off')\n\n    plt.tight_layout()\n    plt.show()\n\n    print()\n    print(\"Authentic Image Path:\", f\"train_images/authentic/{i}.png\")\n    print(\"Forged Image Path:\", f\"train_images/forged/{i}.png\")\n    print(\"Binary Mask Path:\", f\"train_masks/{i}.npy\")","metadata":{"trusted":true,"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(19933)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:00.081111Z","iopub.execute_input":"2025-11-09T12:40:00.081397Z","iopub.status.idle":"2025-11-09T12:40:00.447860Z","shell.execute_reply.started":"2025-11-09T12:40:00.081378Z","shell.execute_reply":"2025-11-09T12:40:00.446905Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(54545)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:01.573030Z","iopub.execute_input":"2025-11-09T12:40:01.573330Z","iopub.status.idle":"2025-11-09T12:40:02.109713Z","shell.execute_reply.started":"2025-11-09T12:40:01.573309Z","shell.execute_reply":"2025-11-09T12:40:02.108815Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(20578)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:03.084343Z","iopub.execute_input":"2025-11-09T12:40:03.084715Z","iopub.status.idle":"2025-11-09T12:40:04.283149Z","shell.execute_reply.started":"2025-11-09T12:40:03.084690Z","shell.execute_reply":"2025-11-09T12:40:04.282043Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(42698)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:04.796293Z","iopub.execute_input":"2025-11-09T12:40:04.796633Z","iopub.status.idle":"2025-11-09T12:40:05.086495Z","shell.execute_reply.started":"2025-11-09T12:40:04.796604Z","shell.execute_reply":"2025-11-09T12:40:05.085465Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(5151)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:04.284389Z","iopub.execute_input":"2025-11-09T12:40:04.284630Z","iopub.status.idle":"2025-11-09T12:40:04.794906Z","shell.execute_reply.started":"2025-11-09T12:40:04.284613Z","shell.execute_reply":"2025-11-09T12:40:04.794033Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(7127)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:07.108156Z","iopub.execute_input":"2025-11-09T12:40:07.108457Z","iopub.status.idle":"2025-11-09T12:40:07.872278Z","shell.execute_reply.started":"2025-11-09T12:40:07.108438Z","shell.execute_reply":"2025-11-09T12:40:07.871055Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(21968)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:07.873996Z","iopub.execute_input":"2025-11-09T12:40:07.874261Z","iopub.status.idle":"2025-11-09T12:40:08.339460Z","shell.execute_reply.started":"2025-11-09T12:40:07.874240Z","shell.execute_reply":"2025-11-09T12:40:08.338528Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(29281)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:09.163841Z","iopub.execute_input":"2025-11-09T12:40:09.164124Z","iopub.status.idle":"2025-11-09T12:40:09.670732Z","shell.execute_reply.started":"2025-11-09T12:40:09.164105Z","shell.execute_reply":"2025-11-09T12:40:09.669640Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(63839)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:08.611114Z","iopub.execute_input":"2025-11-09T12:40:08.611627Z","iopub.status.idle":"2025-11-09T12:40:09.148977Z","shell.execute_reply.started":"2025-11-09T12:40:08.611593Z","shell.execute_reply":"2025-11-09T12:40:09.147666Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(37448)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:10.902553Z","iopub.execute_input":"2025-11-09T12:40:10.902896Z","iopub.status.idle":"2025-11-09T12:40:11.919356Z","shell.execute_reply.started":"2025-11-09T12:40:10.902874Z","shell.execute_reply":"2025-11-09T12:40:11.918389Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(1041)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:40:12.003872Z","iopub.execute_input":"2025-11-09T12:40:12.004202Z","iopub.status.idle":"2025-11-09T12:40:12.321904Z","shell.execute_reply.started":"2025-11-09T12:40:12.004179Z","shell.execute_reply":"2025-11-09T12:40:12.320848Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Distribution of Image height & width","metadata":{}},{"cell_type":"code","source":"D = \"/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/authentic\"\n\nheights = []\nwidths = []\nfor path in os.listdir(D):\n    img = Image.open(os.path.join(D, path))\n    width, height = img.size\n    heights.append(height)\n    widths.append(width)\n\nx, y = widths, heights\n    \nx_label, y_label = \"Image Width\", \"Image Height\"\n    \ndf = pd.DataFrame({x_label: x, y_label: y})\n\n# Create the main figure and GridSpec with adjustable ratios\nfig = plt.figure(figsize=(8, 8))\n\n# Define relative heights (rows) and widths (cols)\n# smaller height for top box, smaller width for right box\ngrid = plt.GridSpec(\n    4, 4,\n    hspace=0.05,\n    wspace=0.05,\n    height_ratios=[0.3, 1, 1, 1],   # top row smaller (0.3)\n    width_ratios=[1, 1, 1, 0.3]     # right column smaller (0.3)\n)\n\n# Define axes\nmain_ax = fig.add_subplot(grid[1:, :-1])     # scatter plot\nx_box  = fig.add_subplot(grid[0, :-1], sharex=main_ax)  # top box\ny_box  = fig.add_subplot(grid[1:, -1], sharey=main_ax)  # right box\n\n# Main scatter plot\nsns.scatterplot(x=x_label, y=y_label, data=df, ax=main_ax, s=40, alpha=0.6)\n\n# Top box plot (horizontal orientation)\nsns.boxplot(x=x_label, data=df, ax=x_box, orient='h')\nx_box.tick_params(axis=\"x\", labelbottom=False)\n\n# Right box plot (vertical orientation)\nsns.boxplot(y=y_label, data=df, ax=y_box, orient='v')\ny_box.tick_params(axis=\"y\", labelleft=False)\n\n# Titles and labels\nmain_ax.set_xlabel(x_label)\nmain_ax.set_ylabel(y_label)\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T12:20:17.463836Z","iopub.execute_input":"2025-11-09T12:20:17.464143Z","iopub.status.idle":"2025-11-09T12:20:17.854426Z","shell.execute_reply.started":"2025-11-09T12:20:17.464120Z","shell.execute_reply":"2025-11-09T12:20:17.853248Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null}]}