1
votes

I having trouble seeing where I'm going wrong. I have python code to use OpenCV2 to calculate the features of 2 images, match then and plot the most similar points. If I run the individual code it works and I can change the name of the 2nd image file, when I try to automate it to loop through a directory of images to compare to the 1st image I get the following error on Ubuntu 14.04, OpenCV 3.10

Besides the roughness of my code, anyone see why the loop errors out but the individual comparisons don't?

opencv/modules/core/src/stat.cpp:3749: error: (-215) type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U) in function batchDistance

Individual Code

import sys
import cv2
import os
import numpy as np
from matplotlib import pyplot as plt

#Load the crest and create a grey version
crest = cv2.imread('Crest.png')
greyCrest = cv2.cvtColor(crest,cv2.COLOR_BGR2GRAY)

#Create the ORB Object and BruteForce
orb=cv2.ORB_create()
#Use Hamming Distance as its ORD (other algorithms would use a different distance measure)
BruteForceMatch = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
#Calculate the keypoints and descriptors for the crest
Crestkeypoints,Crestdescriptor = orb.detectAndCompute(greyCrest,None)

#
testimage = cv2.imread('OtherImage.jpg')
testkeypoints, testdescriptors = orb.detectAndCompute(testimage,None)

#Basic Idea
matches = BruteForceMatch.match(Crestdescriptor,testdescriptors)
#Sort the matches so the strongest are at the top
matches = sorted(matches, key = lambda x:x.distance)
Title = "Total Matched " + str(len(matches)) +" Plotting Top 40"
#display the top 40 matches on the plot
MatchImage = cv2.drawMatches(greyCrest,Crestkeypoints,testimage,testkeypoints,matches[:40],testimage,flags=2)
#This gets rid of the blue tint to the end image when plotting OpenCV image in Matplotlib because of the RGB ,BGR difference
plt.imshow(cv2.cvtColor(MatchImage, cv2.COLOR_BGR2RGB))
plt.title(Title)
plt.show()
#Pause for 10 Seconds so you can see the plot
plt.pause(10)
#Have to close as for some reason the figures weren't plotting correctly when I ran the code the 2nd time
plt.close('all')

Looping Code

Below is code to loop through a directory, load the image into OpenCV, calculate the keypoints and features of the image and compare it to a search image before getting the number of matches and plotting the top 40 matches

#Load the crest and create a grey version
import cv2
import os
import numpy as np
from matplotlib import pyplot as plt
    crest = cv2.imread('Crest.png')
    greyCrest = cv2.cvtColor(crest,cv2.COLOR_BGR2GRAY)

    #Create the ORB Object and BruteForce
    orb2=cv2.ORB_create()
    #Use Hamming Distance as its ORD (other algorithms would use a different distance measure)
    BruteForceMatch = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
    #Calculate the keypoints and descriptors for the crest
    Crestkeypoints,Crestdescriptor = orb2.detectAndCompute(greyCrest,None)


    #Get the folder of Images to be matched with ORB 1 by 1 against the Search Image
    for ImageToProcess in os.listdir('/MatchWithORB'):
        print "Processing Image", ImageToProcess
        #Load the current Image as greyscale and calculate the keypoints, descriptors
        CurrentImage = cv2.imread(ImageToProcess,cv2.IMREAD_GRAYSCALE)
        currImageKeyPoints, currImageDescriptors = orb2.detectAndCompute(CurrentImage,None)
        #Get the matches between the current image and the crest
        matches = BruteForceMatch.match(Crestdescriptor,currImageDescriptors)
        Title = "Crest Total Matched " + str(len(matches)) +" Plotting Top 40 " +ImageToProcess
        # Sort them so the top matches are higher
        matches = sorted(matches, key = lambda x:x.distance)
        MatchImage = cv2.drawMatches(greyCrest,Crestkeypoints,CurrentImage,currImageKeyPoints,matches[:40],CurrentImage,flags=2)
        plt.imshow(MatchImage)
        plt.draw()
        plt.pause(10)
        #tidyup
        BruteForceMatch.clear
    print"Looping"
1

1 Answers

1
votes

old question, but the answer is that if no features are detected, detectAndCompute returns "None" instead of an empty list. Then as the code continues to match, it tries to match a feature list with a None type giving you the described error. easy way to check this:

    if des1 is None or des2 is None:
    print(des1)
    print(des2)
    pdb.set_trace()

they will probably be None