How to use surf and sift detector in OpenCV for Python
Asked Answered
M

4

8

I was trying a code for feature matching which uses the function SURF(). Upon execution it gives an error saying "AttributeError: 'module' object has no attribute 'SURF'".

How can I download this module for Python (Windows) and fix this error?

Mcclees answered 12/11, 2015 at 11:17 Comment(0)
F
12

You can try ORB (Oriented FAST and Rotated BRIEF) as an alternate to SURF in open cv. It almost works as good as SURF and SIFT and it's free unlike SIFT and SURF which are patented and can't be used commercially.
You can read about it more in opencv-python documentation here

Here's the sample code for your ease

import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('text.png',cv2.COLOR_BGR2GRAY) # queryImage
img2 = cv2.imread('original.png',cv2.COLOR_BGR2GRAY) # trainImage
# Initiate SIFT detector
orb = cv2.ORB_create()

# find the keypoints and descriptors with SIFT
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)

# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance) 
# Draw first 10 matches.
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10],None, flags=2)

plt.imshow(img3),plt.show()
Frown answered 12/11, 2015 at 11:23 Comment(4)
Does it work in opencv 2.7 or 2.4? Because I am getting the same error for ORB.Mcclees
I've used it with open cv 3.0Frown
Meanwhile, a few years into the future, the brilliant eggheads at openCV came up with another solution. 2 actually, KAZE and AKAZE. worth looking in to.Tallinn
FYI, the patent for SIFT has run out and has thus been moved from the contrib to the main repository. answers.opencv.org/question/227302/…Wilmerwilmette
U
0

At first

pip install opencv-contrib-python

and then use this hack to create sift object

sift = cv2.xfeatures2d.SIFT_create()
Ugaritic answered 7/12, 2017 at 10:43 Comment(2)
I didn't know about that...gonna test it out!Medford
SIFT and SURF are no longer included in OpenCV Version >= 3. If you want to use them you have to manually compile OpenCV with contrib-modules and OPENCV_ENABLE_NONFREE CMake flag turned on.Rooney
P
0
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('simple.jpg',0)
# Initiate FAST object with default values
fast = cv.FastFeatureDetector_create()
# find and draw the keypoints
kp = fast.detect(img,None)
img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
# Print all default params
print( "Threshold: {}".format(fast.getThreshold()) )
print( "nonmaxSuppression:{}".format(fast.getNonmaxSuppression()) )
print( "neighborhood: {}".format(fast.getType()) )
print( "Total Keypoints with nonmaxSuppression: {}".format(len(kp)) )
cv.imwrite('fast_true.png',img2)
#Disable nonmaxSuppression
fast.setNonmaxSuppression(0)
kp = fast.detect(img,None)
print( "Total Keypoints without nonmaxSuppression: {}".format(len(kp)) )
img3 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
cv.imwrite('fast_false.png',img3)
Pampero answered 3/12, 2020 at 6:15 Comment(0)
H
0

According to this source SIFT patent expired. SIFT should be implemented in the main opencv repository by now. At least cv.SIFT_create() init is working for me. I have opencv version 4.5.5.

Example use with possible combination with other descriptors or detectors(alternative to detectAndCompute() function)

import cv2 as cv
MAX_FEATURES = 5500
GOOD_MATCH_PERCENT = 0.03

def find_matches(im1, im2, detector_type: str, descriptor_type: str):
    # Convert images to grayscale
    im1Gray = cv.cvtColor(im1, cv.COLOR_BGR2GRAY)
    im2Gray = cv.cvtColor(im2, cv.COLOR_BGR2GRAY)

    # init detector
    if detector_type == 'sift':
            detector = cv.SIFT_create(MAX_FEATURES)
    elif detector_type == 'fast':
            detector = cv.FastFeatureDetector_create()
    # ... ORB etc.
    # init descriptor
    if descriptor_type == 'sift':
            descriptor = cv.SIFT_create(MAX_FEATURES)

    keypoints1 = detector.detect(im1Gray, None)
    keypoints2 = detector.detect(im2Gray, None)

    # find descriptors with descriptor SIFT
    keypoints1, descriptors1 = descriptor.compute(im1Gray, keypoints1)
    keypoints2, descriptors2 = descriptor.compute(im2Gray, keypoints2)

    # BFMatcher object
    matcher = cv.BFMatcher(cv.NORM_L1, crossCheck=True)
    matches = list(matcher.match(descriptors1, descriptors2))

    # Sort matches by score
    matches.sort(key=lambda x: x.distance, reverse=False)
    # Remove not so good matches
    numGoodMatches = int(len(matches) * GOOD_MATCH_PERCENT)
    matches = matches[:numGoodMatches]

    # Draw top matches
    imMatches = cv.drawMatches(
        im1, keypoints1, im2, keypoints2, matches, None)
    cv.imwrite("matches.jpg", imMatches)
Hardboard answered 24/3, 2022 at 23:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.