为什么ORB没有给我比SURF更好的结果?

时间:2019-07-11 09:45:48

标签: python opencv computer-vision surf orb

我正在尝试提取任何给定图像或视频帧的特征。我已经阅读了许多有关基于点特征的对象跟踪的论文和文章。最后,我决定使用ORB。这是因为,大多数人在他们的论文中说,ORB比所有特征提取算法都要好。

当我使用ORB时,效果不佳。然后,我决定尝试SURF方法。当我使用SURF时,它给了我很好的效果。

我想知道我的代码有什么问题。我将与您分享代码冲浪和球体。请查看我的代码并注释掉我的错误。

SURF结果

SURF Result

ORB结果

ORB Result

# With SURF Detector

import cv2
import numpy as np

# Initialize parameters for Flann based matcher
FLANN_INDEX_KDTREE = 0

flann_params= dict(algorithm = FLANN_INDEX_KDTREE,
                   table_number = 6, # 12
                   key_size = 12,     # 20
                   trees = 5,
                   multi_probe_level = 1) #2

draw_params = dict(matchesMask=None,
                   singlePointColor=None,
                   matchColor=(255, 0, 0),
                   flags=2)

MIN_MATCH_COUNT = 10

img_object = cv2.imread('form1.jpg', cv2.IMREAD_GRAYSCALE)
img_scene = cv2.imread('form2.jpg', cv2.IMREAD_GRAYSCALE)

if img_object is None or img_scene is None:
    print('Could not open or find the images!')
    exit(0)

#-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
minHessian = 400
detector = cv2.xfeatures2d_SURF.create(hessianThreshold=minHessian)
keypoints_obj, descriptors_obj = detector.detectAndCompute(img_object, None)
keypoints_scene, descriptors_scene = detector.detectAndCompute(img_scene, None)

#-- Step 2: Matching descriptor vectors with a FLANN based matcher
matcher = cv2.FlannBasedMatcher(flann_params, {})                
knn_matches = matcher.knnMatch(descriptors_obj, descriptors_scene, 2)

#-- Filter matches using the Lowe's ratio test
ratio_thresh = 0.75
good_matches = []
for m,n in knn_matches:
    if m.distance < ratio_thresh * n.distance:
        good_matches.append(m)

#-- Draw matches
img_matches = np.empty((max(img_object.shape[0], img_scene.shape[0]), img_object.shape[1]+img_scene.shape[1], 3), dtype=np.uint8)
cv2.drawMatches(img_object, keypoints_obj, img_scene, keypoints_scene, good_matches[:10], img_matches, **draw_params)


if len(good_matches) > MIN_MATCH_COUNT:
    obj_pts = np.float32([ keypoints_obj[good_match.queryIdx].pt for good_match in good_matches ]).reshape(-1,1,2)
    scene_pts = np.float32([ keypoints_scene[good_match.trainIdx].pt for good_match in good_matches ]).reshape(-1,1,2)

H, _ =  cv2.findHomography(obj_pts, scene_pts, cv2.RANSAC, 5.0)

#-- Get the corners from the image_1 ( the object to be "detected" )
obj_corners = np.empty((4,1,2), dtype=np.float32)

obj_corners[0,0,0] = 0
obj_corners[0,0,1] = 0
obj_corners[1,0,0] = img_object.shape[1] # img.shape[1] shows the column of the image
obj_corners[1,0,1] = 0
obj_corners[2,0,0] = img_object.shape[1]
obj_corners[2,0,1] = img_object.shape[0] # img.shape[0] shows the row of the image
obj_corners[3,0,0] = 0
obj_corners[3,0,1] = img_object.shape[0]

scene_corners = cv2.perspectiveTransform(obj_corners, H)

#-- Draw lines between the corners (the mapped object in the scene - image_2 )
cv2.line(img_matches, (int(scene_corners[0,0,0] + img_object.shape[1]), int(scene_corners[0,0,1])),\
    (int(scene_corners[1,0,0] + img_object.shape[1]), int(scene_corners[1,0,1])), (0,255,0), 4)
cv2.line(img_matches, (int(scene_corners[1,0,0] + img_object.shape[1]), int(scene_corners[1,0,1])),\
    (int(scene_corners[2,0,0] + img_object.shape[1]), int(scene_corners[2,0,1])), (0,255,0), 4)
cv2.line(img_matches, (int(scene_corners[2,0,0] + img_object.shape[1]), int(scene_corners[2,0,1])),\
    (int(scene_corners[3,0,0] + img_object.shape[1]), int(scene_corners[3,0,1])), (0,255,0), 4)
cv2.line(img_matches, (int(scene_corners[3,0,0] + img_object.shape[1]), int(scene_corners[3,0,1])),\
    (int(scene_corners[0,0,0] + img_object.shape[1]), int(scene_corners[0,0,1])), (0,255,0), 4)

#-- Show detected matches
cv2.imshow('Good Matches With SURF Detector', img_matches)
cv2.imwrite('SURF_Matches.jpg', img_matches)
cv2.waitKey()
# With ORB Detector

import cv2
import numpy as np


# Initialize parameters for Flann based matcher
FLANN_INDEX_KDTREE = 1
FLANN_INDEX_LSH    = 6

flann_params= dict(algorithm = FLANN_INDEX_LSH,
                   table_number = 6, # 12
                   key_size = 12,     # 20
                   multi_probe_level = 1) #2

draw_params = dict(matchesMask=None,
                singlePointColor=None,
                matchColor=(255, 0, 0),
                flags=2)

MIN_MATCH_COUNT = 10

img_object = cv2.imread('form1.jpg', cv2.IMREAD_GRAYSCALE)
img_scene = cv2.imread('form2.jpg', cv2.IMREAD_GRAYSCALE)

if img_object is None or img_scene is None:
    print('Could not open or find the images!')
    exit(0)

#-- Step 1: Detect the keypoints using ORB Detector, compute the descriptors
detector = cv2.ORB_create(nfeatures=1500)

keypoints_obj = detector.detect(img_object, None)
keypoints_obj, descriptors_obj = detector.compute(img_object, keypoints_obj)

keypoints_scene = detector.detect(img_object, None)
keypoints_scene, descriptors_scene = detector.compute(img_scene, keypoints_scene)

#-- Step 2: Matching descriptor vectors with a BF based matcher
matcher = cv2.FlannBasedMatcher(flann_params, {})
knn_matches = matcher.knnMatch(descriptors_obj, descriptors_scene, k=2)

# Filter matches using the Lowe's ratio test
ratio_thresh = 0.75
good_matches = []
for m,n in knn_matches:
    if m.distance < ratio_thresh * n.distance:
        good_matches.append(m)

#-- Draw matches
img_matches = np.empty((max(img_object.shape[0], img_scene.shape[0]), img_object.shape[1]+img_scene.shape[1], 3), dtype=np.uint8)
cv2.drawMatches(img_object, keypoints_obj, img_scene, keypoints_scene, good_matches[:10], img_matches, **draw_params)

if len(good_matches) > MIN_MATCH_COUNT:
    obj_pts = np.float32([ keypoints_obj[good_match.queryIdx].pt for good_match in good_matches ]).reshape(-1,1,2)
    scene_pts = np.float32([ keypoints_scene[good_match.trainIdx].pt for good_match in good_matches ]).reshape(-1,1,2)

H, _ =  cv2.findHomography(obj_pts, scene_pts, cv2.RANSAC, 5.0)

#-- Get the corners from the image_1 ( the object to be "detected" )
obj_corners = np.empty((4,1,2), dtype=np.float32)

obj_corners[0,0,0] = 0
obj_corners[0,0,1] = 0
obj_corners[1,0,0] = img_object.shape[1] # img.shape[1] shows the column of the image
obj_corners[1,0,1] = 0
obj_corners[2,0,0] = img_object.shape[1]
obj_corners[2,0,1] = img_object.shape[0] # img.shape[0] shows the row of the image
obj_corners[3,0,0] = 0
obj_corners[3,0,1] = img_object.shape[0]

scene_corners = cv2.perspectiveTransform(obj_corners, H)

#-- Draw lines between the corners (the mapped object in the scene - image_2 )
cv2.line(img_matches, (int(scene_corners[0,0,0] + img_object.shape[1]), int(scene_corners[0,0,1])),\
    (int(scene_corners[1,0,0] + img_object.shape[1]), int(scene_corners[1,0,1])), (0,255,0), 4)
cv2.line(img_matches, (int(scene_corners[1,0,0] + img_object.shape[1]), int(scene_corners[1,0,1])),\
    (int(scene_corners[2,0,0] + img_object.shape[1]), int(scene_corners[2,0,1])), (0,255,0), 4)
cv2.line(img_matches, (int(scene_corners[2,0,0] + img_object.shape[1]), int(scene_corners[2,0,1])),\
    (int(scene_corners[3,0,0] + img_object.shape[1]), int(scene_corners[3,0,1])), (0,255,0), 4)
cv2.line(img_matches, (int(scene_corners[3,0,0] + img_object.shape[1]), int(scene_corners[3,0,1])),\
    (int(scene_corners[0,0,0] + img_object.shape[1]), int(scene_corners[0,0,1])), (0,255,0), 4)

#-- Show detected matches
cv2.imshow('Good Matches With ORB Detector', img_matches)
cv2.imwrite('ORB_Matches.jpg', img_matches)
cv2.waitKey()

对于ORB,我得到了非常糟糕的结果。我在相同的图像上进行了测试。 就像大多数人所说的那样,通过使用ORB如何获得非常好的结果?

0 个答案:

没有答案