17

I'm attempting to track landmarks along the contour of facial features obtained via dsift with python 2.7 and openCV 2.4.11. I want to track these features between frames.

However I am receiving the following error. I have checked the input images are 1-channel equal dimensions (and unsigned 8bit type), and likewise with the prev points:

OpenCV Error: Assertion failed ((npoints = prevPtsMat.checkVector(2, CV_32F, tru
e)) >= 0) in cv::calcOpticalFlowPyrLK, file ..\..\..\modules\video\src\lkpyramid.cpp
cv2.error: ..\..\..\modules\video\src\lkpyramid.cpp:845: error: (-215) (npoints
= prevPtsMat.checkVector(2, CV_32F, true)) >= 0 in function cv::calcOpticalFlowP
yrLK

Line causing issue:

new_pts, ttl, err = cv2.calcOpticalFlowPyrLK(self.old_img, i_img, i_old_pts, None)

Does anyone have any idea where I can begin debugging this?

lukemtesta
  • 421
  • 1
  • 4
  • 11

3 Answers3

35

I had the same problem when I did optical flow based tracking. I tried many many different ways to solve this. But in vain.

Finally, there was an example program in which they tracked using shi-tomsi corner points detection and those points were used in the LK algorithm and it worked perfectly. So i probed into the data types and dimensions of the output of the Shi-Tomsi detector and I made sure my points to be tracked were of the same type. It woked!

Here's what you need to know.

  • make sure the images are grayscale.
  • your coordinate parameter that is i_old_pts should be single precision float meaning float32. This type is available in numpy use that. the float in python is float64
  • the coordinate parameter i_old_pts(from your program) should be a numpy array with the dimension (n,1,2) where n represents the number of points.

This should work.

kauDaOtha
  • 1,140
  • 1
  • 14
  • 23
  • np.float32(coorX),np.float32(coorY) helped me – Deepak Sharma Feb 24 '17 at 14:33
  • 4
    I had to initialize my numpy arrays to be of type `np.float32`. – Mateen Ulhaq May 02 '17 at 19:35
  • 3
    Thank you so much! I spend hours trying to figure out what's up.. The cv2 python binding should explicitly mention the expected parameter type in the docs. They do it for the C function signature (e.g. in case of the corner array for the cornerSubPix function its CvPoint2D32f* corners). Let `corners` be my initial corner array, then I used `corners.astype(np.float32)` – trueter Sep 13 '17 at 12:27
  • Thank you so much! These datatype things and the array shape thing are really hard to figure out without you explicitly writing them out. WTH cv2 doesn't directly tell us that? Geez – Sibbs Gambling Nov 26 '17 at 14:54
  • This guy is a god – ntakouris Dec 14 '21 at 09:11
0

I was following opencv sample for optical flow had the same problem. In my case the problem was the type of video file from which I was reading. I was reading from mkv file which didn't work.

Jwalant Bhatt
  • 361
  • 2
  • 7
0

I am not sure why, but after a lot of code evaluation and debugging, I found that the first frame of my video (I captured video from the webcam) was an empty BLACK image. So, I used the second frame:

ret, prevframe = cap.read();
ret, prevframe = cap.read(); # the first frame was black and I was not sure why!!!
Abbasihsn
  • 2,075
  • 1
  • 7
  • 17