How to find which pixel belongs to which clusters or centers?

asked 2016-01-27 01:46:44 -0600

sumit patel gravatar image

updated 2016-01-27 03:48:11 -0600

image description I generated clusters with k-means clustering algorithm. I used 5 centres ( defined in text file like (0,0) (256,200) (500,500) ). I got output windows with 5 groups of points at different place.

I want to find points with cluster numbers.

ex. (1,1) is in cluster no. 1 ; (2,10) is in cluster no. 3

Give me any idea or suggestion about this. 

code:

(Include header files)
using namespace cv;
using namespace cv::ml;
using namespace std;
void readCenters(cv::Mat&, const char *);

int CLUSTER_COUNT=5;//number of clusters
Mat train_data;
Mat test_data;

void printDim(cv::Mat mat,const char *name)

void splitData(cv::Mat &data,cv::Mat &train_data,cv::Mat &test_data)


void readData(cv::Mat& data)
{
    std::vector<const char *> filenames;
    filenames.push_back("Data/ik147_1.txt");
    filenames.push_back("Data/ik147_2.txt");
string line;
    vector<Mat> raw_data(2);//= new std::vector<cv::Mat>(4);
    int row;
    double  min,max;
    for(int i =0;i<2;i++)
    {
        ifstream file( filenames[i] );
        while( file>>row )
        {
            raw_data[i].push_back(row);
        }
        minMaxLoc(raw_data[i],&min,&max);
      cout<<filenames[i]<<" min :"<<min<<", max :"<<max<<std::endl;

    }
    int N=raw_data[0].rows;
   // cv::Mat data(N,3,CV_32FC1);
    cout<<"N value : "<< N << endl;
    int columns_to_read=2;
    data.create(N,columns_to_read,CV_32FC1);

    for(int i=0;i<columns_to_read;i++)
    {
        raw_data[i](Rect(0,0,1,N)).copyTo(data(Rect(i,0,1,N)));
    }

}

void computeLabelledData(Mat& data,Mat &data_with_labels)
{
    Mat labels,centers;    
    kmeans(data, CLUSTER_COUNT, labels,
               TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
               3, KMEANS_PP_CENTERS, centers);


    data_with_labels.create(data.rows,data.cols+1,CV_32FC1);
    data.copyTo(data_with_labels(Rect(0,0,data.cols,data.rows)));
    labels.copyTo(data_with_labels(Rect(data.cols,0,labels.cols,labels.rows)));
}

void print(Mat mat, int prec)
{      
    for(int i=0; i<mat.size().height; i++)
    {
        cout << "[";
        for(int j=0; j<mat.size().width; j++)
        {
            cout << setprecision(prec) << mat.at<float>(i,j);
            if(j != mat.size().width-1)
                cout << ", ";
            else
                cout << "]" << endl; 
        }
    }
}
int main()
{
    // Data for visual representation
    int width = 512, height = 512;
    Mat image = Mat::zeros(height, width, CV_8UC3);

        Mat data;
    readData(data);
    printDim(data,"data");
    Mat data_with_labels,train_data_labels,test_data_labels;
     computeLabelledData(data,data_with_labels);
      splitData(data_with_labels,train_data_labels,test_data_labels);
        //splitData(data,train_data,test_data);

    Mat train_data,train_labels;
    train_data_labels(cv::Rect(0,0,train_data_labels.cols-1,train_data_labels.rows)).copyTo(train_data);
    train_data_labels(cv::Rect(train_data_labels.cols-1,0,1,train_data_labels.rows)).copyTo(train_labels);

    Mat test_data,test_labels,predicted_labels,confusion_matrix;
    test_data_labels(cv::Rect(0,0,test_data_labels.cols-1,test_data_labels.rows)).copyTo(test_data);
    test_data_labels(cv::Rect(test_data_labels.cols-1,0,1,test_data_labels.rows)).copyTo(test_labels);

    printDim(train_data,"train_data"); 
    printDim(test_data,"test_data"); 

    cout <<"train data : "  << endl;
    //print(train_data, 3);
    cout <<"test data : "  << endl;
    //print(test_data, 3);


    int N=test_data.rows; //number of data points
    int K=5;  //number of labels

    RNG rng((unsigned)time(NULL)); 
    RNG rng_center(20);
    int clusterCount=K;
    int sampleCount = N;
    Mat centers(5,2,CV_32FC1);
    readCenters(centers,"centers.txt");
    Mat labelsMat(N,1,CV_32SC1);
    Mat labelsMatKMeans;
    Mat img_kmeans(512, 512, CV_8UC3);

    Point center;
    center.x=0;//centers.at<float>(k,0);
    center.y=0;//:centers.at<float>(k,1 ...
(more)
edit retag flag offensive close merge delete

Comments

can you show us, what you did ? (the txt file sounds weird.)

have a look here , too. opencv's kmeans returns bestLabels, which is probably , what you're looking for.

berak gravatar imageberak ( 2016-01-27 01:55:24 -0600 )edit

center.txt in which i defined initial centres. In my program, i use text file for reading initial center.

sumit patel gravatar imagesumit patel ( 2016-01-27 03:21:13 -0600 )edit

actually , it works the other way round, the centers are inferred from the labels, calculated from kmeans

berak gravatar imageberak ( 2016-01-27 03:28:32 -0600 )edit

show us your program

berak gravatar imageberak ( 2016-01-27 03:33:21 -0600 )edit

where i can add my code?

sumit patel gravatar imagesumit patel ( 2016-01-27 03:38:05 -0600 )edit
  • edit your question
  • paste code at the end
  • mark code with mouse
  • press "10101" button to format it properly
berak gravatar imageberak ( 2016-01-27 03:43:12 -0600 )edit
1

ok thanks. i edited with code.

sumit patel gravatar imagesumit patel ( 2016-01-27 03:48:39 -0600 )edit

now i do not understand your question.

in computeLabelledData(), you already got the labels array, which holds the desired information

berak gravatar imageberak ( 2016-01-27 03:54:45 -0600 )edit

i want output like (1,1) is in cluster 1. SO how can i print it?

sumit patel gravatar imagesumit patel ( 2016-01-27 04:27:25 -0600 )edit

in output image, there are 5 clusters. I want print 1 to 5 numbers assign to cluster in output image. When i print image matrix (img_kmeans) [code : cout << mat << endl ], i got numeric value like 0 0 0 0 10 52 21 10 52 21 ... 0 0 0 44 55 47 44 55 47 0 0 0 I think these is RGB value. How can i know which value are for which cluster ?

sumit patel gravatar imagesumit patel ( 2016-01-27 06:10:06 -0600 )edit