OpenCV + Kmeans + Java

Hi for everyone
There are lot of info how to use kmeans() in python BUT
Please help with info how correctly use kmeans() in java(see attachScreen)
On input I have Mat object with type CV_8UC3
How correctly convert object to required type - ?
How to handle output from kmeans() , f/e for displaying - ?

it’s pretty clumsy in java, but you’ll have to follow the same processing as in c++ or python:

  1. rearrange data into a long vertical strip (to float, reshape channels into columns):
img.convertTo(img, CvType.CV_32F);
Mat data = img.reshape(1, (int)img.total());
  1. call kmeans, there will be a cluster id for each pixel, and a mean color for each cluster center:
int K=15;
Mat bestLabels = new Mat();
TermCriteria criteria = new TermCriteria();
int attempts=5;
int flags = Core.KMEANS_PP_CENTERS;
Mat centers=new Mat();
double compactness = Core.kmeans​(data, K, bestLabels, criteria, attempts, flags, centers);
  1. visualize cluster centers:
Mat draw = new Mat((int)img.total(),1, CvType.CV_32FC3);
Mat colors = centers.reshape(3,K);
for (int i=0; i<K; i++) {
    Mat mask = new Mat(); // a mask for each cluster label
    Core.compare(bestLabels, new Scalar(i), mask, Core.CMP_EQ);
    Mat col = colors.row(i); // can't use the Mat directly with setTo() (see #19100)  
    double d[] = col.get(0,0); // can't create Scalar directly from get(), 3 vs 4 elements
    draw.setTo(new Scalar(d[0],d[1],d[2]), mask);
}
  1. back to 3 channels, uchar:
draw = draw.reshape(3, img.rows());
draw.convertTo(draw, CvType.CV_8U);


p.s.: @duzzi, thanks for the nice example image :wink: !

Awesome!!! :hugs:
Works as required!!!
Are you from the Earth!!!
The biggest THANKS

1 Like