1
import cv2
import numpy as np
import sys
from IPython.display import Image
from matplotlib import pyplot as plt
import numpy
import os


img = cv2.imread('C:\\Users\\not-cropped.jpg')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

search_params = dict(checks = 50)

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



# Initiate STAR detector
star = cv2.xfeatures2d.StarDetector_create()
# Initiate BRIEF extractor
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()

# find the keypoints with STAR
kp_brief_o = star.detect(gray,None)

# compute the descriptors with BRIEF
kp_brief_o, des_brief_o = brief.compute(gray, kp_brief_o)


img66 = cv2.drawKeypoints(gray,kp_brief_o,None,(255,0,0),4)
plt.imshow(img66),plt.show()
##########################################################33
gray_crop = cv2.imread('C:\\Users\\cropped.jpg', 0)

kp_brief_crop = star.detect(gray_crop,None)

kp_brief_crop, des_brief_crop = brief.compute(gray_crop, kp_brief_crop)

flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des_brief_o, des_brief_crop, k=2)

good = []
for m,n in matches:
    if m.distance < 0.7*n.distance:
    good.append(m)

i want to compare an image to another using star as descriptor and brief to detect descriptors, it works as intended on some images, but on others like the attached 2, it will throw an exception although the second is a crop of the first, and it would even throw that same exception when an image is totally different.

Error:

ValueError Traceback (most recent call last)
<ipython-input-56-9685f4afabba> in <module>
     44 
     45 good = []
---> 46 for m,n in matches:
     47     if m.distance < 0.7*n.distance:
     48         good.append(m)

ValueError: not enough values to unpack (expected 2, got 1)

images:

main

main

cropped

cropped

unrelated pic where i'd still get the error

unrelated pic where i'd still get the error

nathancy
  • 42,661
  • 14
  • 115
  • 137
James
  • 77
  • 1
  • 1
  • 6

1 Answers1

0

That sounds like you are not getting any matches back. Try to make sure that you have keypoints. Maybe you can check what len(des_brief_o) and len(des_brief_crop) return. I assume that matches is None in that case.

So I ran your code and i get the same problem:

for m in matches:
    print(m)

And some matches only contain one element or none.

...
[<DMatch 0x10e6b93f0>, <DMatch 0x10e6b9410>]
[<DMatch 0x10e6b9430>, <DMatch 0x10e6b9450>]
[<DMatch 0x10e6b9470>, <DMatch 0x10e6b9490>]
[<DMatch 0x10e6b94b0>, <DMatch 0x10e6b94d0>]
[]
[<DMatch 0x10e6b94f0>, <DMatch 0x10e6b9510>]
[<DMatch 0x10e6b9530>, <DMatch 0x10e6b9550>]
[<DMatch 0x10e6b9570>, <DMatch 0x10e6b9590>]
[]
[<DMatch 0x10e6b95b0>, <DMatch 0x10e6b95d0>]
[<DMatch 0x10e6b95f0>]
[<DMatch 0x10e6b9610>, <DMatch 0x10e6b9630>]
...

Why not skip the results with none or only one match:

good = []
for m in matches:
    if len(m) == 2:
       if m[0].distance < 0.7 * m[1].distance:
          good.append(m[0])
Julian
  • 909
  • 8
  • 21
  • len(des_brief_o.size) isn't valid since it's a len of an int, and yes i checked both, both have keypoints – James Jun 27 '19 at 01:42
  • Doesn't work, the good matches exceeded the number of keypoints for some cases making the percentage over 100% – James Jun 30 '19 at 10:45