OpenCV 3.0 findContours crashes

Viewed 2995

I need to detect the object's contour of an image. For that purpose, I'm using the OpenCV library's function findContours. I'm using OpenCV 3.0 (x86) on Windows 10 (x64) compiled by me with the contrib modules.

The problem

The problem is that, when I try to use this function, the application crashes. The error is not an exception or an assertion failure, I can only see a window saying to me that the application has crashed:

enter image description here

What I have tested

I have checked that the image I'm passing to findContours is a binary image:

I have checked the type of the image, which is 0, the same as CV_8U value.

I have even checked the histogram, and there are only pixels with values 0 and 1.

I have also searched for examples from OpenCV tutorials and forums, and I have tried to do exactly the same than in the example, and the program crashes again.

The code

Here is the code that I'm executing:

// This is the main function:
int test_findContours(const std::string &path){
    Mat img = imread(path, IMREAD_GRAYSCALE);
    if (!img.data){
        cout << "ERROR" << endl;
        return -1;
    }
    Mat mask;
    getRemBackgroundMask(img, mask);

    vector< vector<Point> > contours;

    // Here the program crashes:
    findContours(mask, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
    return 0;
}

// Get the mask to remove the background
void getRemBackgroundMask(const Mat &img, Mat &mask) {
    threshold(img, mask, 70, 1, THRESH_BINARY_INV);

    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
    openning(mask, mask, kernel);
}

void openning(const Mat &binary, Mat &result, const Mat &kernel){
    erode(binary, result, kernel);
    dilate(binary, result, kernel);
}
2 Answers

So far I've found a couple of ways to crash findcontours()

  1. Source image is not grayscale

  2. Incorrect type container for contours - you must use (this structure)

    std::vector<std::vector<cv::Point> > yourContour;

  3. Threshold set as the same value or threshold 2 being smaller than 1

  4. Source image is too large.

And this! is most likely the culprit. Nowadays phones can take pictures at ridiculous resolutions, sadly OpenCv didn't future proof their code and the crash is due an overflow. This is a known issue and more information can be found here: https://github.com/opencv/opencv/issues/7449

Even thought it's listed as fixed, this is in most cases the culprit. I'm using OpenCV 3.4.1 which is the most up-to-date stable version and the fix is just to explicitly declare your source and destination cv::mats at a manageable legacy resolution (like 800x600)

Related