web-dev-qa-db-ja.com

cv :: findContoursによって返される輪郭は一貫した方向を持っていますか?

OpenCVの _cv::findContours_ 関数を使用して、バイナリイメージの輪郭を抽出しています。特に、輪郭の階層を抽出しています(_CV_RETR_CCOMP_フラグを使用)。これらの輪郭をさらに処理するある時点で、これらの輪郭の一貫した頂点の向き(つまり、反時計回りと時計回り)に依存する必要があります

もちろん、輪郭の領域の符号( cv::contourArea(..., true) で計算)を使用して自分でその方向を判断することはできますが、それが必要かどうかも疑問です(それ以外に勝ちました)面積が0の輪郭、つまりソース画像の細い線に対しても機能しません)、または_cv::findContours_が生成された輪郭の一貫した方向をすでに保証している場合でも機能しません。生成された輪郭のいくつかをチェックしましたが、_cv::contourArea_は確かにseemで、外側の輪郭に負の値を返し、内側の輪郭に正の値を返します。ただし、OpenCVのドキュメントでは、この効果に対する実際のguaranteeは見つかりませんでした。

したがって、_cv::findContours_によって返される輪郭が常に一貫した方向を持っていることは特に保証されていますですか?これは文書化されていますかどこか?それともバージョンによって異なりますか(私の場合は2.4.5です)?実際の ドキュメントで参照されているアルゴリズムに関する論文 はすでにこれについて何かを言っていますか?あるいは、OpenCVの実際の実装についてもう少し洞察を持っている人が、インターフェイスのドキュメントよりもこれについてもう少し詳しく言うことができるでしょうか。

cv:findContoursから返される輪郭は、一貫した方向を持っている必要があります。外側の輪郭は反時計回りに、内側の輪郭は時計回りに向ける必要があります。これは、 鈴木と阿部の論文 の付録1に記載されているアルゴリズムから直接得られます。

画像は左上から右下に1行ずつスキャンされます。境界に属するピクセルが見つかると、境界の後に、非背景ピクセルが見つかるまで、最初のピクセルの隣接ピクセルを反時計回りに調べます(アルゴリズムのステップ3.3を参照)。これが輪郭に追加され、検索はこのピクセルから続行されます。

重要なことは、最初の反復で最初に見られる隣人は、それが内側の境界であるか外側の境界であるかによって異なるということです。外側の境界線の場合、右側の隣人が最初に訪問されます。内側の境界線の場合、それは左側の隣人です。次の検索ステップでは、最後にアクセスしたピクセルから検索が開始されます。

左上から右下へのスキャンハッピングにより、外側の境界が検出されると、左側に隣接するすべてのピクセルと境界ピクセルの上部が背景ピクセルであることが保証されます。内側の境界線では、それは正反対であり、左側と上部のすべての隣接ピクセルは非背景ピクセルです。

隣接するピクセルを訪問するための異なる開始位置と組み合わせて、これは輪郭の予測可能な方向をもたらす。

このアルゴリズムは、cv:findContourによって内部的に使用される icvFetchContour function に実装されています。そこから、ピクセルが訪問された順序で輪郭ポリゴンに追加されることは明らかです。

cv::findContoursのドキュメント は、鈴木らによるアルゴリズムを実装したと具体的に述べています。そして、この論文のように、ピクセルを訪問する方向と順序は明示的に定義されているので、方向はある程度保証されていると推測できます。

8

14のステップ1(== ---) ==) 付録I(あなたが参照した[Suzuki85]の論文では、 "ボーダーフォローによるデジタル化されたバイナリ画像のトポロジー構造解析 ")以下に従ってあなたの質問をカバーしてください:

(1)次のいずれかを選択します。
(a)fの場合 i、j = 1およびf i、j-1 = 0の場合、ピクセル(i、j)が外側の境界の開始点に続く境界であると判断し、NBDをインクリメントし、(i 1、j 1 )+(i、j-1)。
(b)...

(2)新しく見つかった境界線のタイプに応じて...

(3)開始点(i、j)から、検出された境界線をたどります...

(4)fの場合 i、j != 1、次にLNBD = | f i、j |ピクセル(i、j + 1)からラスタースキャンを再開します。アルゴリズムは、スキャンが画像の右下隅に到達したときに終了します。

3
Eric