/ Published in: C++
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
void kMeans(vector<CvPoint> &dataVector, const int clusterCount, vector < vector<CvPoint> > &clusterContainer) { /* * Pre: "dataVector" the data to be clustered by K-Means * "clusterCount" how many clusters you want * * Post: "classContainer" I pack the points with the same cluster into vector, so it * is a vetor of vector */ int dataLength = dataVector.size(); // Put data into suitable container CvMat* points = cvCreateMat(dataLength, 1, CV_32FC2); CvMat* clusters = cvCreateMat(dataLength, 1, CV_32SC1 ); for (int row = 0; row < points->rows; row++) { float* ptr = (float*)(points->data.ptr + row*points->step); for (int col = 0; col < points->cols; col++) { *ptr = static_cast<float>(dataVector[row].x); ptr++; *ptr = static_cast<float>(dataVector[row].y); } } // The Kmeans algorithm function (OpenCV function) cvKMeans2(points, clusterCount, clusters, cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 1, 2)); // Pack result to 'classContainer', each element in 'classContainer' means one cluster, // each cluster is one vector<CvPoint> contain all points belong to this cluster int clusterNum; vector<CvPoint> tempClass; for (int i = 0; i < clusterCount; i++) { tempClass.clear(); for (int row = 0; row < clusters->rows; row++) { float* p_point = (float*)(points->data.ptr + row*points->step); int X = static_cast<int>(*p_point) ; p_point++; int Y = static_cast<int>(*p_point); clusterNum = clusters->data.i[row]; if (clusterNum == i) tempClass.push_back(cvPoint(X, Y)); } clusterContainer.push_back(tempClass); } // Remove empty cluster for (vector< vector<CvPoint> >::size_type i = 0; i < clusterContainer.size(); ++i) { bool isEmpty = clusterContainer[i].empty(); if (isEmpty) { vector< vector<CvPoint> >::iterator iter = clusterContainer.begin(); iter = iter + i; clusterContainer.erase(iter); i = i - 1; } } cvReleaseMat(&points); cvReleaseMat(&clusters); }