{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":91498,"databundleVersionId":11655853,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport os \nimport cv2\nfrom PIL import Image","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:12:27.598727Z","iopub.execute_input":"2025-04-13T02:12:27.599035Z","iopub.status.idle":"2025-04-13T02:12:28.400461Z","shell.execute_reply.started":"2025-04-13T02:12:27.599013Z","shell.execute_reply":"2025-04-13T02:12:28.399657Z"}},"outputs":[],"execution_count":2},{"cell_type":"code","source":"train_labels = pd.read_csv('/kaggle/input/image-matching-challenge-2025/train_labels.csv')\ntrain_labels.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:12:30.05931Z","iopub.execute_input":"2025-04-13T02:12:30.059762Z","iopub.status.idle":"2025-04-13T02:12:30.106253Z","shell.execute_reply.started":"2025-04-13T02:12:30.059713Z","shell.execute_reply":"2025-04-13T02:12:30.105578Z"}},"outputs":[{"execution_count":3,"output_type":"execute_result","data":{"text/plain":"          dataset     scene                   image  \\\n0  imc2023_haiper  fountain  fountain_image_116.png   \n1  imc2023_haiper  fountain  fountain_image_108.png   \n2  imc2023_haiper  fountain  fountain_image_101.png   \n3  imc2023_haiper  fountain  fountain_image_082.png   \n4  imc2023_haiper  fountain  fountain_image_071.png   \n\n                                     rotation_matrix  \\\n0  0.122655949;0.947713775;-0.294608417;0.1226706...   \n1  0.474305910;0.359108654;-0.803787832;0.2888416...   \n2  0.565115476;-0.138485064;-0.813305838;0.506678...   \n3  -0.308320392;-0.794654112;0.522937261;0.948141...   \n4  -0.569002830;-0.103808175;0.815757098;0.778745...   \n\n                      translation_vector  \n0   0.093771314;-0.803560988;2.062001533  \n1   0.358946647;-0.797557548;1.910906929  \n2   0.146922468;-0.981392596;2.009002852  \n3   0.206413831;-1.174321103;3.667167680  \n4  -0.015140892;-1.334052012;3.488936597  ","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>dataset</th>\n      <th>scene</th>\n      <th>image</th>\n      <th>rotation_matrix</th>\n      <th>translation_vector</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>imc2023_haiper</td>\n      <td>fountain</td>\n      <td>fountain_image_116.png</td>\n      <td>0.122655949;0.947713775;-0.294608417;0.1226706...</td>\n      <td>0.093771314;-0.803560988;2.062001533</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>imc2023_haiper</td>\n      <td>fountain</td>\n      <td>fountain_image_108.png</td>\n      <td>0.474305910;0.359108654;-0.803787832;0.2888416...</td>\n      <td>0.358946647;-0.797557548;1.910906929</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>imc2023_haiper</td>\n      <td>fountain</td>\n      <td>fountain_image_101.png</td>\n      <td>0.565115476;-0.138485064;-0.813305838;0.506678...</td>\n      <td>0.146922468;-0.981392596;2.009002852</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>imc2023_haiper</td>\n      <td>fountain</td>\n      <td>fountain_image_082.png</td>\n      <td>-0.308320392;-0.794654112;0.522937261;0.948141...</td>\n      <td>0.206413831;-1.174321103;3.667167680</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>imc2023_haiper</td>\n      <td>fountain</td>\n      <td>fountain_image_071.png</td>\n      <td>-0.569002830;-0.103808175;0.815757098;0.778745...</td>\n      <td>-0.015140892;-1.334052012;3.488936597</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}],"execution_count":3},{"cell_type":"markdown","source":"## Scene Summary (for reference only)","metadata":{}},{"cell_type":"code","source":"train_labels['scene'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:12:33.634106Z","iopub.execute_input":"2025-04-13T02:12:33.634398Z","iopub.status.idle":"2025-04-13T02:12:33.645905Z","shell.execute_reply.started":"2025-04-13T02:12:33.634377Z","shell.execute_reply":"2025-04-13T02:12:33.645079Z"}},"outputs":[{"execution_count":4,"output_type":"execute_result","data":{"text/plain":"scene\npeach                   200\ndioscuri                140\noutliers                122\nst_peters_square        100\ngrand_place_brussels    100\nst_pauls_cathedral      100\nlizard                   90\npond                     90\nvineyard_split_3         85\ntrevi_fountain           75\nbrandenburg_gate         75\ntaj_mahal                75\nbritish_museum           75\nbuckingham_palace        75\nsacre_coeur              75\npiazza_san_marco         68\nchurch                   50\nbaalshamin               49\nvineyard_split_1         43\nwall                     43\nvineyard_split_2         35\ncyprus                   30\nstairs_split_1           28\nkyiv-puppet-theater      26\nfountain                 23\nstairs_split_2           23\nchairs                   16\nbike                     15\nanother_ET               10\nET                        9\nName: count, dtype: int64"},"metadata":{}}],"execution_count":4},{"cell_type":"code","source":"dataset_path = \"/kaggle/input\"\ndata_files = os.listdir(dataset_path)\nprint(\"Files and folders in the dataset path:\",data_files)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:12:56.196602Z","iopub.execute_input":"2025-04-13T02:12:56.196921Z","iopub.status.idle":"2025-04-13T02:12:56.201933Z","shell.execute_reply.started":"2025-04-13T02:12:56.196898Z","shell.execute_reply":"2025-04-13T02:12:56.201074Z"}},"outputs":[{"name":"stdout","text":"Files and folders in the dataset path: ['image-matching-challenge-2025']\n","output_type":"stream"}],"execution_count":5},{"cell_type":"code","source":"print(os.listdir(\"/kaggle/input/image-matching-challenge-2025\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:14:20.094638Z","iopub.execute_input":"2025-04-13T02:14:20.09494Z","iopub.status.idle":"2025-04-13T02:14:20.100271Z","shell.execute_reply.started":"2025-04-13T02:14:20.094917Z","shell.execute_reply":"2025-04-13T02:14:20.099333Z"}},"outputs":[{"name":"stdout","text":"['sample_submission.csv', 'train_thresholds.csv', 'train_labels.csv', 'test', 'train']\n","output_type":"stream"}],"execution_count":8},{"cell_type":"code","source":"print(os.path.exists(f\"/kaggle/input/image-matching-challenge-2025/train/fountain/fountain_0123.png\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:14:22.058333Z","iopub.execute_input":"2025-04-13T02:14:22.058635Z","iopub.status.idle":"2025-04-13T02:14:22.062885Z","shell.execute_reply.started":"2025-04-13T02:14:22.058608Z","shell.execute_reply":"2025-04-13T02:14:22.062026Z"}},"outputs":[{"name":"stdout","text":"False\n","output_type":"stream"}],"execution_count":9},{"cell_type":"code","source":"valid_scenes = []\nscene_counts = train_labels['scene'].value_counts().to_dict()\n\nfor scene, count in scene_counts.items():\n    imgs = train_labels[train_labels['scene'] == scene]['image'].values.tolist()[:2]\n\n    if len(imgs) < 2:\n        continue\n\n    path1 = f\"/kaggle/input/image-matching-challenge-2025/train/{scene}/{imgs[0]}\"\n    path2 = f\"/kaggle/input/image-matching-challenge-2025/train/{scene}/{imgs[1]}\"\n\n    if os.path.exists(path1) and os.path.exists(path2):\n        valid_scenes.append(scene)\n\nprint(\"Valid scenes with at least 2 images loaded:\", valid_scenes)\n\nscene_name = valid_scenes[0]\nprint(\"Selected scene:\", scene_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:15:04.16461Z","iopub.execute_input":"2025-04-13T02:15:04.16497Z","iopub.status.idle":"2025-04-13T02:15:04.236382Z","shell.execute_reply.started":"2025-04-13T02:15:04.164941Z","shell.execute_reply":"2025-04-13T02:15:04.23535Z"}},"outputs":[{"name":"stdout","text":"Valid scenes with at least 2 images loaded: []\n","output_type":"stream"},{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)","\u001b[0;32m<ipython-input-10-11b0f2fd1650>\u001b[0m in \u001b[0;36m<cell line: 18>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     16\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Valid scenes with at least 2 images loaded:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalid_scenes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     17\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0mscene_name\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalid_scenes\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     19\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Selected scene:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mscene_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mIndexError\u001b[0m: list index out of range"],"ename":"IndexError","evalue":"list index out of range","output_type":"error"}],"execution_count":10},{"cell_type":"code","source":"scene_name = \"peach\"\nimage_dir = f\"/kaggle/input/image-matching-challenge-2025/train/{scene_name}\"\n\nall_images = train_labels[train_labels[\"scene\"] == scene_name][\"image\"].values.tolist()\nscene_images = []\n\nfor image in all_images:\n    if os.path.exists(f\"{image_dir}/{image}\"):\n        scene_images.append(image)\n    if len(scene_images) == 2:\n        break\n\nfig, axes = plt.subplots(1, 2, figsize=(12, 5))\n\nfor i, image_name in enumerate(scene_images):\n    img_path = f\"{image_dir}/{image_name}\"\n    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)\n    axes[i].imshow(img, cmap=\"gray\")\n    axes[i].set_title(image_name)\n    axes[i].axis(\"off\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T02:15:26.938338Z","iopub.execute_input":"2025-04-13T02:15:26.938617Z","iopub.status.idle":"2025-04-13T02:15:27.264596Z","shell.execute_reply.started":"2025-04-13T02:15:26.938596Z","shell.execute_reply":"2025-04-13T02:15:27.263797Z"}},"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 1200x500 with 2 Axes>","image/png":"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\n"},"metadata":{}}],"execution_count":11},{"cell_type":"code","source":"orb = cv2.ORB_create()\n\nfor image_name in scene_images:\n    img_path = f\"/kaggle/input/image-matching-challenge-2025/train/{scene_name}/{image_name}\"\n    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)\n\n    if img is None:\n        print(\"One of the images was not loaded!\")\n        print(\"img path:\", img_path)\n        continue\n\n    kp, des = orb.detectAndCompute(img, None)\n    img_with_kp = cv2.drawKeypoints(img, kp, None, color=(0,255,0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n\n    plt.figure(figsize=(6, 6))\n    plt.imshow(img_with_kp, cmap='gray')\n    plt.title(f\"Keypoints: {image_name}\")\n    plt.axis('off')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T01:18:33.630688Z","iopub.status.idle":"2025-04-13T01:18:33.630962Z","shell.execute_reply":"2025-04-13T01:18:33.630854Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)\nmatches = bf.match(des1, des2)\nmatches = sorted(matches, key=lambda x: x.distance)\n\nif img1 is None or img2 is None:\n    print(\"One of the images is missing, skipping drawMatches.\")\nelse:\n    img_matches = cv2.drawMatches(img1, kp1, img2, kp2, matches[:20], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)\n    plt.figure(figsize=(14, 6))\n    plt.imshow(img_matches)\n    plt.title('Top 20 Feature Matches')\n    plt.axis('off')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T01:18:33.631916Z","iopub.status.idle":"2025-04-13T01:18:33.632323Z","shell.execute_reply":"2025-04-13T01:18:33.632144Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\n\ndef rank_keypoints_by_harris(img, keypoints, top_k=20):\n    if img is None:\n        print(\"Image not loaded properly!\")\n        return []\n \n    gray = np.float32(img)\n \n    harris_response = cv2.cornerHarris(gray, blockSize=2, ksize=3, k=0.04)\n\n    keypoint_scores = []\n    for kp in keypoints:\n        x, y = int(kp.pt[0]), int(kp.pt[1])\n        if 0 <= y < harris_response.shape[0] and 0 <= x < harris_response.shape[1]:\n            score = harris_response[y, x]\n            keypoint_scores.append((score, kp))\n\n    keypoint_scores = sorted(keypoint_scores, key=lambda x: x[0], reverse=True)\n    ranked_keypoints = [kp for _, kp in keypoint_scores[:top_k]]\n    return ranked_keypoints","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T01:18:33.633048Z","iopub.status.idle":"2025-04-13T01:18:33.633355Z","shell.execute_reply":"2025-04-13T01:18:33.633213Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if img1 is None or img2 is None:\n    print(\"Image not loaded properly!\")\nelse:\n\n    kp1_top = rank_keypoints_by_harris(img1, kp1, top_k=20)\n    kp2_top = rank_keypoints_by_harris(img2, kp2, top_k=20)\n\n    img1_top = cv2.drawKeypoints(img1, kp1_top, None, color=(255, 0, 0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n    img2_top = cv2.drawKeypoints(img2, kp2_top, None, color=(255, 0, 0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n\n    fig, axes = plt.subplots(1, 2, figsize=(14, 6))\n    axes[0].imshow(img1_top, cmap='gray')\n    axes[0].set_title(\"Top 20 Keypoints - Image 1\")\n    axes[1].imshow(img2_top, cmap='gray')\n    axes[1].set_title(\"Top 20 Keypoints - Image 2\")\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T01:18:33.634328Z","iopub.status.idle":"2025-04-13T01:18:33.634685Z","shell.execute_reply":"2025-04-13T01:18:33.634532Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **RESULTS AND SUMMARY**","metadata":{}},{"cell_type":"code","source":"scene_name = \"st_pauls_cathedral\"\n\nscene_images = train_labels[train_labels[\"scene\"] == scene_name][\"image\"].values.tolist()[:2]\n\nimg1_path = f\"/kaggle/input/image-matching-challenge-2025/train/{scene_name}/{scene_images[0]}\"\nimg2_path = f\"/kaggle/input/image-matching-challenge-2025/train/{scene_name}/{scene_images[1]}\"\nimg1 = cv2.imread(img1_path, cv2.IMREAD_GRAYSCALE)\nimg2 = cv2.imread(img2_path, cv2.IMREAD_GRAYSCALE)\n\nif img1 is None or img2 is None:\n    print(\"Image not loaded properly!\")\nelse:\n    kp1_top = rank_keypoints_by_harris(img1, kp1, top_k=20)\n    kp2_top = rank_keypoints_by_harris(img2, kp2, top_k=20)\n\n    img1_top = cv2.drawKeypoints(img1, kp1_top, None, color=(255, 0, 0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n    img2_top = cv2.drawKeypoints(img2, kp2_top, None, color=(255, 0, 0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)\n\n    fig, axes = plt.subplots(1, 2, figsize=(14, 6))\n    axes[0].imshow(img1_top, cmap='gray')\n    axes[0].set_title(\"Top 20 Keypoints - Image 1\")\n    axes[1].imshow(img2_top, cmap='gray')\n    axes[1].set_title(\"Top 20 Keypoints - Image 2\")\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T01:18:33.635344Z","iopub.status.idle":"2025-04-13T01:18:33.635623Z","shell.execute_reply":"2025-04-13T01:18:33.635526Z"}},"outputs":[],"execution_count":null}]}