Comment détecter les bords et les rectangles

14

J'essaie de détecter des rectangles dans les images. Le fond des images est une couleur (la plupart du temps). J'ai essayé deux méthodes pour obtenir une image binaire (1 = fond, 0 = bords), pour faire une transformation Hough plus tard ...

  1. Filtre Sobel ou Canny

  2. Image lisse A, Créer une image de différence A - gauss, Créer une image binaire avec seuil (Créer un histogramme, le bac le plus élevé doit être le fond ...)

Le résultat est une image binaire avec des bords. Je ne sais pas vraiment maintenant quelle méthode fonctionne le mieux pour une variété d'images différentes. Des idées?

Martin Thompson
la source
1
Qu'entendez-vous par «fonctionne mieux»? Canny est très populaire pour ce genre de chose, mais cela dépend de ce que vous essayez de faire une fois que vous avez les bords. Qu'essayez-vous de réaliser exactement?
Paul R
4
Veuillez ne pas voter contre les nouveaux utilisateurs pour leur toute première question sur la communauté!
1
Ce fil pourrait être utile
Jim Clay
Explication des
penelope
"Le résultat est une image binaire avec des bords. Je ne sais pas vraiment maintenant quelle méthode fonctionne mieux pour une variété d'images différentes. Des idées?" Peut-être avez-vous besoin d'une bibliothèque de test d'image pour trouver la réponse ou prendre des photos dans les environnements que vous comptez peut-être. S'il existe un meilleur algorithme dans ce domaine, pourquoi devrions-nous en apprendre tant d'autres? Je crois que tout algorithme a parfois son avantage, au sens des probabilités.

Réponses:

10

J'ai écrit une fois une application pour la détection de rectangle. Il a utilisé la détection de bord Sobel et la transformation de Hough en ligne.

Au lieu de rechercher des pics uniques dans l'image de Hough (lignes), le programme a recherché 4 pics avec une distance de 90 degrés entre eux.

Pour chaque colonne de l'image de Hough (correspondant à un certain angle), trois autres colonnes ont été recherchées pour les maxima locaux. Lorsqu'un pic satifactif a été trouvé dans chacune des quatre colonnes, le rectangle a été détecté.

Le programme a construit le rectangle et fait des vérifications supplémentaires pour la cohérence des couleurs à l'intérieur et à l'extérieur du rectangle pour discriminer les faux positifs. Le programme visait à détecter le placement du papier dans des feuilles de papier numérisées.

Libor
la source
5

Vous pourriez trouver que le détecteur de bord laplacien de gaussien est un meilleur choix. Il devrait vous donner des contours fermés plus souvent que le détecteur de bord Canny. Je crois que c'est ce que vous voulez puisque votre prochaine étape consiste à appliquer la transformation de Hough.

chippies
la source
2

Ça pourrait être utile pour vous mais c'est trop tard car je visite ce site aujourd'hui

        Bitmap bmp=new Bitmap(pictureBox1.Image);
        int x1=0, x2=0, y1=0, y2=0;            
        for (int i = 1; i < bmp.Height;i++ )
        {                
            for (int j = 1; j < bmp.Width;j++ )
            {
                if( bmp.GetPixel(j,i).R<7  &&  bmp.GetPixel(j-1,i).R>240  && bmp.GetPixel(j,i-1).R>240 ){

                    for (int k = j; k < bmp.Width - 1;k++ )
                    {

                        if ((bmp.GetPixel(k, i).R < 7) && (bmp.GetPixel(k+1, i).R > 240) && (k-j>30)) {
                            int count1 = 0;

                            for (int g = j; g < k;g++ ){
                                if(bmp.GetPixel(g,i).R<7){
                                    count1++;                                    
                                }
                            }//get total width

                         if(count1==k-j){                                 
                             x1 = j;
                             y1 = i;
                             x2 = k;
                         }
                        }
                    }
                         for (int a = i; a < bmp.Height - 1;a++ )
                         {
                             if ((bmp.GetPixel(j, a).R < 7) && (bmp.GetPixel(j, a+1).R > 240) && (a- i > 30)) {

                                 int count2 = 0;

                                 for (int x = i; x < a;x++ )
                                 {
                                     if(bmp.GetPixel(j,x).R<7){                                            
                                         count2++;
                                     }
                                 }


                                 if (count2 == (a - i))
                                 {

                                     y2 = a;
                                 }
                                 else {
                                     Console.WriteLine("check");
                                 }
                             }

                         }

                         if ((bmp.GetPixel(x2, y2).R < 7) && (bmp.GetPixel(x2 + 1, y2).R > 240) && (bmp.GetPixel(x2, y2+1).R > 240))
                         {

                             bool r1 = false;
                             bool r2 = false;
                             int count3 = 0;
                             for (int y = y1; y < y2;y++ )
                             {
                                 if(bmp.GetPixel(x2,y).R<7){
                                     count3++;                                     
                                 }
                             }

                             if (count3== y2 - y1) {
                                 r1 = true;
                             }                                
                             if(r1==true){
                                 int count4=0;
                                 for (int x = x1; x < x2;x++ )
                                 {
                                     if(bmp.GetPixel(x,y1).R<7){
                                         count4++;
                                     }
                                 }

                                 if(count4==x2-x1){
                                     r2 = true;
                                     Console.WriteLine("values :  X1 " + x1 + "   y1 :" + y1 + "   width : " + (x2 - x1) + "  height :  " + (y2 - y1));
                                     Pen pen = new Pen(Color.Red, 2);
                                     pictureBox1.CreateGraphics().DrawRectangle(pen, x1, y1, x2 - x1, y2 - y1);
                                 }                     
                             }
                            }

                }

                    }// initial point loop




                }// first if
Zunera Altaf
la source
2
Bienvenue sur dsp.stackexchange :) Toute réponse, même tardive, est la bienvenue, mais ce serait bien si vous fournissiez un peu de contexte avec votre réponse. Les réponses qui fournissent des explications et des sources sont préférées - pourriez-vous modifier votre réponse, écrire quelques phrases de ce que fait le code et comment cela pourrait aider à résoudre le problème posé, et peut-être citer la source si ce n'est pas vous? Cela rendrait votre réponse bien meilleure. Modifiez également votre identité s'il vous plaît - j'ai essayé, mais je me suis perdu après avoir parcouru un tiers de votre code.
penelope
0

Si votre image est relativement propre, vous avez des rectangles évidents sans beaucoup de ruptures. L'alternative à une transformation de Hough est de créer des contours et de les réduire jusqu'à ce qu'ils forment un contour à 4 côtés = votre rectangle.

Il existe des exemples d'opencv pour ce faire

Martin Beckett
la source