Assertion failure within findContours / _OutputArray::create
I am currently trying to use the findContours function as presented in the tutorials.
However, it fails on the assertion..
CV_Assert( i < 0 );
..on row 1422 of matrix.cpp (based on release 248, corresponds to rows 2133 and onwards in current master branch), within the function
_OutputArray::create(int, const int *, int, int, bool, int)
There are several of the same assertion querying i to be negative, even if i is not used where the program flows if I move the debug pointer beyond the assertion each time.
In contours.cpp, function cv::findContours(InputOutputArray, OutputArrayOfArrays, OutputArray, int, int, Point) there is a for-loop on lines 1722 to 1730 which calls..
_contours.create((int)c->total, 1, CV_32SC2, i, true);
..each iteration. i goes from 0 to total (amount of found contours?), triggering said assertion each time because the requested matrix-type demands it or something. allowTransposed is set to true and i is 0 or positive, making it call the specific/default constructor mentioned above. k or kind value is also set to MAT (65536)
Even if I move the debug flow to skip that assertion it will fail on an assertion later on within the following line in cv::findContours:
Mat ci = _contours.getMat(i);
I am guessing this means that the matrices are not created properly/as intended to be used by the findContours function.
Are there any further prerequisites for the input image, or what else could be the problem? I have managed to get several other filters to work with little to no trouble compared to this (Canny, cornerHarris, threshold, etc).
Input image is single-channel 1 byte per pixel (type CV_8UC1).
Is your image a non-const one channel uchar matrix? Also note that the input matrix will be modified during execution (i.e. you should clone it before using findContours if you need it afterwards).
Yup, channels() return 1 and type() is equal to CV_8UC1, which should be correct. Edited to add it at the end of the post.
what are you passing in for the contours ? showing some bits of your code might be much more helpful than diving into the dungeon above
I have tried both using the output of Canny, as in the tutorial, but also the output of threshold.
it does not complain about your input , but about constructing the OutputArray. you should have supplied a
vector< vector< Point > >
there. also, imho, you can't reuse it for several iterations of findContours
again, time to show your code. otherwise we're left to helpless guessing
That was the issue, yes. I was incorrectly using cv::Mat for both outputs (the contours and the hierarchy). Got it pointed out around the time you suggested the solution by my collegue/supervisor. It's interesting though that it didn't give any compilation errors. What is the relation between cv::Mat and these output data? Are they related at all?
there are conversion operators between std::vector and cv::Mat, unfortunately this seems to break with a vector<vector<Point>>. (but i'm positive, that it will work with a vector<Mat> for contours)
Yup! std::vector<cv::Mat> seemed to work for the contours. o.o So.. cv::Mat is interchangable with std::vector<cv::Point> pretty much?
vector -> Mat yes. but not the other way