CornerSubPix function crashes on small frames

asked 2019-08-25 15:56:32 -0600

updated 2019-08-26 10:09:28 -0600

I' m modifying the algorithm that compute the optical flow. I want subdivide the input video (I'm using a file as input) in a perfect square number of subvideos in order to compute the optical flow separately and merge the final results in a single output.

I've written the part of code that split my original B/W frame in 9 subframes and everything works. Before iterating the optical flow computation over all the 9 subframes and merge the result, I want to try to compute the optical flow only on a single subframe, let's say, the upper left one. The code compiles but when it runs I get this error

OpenCV Error: Assertion failed (count >= 0) in cornerSubPix, file 
/build/opencv-L2vuMj/opencv- 
3.2.0+dfsg/modules/imgproc/src/cornersubpix.cpp, line 58
terminate called after throwing an instance of 'cv::Exception'
what():  /build/opencv-L2vuMj/opencv- 
3.2.0+dfsg/modules/imgproc/src/cornersubpix.cpp:58: error: (-215) count 
>= 0 in function cornerSubPix

This is the core part of the code

Mat gray, prevGray, image, frame;
vector<Point2f> points[2];

for(;;)
{
    cap >> frame;
    if( frame.empty() )
        break;
    frame.copyTo(image);
    cvtColor(image, gray, COLOR_BGR2GRAY);
    Mat * cells = subdivide(gray);
    Mat * prevCells = subdivide(prevGray);
    if( needToInit )
    {
        // automatic initialization
        goodFeaturesToTrack(cells[0], points[1], MAX_COUNT, 0.01, 10, Mat(), 3, 0, 0.04);
        cornerSubPix(cells[0], points[1], subPixWinSize, Size(-1,-1), termcrit);
        addRemovePt = false;
        needToInit=false;
    }
    else if( !points[0].empty() )
    {
        vector<uchar> status;
        vector<float> err;
        if(prevCells[0].empty())
            cells[0].copyTo(prevCells[0]);
        calcOpticalFlowPyrLK(prevCells[0], cells[0], points[0], points[1], status, err, winSize,
                             3, termcrit, 0, 0.001);
        size_t i, k;
        for( i = k = 0; i < points[1].size(); i++ )
        {
            if( addRemovePt )
            {
                if( norm(point - points[1][i]) <= 5 )
                {
                    addRemovePt = false;
                    continue;
                }
            }
            if( !status[i] )
                continue;
            points[1][k++] = points[1][i];
            circle( image, points[1][i], 3, Scalar(0,255,0), -1, 8);
        }
        points[1].resize(k);
    }
    if( addRemovePt && points[1].size() < (size_t)MAX_COUNT )
    {
        vector<Point2f> tmp;
        tmp.push_back(point);
        cornerSubPix( cells[0], tmp, winSize, Size(-1,-1), termcrit);
        points[1].push_back(tmp[0]);
        addRemovePt = false;
    }
    needToInit = false;
    imshow("LK Demo", image);
    char c = (char)waitKey(10);

    std::swap(points[1], points[0]);
    cv::swap(prevCells[0], cells[0]);
}
return 0;

subdivide(Mat input) is the function that returns an array of Mat. In the previous code, if i write gray instead of cells[0] and prevGray instead of prevCells[0] everything works.

The code that i'm using as base is a demo provided by opencv (link to the page) The only thing that I've added is the subdivide function, and I've removed from my code all the parts that allow different options that I don't need like nightmode. How can I solve it?

EDIT: This is the code of the subdivide function

#define SQRT 3
static Mat * subdivide(Mat input)
{

    static Mat output[9];

    int rows = input.rows;
    int cols = input.cols;

    cv::Size ...
(more)
edit retag flag offensive close merge delete

Comments

returning a pointer to cv::Mat from your function is highly suspicious (don't do that !)

please show the code for that function, very likely you're returning someting invalid this way (dangling pointer)

berak gravatar imageberak ( 2019-08-26 01:53:05 -0600 )edit
1

Thanks, just edited

LorenzoEpifani gravatar imageLorenzoEpifani ( 2019-08-26 09:06:44 -0600 )edit