11

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

如何轻松检查第二个是否在第一个轮廓内?我考虑过检查边界框之间的关系,但这并没有涵盖所有可能的情况。

4

2 回答 2

10

用于cv::pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)了解轮廓中的点是否在另一个点内。

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

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

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

当 时measureDist=false,返回值分别为 +1、-1 和 0。否则,返回值是该点与最近轮廓边缘之间的有符号距离。

于 2011-12-14T18:09:19.107 回答
1

如果您知道轮廓是闭合的(在 4 连通的意义上),那么您可能可以使用 ray-to-infinity 测试,它更常用于测试点是否在闭合多边形内。(还假设轮廓不交叉,大概它们不能。)

取候选轮廓上的任何点,然后从那里向任何方向前进到“无限远”(选择一个对齐的轴,以便于实施):如果您一直到达图像的边缘并越过外部轮廓奇数次然后您开始的轮廓在该轮廓内。

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

  . 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 连接轮廓,但它似乎很有可能。

当然,这一切都依赖于闭合的外轮廓。

于 2011-12-14T17:46:21.530 回答