Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I've tried to replicate your results, but it works fine for me. Here is the code (C++)

Note that I have padded the input image, in order to have the correct contour (findContours() splits the contour because it touches the image edges). It may that this is your problem.

Also, note the different parameters for findContours. With your flags, the correct contour is the second one (index 1, not 0) in my test. With my flags, the good one is the first (index 0).

cv::Mat contourImg = imread("contour.png");
std::vector<cv::Mat> channels;
cv::split(contourImg, channels);

    // On these lines, the input image is padded
cv::Mat gray(contourImg.rows+20, contourImg.cols+20, CV_8UC1);
gray = 255;
channels[0].copyTo(gray(cv::Rect(10,10,contourImg.cols, contourImg.rows)));

cv::imshow("Original", gray);
std::vector<std::vector<cv::Point> > contours;
cv::findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
cv::Mat drawing(gray.size(), CV_8UC3);
cv::Mat draw2 = drawing.clone();

cv::drawContours(drawing, contours,0, cv::Scalar(20,175,20),1,CV_AA);

double dist, maxdist = -1;

cv::Point center;
for(int i = 0;i< contourImg.cols;i++)
{
    for(int j = 0;j< contourImg.rows;j++)
    {

        dist = pointPolygonTest(contours[0], cv::Point(i,j),true);
        if(dist > maxdist)
        {
            maxdist = dist;
            center = cv::Point(i,j);
        }
    }
}

cv::circle(drawing, center, maxdist, cv::Scalar(220,75,20),1,CV_AA);
cv::imshow("Contours", drawing);

cv::waitKey();
return 0;

I've tried to replicate your results, but it works fine for me. Here is the code (C++)

Note that I have padded the input image, in order to have the correct contour (findContours() splits the contour because it touches the image edges). It may that this is your problem.

Also, note the different parameters for findContours. With your flags, the correct contour is the second one (index 1, not 0) in my test. With my flags, the good one is the first (index 0).

image description

cv::Mat contourImg = imread("contour.png");
std::vector<cv::Mat> channels;
cv::split(contourImg, channels);

    // On these lines, the input image is padded
cv::Mat gray(contourImg.rows+20, contourImg.cols+20, CV_8UC1);
gray = 255;
channels[0].copyTo(gray(cv::Rect(10,10,contourImg.cols, contourImg.rows)));

cv::imshow("Original", gray);
std::vector<std::vector<cv::Point> > contours;
cv::findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
cv::Mat drawing(gray.size(), CV_8UC3);
cv::Mat draw2 = drawing.clone();

cv::drawContours(drawing, contours,0, cv::Scalar(20,175,20),1,CV_AA);

double dist, maxdist = -1;

cv::Point center;
for(int i = 0;i< contourImg.cols;i++)
{
    for(int j = 0;j< contourImg.rows;j++)
    {

        dist = pointPolygonTest(contours[0], cv::Point(i,j),true);
        if(dist > maxdist)
        {
            maxdist = dist;
            center = cv::Point(i,j);
        }
    }
}

cv::circle(drawing, center, maxdist, cv::Scalar(220,75,20),1,CV_AA);
cv::imshow("Contours", drawing);

cv::waitKey();
return 0;