Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color classification with k-means in OpenCV

I want to cluster a lot of images with the K-Means Algorithm. I want to set up the clusters, so that each cluster represent the dominant color or the hue of the image. I've read something about this in the paper Colour Image Clustering using K-Means

Does someone have an idea to do this in OpenCV?

Maybe I can compare the histograms of each image. But if I have a lot of pictures it takes a very long time

like image 650
501 - not implemented Avatar asked Jul 10 '12 11:07

501 - not implemented


People also ask

What is K in Opencv?

K-means is a clustering algorithm. The goal is to partition n data points into k clusters. Each of the n data points will be assigned to a cluster with the nearest mean. The mean of each cluster is called its “centroid” or “center”. Overall, applying k-means yields k separate clusters of the original n data points.

What does K mean in classification?

K-means alone is not designed for classification, but we can adapt it for the purpose of supervised classification. If we use k-means to classify data, there are two schemes. One method used is to separate the data according to class labels and apply k-means to every class separately.

Is k-means used for binary classification?

Kmeans is used as an unsupervised algorithm for clustering. We can actually use this feature for classification and compare it with other supervised algorithms. From generated 1000 data, I have split to train and test part.

What is K-means clustering in image segmentation?

K -means clustering algorithm is an unsupervised algorithm and it is used to segment the interest area from the background. But before applying K -means algorithm, first partial stretching enhancement is applied to the image to improve the quality of the image.


1 Answers

You can vectorize your image so each row is a set of RGB, and than use cv::kmeans to cluster, something like:

    std::vector<cv::Mat> imgRGB;
    cv::split(img,imgRGB);
    int k=5;
    int n = img.rows *img.cols;
    cv::Mat img3xN(n,3,CV_8U);
    for(int i=0;i!=3;++i)  
      imgRGB[i].reshape(1,n).copyTo(img3xN.col(i));
    img3xN.convertTo(img3xN,CV_32F);
    cv::Mat bestLables;
    cv::kmeans(img3xN,k,bestLables,cv::TermCriteria(),10,cv::KMEANS_RANDOM_CENTERS );
    bestLables= bestLables.reshape(0,img.rows);
    cv::convertScaleAbs(bestLables,bestLables,int(255/k));
    cv::imshow("result",bestLables);
    cv::waitKey();
like image 106
Mercury Avatar answered Sep 29 '22 06:09

Mercury