Skip to content

Instantly share code, notes, and snippets.

@ot32em
Last active December 12, 2022 04:31
Show Gist options
  • Save ot32em/b44fecefd25c49d230ee198ec1cb631e to your computer and use it in GitHub Desktop.
Save ot32em/b44fecefd25c49d230ee198ec1cb631e to your computer and use it in GitHub Desktop.
Play opencv SIFT, SURF, BRISK, or ORB
# Step 1: https://www.python.org/downloads/ => Install Python 3
# Step 2: `python -m pip install --upgrade pip` => Update the pip
# Step 3: `pip install opencv-python` => Install opencv
# Step 4: `pip install opencv-contrib-python` => Install opencv contrib for non-free modules `xfeatures2d`
import numpy as np
import cv2
''' Configure '''
# configure 1/4: show matches or keypoint only
showMatches = True
# configure 2/4: pick a detector
detectorName = ["SIFT", "SURF", "BRISK", "ORB"][2]
# configure 3/4: pick a clip
clip = ["1.mp4", "2.mp4"][0]
''' Feature Detector '''
if detectorName == "SIFT":
detector = cv2.xfeatures2d.SIFT_create(400)
distanceType = cv2.NORM_L2
elif detectorName == "SURF":
detector = cv2.xfeatures2d.SURF_create(400)
distanceType = cv2.NORM_L2
elif detectorName == "BRISK":
detector = cv2.BRISK_create()
distanceType = cv2.NORM_HAMMING
else:
detector = cv2.ORB_create()
distanceType = cv2.NORM_HAMMING
cap = cv2.VideoCapture(clip)
''' Matcher '''
if showMatches:
bf = cv2.BFMatcher(distanceType, crossCheck=True)
''' 1st frame as reference frame '''
ret, frame1 = cap.read()
kp1, des1 = detector.detectAndCompute(frame1, None)
while(1):
''' 2nd-nth Running frames '''
ret, frame2 = cap.read()
if showMatches:
kp2, des2 = detector.detectAndCompute(frame2, None)
matches = bf.match(des1, des2)
matches = selectMatcheInPts(matches, kp1)
img2 = cv2.drawMatches(frame1, kp1, frame2, kp2, matches, None, flags=2)
else:
img2 = cv2.drawKeypoints(frame2, kp, None, color=(0,255,0), flags=0)
cv2.imshow(detectorName, img2)
k = cv2.waitKey(0) & 0xff
if k == 27: # press esc to exit
break
cap.release()
cv2.destroyAllWindows()
# optional configure 4/4: only select matches around the pts or select all
def selectMatcheInPts(matches, kps, pts):
pts = [] # empty means no filter
# pts = [(300, 190), (273, 430), (781, 145), (790, 387)]
if pts:
return [match in matches
if any( x-10 < kps[match.queryIdx].pt[0] < x+10 and y-10 < kp1[match.queryIdx].pt[1] < y+10 for x, y in pts)]
else:
return matches
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment