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


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

结果是带有边缘的二进制图像。我现在真的不知道哪种方法对各种不同的图像效果更好。有什么想法吗?

评论

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

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

此线程可能有用-dsp.stackexchange.com/questions/2975/…

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

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

#1 楼

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

程序没有在Hough图像(线)中查找单个峰,而是搜索了4个峰之间的90度距离。

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

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

#2 楼

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

#3 楼

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

        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


评论


$ \ begingroup $
欢迎使用dsp.stackexchange :)任何答案,即使是较晚的答案,也都非常受欢迎,但是如果您在答案中提供了一些上下文,那就太好了。提供解释性说明和来源的答案是首选的-您可以编辑答案,写一些代码功能以及如何解决所问问题的句子,甚至可以引用源代码吗?如果可以使您的答案好得多。另外,请编辑您的标识-我已经尝试过,但是在查看了三分之一的代码后迷路了。
$ \ endgroup $
–佩内洛普
2012年11月23日12:54

#4 楼

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

有使用opencv示例进行此操作

#5 楼

查找矩形的Python教程
从头开始编写。使用Canny和Hough线。