-
Notifications
You must be signed in to change notification settings - Fork 5
/
Kmeans.java
125 lines (106 loc) · 3.7 KB
/
Kmeans.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package org.genericsystem.cv;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.TermCriteria;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.utils.Converters;
import org.opencv.videoio.VideoCapture;
public class Kmeans {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
private static VideoCapture camera = new VideoCapture(0);
private final static int MAX_ITER = 10;
private final static int CLUSTERS = 8;
public static void main(String[] args) {
JFrame jframe = new JFrame("Kmeans");
jframe.setResizable(false);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel vidpanel = new JLabel();
jframe.setContentPane(vidpanel);
Mat img = new Mat();
camera.read(img);
jframe.setSize(img.width(), img.height());
jframe.setVisible(true);
for (;;) {
camera.read(img);
Mat clusters = colorMapKMeans(img, CLUSTERS);
// Mat clusters = cluster(img, CLUSTERS).get(1);
ImageIcon image = new ImageIcon(mat2bufferedImage(clusters));
vidpanel.setIcon(image);
vidpanel.repaint();
}
}
public static Mat colorMapKMeans(Mat img, int K) {
Mat m = img.reshape(1, img.rows() * img.cols());
m.convertTo(m, CvType.CV_32F);
Mat bestLabels = new Mat(m.rows(), 1, CvType.CV_8U);
Mat centroids = new Mat(K, 1, CvType.CV_32F);
Core.kmeans(m, K, bestLabels, new TermCriteria(TermCriteria.COUNT | TermCriteria.EPS, MAX_ITER, 1E-5), 1, Core.KMEANS_PP_CENTERS, centroids);
List<Integer> idx = new ArrayList<>(m.rows());
Converters.Mat_to_vector_int(bestLabels, idx);
Mat imgMapped = new Mat(m.size(), m.type());
for (int i = 0; i < idx.size(); i++) {
Mat row = imgMapped.row(i);
centroids.row(idx.get(i)).copyTo(row);
}
Mat result = new Mat();
Mat mat32 = imgMapped.reshape(3, img.rows());
mat32.convertTo(result, CvType.CV_8U);
return result;
}
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);
Mat labels = new Mat();
Mat centers = new Mat();
Core.kmeans(samples32f, k, labels, new TermCriteria(TermCriteria.COUNT | TermCriteria.EPS, MAX_ITER, 1E-5), 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<>();
for (int i = 0; i < centers.rows(); i++) {
clusters.add(Mat.zeros(cutout.size(), cutout.type()));
}
Map<Integer, Integer> counts = new HashMap<>();
for (int i = 0; i < centers.rows(); i++)
counts.put(i, 0);
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;
}
public static BufferedImage mat2bufferedImage(Mat image) {
MatOfByte bytemat = new MatOfByte();
Imgcodecs.imencode(".jpg", image, bytemat);
try {
return ImageIO.read(new ByteArrayInputStream(bytemat.toArray()));
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}