OpenCV error while feature matching with FLANN - python

I have a piece of code for matching features between a movie clip and a reference image. It generally works well, but sometimes it throws an error in the middle of a clip. Since it's always in the same clips, and at the same time, I guess there is something wrong with the frame it tries to analyze.
My code:
cap = cv2.VideoCapture(clip_file)
img1 = cv2.imread(ref_image,0)
while(cap.isOpened()):
# read the frame and convert to gray-scale
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Initiate ORB detector
orb = cv2.ORB_create()
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(gray,None)
# FLANN parameters
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) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
cv2.imshow('img3',frame)
The error it throws sometimes during the clip playing:
Traceback (most recent call last):
File "movie_test.py", line 81, in <module>
flann_movie('data/movie.avi','data/ref.jpg')
File "movie_test.py", line 35, in flann_movie
matches = flann.knnMatch(des1,des2,k=1)
cv2.error: OpenCV(3.4.2) C:\projects\opencv-
python\opencv\modules\flann\src\miniflann.cpp:317: error: (-5:Bad
argument) Only continuous arrays are supported in function
'cv::flann::buildIndex_'
Any suggestions on what causes the error would be appreciated. Thanks.

I think error is caused by frames of your video where no trace of original feature template was detected. Check what mid-results of matching are for each frame and then if that is the cause change the parameters of FLANN or simply skip those frames before the error occurs.

You have the following:
matches = flann.knnMatch(des1,des2,k=2)
With k=2 it means each element needs to have 2-nearest neighbors. As a result, each list of descriptors needs to have more than 2 elements each:
if(des1 is not None and len(des1)>2 and des2 is not None and len(des2)>2):
matches = flann.knnMatch(des1,des2,k=2)
(k-nearest neighbors algorithm)

Related

OpenCV Homography gives error: The input arrays should have at least

Following this https://www.youtube.com/watch?v=I8tHLZDDHr4&list=WL&index=1&ab_channel=Pysource tutorial on YouTube for my own project, answers I found basically had the exact same code, but my code gives me this error:
Traceback (most recent call last): File "c:\Users\NoName69\Desktop\ProJects\PyJects\Homography\test.py", line 31, in <module> matrix, mask = cv2.findHomography(query_p, train_p, cv2.RANSAC, 5.0) cv2.error: OpenCV(4.5.1) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build 5rb_9df3\opencv\modules\calib3d\src\fundam.cpp:385: error: (-28:Unknown error code -28) The input arrays should have at least 4 corresponding point sets to calculate Homography in function "cv::findHomography"
Code:
from cv2 import cv2
import numpy as np
img1 = cv2.cvtColor(cv2.imread("Aim Circle.png"), cv2.COLOR_RGB2GRAY)
img2 = cv2.cvtColor(cv2.imread("Map.png"), cv2.COLOR_RGB2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
kp_img1, desc_img1 = sift.detectAndCompute(img1, None)
kp_img2, desc_img2 = sift.detectAndCompute(img2, None)
img1 = cv2.drawKeypoints(img1, kp_img1, img1)
img2 = cv2.drawKeypoints(img2, kp_img2, img2)
index_params = dict(algorithm = 0, trees = 5)
search_params = dict()
flann = cv2.FlannBasedMatcher(index_params, search_params)
while True:
matches = flann.knnMatch(desc_img1, desc_img2, k = 2)
good_kp = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good_kp.append(m)
if len(good_kp) > 2:
query_p = np.float32([kp_img1[m.queryIdx].pt for m in good_kp]).reshape(-1, 1 ,2)
train_p = np.float32([kp_img2[m.trainIdx].pt for m in good_kp]).reshape(-1, 1, 2)
matrix, mask = cv2.findHomography(query_p, train_p, cv2.RANSAC, 5.0)
if cv2.waitKey(25) & 0xFF == ord(" "):
cv2.destroyAllWindows()
break
OpenCv also gives this warning:
[ WARN:0] global c:\users\appveyor\appdata\local\temp\1\pip-req-build-5rb_9df3\opencv_contrib\modules\xfeatures2d\misc\python\shadow_sift.hpp (15) cv::xfeatures2d::SIFT_create DEPRECATED: cv.xfeatures2d.SIFT_create() is deprecated due SIFT tranfer to the main repository. https://github.com/opencv/opencv/issues/16736
I have found out the problem. OpenCV cannot find enough features in the file "Aim Circle.png", and so gives this error. If anyone knows another way to find a picture that is similar embedded in another picture it would be greatly appreciated.
i think in
if len(good_kp) > 2:
you have to substiture the value of 2 with a value greater than 4:
example: if len(good_kp) > 10:

error in applying flann based matcher in opencv python

I am finding similarity between two images. My code is
img1 = cv2.imread(os.path.join("/home/atul/Documents/Data/objectdetection/imboxes1/images000.jpeg/car0.jpg"))
img2 = cv2.imread(os.path.join("/home/atul/Documents/Data/objectdetection/frames1/images000.jpeg"))
sift = cv2.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks = 50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1,des2,k=2)
The error i am facing is-
error Traceback (most recent call last)
in ()
----> 1 matches = flann.knnMatch(des1,des2,k=2) error: /feedstock_root/build_artefacts/work/opencv-3.1.0/modules/python/src2/cv2.cpp:163:
error: (-215) The data should normally be NULL! in function allocate'
How can i resolve this? Please suggest
Thanks!
In your code please check your path as your extension is irrelevant
"/home/atul/Documents/Data/objectdetection/imboxes1/images000.jpeg/car0.jpg"
please change the images000.jpeg to simple folder images000/car0.jpg
Also check the size of query image should be smaller than that of original image

opencv 3 python feature detection error on function cv2.detectAndCompute and also on cv2.compute

i use opencv 3.0.0 and python 2.7.5_x32
This is my code (ORB_feature_detection):
import numpy as np
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('C:\\Python27\\madar1.jpg',0) # queryImage
img2 = cv2.imread('C:\\Python27\\madar2.jpg',0) # trainImage
# Initiate SIFT detector
orb = cv2.ORB_create()
# line 12
# find the keypoints and descriptors with SIFT
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
# Draw first 10 matches.
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10], flags=2)
plt.imshow(img3),plt.show()
cv2.waitKey()
cv2.destroyAllWindows()
and this is the error message, the error message is on the
kp1, des1 = orb.detectAndCompute(img1,None) part,
i did work on opencv 2.4.11 and it doesn't work on opencv 3.0.0 !
Traceback (most recent call last):
File "C:\Python27\orb_matcher.py", line 12, in <module>
kp1, des1 = orb.detectAndCompute(img1,None)
error: ..\..\..\modules\python\src2\cv2.cpp:163: error: (-215) The data should normally be NULL! in function NumpyAllocator::allocate
please help me, what should i do to make this work?
You can try add this script after import cv2 and others cv2.ocl.setUseOpenCL(False) this solved my issue.
This is a known bug. You can find more information here https://github.com/opencv/opencv/issues/6081.
Today someone is fixing this issue: T-API python support implemented #6847.

TypeError: data type not understood opencv python

thats my python3 opencv3 code i get this error when i run this code i did't finished it yet that's are the error can some one help ?
line 19, in <module>
matches = bf.match(np.array(kpTrain, desTrain))
TypeError: data type not understood
that's my code
import numpy as np
import cv2
camera = cv2.VideoCapture(0)
orb = cv2.ORB_create()
img = cv2.imread('/home/shar/home.jpg')
imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kpTrain = orb.detect(imggray,None)
kpTrain, desTrain = orb.compute(imggray, kpTrain)
ret, imgCamColor = camera.read()
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(np.array(kpTrain, desTrain))
Again here, as in this question you are trying to to match keypoints and the descriptors from one image. The matching of descriptors is done with two images.
1. Find Keypoints in 2 images
2. Calculate descriptors for the two images
3. Perform the matching.
In your case it should be something like this:
import numpy as np
import cv2
orb = cv2.ORB_create()
img = cv2.imread('/home/shar/home.jpg')
imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# load second image in grayscale
imggray2=cv2.imread('/path/to/image.jpg',0)
#Detector and descriptors for 1st image
kpTrain = orb.detect(imggray,None)
kpTrain, desTrain = orb.compute(imggray, kpTrain)
#Detector and descriptors for 2nd image
kpTrain2 = orb.detect(imggray2,None)
kpTrain2, desTrain2 = orb.compute(imggray2, kpTrain2)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(desTrain,desTrain2)

OpenCV doesn't come with "external" libraries

I tried this example from the OpenCV website:
import numpy as np
import cv2
from matplotlib import pyplot as plt
# changed the image names from box* since the sample images were not given on the site
img1 = cv2.imread('burger.jpg',0) # queryImage
img2 = cv2.imread('burger.jpg',0) # trainImage
# Initiate SIFT detector
sift = cv2.SIFT()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
# Need to draw only good matches, so create a mask
matchesMask = [[0,0] for i in xrange(len(matches))]
# ratio test as per Lowe's paper
for i,(m,n) in enumerate(matches):
if m.distance < 0.7*n.distance:
matchesMask[i]=[1,0]
draw_params = dict(matchColor = (0,255,0),
singlePointColor = (255,0,0),
matchesMask = matchesMask,
flags = 0)
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)
plt.imshow(img3,),plt.show()
Executing the example, viz. python test.py, gives the following error:
Traceback (most recent call last):
File "test.py", line 10, in <module>
sift = cv2.SIFT()
AttributeError: 'module' object has no attribute 'SIFT'
I had installed OpenCV from source, building manually. All modules were built by make, if I recall correctly.
This question suggested that I install opencv-contrib from its GitHub repository. I did, and I still get this error.
My system is Ubuntu 15.04 64-bit.
I'm not entirely sure if this is applicable, but at some point they stopped supporting SIFT in the later versions of opencv I believe due to the fact that it is patented or something related (source?), however an alternate is to use ORB which will have a similar effect.
You could try something like this:
from cv2 import ORB as SIFT
However in the event that you get an import error this also might work for you:
SIFT = cv2.ORB_create
If you insert those near the top of your file, then likely you can leave "SIFT" as it is throughout the file (well more or less, you get the idea, basically replace the cv2.Sift() with sift = SIFT() and you should be in better shape.)

Categories