Reputation: 11
i use this code. its should print the clusters labels an then the centroids. but the 'center"matrix with the centriod seems to be empty,full of zeros. what is wrong my friends?
#include <iostream>
#include <stdio.h>
#include "cxcore.h"
#include "highgui.h"
using namespace cv;
int main( int argc, char** argv )
{
int i,j;
CvMat* points = cvCreateMat( 5, 2, CV_32FC1 );
CvMat* centers2 = cvCreateMat( 5, 2, CV_32FC1 );
CvMat* clusters = cvCreateMat( 5, 1, CV_32SC1 );
cvSetReal2D( points, 0, 0,1);
cvSetReal2D( points, 0, 1,1);
cvSetReal2D( points, 1, 0,2);
cvSetReal2D( points, 1, 1,2);
cvSetReal2D( points, 2, 0,6);
cvSetReal2D( points, 2, 1,6);
cvSetReal2D( points, 3, 0,5);
cvSetReal2D( points, 3, 1,5);
cvSetReal2D( points, 4, 0,10);
cvSetReal2D( points, 4, 1,10);
cvKMeans2(points,3,clusters,cvTermCriteria(CV_TERMCRIT_EPS,1000,0 ),
1000,0,KMEANS_RANDOM_CENTERS,centers2,0);
for(i=0;i<5;i++)
printf( " %lf \n", cvGetReal2D(clusters,i, 0));
for(i=0;i<5;i++){
for(j=0;j<2;j++){
printf( "center %i %i = %f \n", i, j, cvGetReal2D(centers2,i, j));
}
}
cvReleaseMat(&points);
cvReleaseMat(¢ers2);
cvReleaseMat(&clusters);
}
Upvotes: 0
Views: 3040
Reputation: 30122
Your code does not work because size of centers2
is bigger then number of requested clusters. However it seems that you have found an OpenCV bug - centers2
has to be reallocated but is does not.
Change your code to
CvMat* centers2 = cvCreateMat( 3, 2, CV_32FC1 );
and
for(i=0;i<3;i++){
for(j=0;j<2;j++){
printf( "center %i %i = %f \n", i, j, cvGetReal2D(centers2,i, j));
But better use C++ interface (C version of kmeans is just a wrapper over C++ implementation):
float pointsdata[] = { 1,1, 2,2, 6,6, 5,5, 10,10};
Mat points(5, 2, CV_32F, pointsdata);
Mat labels, centers;
kmeans(points, 3, labels, TermCriteria(CV_TERMCRIT_EPS, 1000, 0), 1000, KMEANS_RANDOM_CENTERS, centers);
cout << "labels: " << labels << endl;
cout << "centers " << centers << endl;
Upvotes: 3