0

OpenCV C API で cvFindContours を使用して、バイナリ イメージで連結要素を見つける簡単で不自然な例があります。(これは C で書かれた大きなソフトウェアの一部であるため、C++ API を使用することはできません。)

サンプルの入力画像は、黒い背景に重なっていない 2 つの塗りつぶされた白い正方形で構成されています。これから、各正方形の周囲を構成する接続されたコンポーネントを表す 2 つの等高線が得られると予想されます。代わりに、4 つのコンポーネントを取得します。なんで?詳細は以下。

まず、背景ピクセルが 0.0 で値が 1.0 の白いピクセル (2 つの正方形) を持つ CV_32FC1 画像である「自己」で入力画像をしきい値処理します。

cvThreshold(self, self, 0.8, 1.0, CV_THRESH_BINARY);

次に、cvScale を使用して入力画像を同じサイズの CV_32SC1 画像にコピーします。

CvMat * temp = cvCreateMat(height, width, CV_32SC1);
cvConvertScale(self, temp, 1, 0);

次に、接続されたコンポーネントを取得するために cvFindContours を実行します。

CvSeq * components = 0;
CvMemStorage * mem = cvCreateMemStorage(0);
cvFindContours(temp, mem, &components, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

次に、次のようにして、輪郭を構成するポイントを出力し、それらをウィンドウに描画します。

for(; components != 0; components = components->h_next)
    {
        printf("===============NEW COMPONENT!============\n");
        if (components->v_next) printf("This has a child.\n");
        CvPoint * pt_array = (CvPoint *)malloc(components->total*sizeof(CvPoint));

        cvCvtSeqToArray(components, pt_array, CV_WHOLE_SEQ);
        for (int i = 0; i < components->total; i++)
        {
            printf("Point %i: %i, %i\n", i, pt_array[i].x, pt_array[i].y);
    }
    free(pt_array);
    outer_color = CV_RGB(rand()%255, rand()%255, rand()%255);
    cvDrawContours(dst, components, outer_color, inner_color, -3, 1, 8, cvPoint(0,0));
}

これにより、バイナリ イメージの 2 つの白い正方形の周囲を表す 2 つの等高線が生成されることが期待されます。代わりに、ほぼ重なり合う 4 つのトップレベルの輪郭を取得します。何を与える?

4 つの輪郭のポイントは次のとおりです。

===============NEW COMPONENT!============
Point 0: 200, 150
Point 1: 200, 199
Point 2: 199, 200
Point 3: 150, 200
Point 4: 149, 199
Point 5: 149, 150
Point 6: 150, 149
Point 7: 199, 149
===============NEW COMPONENT!============
Point 0: 150, 150
Point 1: 150, 199
Point 2: 199, 199
Point 3: 199, 150
===============NEW COMPONENT!============
Point 0: 50, 10
Point 1: 50, 49
Point 2: 49, 50
Point 3: 10, 50
Point 4: 9, 49
Point 5: 9, 10
Point 6: 10, 9
Point 7: 49, 9
===============NEW COMPONENT!============
Point 0: 10, 10
Point 1: 10, 49
Point 2: 49, 49
Point 3: 49, 10
4

1 に答える 1

0

暗闇でのショットですが、輪郭メソッドのフラグが結果セットの構造を制御することはわかっています。おそらく、CV_RETR_CCOMP フラグをここで説明されているいずれかのフラグと交換してみてください。

このリンクは、フラグ CV_RETR_CCOMP がどのように機能するかについて少し説明しています。

奇妙ですが、あなたの結果も期待できません。

于 2013-02-27T21:59:31.887 に答える