11

2 つの輪郭があり、それらの間の関係を確認したい (そのうちの 1 つがネストされている場合)。通常、検索モードで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 

2 番目の輪郭が最初の輪郭の内側にあることを簡単に確認するにはどうすればよいですか? バウンディングボックスの関係を調べようと思ったのですが、すべてのケースを網羅しているわけではありません。

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
  . . .

3x3 の近傍に基づいて 4 連結された等高線を交差するための一貫したテストを構築できるかどうかは 100% 確信が持てませんが、可能性は高いと思われます。

もちろん、これはすべて外側の輪郭が閉じていることに依存しています。

于 2011-12-14T17:46:21.530 に答える