我想问是否有更好或更快的替代方法来获得几乎矩形轮廓内的最大矩形。
矩形应与 x 轴和 y 轴对齐,并且应完全位于矩形轮廓内。这意味着它不会包含任何外部白色像素,但会占据轮廓中的最大区域。
测试图像在这里:
我试过these two但我正在寻找是否有更快更整洁的方法来解决这个问题。
我还尝试通过轮廓点并获得最小和最大点,如 here但当然,它只是显示与 cv2.boundingRect
类似的结果已经做到了。
最佳答案
也许这有点横向思考,但是当不使用外部边界框填充白色尖刺时,请查看您的示例和规范。 (就像油漆类型应用程序中的“油漆 jar ”刷子)。
例如。 (红色像素是你会从白色变成黑色的像素):
您甚至可以将过程限制为外部 N 个像素。
==============================
那么如何实现呢?它本质上是像素图形程序中使用的“填充”算法的一个版本,不同之处在于您不是从单个种子像素开始,而是检查外部边界矩形边缘上的每个点。你开始填写并建立一堆你需要返回的点,因为你不一定能同时关注每个领域,可能需要回到你自己。
您可以查看该算法,但如果您推送您现在无法遵循的每个点,特别是从形状的整个边界开始,“纯”版本将非常堆叠。
我没有以这种方式实现它,但我的第一个想法是从边界向内扫描,一次取一整行像素并用新的第三种颜色标记所有“白色”像素,然后在下一行您填充所有接触先前标记的像素的白色像素,依此类推。 (无论您是否将更改的像素标记为第三种颜色、蒙版或 alpha channel 或其他任何内容 - 但您必须能够区分新填充的像素和旧的黑色像素。
当你走的时候,你需要检查任何需要向后工作的“搁浅”区域,以填充不直接连接到外部的白色区域:
从边缘开始填充...
当心滞留区域 - 如果您找到一个,在去之前的地方之前向后扫描以填充,携带一个(如果您滞留区域再次自行恢复,您可能需要递归,尽管在您的特定应用程序中这不应该'与某些图形应用程序不同,这不是一个大问题)
继续,如果需要,不要忘记从其他边缘填充(见下面的注释),直到你到达没有更多像素要填充并且不再需要回填的行。然后在图像的另一侧重新开始,因为您需要从另一侧开始向后传球以捕捉该侧的其他任何东西。
对于实际的实现,需要考虑一些事情。您的示例将在边缘进行大量填充,但通过遵循复杂的内部形状不会太多,这使事情变得简单。但是您需要从所有 4 个方面进行工作才能有效地完成工作——也许以一系列同心矩形的形式工作,而不是一次工作在一个方面。通过设计工作的复杂性更高,但在此示例中效率更高。
总之值得深思。
关于python - 如何获得轮廓内最大的矩形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58563616/