如何检测边缘和矩形

信息处理 图像处理
2021-12-31 05:26:32

我尝试检测图像中的矩形。图像的背景是一种颜色(大部分时间)。我尝试了两种方法来获取二进制图像(1 = 背景,0 = 边缘),稍后进行霍夫变换......

  1. Sobel 或 Canny 过滤器

  2. 平滑图像 A,创建差异图像 A - 高斯,创建具有阈值的二值图像(创建直方图,最高 bin 应该是背景...)

结果是带有边缘的二值图像。我现在真的不知道哪种方法更适合各种不同的图像。有任何想法吗?

4个回答

我曾经写过一个矩形检测的应用程序。它使用 Sobel 边缘检测和线 Hough 变换。

该程序不是在霍夫图像(线)中寻找单个峰,而是搜索它们之间距离为 90 度的 4 个峰。

对于霍夫图像中的每一列(对应于某个角度),搜索其他三列以寻找局部最大值。当在四列中的每一列中都发现了令人满意的峰时,就检测到了矩形。

该程序构建了矩形,并对矩形内外的颜色一致性进行了额外的检查,以区分误报。该程序用于检测扫描的纸张中的纸张位置。

您可能会发现高斯边缘检测器的拉普拉斯算子是更好的选择。它应该比 Canny 边缘检测器更频繁地为您提供闭合轮廓。我相信这就是您想要的,因为您的下一步是应用霍夫变换。

可能对您有帮助,但为时已晚,因为我今天访问此网站

        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

如果您的图像相对干净,则您有明显的矩形,没有很多中断,霍夫变换的替代方法是创建轮廓并缩小它们,直到它们形成 4 边轮廓 = 您的矩形。

有opencv示例可以做到这一点