import cv2 import numpy as np import gradio as gr def sift_ransac_matching(image, template): # Convert to grayscale gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray_template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) # Initialize SIFT detector sift = cv2.SIFT_create() # Find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(gray_image, None) kp2, des2 = sift.detectAndCompute(gray_template, None) # BFMatcher with default params bf = cv2.BFMatcher() matches = bf.knnMatch(des1, des2, k=2) # Apply ratio test good_matches = [] for m, n in matches: if m.distance < 0.75 * n.distance: good_matches.append(m) if len(good_matches) > 4: # Extract location of good matches src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) # Use RANSAC to find homography M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) if M is not None: # Compute the match score num_matches = np.sum(mask) match_score = num_matches / len(good_matches) # Matching score as a ratio # Set a threshold for match score threshold = 0.8 # Adjust this threshold as needed # Determine if the template is found based on the match score if match_score >= threshold: return "Template found" else: return "Template not found" else: return "Template not found" else: return "Not enough good matches are found. Template not found" # Gradio interface iface = gr.Interface( fn=sift_ransac_matching, inputs=[ gr.Image(type="numpy", label="Image"), gr.Image(type="numpy", label="Template"), ], outputs=gr.Text(label="Result"), title="Advanced Template Matching", description="Upload an image and a template to check if the template is present in the image using SIFT and RANSAC.", ) iface.launch()