|
import cv2
|
|
import numpy as np
|
|
import gradio as gr
|
|
|
|
def sift_ransac_matching(image, template):
|
|
|
|
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
|
gray_template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
|
|
|
|
|
|
sift = cv2.SIFT_create()
|
|
|
|
|
|
kp1, des1 = sift.detectAndCompute(gray_image, None)
|
|
kp2, des2 = sift.detectAndCompute(gray_template, None)
|
|
|
|
|
|
bf = cv2.BFMatcher()
|
|
matches = bf.knnMatch(des1, des2, k=2)
|
|
|
|
|
|
good_matches = []
|
|
for m, n in matches:
|
|
if m.distance < 0.75 * n.distance:
|
|
good_matches.append(m)
|
|
|
|
if len(good_matches) > 4:
|
|
|
|
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)
|
|
|
|
|
|
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
|
|
|
|
if M is not None:
|
|
|
|
num_matches = np.sum(mask)
|
|
match_score = num_matches / len(good_matches)
|
|
|
|
|
|
threshold = 0.8
|
|
|
|
|
|
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"
|
|
|
|
|
|
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()
|
|
|