如何识别此图像中的矩形?

时间:2009-11-30 01:23:55

标签: graphics artificial-intelligence machine-learning computer-vision

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

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


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

9 个答案:

答案 0 :(得分:22)

Opencv(用c语言编写的图像处理和计算机视觉库)具有hough变换的实现(简单的hough变换在图像中找到行,而广义的变换找到更复杂的对象)所以这可能是一个好的开始。对于有封闭角落的矩形,还有角落探测器,例如cornerHarris可以提供帮助。

我运行了opencv提供的houghlines演示,这是你给出的图像上的结果(检测到的行以红色标记): alt text
(来源:splintec.com

答案 1 :(得分:8)

我相信您正在寻找generalized Hough transform

答案 2 :(得分:4)

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

答案 3 :(得分:3)

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

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

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

答案 4 :(得分:2)

您的问题有几种不同的方法。我会使用像morphological image processing这样的this one工具。您可以灵活地定义“矩形”甚至是“完全关闭”的东西(填充算法失败的地方)。

另一种可能性是使用machine learning方法,它基本上比前一个方法更像数据驱动而不是定义驱动。你必须给你的算法几个矩形的“例子”,它最终会学习(bias和错误率)。

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

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

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

答案 7 :(得分:1)

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

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

从左到右遍历所有像素,每当找到有色像素时,将其坐标添加到数组

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

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

答案 8 :(得分:1)

从几乎触摸水平和垂直线的图像到矩形:

  1. 转换为二进制(即所有行 是白色,其余是黑色的)
  2. 执行Binary dilation(此处您可以使每个像素接触源图像中的白色像素,或者是源图像中的白色像素白色。触摸仅为直线(因此每个像素“触摸”像素为它的左侧,右侧,上方和下方)这称为“4连接”
  3. 如果两端之间的间隙大于2像素宽,则重复步骤3几次,但不要太频繁!
  4. 执行骨架操作(如果源图像中的白色像素触及至少一个黑色像素并且触摸的白色像素(在源图像中)全部触摸,则输出图像中的每个像素都是黑色的再次触摸定义为4连通性。请参见下面的示例。
  5. 重复步骤4,直到重复后图像不会改变(所有白色像素为线端或连接器)
  6. 运气好的话,首先会显示厚胖线的方框,在整个图像上留下厚厚的脂肪(步骤3之后),然后在步骤5之后,所有厚厚的脂肪都会被删除,而所有的盒子都留下您需要在步骤3中调整重复次数以获得最佳结果。如果您对图像形态感兴趣,this is the book of a really good introductory course I took.

    示例:(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