3

私は opencv kmeans を使用して、凸包から返されたポイントをクラスター化しています。

私の場合、3ポイントが返ってきます。次のループで、最後に見つかった 3 つのポイントを kmeans に提供したいと思います。KMEANS_USE_INITIAL_LABELS を設定する必要があることを読みました。

しかし、初期ラベル/ポイントを設定するにはどうすればよいですか?

これは私がこれまでに持っているものですが、エラーを返します:

//get all convexhull points and average them in 3 groups
                    int dimensions = 2;
                    float pointsdata[sampleCount*2]; //[] = {1,1, 2,2, 6,6, 5,5, 10,10};

                    int cnt = 0;
                    for(int a=0; a<sampleCount; a++){
                        pointsdata[cnt] = convexHull[a].x;
                        cnt++;
                        pointsdata[cnt] = convexHull[a].y;
                        cnt++;
                    }

                    cv::Mat points;
                    points = cv::Mat(sampleCount,dimensions, CV_32F,pointsdata);

                    int clusterCount = 3; //i want 3 averaged points back

                    cv::Mat labels;
                    labels = cv::Mat(3,1,points.type());
                    labels.at<float>(0,0) = pointA.x;
                    labels.at<float>(0,1) = pointA.y;

                    labels.at<float>(0,2) = pointB.x;
                    labels.at<float>(0,3) = pointB.y;

                    labels.at<float>(0,4) = pointC.x;
                    labels.at<float>(0,5) = pointC.y;

                    cv::Mat centers;
                    centers = cv::Mat(clusterCount, 1, points.type());



                    kmeans(points, 3, labels, cv::TermCriteria(), 2,cv::KMEANS_USE_INITIAL_LABELS, &centers);

更新:わかりました、ラベルは実際の座標ではなく、入力クラスター内のポイントへのインデックスを意味することがわかりました。だからもっとこうあるべき。しかし、まだ間違っています。

cv::Mat labels;
                    labels = cv::Mat(3,1,points.type());
                    labels.at<int>(0,0) = labelA;
                    labels.at<int>(0,1) = labelB;
                    labels.at<int>(0,2) = labelC;
4

3 に答える 3

1

CV_32S初期クラスター割り当ては、タイプが notである必要がありますCV_32F。その他の条件は、matrix.cpp で確認できます。

CV_Assert( (best_labels.cols == 1 || best_labels.rows == 1) &&
              best_labels.cols*best_labels.rows == N &&
              best_labels.type() == CV_32S &&
              best_labels.isContinuous());

ラベルの値は、行数の範囲内[0,N)にある必要がNあります。

于 2014-03-25T23:49:01.890 に答える
0

ラベルは行ごとに 1 つ割り当てる必要があります。したがって、あなたの場合、次のように割り当てる必要があります。

cv::Mat labels;
labels = cv::Mat(3,1,points.type());
labels.at<int>(0,0) = labelA;
labels.at<int>(1,0) = labelB;
labels.at<int>(2,0) = labelC;

余談ですが、上記の編集のコードは間違っています。3 つの行を割り当て、3 つの列に書き込んでいます。

于 2012-04-20T05:20:53.200 に答える
0
cv::Mat labels;
labels = cv::Mat(sampleCount,1,CV_32S);
for(int i = 0; i < sampleCount; i++)
    labels.at<int>(i,0) = 0;
labels.at<int>(position1, 0) = 0;
labels.at<int>(position2, 0) = 1;
labels.at<int>(position3, 0) = 2;

labels は、サンプル内の各点のクラスタ ID を格納する 1*N または N*1 の整数配列です。だから、それを確認してください

  1. ラベルのサイズ: 1*N または N*1 (1*K または K*1 ではない)
  2. ラベルのタイプ: CV_32S。clusterid を格納するため、整数にする必要があります。
  3. ラベルの範囲: ラベルの各要素は [0, K) にあります
于 2017-01-04T06:18:50.353 に答える