Ask Your Question

Assertion failure within findContours / _OutputArray::create

asked 2014-04-15 03:09:04 -0500

erenik gravatar image

updated 2020-10-23 07:09:53 -0500

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).

edit retag flag offensive close merge delete


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).

Guanta gravatar imageGuanta ( 2014-04-15 03:28:27 -0500 )edit

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.

erenik gravatar imageerenik ( 2014-04-15 03:37:06 -0500 )edit

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

berak gravatar imageberak ( 2014-04-15 03:47:50 -0500 )edit

I have tried both using the output of Canny, as in the tutorial, but also the output of threshold.

erenik gravatar imageerenik ( 2014-04-15 03:57:23 -0500 )edit

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

berak gravatar imageberak ( 2014-04-15 04:47:15 -0500 )edit

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?

erenik gravatar imageerenik ( 2014-04-15 05:48:57 -0500 )edit

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)

berak gravatar imageberak ( 2014-04-15 06:04:06 -0500 )edit

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?

erenik gravatar imageerenik ( 2014-04-15 06:23:07 -0500 )edit

vector -> Mat yes. but not the other way

berak gravatar imageberak ( 2014-04-15 06:44:31 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2014-04-24 09:24:27 -0500

erenik gravatar image

updated 2014-04-24 09:25:39 -0500

Was incorrectly assuming all outputs were of cv::Mat types.

Solution was to use std::vector<std::vector<cv::Point>> (or std::vector<cv::Mat>) for the contours and std::vector<cv::Vec4i> for the contour hierarchy.

edit flag offensive delete link more

Question Tools


Asked: 2014-04-15 03:09:04 -0500

Seen: 1,700 times

Last updated: Apr 24 '14