import cv2 as cv import numpy as np import os, sys key_and_desc_cache = {} def getKeyAndDesc(img_path1): global key_and_desc_cache key = img_path1 if key in key_and_desc_cache: pass else: detector = cv.SIFT_create() img1 = cv.imread(img_path1) key_and_desc_cache[key] = detector.detectAndCompute(img1, None) return key_and_desc_cache[key] def SIFT(img_path1, img_path2): try: img1 = cv.imread(img_path1) img2 = cv.imread(img_path2) if img1 is None or img2 is None: print("Error loading images!") exit(0) except: print("Error loading images!") exit(0) # -- Step 1: Detect the keypoints using SIFT Detector, compute the descriptors minHessian = 400 keypoints1, descriptors1 = getKeyAndDesc(img_path1) keypoints2, descriptors2 = getKeyAndDesc(img_path2) # -- Step 2: Matching descriptor vectors with a brute force matcher matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_BRUTEFORCE) matches = matcher.match(descriptors1, descriptors2) # -- Draw matches # img_matches = np.empty((max(img1.shape[0], img2.shape[0]), img1.shape[1] + img2.shape[1], 3), dtype=np.uint8) # cv.drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches) # # -- Show detected matches # cv.imshow("Matches: SIFT (Python)", img_matches) # cv.waitKey() # draw good matches matches = sorted(matches, key=lambda x: x.distance) min_dist = matches[0].distance good_matches = tuple(filter(lambda x: x.distance <= 1.1 * min_dist, matches)) # img_matches = np.empty((max(img1.shape[0], img2.shape[0]), img1.shape[1] + img2.shape[1], 3), dtype=np.uint8) # cv.drawMatches( # img1, keypoints1, img2, keypoints2, good_matches, img_matches, flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS # ) return len(good_matches) # -- Show detected matches # cv.imshow("Good Matches: SIFT (Python)", img_matches) # cv.waitKey()