如何在这张图片中识别矩形?

33
我有一张由水平和垂直线组成的图片,实际上这张图片是BBC网站转化为水平和垂直线后的结果。我的问题在于我想要能够找到图片中的所有矩形。我希望编写一个计算机程序来查找所有的矩形。
请问有人知道如何做到这一点或有哪些建议可以帮助我入手吗?对于我来说,作为人来找到视觉中的矩形是很容易的,但我不确定如何将其描述为程序。
图片链接:http://www.bbc.co.uk/ 更新:我编写了将BBC网站图片转换为水平和垂直线的代码,但问题在于这些线段不完全相交于角落,并且有时它们也不能形成一个完整的矩形。谢谢!

3
整洁。用什么程序创建了这张图片?您能使用它的源代码 - 识别框以便绘制它们 - 以满足自己的需求吗?还是只有最终的.png图像可供使用? - poundifdef
请问您能否分享一下您的结果以及您是如何得出上述图形的? - Xolve
你能重新上传图片吗? - endolith
请不要访问ironnine.com的链接,该网站上检测到了恶意软件。 - Mirko Brunner
任何有效的 Github 链接以测试实际答案。我正在寻找从图像中检测矩形并显示计数的方法。 - srikar nagadevara
显示剩余2条评论
9个回答

24

Opencv 是一个用C语言编写的图片处理和计算机视觉库,其中实现了Hough变换(简单的Hough变换可以在图像中检测直线,而广义的Hough变换则可以检测更复杂的对象),这可能是一个很好的起点。对于那些有闭合角落的矩形,也可以使用类似cornerHarris的角点检测器来帮助。

我运行了Opencv提供的houghlines演示程序,并得到以下结果(在给出的图片上检测到的线条用红色标注出来): alt text
(来源:splintec.com


请问您能否提供GitHub或任何存储库链接以尝试此代码?https://stackoverflow.com/users/235263/elijah - srikar nagadevara

10

4
在计算机视觉中,有一种名为广义霍夫变换的算法,也许可以解决您的问题。已经有实现此算法的开源代码可供搜索。

3
假设这是一张相对清晰的图片(不是屏幕录像),那么使用简单的泛洪算法之一即可。您可能需要在图像上运行膨胀/腐蚀操作来填补空隙。
找到线条的常规方法是霍夫变换(然后找到直角线)。Opencv 是最简单的方法。
请参考此问题:OpenCV 对象检测 - 中心点。 OpenCV Object Detection - Center Point

2
你的问题有几种不同的方法。我会使用像形态学图像处理这样的工具,比如这个。你将能够灵活定义“矩形”,甚至可以是一些“不完全闭合”的东西(填充算法将失败)。
另一个可能性是使用机器学习方法,这基本上比前面那个更加数据驱动而不是定义驱动。你需要给你的算法几个“例子”来说明什么是矩形,它最终会学习(带有偏差和错误率)。

1
另一种方法是在图像上找到任何有颜色的像素,然后执行。
while(pixel under current is colored)
{
  lowest pixel coordinate = pixel under current
  current = pixel under
}

然后向上执行相同的操作。 现在您已经定义了一条单独的线。然后使用线的端点将线条近似匹配成矩形。如果它们不是像素完美的,您可以进行某种阈值处理。


简单的方法,但需要大量编码。 - FindOutIslamNow

1

从具有几乎接触的水平和垂直线的图像到仅矩形的转换:

  1. 转换为二进制(即所有线条均为白色,其余部分为黑色)
  2. 执行二值膨胀(在此处,您使源图像中与白色像素接触或是白色像素的每个像素变为白色。接触仅为直线(因此每个像素“接触”其左侧、右侧、上方和下方的像素),这称为“4连通”)
  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    

1

从左到右迭代,直到遇到彩色像素,然后使用修改的泛洪填充算法。有关该算法的更多信息,请参见维基上的泛洪填充


1
洪水填充算法可行,或者你可以使用边缘跟踪算法的修改版。
你要做的是: 创建一个二维数组(或任何其他d2数据结构)-每一行代表屏幕上的水平像素线,每一列代表垂直线。
从左到右遍历所有像素,每当找到一个有颜色的像素,就将其坐标添加到数组中。
遍历数组,找到线并存储每条线的起始和结束像素(不同的数据结构)。
知道每条线的起始像素是它的左/上像素,你可以轻松地检查是否有任何4条线组成一个矩形。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接