如何识别这个图像中的矩形?

我有一个水平和垂直线的图像。 事实上,这个形象是BBC网站转换成横向和纵向的线条。 我的问题是,我想能够find图像中的所有矩形。 我想编写一个计算机程序来查找所有的矩形。 有谁知道如何做到这一点或build议如何开始的想法? 这个任务对我来说很容易find视觉矩形,但我不知道如何将其描述为一个程序。

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

谢谢,菲利普


更新到这里,我写了将BBC网站图片转换成水平和垂直线的代码,问题是这些线条在angular落处并不完全相遇,有时它们并不完全形成矩形。 谢谢!

Opencv (用c编写的image processing和计算机视觉库)具有hough变换的实现(简单的hough变换在图像中查找线,而泛化的变换find更复杂的对象),这可能是一个好的开始。 对于确实有闭angular的矩形,还有angular点探测器,如cornerHarris,它可以帮助。

我跑了与opencv提供的houghlines演示,这里是你给的图像的结果(检测到的线条标记为红色): alt text http://imageapp.splintec.comhttp://img.dovov.comScreenshot2.png

我相信你正在寻找广义Hough变换 。

在计算机视觉中有一种叫做广义霍夫变换的algorithm,可以解决你的问题。 应该有开源的代码已经实现了这个algorithm。 只要search它。

假设这是一个合理的无噪声图像(而不是一个屏幕的video),那么简单的洪泛algorithm之一应该工作。 您可能需要在图像上运行扩张/侵蚀以缩小差距。

寻找线的正常方法是霍夫变换(然后find直angular线)Opencv是最简单的方法。

看看这个问题OpenCV对象检测 – 中心点

有几个不同的方法来解决你的问题。 我会使用像这样的形态image processing工具。 您将可以灵活地定义“矩形”,即使是“完全closures”(填充algorithm将失败)的东西。

另一种可能是使用机器学习方法,基本上比上一个定义驱动更多的数据驱动。 你必须给你的algorithm几个矩形的“例子”,它最终将学习( 偏见和错误率)。

从左到右迭代,直到你点击一个彩色像素,然后使用修改的洪水填充algorithm。 更多关于algo flood fill @ wiki的信息

洪水填充将工作,或者你可以使用边缘跟踪algorithm的修改。

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

遍历所有的像素,从左到右,每当你find一个彩色的坐标添加到数组

迭代遍历数组,find行并存储每个元素的开始和结束像素(不同的数据结构)

知道每一行的开始是它的左/顶像素,你可以很容易地检查是否有任何4行包含一个矩形

从几乎感人的水平线和垂直线的图像中,只能看到矩形:

  1. 转换为二进制(即所有的行是白色的,其余的是黑色的)
  2. 执行二进制扩张 (在这里,您将使每个像素都接触到源图像中的白色像素,或者是源图像中的白色像素是白色的,只是触摸是直线的(所以每个像素“接触”像素在其左上方,右上方和下面)这被称为“四连接”
  3. 重复步骤3几次,如果两端之间的差距大于2像素宽,但不太经常!
  4. 执行一个骨架操作(在这里,如果input图像中的每个像素是源图像中的一个白色像素,触摸至less一个黑色像素,并且它接触到的白色像素(在源图像中)全部触摸海誓山盟,则再次触摸定义为4连通性,见下面的示例。
  5. 重复第4步,直到重复后图像不会改变(所有的白色像素是行结束或连接器)

这将有一点运气,首先显示厚厚的线条框,在整个图像(步骤3之后)留下厚厚的人工制品,然后在步骤5后,所有厚厚的人工制品将被删除,而所有的盒子仍然保留。 您需要在第3步中重复重复次数以获得最佳结果。 如果你对图像形态感兴趣, 这是我所学的一门非常好的入门课程。

示例:(0 =黑色,1 =白色,正在考虑每个3×3块的中心的像素,input左边,输出右边)

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 

另一种方法是在图像上find任意颜色的像素,然后去处理

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

然后向上做同样的事情。 现在你已经定义了一条线。 然后使用行的末端来将线条近似匹配成矩形。 如果他们不是像素完美的,你可以做一些类似的tresholding。