0

I'm continuing my work with openCV, my first adventures I described here. It goes on quite well, but I've stumbled upon another tricky thing. I want to find contours on the image I've applied adaptive threshold to:

enter image description here

So the cvFindContours seems to work quite nice and here's the result:

enter image description here

The problem is, when I try to iterate over the found countours, it says there's only one contour (contours->total in the following code equals 1). Here's the code:

IplImage* img;
if((img = cvLoadImage( "photos/img-000012.ppm", 1)) == 0 )
{
    perror("cvLoadImage");
    return 1;
}
cvNamedWindow( "Image view", 1 );
cvShowImage( "Image view", img );

IplImage* gray = cvCreateImage( cvGetSize(img), 8, 1 ); // allocate a 1 channel byte image
cvCvtColor( img, gray, CV_BGR2GRAY );
cvShowImage( "Image view", gray );
cvWaitKey(0);

cvAdaptiveThreshold(gray, gray,
        255,    //  Non-zero value assigned to the pixels for which the condition is satisfied
        CV_ADAPTIVE_THRESH_MEAN_C, // adaptiveMethod
        CV_THRESH_BINARY_INV,   // thresholdType
        11, // blockSize
        5); // Constant subtracted from the mean or weighted mean
cvShowImage( "Image view", gray );
cvWaitKey(0);

IplConvKernel *se = cvCreateStructuringElementEx(3, 3, 1,  1,  CV_SHAPE_RECT, NULL);
cvErode(gray, gray, se, 1);
cvShowImage( "Image view", gray );
cvWaitKey(0);

IplImage *canny_out = cvCreateImage(cvGetSize(gray), 8, 1);
cvCanny(gray, canny_out, 50, 100, 3);
cvShowImage( "Image view", canny_out );
cvWaitKey(0);

CvMemStorage *storage = cvCreateMemStorage(0);
CvSeq *contours = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), storage);
cvFindContours(gray, storage, &contours, sizeof(CvContour), CV_RETR_LIST,
        CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
printf("contours->total = %d\n", contours->total);

cvDrawContours(img, contours, CV_RGB(0,255,0), CV_RGB(0,0,255),
        2, 1, 8, cvPoint(0, 0));
cvShowImage( "Image view", img );
cvWaitKey(0);

Should it be this way, that there's only one contour? Maybe I don't understand the openCV's definition of a contour? I'd appreciate your help.

Community
  • 1
  • 1
Wojtek
  • 2,514
  • 5
  • 26
  • 31

2 Answers2

2

Actually cvFindContours returns number of founded contours (I tested your picture and it returned >1). See docs. But I don't know why total equals one.

ArtemStorozhuk
  • 8,715
  • 4
  • 35
  • 53
  • 1
    Yes, I've found another way to iterate through it here: http://stackoverflow.com/questions/6044119/opencv-cvfindcontours-how-do-i-separate-components-of-a-contour (karlphillip's post) and indeed there's more than one contour. I don't know either why `total` says it's one. Anyway thank you for the answer, if I had not found that post I would probably still have pondered why it did't work :) – Wojtek Aug 07 '12 at 19:52
0
  1. you don't need to cvCreateSeq() before cvFindContours()
  2. instead of contours->total, iterate through them.

    for (; contours != 0; contours = contours->h_next)

Matthias
  • 3,582
  • 2
  • 30
  • 41
srgb
  • 1
  • 1