5

I'm trying to detect the four dots you can see in the center of this picture: enter image description here This one is converted to png, I actually use a ppm format (after conversion from raw output from the camera). The actual processed image is available here

I'm new to opencv and therefore have a huge problem detecting those dots. Here's my so far best result: enter image description here

As you can see, I've detected 3 of the dots, but aside from that also lots of other things in the picture are recognized as circles.

And 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 );
//  cvWaitKey(0);

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

    cvSmooth( gray, gray, CV_GAUSSIAN, 3, 3, 0, 0 );
    cvShowImage( "Image view", gray );
    cvWaitKey(0);

    CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT,
            4,      // inverse ratio of the accumulator resolution
            1,      // minimum distance between circle centres
            100,    // higher threshold value for Canny
            20,     // accumulator threshold for the circle centers; smaller->more false circles
            1,  // minimum radius
            10 );   // maximum radius

    printf("circles == %d\n", circles->total);
    int i;
    for (i = 0; i < circles->total; i++) {
        float *p = (float*)cvGetSeqElem(circles, i);
        CvPoint center = cvPoint(cvRound(p[0]),cvRound(p[1]));
        CvScalar val = cvGet2D(gray, center.y, center.x);
        if (val.val[0] < 1) continue;
        printf("%d %d %d\n", cvRound(p[0]),cvRound(p[1]), cvRound(p[2]));
        cvCircle(img,  center, cvRound(p[2]),             CV_RGB(0,255,0), 1, CV_AA, 0);
    }
    cvShowImage( "Image view", img );
    cvWaitKey(0);

Do you have any idea how to help that? I would be most grateful. I think it's quite easy for a human eye to spot the dots, so I hope I can detect them using a computer.

Wojtek
  • 2,514
  • 5
  • 26
  • 31

2 Answers2

4

You should have a look at this post.

With the application I am developing based on it, I got:

enter image description here

You could basically adapt this method to you case and make it much more efficient: "5." ("validate or invalidate contours on the grant of their shape (size, area, convexity..."). In your case could be much more stringent since you do not have clusters of circles. You could just map objects that are almost perfect circles. In addition, you know that your circles have the same size/relative intensity...

Tell me if anything is not clear,

Good luck,

Community
  • 1
  • 1
Quentin Geissmann
  • 2,240
  • 1
  • 21
  • 36
  • Since you have already implemented this, do you think this approach can be feasible on real-time system? We plan to use the image recognition in such system with 600 MHz clock. I'm mainly thinking about adaptive thresholding, as it says to be time-consuming. I can understand, from roughly skimming through it, your idea. And the results you provided are very promising, will definitely try to do something similar. – Wojtek Aug 05 '12 at 15:10
  • yes, it could be feasible is so far as 1) you do not have to call the function cv::adaptiveThreshold for each iteration/threshold value (you can convolve an image so you just have to threshold each time). 2) you can work in grey-scale. – Quentin Geissmann Aug 05 '12 at 16:53
0

I think that hough transform is not a best case. Probably you can segment them and simply recognize using their color and geometric parameters.

Alex Hoppus
  • 3,821
  • 4
  • 28
  • 47
  • Perhaps, but as you can see the color is really hard to distinguish here, the whole image looks almost like greyscale. Also, I don't think I can rely on geometric parameters, because ultimately we would like to be able to detect the dots scattered throughout the whole ceiling, so the further ones will appear smaller and could therefore be omitted if I set a fixed-radius circles for the algorithm to find. And what do you mean by segmenting them? – Wojtek Aug 05 '12 at 12:22