Почему ORB не дал мне лучший результат, чем SURF? - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь извлечь функции для любого изображения или видеокадра. Я прочитал много статей и статей об отслеживании объектов на основе точечных объектов. Наконец, я решил использовать 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, как говорят большинство людей?

...