I am new to OpenCV and I'm trying to register images with ORB using FLANN to match key points, but when I try to loop over my matches to apply Lowe's ratio I get the following:
import cv2 as cv
# Read images
src_img = cv.imread('pop_src.jpg')
dst_img = cv.imread('pop_dst.jpg')
# Create the ORB instance
orb = cv.ORB_create()
# Find keypoints and compute descriptors
src_kpts, src_desc = orb.detectAndCompute(src_img, None)
dst_kpts, dst_desc = orb.detectAndCompute(dst_img, None)
# Use FLANN to Find the Best Keypoint Matches
FLANN_INDEX_LSH = 6
index_params= dict(algorithm = FLANN_INDEX_LSH,
table_number = 12,
key_size = 20,
multi_probe_level = 2)
search_params = {}
flann = cv.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(src_desc, dst_desc, k = 2)
# Store the Keypoint Matches that Pass Lowe's Ratio Test
good_matches = []
for m, n in matches:
if m.distance < 0.7*n.distance:
good_matches.append(m)
matched_img = cv.drawMatches(src_img, src_kpts, dst_img, dst_kpts, good_matches, src_img, flags = 2)
---------------------------------------------------------------------------
error Traceback (most recent call last)
/tmp/ipykernel_22575/771507388.py in <module>
24 flann = cv.FlannBasedMatcher(index_params, search_params)
25
---> 26 matches = flann.knnMatch(src_desc, dst_desc, k = 2)
27
28 # Store the Keypoint Matches that Pass Lowe's Ratio Test
error: OpenCV(4.7.0) /io/opencv/modules/flann/src/miniflann.cpp:338: error: (-5:Bad argument) Only continuous arrays are supported in function 'buildIndex_'
After reading this Q&A I though it might be a result of my k value in flann.knnMatch(), but that just resulted in a different issue:
import cv2 as cv
# Read images
src_img = cv.imread('pop_src.jpg')
dst_img = cv.imread('pop_dest.jpg')
# Create the ORB instance
orb = cv.ORB_create()
# Find keypoints and compute descriptors
src_kpts, src_desc = orb.detectAndCompute(src_img, None)
dst_kpts, dst_desc = orb.detectAndCompute(dst_img, None)
# Use FLANN to Find the Best Keypoint Matches
FLANN_INDEX_LSH = 6
index_params= dict(algorithm = FLANN_INDEX_LSH,
table_number = 12,
key_size = 20,
multi_probe_level = 2)
search_params = {}
flann = cv.FlannBasedMatcher(index_params, search_params)
# Added this per the Q & A
if(src_desc is not None and len(src_desc) > 2 and dst_desc is not None and len(dst_desc) > 2):
matches = flann.knnMatch(src_desc, dst_desc, k = 2)
# Store the Keypoint Matches that Pass Lowe's Ratio Test
good_matches = []
for m, n in matches:
if m.distance < 0.7*n.distance:
good_matches.append(m)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/tmp/ipykernel_22575/3672753189.py in <module>
29 # Store the Keypoint Matches that Pass Lowe's Ratio Test
30 good_matches = []
---> 31 for m, n in matches:
32 if m.distance < 0.7*n.distance:
33 good_matches.append(m)
ValueError: not enough values to unpack (expected 2, got 0)
I have a very similar script using SIFT and it runs with no issues. How is ORB storing key points, how does it differ from the way in which SIFT stores key points, and how do I properly use FLANN with ORB in a way that allows me to apply Lowe's ratio?