2

openCV (C を使用) で画像に kmeans クラスタリングを実装しようとしています。クラスタ化された画像がいくつかのカラー レイヤーになる代わりに、出力はかなり奇妙です。コードのデバッグも試みましたが、どこが間違っているのかわかりませんでした。

入力イメージと出力イメージは次のとおりです。

ここに画像の説明を入力

右が出力画像、左が入力画像です。

コードは次のとおりです。

image = cvLoadImage( "pic65.png", CV_LOAD_IMAGE_UNCHANGED);
sample = cvCreateMat( image->height*image->width, 5, CV_32FC1 );
clusters = cvCreateMat( image->height*image->width, 1, CV_32SC1 );

data = (uchar *)image->imageData;
for(i=0;i<image->height;i++)
{
                            for(j=0;j<image->width;j++)
                            {
                            cvSetReal2D( sample, k, 0, i);
                            cvSetReal2D( sample, k, 1, j);
                            b = data[i*image->widthStep + j*image->nChannels +0];
                            g = data[i*image->widthStep + j*image->nChannels +1];
                            r = data[i*image->widthStep + j*image->nChannels +2];
                            cvSetReal2D( sample, k, 2, b);
                            cvSetReal2D( sample, k, 3, g);
                            cvSetReal2D( sample, k, 4, r);
                            k++;
                            }
}
count = get_clusters();

cvKMeans2(sample,count,clusters,cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,100,0 ));

for (x = 0; x < image->height; x++)
{
for (y = 0; y < image->width; y++)
{
    index = x * image->width + y;
    cluster_index = cvGetReal2D(clusters,index,0);
    data[x*image->widthStep + y*image->nChannels +0] = cl[cluster_index][0];
    data[x*image->widthStep + y*image->nChannels +1] = cl[cluster_index][2];
    data[x*image->widthStep + y*image->nChannels +2] = cl[cluster_index][2];
}
}

get_clusters メソッドは、この場合は 30 であるしきい値に応じて、入力イメージ内のカラー クラスターの数を返します。必要な場合は、get_clusters のコードも提供できますが、正しいと思います。

誰かがどこが間違っているかを指摘できますか。どんな種類の助けも大歓迎です。前もって感謝します。

編集:私の希望する出力は以下のとおりです:

ここに画像の説明を入力

4

1 に答える 1

1

「望ましい出力」イメージから判断すると、kmeans の使用法は間違っています。クラスタリングでは、ピクセル座標は何の役割も果たさないようにする必要があります。色のトリプレットのみを kmeans に渡す必要があります。

sample = cvCreateMat( image->height*image->width, 3, CV_32FC1 );

…</p>

                  for(j=0;j<image->width;j++)
                      {
                        b = data[i*image->widthStep + j*image->nChannels +0];
                        g = data[i*image->widthStep + j*image->nChannels +1];
                        r = data[i*image->widthStep + j*image->nChannels +2];
                        cvSetReal2D( sample, k, 0, b);
                        cvSetReal2D( sample, k, 1, g);
                        cvSetReal2D( sample, k, 2, r);
                        k++;
                      }

次に、データを設定するときに、インデックス作成のバグもあります。

于 2012-06-29T08:44:40.317 に答える