Come rilevare bordi e rettangoli


14

Provo a rilevare rettangoli nelle immagini. Lo sfondo delle immagini è di un colore (il più delle volte). Ho provato due metodi per ottenere un'immagine binaria (1 = sfondo, 0 = bordi), per fare una trasformazione di Hough in seguito ...

  1. Filtro Sobel o Canny

  2. Immagine uniforme A, Crea immagine differenza A - gauss, Crea immagine binaria con soglia (Crea istogramma, il cestino più alto dovrebbe essere sfondo ...)

Il risultato è un'immagine binaria con bordi. Non so davvero quale metodo funzioni meglio per una varietà di immagini diverse. Qualche idea?


1
Cosa intendi con "funziona meglio"? Canny è molto popolare per questo tipo di cose, ma dipende da cosa stai cercando di fare una volta che hai i bordi. Cosa stai cercando di ottenere, esattamente?
Paolo R

4
Per favore, non votare verso il basso i nuovi utenti per la loro prima domanda sulla community!

1
Questa discussione potrebbe essere utile- dsp.stackexchange.com/questions/2975/…
Jim Clay

Spiegazione dei rilevatori di bordi: dsp.stackexchange.com/q/74/1273
penelope,

"Il risultato è un'immagine binaria con i bordi. Non so davvero quale metodo funzioni meglio per una varietà di immagini diverse. Qualche idea?" Forse hai bisogno di un po 'di lib di test di immagini per trovare la risposta o scattare alcune foto negli ambienti che potresti contare. Se esistono i migliori algoritmi in questo campo, perché dovremmo imparare così tanti altri? Credo che ogni algoritmo abbia qualche vantaggio, a volte in senso probabilistico.

Risposte:


10

Una volta ho scritto un'applicazione per il rilevamento di rettangoli. Ha utilizzato il rilevamento del bordo Sobel e la trasformazione della linea Hough.

Invece di cercare singoli picchi nell'immagine (linee) di Hough, il programma ha cercato 4 picchi con una distanza di 90 gradi tra di loro.

Per ogni colonna nell'immagine di Hough (corrispondente ad un angolo), sono state cercate altre tre colonne per i massimi locali. Quando è stato trovato il picco satifattivo in ciascuna delle quattro colonne, il rettangolo è stato rilevato.

Il programma ha costruito il rettangolo e fatto ulteriori controlli per la coerenza dei colori all'interno e all'esterno del rettangolo per discriminare i falsi positivi. Il programma prevedeva il rilevamento del posizionamento della carta nei fogli di carta scansionati.


5

Potresti scoprire che il Laplacian of Gaussian edge detector è una scelta migliore. Dovrebbe darti contorni chiusi più spesso del rilevatore di bordi Canny. Credo che sia quello che vuoi dal momento che il tuo prossimo passo è applicare la trasformazione di Hough.


2

Potrebbe esserti utile, ma è troppo tardi perché visito questo sito oggi

        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
Benvenuto in dsp.stackexchange :) Qualsiasi risposta, anche in ritardo, è molto gradita, ma sarebbe bello se tu fornissi un contesto alla tua risposta. Le risposte che forniscono spiegazioni e fonti sono preferite: potresti modificare la tua risposta, scrivere alcune frasi su ciò che fa il codice e su come potrebbe aiutare con il problema chiesto e magari citare la fonte se non sei tu? Se renderebbe la tua risposta molto migliore. Inoltre, modifica la tua identificazione per favore - ci ho provato, ma mi sono perso dopo aver esaminato un terzo del tuo codice.
penelope,

0

Se la tua immagine è relativamente pulita, hai rettangoli evidenti senza molte interruzioni, l'alternativa a una trasformazione di Hough è quella di creare contorni e ridurli fino a formare un contorno a 4 lati = il tuo rettangolo.

Ci sono campioni opencv per fare questo


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.