0

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?

Renzzy
  • 25
  • 1
  • 8
  • ORB has binary descriptor entries, probably encoded in a single N Byte value. So you will need a binary descriptor distance metric like HAMMING. See https://answers.opencv.org/question/547/using-flann-with-binary-descriptors-brieforb/ – Micka Jan 07 '23 at 22:59
  • See here https://stackoverflow.com/q/43830849/2393191 – Micka Jan 07 '23 at 23:04
  • I am still learning the inner workings of it all, so those links are very informative. Thanks Micka! – Renzzy Jan 07 '23 at 23:12
  • 1
    For the record, I found this link very helpful in understanding what you meant by binary descriptors. I appreciate the insight. https://www.ipb.uni-bonn.de/html/teaching/msr2-2020/sse2-10-features-descriptors.pdf – Renzzy Jan 09 '23 at 16:36

1 Answers1

0

The fix was simply changing the values in my index_params dictionary. The script runs as intended now, but I would be very interested in knowing why that fixes it.

index_params= dict(algorithm = FLANN_INDEX_LSH,
                   table_number = 6,         # was 12
                   key_size = 12,            # was 20
                   multi_probe_level = 1)    # was 2
Renzzy
  • 25
  • 1
  • 8