{"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":"none","dataSources":[{"sourceId":91498,"databundleVersionId":11655853,"isSourceIdPinned":false,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# ORB Feature Detection and Matching","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"\n\n### Key Technical Points:\n1. **ORB Advantages**:\n   - Rotation invariant\n   - Computationally efficient\n   - Patent-free (unlike SIFT/SURF)\n\n2. **Matching Process**:\n   - For each descriptor in image1, find closest descriptor in image2\n   - Hamming distance measures bit differences (for binary descriptors)\n\n3. **Visual Interpretation**:\n   - Connected points represent algorithm's best guess at corresponding features\n   - Line colors often indicate match quality\n   - Top matches (shown first) are most reliable\n\nThis fundamental technique forms the basis for many computer vision applications including image stitching, object recognition, and 3D reconstruction. The parameter `matches[:5]` can be adjusted to show more or fewer matches based on requirements.","metadata":{}},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\nimport numpy as np","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-04T13:17:00.057929Z","iopub.execute_input":"2025-05-04T13:17:00.058308Z","iopub.status.idle":"2025-05-04T13:17:00.470794Z","shell.execute_reply.started":"2025-05-04T13:17:00.058263Z","shell.execute_reply":"2025-05-04T13:17:00.469543Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image1_path='/kaggle/input/image-matching-challenge-2025/train/imc2023_haiper/bike_image_137.png'\nimage2_path='/kaggle/input/image-matching-challenge-2025/train/imc2023_haiper/bike_image_139.png'\n\n\nimg1 = cv2.imread(image1_path, cv2.IMREAD_GRAYSCALE)\nimg2 = cv2.imread(image2_path, cv2.IMREAD_GRAYSCALE)\n\n\nimg1 = cv2.resize(img1, (800, 600))\nimg2 = cv2.resize(img2, (800, 600))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-04T13:17:00.471573Z","iopub.execute_input":"2025-05-04T13:17:00.471973Z","iopub.status.idle":"2025-05-04T13:17:00.550140Z","shell.execute_reply.started":"2025-05-04T13:17:00.471944Z","shell.execute_reply":"2025-05-04T13:17:00.548795Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"\n\n#### 1. ORB Feature Initialization and Detection\n```python\norb = cv2.ORB_create()\nkp1, des1 = orb.detectAndCompute(img1, None)\nkp2, des2 = orb.detectAndCompute(img2, None)\n```\n\n- **`cv2.ORB_create()`**: Initializes the ORB (Oriented FAST and Rotated BRIEF) feature detector.\n  - Combines the FAST keypoint detector with BRIEF descriptor\n  - Adds rotation invariance to BRIEF\n  - More efficient than SIFT/SURF while maintaining good performance\n\n- **`detectAndCompute()`**: Performs both feature detection and descriptor computation in one step.\n  - `kp1`, `kp2`: Lists of keypoints (containing location, size, orientation etc.)\n  - `des1`, `des2`: Feature descriptors (numeric representations of local features)\n  - `None`: Optional mask parameter (not used here)\n\n\n","metadata":{}},{"cell_type":"code","source":"orb = cv2.ORB_create()\nkp1, des1 = orb.detectAndCompute(img1, None)\nkp2, des2 = orb.detectAndCompute(img2, None)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-04T13:17:00.552730Z","iopub.execute_input":"2025-05-04T13:17:00.553241Z","iopub.status.idle":"2025-05-04T13:17:00.624190Z","shell.execute_reply.started":"2025-05-04T13:17:00.553194Z","shell.execute_reply":"2025-05-04T13:17:00.622810Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 2. Feature Matching\n```python\nbf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)\nmatches = bf.match(des1, des2)\nmatches = sorted(matches, key=lambda x: x.distance)\n```\n\n- **`cv2.BFMatcher()`**: Creates a Brute-Force matcher object.\n  - `cv2.NORM_HAMMING`: Appropriate distance metric for binary descriptors (ORB)\n  - `crossCheck=True`: Enables mutual consistency check (more reliable matches)\n\n- **`bf.match()`**: Finds the best match for each descriptor.\n  - Returns a list of `DMatch` objects containing:\n    - `.distance`: Similarity measure (lower = better match)\n    - `.queryIdx`: Index in the first image's keypoints\n    - `.trainIdx`: Index in the second image's keypoints\n\n- **`sorted()`**: Orders matches by ascending distance (best matches first)\n","metadata":{}},{"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)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-04T13:17:00.626107Z","iopub.execute_input":"2025-05-04T13:17:00.626674Z","iopub.status.idle":"2025-05-04T13:17:00.644114Z","shell.execute_reply.started":"2025-05-04T13:17:00.626616Z","shell.execute_reply":"2025-05-04T13:17:00.642819Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 3. Visualization\n```python\nmatched_img = cv2.drawMatches(img1, kp1, img2, kp2, matches[:5], None, flags=2)\n```\n\n- **`cv2.drawMatches()`**: Generates a side-by-side visualization.\n  - `matches[:5]`: Only shows the top 5 best matches\n  - `flags=2`: Drawing specification (equivalent to `cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS`)\n    - Only draws matched keypoints\n    - Connects matches with lines","metadata":{}},{"cell_type":"code","source":"matched_img = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-04T13:17:00.645336Z","iopub.execute_input":"2025-05-04T13:17:00.645765Z","iopub.status.idle":"2025-05-04T13:17:00.670350Z","shell.execute_reply.started":"2025-05-04T13:17:00.645722Z","shell.execute_reply":"2025-05-04T13:17:00.669036Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(12,8))#Width,Height\nplt.imshow(matched_img)\nplt.axis('off')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-04T13:19:09.507328Z","iopub.execute_input":"2025-05-04T13:19:09.507796Z","iopub.status.idle":"2025-05-04T13:19:09.801191Z","shell.execute_reply.started":"2025-05-04T13:19:09.507753Z","shell.execute_reply":"2025-05-04T13:19:09.799537Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}