我正在使用opencv kmeans来聚集从bumphull返回的点。
在我的情况下,我会得到3分。 在下一个循环中,我想提供kmeans最后发现的3分。 我读过我必须设置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, ¢ers);
更新: 好吧,我现在知道标签意味着输入集群中的点的索引,而不是实际坐标。 所以应该更像这样。但还是错的。
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;
答案 0 :(得分:1)
初始群集分配必须是CV_32S
而不是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
是行数。
答案 1 :(得分:0)
每行需要分配一个标签。因此,在您的情况下,他们必须分配为:
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;
旁注:上面编辑中的代码错误。您已分配了三行并正在写入三列。
答案 2 :(得分: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;
标签是1 * N或N * 1整数数组,用于存储样本中每个点的clusterid。所以请确保