如何检查一个轮廓是否嵌套/嵌入在opencv中
我有两个轮廓,我想检查它们之间的关系(如果其中之一是嵌套的)。 通常,我会使用 findContours 函数,具有 CV_RETR_TREE
检索模式。但是,我从不同的来源获得了轮廓(使用 MSER 方法)。实际上,我不仅有轮廓,还有区域蒙版(如果有帮助的话)。例如,假设我想分割字母“O”,那么我将有以下蒙版或轮廓:
1)
0 0 0 0 0 0
0 1 1 1 1 0
0 1 0 0 1 0
0 1 0 0 1 0
0 1 1 1 1 0
0 0 0 0 0 0
2)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
我如何轻松检查第二个在第一个轮廓内?我考虑过检查边界框之间的关系,但这并不能涵盖所有可能的情况。
I have two contours and I want to check the relation between them (if one of them is nested).
Normally, I would use the findContours function with CV_RETR_TREE
retrieval mode. However, I obtained the contours from a different source (using MSER method). I actually not only have the contours, but also the region mask if that helps. For example, lets say I want to segment the letter 'O', then I would have the following masks or contours:
1)
0 0 0 0 0 0
0 1 1 1 1 0
0 1 0 0 1 0
0 1 0 0 1 0
0 1 1 1 1 0
0 0 0 0 0 0
2)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
How can I easily check that the second one is inside the first contour? I thought about checking the relation between the bounding boxes, but this doesn't cover all possible cases.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用
cv::pointPolygonTest(InputArray轮廓,Point2f pt, boolmeasureDist)
来了解轮廓中的一个点是否在另一个点内部。您必须检查边界情况(您选择的第一个点对于两个多边形都是公共的,等等)
该函数确定该点是在轮廓内部、外部还是位于边缘上(或与顶点重合)。它相应地返回正(内部)、负(外部)或零(边缘)值。
当
measureDist=false
时,返回值分别为 +1、-1 和 0。否则,返回值是该点与最近的轮廓边缘之间的有符号距离。Use
cv::pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)
to know whether a point from a contour is inside the other.You have to check for border cases (the first point you pick is common to both polygons, etc)
The function determines whether the point is inside a contour, outside, or lies on an edge (or coincides with a vertex). It returns positive (inside), negative (outside), or zero (on an edge) value, correspondingly.
When
measureDist=false
, the return value is +1, -1, and 0, respectively. Otherwise, the return value is a signed distance between the point and the nearest contour edge.如果您知道轮廓是闭合的(在 4 连通意义上),那么您可能可以使用射线至无穷大测试,该测试更常用于测试点是否位于闭合多边形内部。 (还假设轮廓不交叉,这大概是不可能的。)
取候选轮廓上的任意点,并从那里沿任意方向前进到“无穷大”(选择一个对齐的轴,以便于实现) :如果您一直到达图像边缘并穿过外部轮廓奇数次,那么您开始的轮廓就在该轮廓内部。
“穿过”外部轮廓实际上有点棘手,例如:
因此,要测试光线是否在某个点“穿过”轮廓,您确实需要考虑 3x3 相邻点。我认为您最终会得到一组看起来像这样的情况:
我不能 100% 确定是否可以构建一个一致的测试来跨越基于 3x3 邻域的 4 连通轮廓,但似乎很可能这是。
当然,这一切都依赖于外部轮廓的闭合。
If you know that the contours are closed (in a 4-connected sense), then you can probably use the ray-to-infinity test, which is more commonly used to test whether points are inside closed polygons. (Also assuming the contours don't cross over, which presumably they can't.)
Take any point on the candidate contour, and proceed from there to 'infinity' in any direction (pick an axis aligned one, for ease of implementation): if you get all the way to the edge of your image and cross the outside contour an odd number of times then the contour you started on is inside that contour.
'crossing' the outer contour is actually slightly tricky, for example:
So to test if a ray is 'crossing' a contour at a point you really need to consider the 3x3 neighbouring points. I think you'll end up with a set of cases that look something like this:
I'm not 100% sure that it's possible to build a consistent test for crossings a 4-connected contour based on 3x3 neighbourhoods, but it seems likely that it is.
This all relies on the outer contour being closed, of course.