Color classification
I am goint to find out hsv values of four main colors in a image like this, so that I could get those values.(minH1, minS1, ..., maxS4, maxV4). What would be the best way to make a color clustering?
Scalar lowerA = new Scalar( minH1,minS1,minV1);
Scalar upperA = new Scalar(maxH1,maxS1,maxV1);
Scalar lowerB = new Scalar( minH2,minS2,minV2);
Scalar upperB = new Scalar(maxH2,maxS2,maxV2);
Scalar lowerC = new Scalar( minH3,minS3,minV3);
Scalar upperC = new Scalar(maxH3,maxS3,maxV3);
Scalar lowerD = new Scalar( minH4,minS4,minV4);
Scalar upperD = new Scalar(maxH4,maxS4,maxV4);
The k-mean clustering are not doing quite well in the HSV domain. How could I solve it?
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.TermCriteria;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
//import org.opencv.highgui.Highgui;
public class TestingOpenCV {
public static void main (String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat img = Imgcodecs.imread("C:\\imagetesting\\defimgGray.jpg"); // 入力画像の取得
int k = 5;
Mat hsv = new Mat();
Mat cropped_hsv = new Mat();
Imgproc.cvtColor(img, hsv, Imgproc.COLOR_RGB2HSV);
List<Mat> channels = new ArrayList<Mat>();
Core.split(hsv,channels);
cropped_hsv = channels.get(0);
List<Mat> temp = new ArrayList<Mat>();
temp = cluster(hsv, k);
Mat clusters1 = temp.get(0);
Mat clusters2 = temp.get(1);
Mat clusters3 = temp.get(2);
Mat clusters4 = temp.get(3);
Mat clusters5 = temp.get(4);
Imgcodecs.imwrite("C:\\imagetesting\\clusters1.jpg",clusters1); // 画像をJPG形式で保存
Imgcodecs.imwrite("C:\\imagetesting\\clusters2.jpg",clusters2); // 画像をJPG形式で保存
Imgcodecs.imwrite("C:\\imagetesting\\clusters3.jpg",clusters3); // 画像をJPG形式で保存
Imgcodecs.imwrite("C:\\imagetesting\\clusters4.jpg",clusters4); // 画像をJPG形式で保存
Imgcodecs.imwrite("C:\\imagetesting\\clusters5.jpg",clusters5); // 画像をJPG形式で保存
}
public static List<Mat> cluster(Mat cutout, int k) {
Mat samples = cutout.reshape(1, cutout.cols() * cutout.rows());
Mat samples32f = new Mat();
samples.convertTo(samples32f, CvType.CV_32F, 1.0 / 255.0);
Mat labels = new Mat();
TermCriteria criteria = new TermCriteria(TermCriteria.COUNT, 100, 1);
Mat centers = new Mat();
Core.kmeans(samples32f, k, labels, criteria, 1, Core.KMEANS_PP_CENTERS, centers);
return showClusters(cutout, labels, centers);
}
private static List<Mat> showClusters (Mat cutout, Mat labels, Mat centers) {
centers.convertTo(centers, CvType.CV_8UC1, 255.0);
centers.reshape(3);
List<Mat> clusters = new ArrayList<Mat>();
for(int i = 0; i < centers.rows(); i++) {
//clusters.add(Mat.zeros(cutout.size(), cutout.type()));
Mat light = new Mat(cutout.size(),cutout.type(), new Scalar(255,255,255));
clusters.add(light);
}
int rows = 0;
for(int y = 0; y < cutout.rows(); y++) {
for(int x = 0; x < cutout.cols(); x++) {
int label = (int)labels.get(rows, 0)[0];
int r = (int)centers.get(label, 2)[0];
int g = (int)centers.get(label, 1)[0];
int b = (int)centers.get(label, 0)[0];
Mat tempMat = new Mat();
tempMat = clusters.get(label);
tempMat.put(y, x, b, g, r);
clusters.set(label,tempMat);
rows++;
}
}
return clusters;
}
}