OpenCV python error when using ORB images feature matching
Asked Answered
E

1

7

I was trying to match two images using OpenCV ORB as explained in this tutorial.

Here is my code:

import numpy as np
import cv2
import six
import pyparsing
import dateutil
from matplotlib import pyplot as plt
import timeit
import os
import sys

img1_path  = 'img1.jpg'
img2_path  = 'img2.jpg'

img1 = cv2.imread(img1_path,0) # queryImage
img2 = cv2.imread(img2_path,0) # trainImage

orb = cv2.ORB()

kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

FLANN_INDEX_LSH = 6

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

search_params = dict(checks = 50)
flann = cv2.FlannBasedMatcher(index_params, search_params)

matches = flann.knnMatch(des1,des2,k=2)

if len(matches)>0:
    print "%d total matches found" % (len(matches))
else:
    print "No matches were found - %d" % (len(good))
    sys.exit()

# store all the good matches as per Lowe's ratio test.
good = []
for m,n in matches:
    if m.distance < 0.6*n.distance:
        good.append(m)

I ran this script with two images that are quite similar. In most cases the script works fine and finds matching key-points.

However, in some cases I get this error (it refers to the last three lines of code):

Traceback (most recent call last):
    for m,n in matches:
ValueError: need more than 1 value to unpack

It happens when img2 is significantly a smaller sub-image of img1.

(if img2 is the original image, and img1 is the modified images, it means that someone added details to the original image).

If I switch between the file names img1,img2 then the script runs with no problems.

Must be the query image (img1) smaller, or equal to the train image (img2)?

Entremets answered 29/7, 2014 at 14:54 Comment(0)
R
6

Each member of the matches list must be checked whether two neighbours really exist. This is independent of image sizes.

good = []
for m_n in matches:
  if len(m_n) != 2:
    continue
  (m,n) = m_n
  if m.distance < 0.6*n.distance:
    good.append(m)
Ridenhour answered 2/9, 2015 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.