So erkennen Sie Kanten und Rechtecke


14

Ich versuche Rechtecke in Bildern zu erkennen. Der Hintergrund der Bilder ist (meistens) einfarbig. Ich habe zwei Methoden ausprobiert, um ein Binärbild (1 = Hintergrund, 0 = Kanten) zu erhalten und später eine Hough-Transformation durchzuführen ...

  1. Sobel oder Canny Filter

  2. Bild glätten A, Differenzbild erstellen A - Gauss, Binärbild mit Schwelle erstellen (Histogramm erstellen, oberste Bin sollte Hintergrund sein ...)

Das Ergebnis ist ein Binärbild mit Kanten. Ich weiß jetzt nicht wirklich, welche Methode für eine Vielzahl von verschiedenen Bildern besser funktioniert. Irgendwelche Ideen?


1
Was meinst du mit "funktioniert besser"? Canny ist sehr beliebt für diese Art von Dingen, aber es hängt davon ab, was Sie versuchen, sobald Sie die Kanten haben. Was genau versuchst du zu erreichen?
Paul R

4
Bitte stimmen Sie neue Benutzer nicht für ihre allererste Frage in der Community ab!

1
Dieser Thread könnte nützlich sein- dsp.stackexchange.com/questions/2975/…
Jim Clay

Kantendetektoren erklärt: dsp.stackexchange.com/q/74/1273
penelope

"Das Ergebnis ist ein binäres Bild mit Kanten. Ich weiß nicht, welche Methode für eine Vielzahl verschiedener Bilder besser geeignet ist. Irgendwelche Ideen?" Möglicherweise benötigen Sie eine Bildtestbibliothek, um die Antwort zu finden, oder machen Sie einige Fotos in Umgebungen, die Sie möglicherweise zählen. Wenn es auf diesem Gebiet die besten Algorithmen gibt, warum sollten wir dann so viel lernen? Ich glaube, dass Algorithmen manchmal im Sinne der Wahrscheinlichkeit einen Vorteil haben.

Antworten:


10

Ich habe einmal eine Anwendung zur Rechteckerkennung geschrieben. Es wurden die Sobel-Kantenerkennung und die Line-Hough-Transformation verwendet.

Anstatt einzelne Peaks im Hough-Bild (Linien) zu suchen, hat das Programm 4 Peaks mit einem Abstand von 90 Grad zwischen ihnen gesucht.

Für jede Spalte im Hough-Bild (entsprechend einem bestimmten Winkel) wurden drei weitere Spalten nach lokalen Maxima durchsucht. Wenn in jeder der vier Spalten ein zufriedenstellender Peak gefunden wurde, wurde das Rechteck erkannt.

Das Programm erstellte das Rechteck und überprüfte zusätzlich die Farbkonsistenz innerhalb und außerhalb des Rechtecks, um falsche Positive zu erkennen. Das Programm diente zum Erkennen der Papierplatzierung in gescannten Papierbögen.


5

Möglicherweise ist der Laplace-Gauß-Kantendetektor die bessere Wahl. Es sollte Ihnen häufiger geschlossene Konturen geben als der Canny-Kantendetektor. Ich glaube, das ist es, was Sie wollen, da Ihr nächster Schritt darin besteht, die Hough-Transformation anzuwenden.


2

Könnte hilfreich für Sie sein, aber es ist zu spät, als ich diese Seite heute besuche

        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

2
Willkommen bei dsp.stackexchange :) Jede Antwort, auch eine späte, ist sehr willkommen, aber es wäre schön, wenn Sie einen Kontext mit Ihrer Antwort angeben würden. Antworten mit Erklärungen und Quellen werden bevorzugt - könnten Sie Ihre Antwort bearbeiten, ein paar Sätze schreiben, was der Code bewirkt und wie es bei dem gestellten Problem helfen würde, und vielleicht die Quelle angeben, wenn Sie es nicht sind? Wenn würde Ihre Antwort viel besser machen. Bearbeiten Sie bitte auch Ihre Identität - ich habe es versucht, aber ich habe mich verlaufen, nachdem ich ein Drittel Ihres Codes durchgearbeitet habe.
Penelope

0

Wenn Ihr Bild relativ sauber ist, haben Sie offensichtliche Rechtecke ohne viele Unterbrechungen. Die Alternative zu einer Hough-Transformation besteht darin, Konturen zu erstellen und zu verkleinern, bis sie eine vierseitige Kontur = Ihr Rechteck bilden.

Dafür gibt es opencv-Beispiele


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.