5 votes

Détection de petits cercles avec OpenCV (mauvaise qualité d'image)

J'essaie de détecter les quatre points que vous pouvez voir au centre de cette image : enter image description here Celui-ci est converti en png, j'utilise en fait un format ppm (après conversion à partir de la sortie brute de l'appareil photo). L'image traitée est disponible aquí

Je suis nouveau à opencv et j'ai donc un énorme problème pour détecter ces points. Voici le meilleur résultat que j'ai obtenu jusqu'à présent : enter image description here

Comme vous pouvez le voir, j'ai détecté 3 des points, mais à part cela, beaucoup d'autres éléments de l'image sont reconnus comme des cercles.

Et voici le 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);

Avez-vous une idée sur la manière de résoudre ce problème ? Je vous en serais très reconnaissant. Je pense qu'il est assez facile pour un œil humain de repérer les points, j'espère donc pouvoir les détecter à l'aide d'un ordinateur.

4voto

Quentin Geissmann Points 1110

Vous devriez jeter un coup d'œil sur ce poste .

Avec l'application que je suis en train de développer sur cette base, j'ai obtenu :

enter image description here

Vous pourriez en fait adapter cette méthode à votre cas et le rendre beaucoup plus efficace : "5." ("valider ou invalider les contours en fonction de leur forme (taille, surface, convexité..."). Dans votre cas, les conditions pourraient être beaucoup plus strictes puisque vous n'avez pas de groupes de cercles. . Vous pourriez simplement mapper des objets qui sont presque cercles parfaits . De plus, vous savez que vos cercles ont la même taille/intensité relative...

Dites-moi si quelque chose n'est pas clair,

Bonne chance,

0voto

Alex Hoppus Points 618

Je pense que même si la transformation n'est pas le meilleur cas. Vous pouvez probablement les segmenter et les reconnaître simplement à l'aide de leur couleur et de leurs paramètres géométriques.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X