如何检测边缘和矩形


14

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

  1. Sobel或Canny筛选器

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

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


1
你说“做得更好”是什么意思?Canny在这种事情上非常流行,但是这取决于您掌握优势后要尝试执行的操作。您到底想达到什么目的?
Paul R

4
请不要对新用户在社区中的第一个问题投反对票!


边缘检测器说明:dsp.stackexchange.com/q/74/1273
penelope

“结果是带有边缘的二进制图像。我现在真的不知道哪种方法对各种不同的图像更有效。有什么想法吗?” 也许您需要一些图像测试库来找到答案,或者在您可能需要的环境中拍照。如果在这个领域有最好的算法,那为什么还要学习很多呢?

Answers:


10

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

该程序没有在霍夫图像(线)中寻找单个峰,而是搜索了四个峰之间的90度距离的峰。

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

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


5

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


2

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

        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
欢迎使用dsp.stackexchange :)非常欢迎任何答案,即使是较晚的答案,但是如果您提供一些答案的上下文,那将是很好的。提供解释来源的答案是优选的-您可以编辑答案,写一些代码做什么以及如何解决所遇到的问题的句子,如果不是您,您可以引用源代码吗?如果可以使您的答案好得多。另外,请编辑您的标识-我已经尝试过,但是在查看了三分之一的代码后迷路了。
penelope

0

如果您的图像相对干净,则您可以看到明显的矩形而没有很多间断。霍夫变换的另一种选择是创建轮廓并将其缩小,直到它们形成4边轮廓=您的矩形。

有opencv示例可以做到这一点


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.