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:
- 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());
- 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);
- 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);
}
- 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 !
Awesome!!!
Works as required!!!
Are you from the Earth!!!
The biggest THANKS
1 Like