5

画像処理には OpenCV を使用しています。分離したい人体を探しています(セグメント)。

現在、体の輪郭を見つけて、ポリゴンで輪郭を近似することができます。次に、その輪郭を cvWatershed で使用して、体を実際に分離します。

中心に向かってオフセットして輪郭を描く方法を知っている人はいますか? 説明のために、下の画像を参照してください。

ここに画像の説明を入力

青: 輪郭のポリゴン近似

赤: 欲しいポリゴンですが、見つかりません。(上の画像はPhotoshopを使っていますが…)

現在の輪郭を見つけて描画する方法は次のとおりです。

CvContourScanner scanner = cvStartFindContours(mask, pStorage, sizeof(CvContour),    CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
CvSeq* c;
CvSeq* polyContour;
int numCont = 0;
int perimScale = 4;
int contour_approx_level = 6;
while((c = cvFindNextContour(scanner)) != NULL)
{
    CvSeq* c_new;

    // Polygonal approximation
    c_new = cvApproxPoly(c, sizeof(CvContour), pStorage, CV_POLY_APPROX_DP, contour_approx_level, 0);

    // Create the new contour
    cvSubstituteContour(scanner, c_new);
    numCont++;
}

polyContour = cvEndFindContours(&scanner);
int i = 0;
for(i=0, c=polyContour; c!=NULL; c = c->h_next, i++)
{
    cvDrawContours(pOutput, c, cvScalar(255,125,0), cvScalar(255,255,0), -1, 2, 8);
}

/* Draw the contour at an offset towards the center here */
// Based upon the answers, I found 2 solutions

編集:以下の回答に基づいて、2つの解決策を見つけました:

// 1) Erode - 
// void cvErode( const CvArr* A, CvArr* C, IplConvKernel* B=0, int iterations=1 );
cvErode(pOutput, pOutput, NULL, 3);

// 2) Another option - draw with a black border and thick pencil:
cvDrawContours(pOutput, c, cvScalarAll(0), cvScalarAll(0), 12, 2, 8);
4

2 に答える 2

3

輪郭を取得する前に、見つけた青いポリゴンを 侵食するだけです。ここでは C API について説明します (申し訳ありませんが、私は C API にあまり詳しくありません)。

// void cvErode( const CvArr* A, CvArr* C, IplConvKernel* B=0, int iterations=1 );
cvErode(pOutput, pOutput, NULL, 3);
于 2012-05-04T12:08:29.437 に答える
2

これはおそらく最もエレガントなものではありませんが、確実に機能します。

  1. 元の輪郭を新しい配列に描画します。
  2. その距離変換を計算します。
  3. しきい値: 10 ピクセルのオフセットが必要な場合は、距離マップのピクセルを 10 より高くします。
  4. 新しい画像の輪郭を見つけます。

関数 を使用して、同様の、おそらくそれほど厳格でないことを輪郭上で直接行うことができますpointPolygonTest()

于 2012-05-04T11:57:31.893 に答える