如何检查一个轮廓是否嵌套/嵌入在opencv中

发布于 2024-12-21 08:36:48 字数 893 浏览 1 评论 0原文

我有两个轮廓,我想检查它们之间的关系(如果其中之一是嵌套的)。 通常,我会使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酒与心事 2024-12-28 08:36:48

使用cv::pointPolygonTest(InputArray轮廓,Point2f pt, boolmeasureDist) 来了解轮廓中的一个点是否在另一个点内部。

您必须检查边界情况(您选择的第一个点对于两个多边形都是公共的,等等)

if(pointPolygonTest(contour, pointFromOtherContour, false) > 0)
{
    // it is inside
}

该函数确定该点是在轮廓内部、外部还是位于边缘上(或与顶点重合)。它相应地返回正(内部)、负(外部)或零(边缘)值

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)

if(pointPolygonTest(contour, pointFromOtherContour, false) > 0)
{
    // it is inside
}

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.

吃素的狼 2024-12-28 08:36:48

如果您知道轮廓是闭合的(在 4 连通意义上),那么您可能可以使用射线至无穷大测试,该测试更常用于测试点是否位于闭合多边形内部。 (还假设轮廓不交叉,这大概是不可能的。)

取候选轮廓上的任意点,并从那里沿任意方向前进到“无穷大”(选择一个对齐的轴,以便于实现) :如果您一直到达图像边缘并穿过外部轮廓奇数次,那么您开始的轮廓就在该轮廓内部。

“穿过”外部轮廓实际上有点棘手,例如:

  . 1 1 1 1 1 1 1
  . 1 . . X X X 1
  . 1 . . X . X 1
<-.-1-1-.-X X X 1 : here a naiive implementation counts two crossings
  . . 1 1 1 1 1 1

因此,要测试光线是否在某个点“穿过”轮廓,您确实需要考虑 3x3 相邻点。我认为您最终会得到一组看起来像这样的情况:

  . . .
<-1-1 1 // not crossing
  . . .

  1 . 1
<-1-1 1 // not crossing
  . . .

  . . 1
<-1-1 1 // crossing
  . . .

  1 . .
<-1-1 1 // crossing
  . . .

我不能 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:

  . 1 1 1 1 1 1 1
  . 1 . . X X X 1
  . 1 . . X . X 1
<-.-1-1-.-X X X 1 : here a naiive implementation counts two crossings
  . . 1 1 1 1 1 1

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:

  . . .
<-1-1 1 // not crossing
  . . .

  1 . 1
<-1-1 1 // not crossing
  . . .

  . . 1
<-1-1 1 // crossing
  . . .

  1 . .
<-1-1 1 // crossing
  . . .

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文