【问题标题】:How to get the largest rectangle inside a contour?如何获得轮廓内最大的矩形?
【发布时间】:2019-10-29 02:39:19
【问题描述】:

我想问一下是否有更好或更快的替代方法来获得几乎矩形轮廓内的最大矩形。

矩形应与 x 轴和 y 轴对齐,并且应完全位于矩形轮廓内。这意味着它不会包含任何外部白色像素,但会占据轮廓中的最大区域。

测试图片在这里:

我已经尝试过thesetwo,但我正在寻找是否有更快更简洁的方法来解决这个问题。

我还尝试通过轮廓的点并获得最小和最大点,如 here 但当然,它只是显示与 cv2.boundingRect 已经做的类似的结果。

【问题讨论】:

标签: python python-3.x opencv


【解决方案1】:

也许这有点横向思考,但是看看你的例子和规范,而不是用外部边界框填充白色尖刺。 (就像 Paint 类型应用程序中的“油漆罐”画笔)。

例如(红色像素是你会从白色变成黑色的像素):

您甚至可以将处理限制在外部 N 个像素。

=============================

那么如何实现呢?它本质上是像素图形程序中使用的“填充”算法的一个版本,只是您不是从单个种子像素开始,而是检查外部边界矩形边缘上的每个点。您开始填写并建立一堆您需要返回的点,因为您不一定必须同时关注每个区域,并且可能需要自己返回。

您可以查看该算法,但如果您推送您现在无法遵循的每个点,特别是从形状的整个边界开始,“纯”版本将非常大量堆栈。

我还没有以这种方式实现它,但我的第一个想法是从边界向内扫描,一次获取一整行像素,并用新的第三种颜色标记所有“白色”像素,然后打开下一行填充所有接触先前标记的像素的白色像素,依此类推。 (无论您是否将更改的像素标记为第三种颜色、蒙版或 alpha 通道或其他任何内容 - 但您必须能够区分新填充的像素和旧的黑色像素。

在进行过程中,您需要检查是否有任何“搁浅”区域,您需要向后工作以填充未直接连接到外部的白色区域:

从边缘开始填充...

当心滞留区域 - 如果您找到一个,请向后扫描以填充,然​​后再前往您之前所在的位置,然后携带一个(如果您的滞留区域再次自行恢复,您可能需要递归,尽管在您的特定应用程序中与某些图形应用程序不同,这应该不是一个大问题)

然后继续,如果需要,不要忘记从其他边缘进行填充(请参阅下面的注释),直到您到达没有更多像素要填充且不再需要回填的行。然后在图像的另一侧重新开始,因为您需要从另一侧开始向后传球以捕捉该侧的其他任何东西。

对于实际的实现,需要考虑一些事情。您的示例将在边缘进行大量填充,但通过遵循复杂的内部形状不会太多,这使事情变得简单。但是您需要从所有 4 个方面进行工作才能有效地完成工作——也许以一系列同心矩形的形式工作,而不是一次工作在一个方面。设计过程中的复杂性更高,但在此示例中效率更高。

无论如何都值得深思。

【讨论】:

  • 这是一个有趣的方法!你是怎么做到的?
  • 我还没有按照描述的那样实现这个,但是在过去的日子里,我为计算机图形应用程序做了类似的事情。虽然你会一致地递归,如果那里的洞自己回来,它不会经常发生,所以一个简单的点列表/堆栈可以覆盖它。可以看到很多实现每行填充的方法,但这似乎并不密集,因此您不必非常复杂。
  • 它确实给了我洞察力。最终目标是在忽略噪音的情况下可靠地读取字符。我用类似的方法完成了这个程序,尽管方法很简单:我只是“淹没”了图像两次(一个用于盒子的外部,另一个用于内部),剩下的必须是里面的数字。但它并不完美,与框相交的字符被淹没,导致它被忽略或被读取为两个单独的字符。无论如何,谢谢!
猜你喜欢
  • 2019-01-26
  • 2019-08-19
  • 2016-09-19
  • 2022-01-10
  • 2021-11-19
  • 1970-01-01
  • 2021-09-01
  • 2017-07-31
  • 2018-03-11
相关资源
最近更新 更多