Return to Snippet

Revision: 31869
at September 15, 2010 00:46 by browny


Initial Code
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);
 
 
}

Initial URL


Initial Description


Initial Title
[OpenCV] K-Means Clustering CvPoint

Initial Tags


Initial Language
C++