I have the following code which takes an image and displays a color palette using K-means clustering.
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
using namespace cv;
using namespace std;
Mat showCenters(const Mat& centers, const Mat& data, int siz = 64) {
Mat cent = centers.reshape(3, centers.rows);
//april 4 int dat = data.total();
// make a horizontal bar of K color patches:
Mat draw(siz, siz * cent.rows, cent.type(), Scalar::all(0));
cout << endl << "BGR Dominance in order\n";
for (int i = 0; i < cent.rows; i++) {
// set the resp. ROI to that value (just fill it):
draw(Rect(i * siz, 0, siz, siz)) = cent.at<Vec3f>(i, 0);
cout << i+1 << ": " <<cent.at<Vec3f>(i, 0) << endl << endl;
//cout << dat << endl;
}
draw.convertTo(draw, CV_8U);
// optional visualization:
imshow("CENTERS", draw);
waitKey();
//imwrite("centers.png", draw);
return draw;
}
int main()
{
Mat src;
std::string image_path = samples::findFile(" "); //put file path within parameter
// do kmeans
//iterate through each and every compactness to determine optimal k:
for (int k = 1; k < 15; k++)
{
src = imread(image_path, IMREAD_COLOR);
Mat labels, centers;
Mat data;
src.convertTo(data, CV_32F);
data = data.reshape(1, data.total());
double compactness = kmeans(data, k, labels, TermCriteria(TermCriteria::MAX_ITER, 10, 1.0), 3, KMEANS_PP_CENTERS, centers);
// reshape both to a single row of Vec3f pixels:
centers = centers.reshape(3, centers.rows);
data = data.reshape(3, data.rows);
// replace pixel values with their center value:
Vec3f* p = data.ptr<Vec3f>();
for (size_t i = 0; i < data.rows; i++) {
int center_id = labels.at<int>(i);
p[i] = centers.at<Vec3f>(center_id);
}
// back to 2d, and uchar:
src = data.reshape(3, src.rows);
src.convertTo(src, CV_8U);
std::cout << "compactness at K = " << k << ": " << compactness << endl;
//visualize data:
imshow("Image", src);
showCenters(centers, data);
destroyAllWindows();
}
}
Now, I would like to grab the amount of data points (or pixels) that are initialized to a cluster. How would I be able to do that? Is there a function will allows me to do that?
Hopefully, I would be able to grab the percentage of colours using that data.