32

我有一张带有水平线和垂直线的图像。其实这张图片是BBC网站转换成横竖线的。我的问题是我希望能够找到图像中的所有矩形。我想编写一个计算机程序来查找所有矩形。有谁知道如何做到这一点或建议如何开始?作为一个人,这个任务很容易找到视觉矩形,但我不知道如何将它描述为一个程序。

图片是这里的 BBC 网站http://www.bbc.co.uk/


对此更新,我编写了将 BBC 网站图像转换为水平和垂直线的代码,问题是这些线在拐角处不完全相交,有时它们不完全形成一个矩形。谢谢!

4

9 回答 9

24

Opencv(用 c 编写的图像处理和计算机视觉库)实现了霍夫变换(简单的霍夫变换在图像中找到线,而广义的变换找到更复杂的对象),这可能是一个好的开始。对于确实有闭合角的矩​​形,还有角检测器,例如cornerHarris,可以提供帮助。

我运行了 opencv 提供的 houghlines 演示,这是您提供的图像上的结果(检测到的线标记为红色):( 来源:splintec.com替代文字

于 2009-12-22T22:57:52.360 回答
10

我相信您正在寻找广义霍夫变换

于 2009-11-30T02:23:19.530 回答
4

在计算机视觉中,有一种称为广义霍夫变换的算法可能可以解决您的问题。应该有实现该算法的开源代码。只是搜索它。

于 2009-11-30T07:24:23.397 回答
3

假设它是一个合理的无噪声图像(不是屏幕视频),那么其中一个简单的填充算法应该可以工作。您可能需要在图像上运行扩张/腐蚀以缩小差距。

查找线的正常方法是 Hough 变换(然后查找直角线) Opencv 是最简单的方法。

看看这个问题OpenCV Object Detection - Center Point

于 2009-11-30T02:06:53.197 回答
2

有几种不同的方法可以解决您的问题。我会使用像这样的形态图像处理工具。您将可以灵活地定义“矩形”,即使是不“完全闭合”的东西(填充算法将失败)。

另一种可能性是使用机器学习方法,它基本上是数据驱动的,而不是像前一个那样的定义驱动的。您必须为您的算法提供几个矩形的“示例”,它最终会学习(带有偏差和错误率)。

于 2009-11-30T02:07:47.553 回答
1

从左到右迭代,直到你碰到一个颜色像素,然后使用修改后的洪水填充算法。有关算法洪水填充的更多信息 @ wiki

于 2009-11-30T01:31:20.280 回答
1

另一种方法是在图像上找到任何彩色像素,然后使用

while(pixel under current is colored)
{
  lowest pixel coordinate = pixel under current
  current = pixel under
}

然后向上做同样的事情。现在你已经定义了一条线。然后使用线条的末端将线条近似匹配为矩形。如果它们不是像素完美的,您可以进行某种阈值处理。

于 2009-11-30T01:42:50.903 回答
1

洪水填充会起作用,或者您可以使用边缘跟踪算法的修改。

你要做的是:创建一个二维数组(或任何其他 d2 数据结构)- 每行代表屏幕上的一条水平像素线,每列代表一条垂直线

遍历所有像素,从左到右,当你找到一个有颜色的像素时,将它的坐标添加到数组中

遍历数组并查找行并存储每个行的开始和结束像素(不同的数据结构)

知道每行的开头是其左/顶部像素,您可以轻松检查是否有任何 4 行包含一个矩形

于 2009-11-30T01:48:40.707 回答
1

要从几乎接触水平和垂直线到矩形的图像中获取:

  1. 转换为二进制(即所有的行都是白色的,其余的都是黑色的)
  2. 执行二元膨胀(在这里,您将接触源图像中的白色像素或源图像中的白色像素的每个像素设置为白色。触摸只是笔直的(因此每个像素“接触”其左侧、右侧、上方的像素)在它下面)这被称为“4-connected”
  3. 如果两端之间的间隙大于 2 像素宽,则重复步骤 3 几次,但不要太频繁!
  4. 执行骨架操作(如果源图像中的一个白色像素至少接触一个黑色像素并且它接触到的白色像素(在源图像中)都相互接触,则在此处将输出图像中的每个像素设为黑色。再次触摸定义为 4 连通性。请参见下面的示例。
  5. 重复步骤 4,直到重复后图像没有变化(所有白色像素都是线端或连接器)

运气好的话,这将首先显示带有粗粗线条的框,在整个图像上留下粗粗伪影(在步骤 3 之后),然后在步骤 5 之后,所有粗粗伪影都将被移除,而所有框仍然存在. 您需要调整步骤 3 中的重复次数以获得最佳结果。如果您对图像形态学感兴趣,这是我学习的一门非常好的入门课程的书。

样本:(0=黑色,1=白色,正在考虑每个 3x3 块中心的像素,左输入,右输出)

011 => 011    
011 => 001  all other white pixels touch, so eliminate      
011 => 011    

010 => 010    
010 => 010  top pixel would become disconnected, so leave      
010 => 010    

010 => 010    
010 => 000  touches only one white pixel, so remove     
000 => 000    

010 => 010    
111 => 111  does not touch black pixels, leave    
010 => 010    

010 => 010    
011 => 011  other pixels do not touch. so leave    
000 => 000    
于 2009-12-07T22:54:34.340 回答