# 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) {
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++) {
Mat light = new Mat(cutout.size(),cutout.type(), new Scalar(255,255,255));
}

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;
}
}

edit retag close merge delete

Sort by » oldest newest most voted

currently, all your 5 cluster images reference the same set of pixels, so you get 5 times the same image.

solution: make a new (seperate) Mat for each cluster.

for(int i = 0; i < centers.rows(); i++) {
Mat light = new Mat(cutout.size(),cutout.type(), new Scalar(255,255,255));
}

more

Thanks for your help. They are different now. But when I convert the image to HSV domain for further clustering, the resulting clustered image are quite dirty, how can I split the character better? I am going to do the masking afterwards.

( 2016-03-08 02:57:36 -0500 )edit

This is a job for K-means clustering. And in fact, this is the subject of one of the tutorials on the subject. Take a look.

more

I have changed my method to K-means clustering, but I got all the same images at the end.

( 2016-03-07 23:43:22 -0500 )edit

Official site

GitHub

Wiki

Documentation