我正在尝试使用 OpenCV 简化以下图像:
我们这里有很多红色的形状。其中一些完全包含其他。其中一些与邻居相交。我的目标是通过将任意两个相交的形状替换为联合多边形的边界框来统一所有相交 的形状。 (重复直到不再有相交的形状)。
我所说的相交也意味着接触。希望这能让它 100% 清楚:
我正在尝试使用标准形态学操作有效地做到这一点;显然它可以在 O(N^2)
中天真地完成,但是那会太慢了。扩张没有帮助,因为有些形状仅相隔 1 像素,如果它们不相交,我不希望它们合并。
最佳答案
更新:我之前误解了这个问题。我们不想删除完全在其他人内部的矩形。我们只想替换相交 矩形。因此对于第一种情况,我们什么都不用做。
新的 api (2.4.9) 支持 & 和 |运营商。
来自 opencv doc :
- rect = rect1 & rect2(矩形交集)
- rect = rect1 | rect2(包含 rect2 和 rect3 的最小面积矩形)
还支持相等比较(==)
- rect == rect1
所以现在很容易完成任务。对于每一对矩形 rect1 和 rect2,
if((rect1 & rect2) == rect1) ... // rect1 is completely inside rect2; do nothing.
else if((rect1 & rect2).area() > 0) // they intersect; merge them.
newrect = rect1 | rect2;
... // remove rect1 and rect2 from list and insert newrect.
更新 2:(用于在 java 中进行翻译)
我对java知之甚少。我也从未使用过 java API。我在这里给出一些伪代码(我认为可以很容易地翻译)
对于 &
运算符,我们需要一个方法来找到两个矩形的交集。
Method: Intersect (Rect A, Rect B)
left = max(A.x, B.x)
top = max(A.y, B.y)
right = min(A.x + A.width, B.x + B.width)
bottom = min(A.y + A.height, B.y + B.height)
if(left <= right && top <= bottom) return Rect(left, top, right - left, bottom - top)
else return Rect()
对于|
操作符,我们需要类似的方法
Method: Merge (Rect A, Rect B)
left = min(A.x, B.x)
top = min(A.y, B.y)
right = max(A.x + A.width, B.x + B.width)
bottom = max(A.y + A.height, B.y + B.height)
return Rect(left, top, right - left, bottom - top)
对于==
操作符,我们可以使用重载的equals
方法。
关于image - 组合相交边界矩形的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19079619/