Cómo detectar aristas y rectángulos

14

Intento detectar rectángulos en las imágenes. El fondo de las imágenes es de un color (la mayoría de las veces). Intenté dos métodos para obtener una imagen binaria (1 = fondo, 0 = bordes), para hacer una Transformación Hough más adelante ...

  1. Filtro Sobel o Canny

  2. Imagen suave A, Crear imagen de diferencia A - gauss, Crear imagen binaria con umbral (Crear histograma, el bin más alto debe ser de fondo ...)

El resultado es una imagen binaria con bordes. Realmente no sé qué método funciona mejor para una variedad de imágenes diferentes. ¿Algunas ideas?

Martin Thompson
fuente
1
¿Qué quieres decir con "funciona mejor"? Canny es muy popular para este tipo de cosas, pero depende de lo que intentes hacer una vez que tengas los bordes. ¿Qué estás tratando de lograr exactamente?
Paul R
44
¡Por favor, no vote a los nuevos usuarios por su primera pregunta en la comunidad!
1
Este hilo podría ser útil- dsp.stackexchange.com/questions/2975/…
Jim Clay
Detectores de bordes explicados: dsp.stackexchange.com/q/74/1273
penelope
"El resultado es una imagen binaria con bordes. Realmente no sé qué método funciona mejor para una variedad de imágenes diferentes. ¿Alguna idea?" Tal vez necesite un poco de lib de prueba de imagen para encontrar la respuesta o tomar algunas fotos en los entornos que tal vez cuente. Si existe un mejor algoritmo en este campo, ¿por qué deberíamos aprender tanto otros? Creo que cualquier algoritmo tiene su ventaja a veces, en sentido de probabilidad.

Respuestas:

10

Una vez escribí una aplicación para la detección de rectángulos. Utilizó la detección de bordes Sobel y la transformación de línea Hough.

En lugar de buscar picos individuales en la imagen de Hough (líneas), el programa buscó 4 picos con una distancia de 90 grados entre ellos.

Para cada columna en la imagen de Hough (correspondiente a algún ángulo), se buscaron en otras tres columnas los máximos locales. Cuando se encontró un pico satisfactorio en cada una de las cuatro columnas, se detectó el rectángulo.

El programa construyó el rectángulo e hizo verificaciones adicionales para la consistencia del color dentro y fuera del rectángulo para discriminar falsos positivos. El programa fue para detectar la colocación de papel en hojas de papel escaneadas.

Libor
fuente
5

Es posible que el detector de bordes laplaciano de Gauss sea una mejor opción. Debería darle contornos cerrados con más frecuencia que el detector de bordes Canny. Creo que eso es lo que desea, ya que su próximo paso es aplicar la transformación Hough.

chippies
fuente
2

Puede ser útil para usted, pero es demasiado tarde cuando visito este sitio hoy

        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
fuente
2
Bienvenido a dsp.stackexchange :) Cualquier respuesta, incluso una tardía, es muy bienvenida, pero sería bueno si proporcionara algún contexto con su respuesta. Se prefieren las respuestas que proporcionan explicaciones y fuentes : ¿podría editar su respuesta, escribir algunas oraciones de lo que hace el código y cómo ayudaría con el problema planteado, y tal vez citar la fuente si no es usted? Si tu respuesta fuera mucho mejor. Además, edite su idea por favor, lo he intentado, pero me perdí después de pasar por un tercio de su código.
Penélope
0

Si su imagen es relativamente limpia, tiene rectángulos obvios sin muchos cortes, la alternativa a una transformación Hough es crear contornos y reducirlos hasta que formen un contorno de 4 lados = su rectángulo.

Hay muestras de opencv para hacer esto

Martin Beckett
fuente