Ask Your Question

Revision history [back]

Use the following code to check what is wrong with your image

#include <iostream>

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat image = imread("/data/fake.png");
    Mat work_image;
    cvtColor(image, work_image, COLOR_BGR2GRAY);
    threshold(work_image, work_image, 0, 255, THRESH_BINARY);
    imshow("binary", work_image); waitKey(0);

    vector< vector<Point> > contours;
    findContours(work_image, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    drawContours(image, contours, -1, Scalar(0,0,255), 2);

    imshow("contours", image);
    waitKey(0);

    return 0;
}

Which will result into

image description

And where you will see the small dot that is resulting in an extra contour with the wrong info. Since it is closer to the top left top, it gets the first index.

To avoid this, perform a small erode-dilate operation beforehand like this:

#include <iostream>

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat image = imread("/data/fake.png");
    Mat work_image;
    cvtColor(image, work_image, COLOR_BGR2GRAY);
    threshold(work_image, work_image, 0, 255, THRESH_BINARY);
    imshow("binary", work_image); waitKey(0);

    // Erode-dilate
    erode(work_image, work_image, Mat());
    dilate(work_image, work_image, Mat());

    imshow("clean binary", work_image); waitKey(0);

    vector< vector<Point> > contours;
    findContours(work_image, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    drawContours(image, contours, -1, Scalar(0,0,255), 2);

    imshow("contours", image);
    waitKey(0);

    return 0;
}

And the result

image description