Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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 way to do as color clustering?

image description

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

I have tired the following java code, but no desired result is shown:

    Imgcodecs.imread("C:\\photo.jpg");
    Imgproc.cvtColor(mat,hsvMat,Imgproc.COLOR_BGR2HSV); 

    int hBins = 50;
    int sBins = 60;
    MatOfInt histSize = new MatOfInt( hBins,  sBins);

    // hue varies from 0 to 179, saturation from 0 to 255
    MatOfFloat ranges =  new MatOfFloat( 0f,180f,0f,256f );

    // we compute the histogram from the 0-th and 1-st channels
    MatOfInt channels = new MatOfInt(0, 1);
    Mat histRef = new Mat();
    Mat histSource = new Mat();

    ArrayList<Mat> histImages=new ArrayList<Mat>();
    histImages.add(hsvMat);

    Imgproc.calcHist(histImages,
            channels,
            new Mat(),
            histSource,
            histSize,
            ranges,
            false);

    Core.normalize(histSource,
            histSource,
            0,
            1,
            Core.NORM_MINMAX,
            -1,
            new Mat());


    for( int i = 0; i < (int)histSize.get(0, 0)[0]; i++ )
    {                   
        Imgproc.line(
                    histSource,
                    new org.opencv.core.Point( i, histSource.rows() ),
                    new org.opencv.core.Point( i, histSource.rows()-Math.round( histSource.get(i,0)[0] )) ,
                    new Scalar( 255, 255, 255),
                    1, 8, 0 );
    }

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 way to do as color clustering?

image description

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

I have tired the following java code, but no desired result is shown:

    Imgcodecs.imread("C:\\photo.jpg");
    Imgproc.cvtColor(mat,hsvMat,Imgproc.COLOR_BGR2HSV); 

    int hBins = 50;
    int sBins = 60;
    MatOfInt histSize = new MatOfInt( hBins,  sBins);

    // hue varies from 0 to 179, saturation from 0 to 255
    MatOfFloat ranges =  new MatOfFloat( 0f,180f,0f,256f );

    // we compute the histogram from the 0-th and 1-st channels
    MatOfInt channels = new MatOfInt(0, 1);
    Mat histRef = new Mat();
    Mat histSource = new Mat();

    ArrayList<Mat> histImages=new ArrayList<Mat>();
    histImages.add(hsvMat);

    Imgproc.calcHist(histImages,
            channels,
            new Mat(),
            histSource,
            histSize,
            ranges,
            false);

    Core.normalize(histSource,
            histSource,
            0,
            1,
            Core.NORM_MINMAX,
            -1,
            new Mat());


    for( int i = 0; i < (int)histSize.get(0, 0)[0]; i++ )
    {                   
        Imgproc.line(
                    histSource,
                    new org.opencv.core.Point( i, histSource.rows() ),
                    new org.opencv.core.Point( i, histSource.rows()-Math.round( histSource.get(i,0)[0] )) ,
                    new Scalar( 255, 255, 255),
                    1, 8, 0 );
    }

I have turned to use k-mean clustering, but I got same clustered images. Why would it be like that?

 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;

public class TestingOpenCV {
    public static void main (String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat img = Imgcodecs.imread("C:\\imagetesting\\1.jpg");    
        int k = 5;
        List<Mat> temp;
        temp = cluster(img, 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);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters2.jpg",clusters2);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters3.jpg",clusters3);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters4.jpg",clusters4);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters5.jpg",clusters5);             

    }
    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>();
        Mat light = new Mat(cutout.size(),cutout.type(), new Scalar(255,255,255));
        for(int i = 0; i < centers.rows(); i++) {
            //clusters.add(Mat.zeros(cutout.size(), cutout.type()));
            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];
                clusters.get(label).put(y, x, b, g, r);             
                rows++;
            }
        }
        return clusters;
    }
}

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 way to do as color clustering?

image description

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

I have tired the following java code, but no desired result is shown:

    Imgcodecs.imread("C:\\photo.jpg");
    Imgproc.cvtColor(mat,hsvMat,Imgproc.COLOR_BGR2HSV); 

    int hBins = 50;
    int sBins = 60;
    MatOfInt histSize = new MatOfInt( hBins,  sBins);

    // hue varies from 0 to 179, saturation from 0 to 255
    MatOfFloat ranges =  new MatOfFloat( 0f,180f,0f,256f );

    // we compute the histogram from the 0-th and 1-st channels
    MatOfInt channels = new MatOfInt(0, 1);
    Mat histRef = new Mat();
    Mat histSource = new Mat();

    ArrayList<Mat> histImages=new ArrayList<Mat>();
    histImages.add(hsvMat);

    Imgproc.calcHist(histImages,
            channels,
            new Mat(),
            histSource,
            histSize,
            ranges,
            false);

    Core.normalize(histSource,
            histSource,
            0,
            1,
            Core.NORM_MINMAX,
            -1,
            new Mat());


    for( int i = 0; i < (int)histSize.get(0, 0)[0]; i++ )
    {                   
        Imgproc.line(
                    histSource,
                    new org.opencv.core.Point( i, histSource.rows() ),
                    new org.opencv.core.Point( i, histSource.rows()-Math.round( histSource.get(i,0)[0] )) ,
                    new Scalar( 255, 255, 255),
                    1, 8, 0 );
    }

I have turned to use k-mean clustering, but I got same clustered images. Why would it be like that?

 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;

public class TestingOpenCV {
    public static void main (String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat img = Imgcodecs.imread("C:\\imagetesting\\1.jpg");    
        int k = 5;
        List<Mat> temp;
        temp = cluster(img, 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);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters2.jpg",clusters2);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters3.jpg",clusters3);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters4.jpg",clusters4);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters5.jpg",clusters5);             

    }
    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>();
        Mat light = new Mat(cutout.size(),cutout.type(), new Scalar(255,255,255));
        for(int i = 0; i < centers.rows(); i++) {
            //clusters.add(Mat.zeros(cutout.size(), cutout.type()));
            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];
                clusters.get(label).put(y, x, b, g, r);             
                rows++;
            }
        }
        return clusters;
    }
}
click to hide/show revision 4
retagged

updated 2016-03-08 01:17:09 -0600

berak gravatar image

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 way to do as color clustering?

image description

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

I have turned to use k-mean clustering, but I got same clustered images. Why would it be like that?

 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;

public class TestingOpenCV {
    public static void main (String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat img = Imgcodecs.imread("C:\\imagetesting\\1.jpg");    
        int k = 5;
        List<Mat> temp;
        temp = cluster(img, 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);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters2.jpg",clusters2);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters3.jpg",clusters3);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters4.jpg",clusters4);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters5.jpg",clusters5);             

    }
    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>();
        Mat light = new Mat(cutout.size(),cutout.type(), new Scalar(255,255,255));
        for(int i = 0; i < centers.rows(); i++) {
            //clusters.add(Mat.zeros(cutout.size(), cutout.type()));
            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];
                clusters.get(label).put(y, x, b, g, r);             
                rows++;
            }
        }
        return clusters;
    }
}

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 way to do as color clustering?

image description

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

I have turned to use k-mean clustering, but I got same clustered images. Why would it be like that?

 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;

public class TestingOpenCV {
    public static void main (String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat img = Imgcodecs.imread("C:\\imagetesting\\1.jpg");    
        int k = 5;
        List<Mat> temp;
        temp = cluster(img, 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);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters2.jpg",clusters2);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters3.jpg",clusters3);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters4.jpg",clusters4);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters5.jpg",clusters5);             

    }
    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>();
        Mat light = new Mat(cutout.size(),cutout.type(), new Scalar(255,255,255));
         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];
                clusters.get(label).put(y, x, b, g, r);             
                rows++;
            }
        }
        return clusters;
    }
}

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 do as make a color clustering?

image description

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

I have turned to use k-mean clustering, but I got same clustered images. Why would it be like that?

 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;

public class TestingOpenCV {
    public static void main (String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat img = Imgcodecs.imread("C:\\imagetesting\\1.jpg");    
        int k = 5;
        List<Mat> temp;
        temp = cluster(img, 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);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters2.jpg",clusters2);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters3.jpg",clusters3);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters4.jpg",clusters4);            
        Imgcodecs.imwrite("C:\\imagetesting\\clusters5.jpg",clusters5);             

    }
    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));
            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];
                clusters.get(label).put(y, x, b, g, r);             
                rows++;
            }
        }
        return clusters;
    }
}

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?

image description

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

he k-mean clustering are not doing quite well in the HSV domain. How could I have turned to use k-mean clustering, but I got same clustered images. Why would it be like that?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\\1.jpg");    
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> temp;
        channels = new ArrayList<Mat>();
        Core.split(hsv,channels);
        cropped_hsv = channels.get(0);
        List<Mat> temp = cluster(img, 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];
                clusters.get(label).put(y, 
                Mat tempMat = new Mat(); 
                tempMat = clusters.get(label);
                tempMat.put(y, x, b, g, r); r);
                clusters.set(label,tempMat);                    
                rows++;
            }
        }
        return clusters;
    }
}

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?

image description

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

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