OpenCV's calcOpticalFlowPyrLK throws exception

Suedocode picture Suedocode · Mar 25, 2013 · Viewed 13.2k times · Source

I have been trying to form a small optical flow example with OpenCV for a while now. Everything works except the function call calcOpticalFlowPyrLK, which prints the following failed assertion in the console window:

OpenCV Error: Assertion failed (mytype == typ0 || (CV_MAT_CN(mytype) == CV_MAT_CV(type0) && ((1 << type0) & fixedDepthMask) != 0)) in unknown function, file ......\src\opencv\modules\core\src\matrix.cpp, line 1421

The video that I'm parsing is separated into 300 images, labelled as "caml00000.jpeg", "caml00001.jpeg", ..., "caml00299.jpeg". Here is the code I wrote:

#include <cv.h>
#include "opencv2/highgui/highgui.hpp"

using namespace cv;
using namespace std;

int main( int argc, char** argv ){

    char buff[100];
    int numFrames=300;
    char fileFormat[]="images/caml%05d.jpeg";

    string winname="Test Window";

    vector<Mat> imgVec(numFrames);

    auto itrImg=begin(imgVec);
    auto itrEnd=end(imgVec);
    vector<Point2f> featuresPrevious;
    vector<Point2f> featuresCurrent;

    namedWindow( winname, CV_WINDOW_AUTOSIZE );
    int fileNum=0;
    while(itrImg!=itrEnd){
        Mat& imgRef=*itrImg; //get this frame's Mat from the vector iterator

        //Calculate the name of the file;
        sprintf(buff,fileFormat,fileNum);
        string fileName=buff;
        //string fileName="kitty.jpg"; //attempted using a static picture as well
        cout << fileName << endl;

        Mat cImage=imread(fileName, CV_LOAD_IMAGE_GRAYSCALE);
        cImage.convertTo(imgRef, CV_8U); //also tried CV_8UC1
        featuresPrevious=std::move(featuresCurrent);
        goodFeaturesToTrack(imgRef,featuresCurrent,30, 0.01, 30); //calculate the features for use in next iteration
        if(!imgRef.data){ //this never executes, so there isn't a problem reading the files
            cout << "File I/O Problem!" << endl;
            getchar();
            return 1;
        }

        if(fileNum>0){
            Mat& lastImgRef=*(itrImg-1); //get the last frame's image
            vector<Point2f> featuresNextPos;
            vector<char> featuresFound;
            vector<int> err;
            calcOpticalFlowPyrLK(lastImgRef,imgRef,featuresPrevious,featuresNextPos,featuresFound,err); //problem line 
            //Draw lines connecting previous position and current position
            for(size_t i=0; i<featuresNextPos.size(); i++){
                if(featuresFound[i]){
                    line(imgRef,featuresPrevious[i],featuresNextPos[i],Scalar(0,0,255));
                }
            }
        }

        imshow(winname, imgRef);

        waitKey(1000/60); //not perfect, but it'll do

        ++itrImg;
        ++fileNum;
    }

    waitKey(0);
    return 0;
}

The only thing I've read about this exception is that it is caused when Mats are in different formats, however I've tried reading a static image (see code above regarding "kitty.jpg") and I still get the same failed assertion. Any ideas?

Answer

morynicz picture morynicz · Mar 26, 2013

Change line vector<char> featuresFound; to vector<uchar> featuresFound; and vector<int> err; to Mat err;

I can't explain why, but that's how it has to be done.

Edit: As @Sluki said in the comments - err vector has to be stored in floating point precision std::vector or cv::Mat.