Als Alternative, um die Eingangsmatrix manuell zu Umformen, können Sie OpenCV reshape Funktion ähnliches Ergebnis mit weniger Code zu erreichen. Hier ist meine Arbeits Umsetzung von Farben zählen mit K-Means-Verfahren zu reduzieren (in Java):
private final static int MAX_ITER = 10;
private final static int CLUSTERS = 16;
public static Mat colorMapKMeans(Mat img, int K, int maxIterations) {
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, maxIterations, 1E-5),
1, Core.KMEANS_RANDOM_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);
}
return imgMapped.reshape(3, img.rows());
}
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Highgui.imwrite("result.png",
colorMapKMeans(Highgui.imread(args[0], Highgui.CV_LOAD_IMAGE_COLOR),
CLUSTERS, MAX_ITER));
}
OpenCV liest Bild in 2-dimensionale, 3-Kanalmatrix. Erster Aufruf an reshape
- img.reshape(1, img.rows() * img.cols());
- im Wesentlichen entrollt 3 Kanäle in Spalten. In der resultierenden Matrix entspricht eine Reihe einem Pixel des Eingangsbildes und 3 Spalten entsprechen den RGB-Komponenten.
Nach K-Means-Algorithmus beendet seine Arbeit, und die Farbzuordnung angewendet wurde, rufen wir reshape
wieder - imgMapped.reshape(3, img.rows())
, aber jetzt Spalten zurück in die Kanäle, und die Verringerung der Zeilennummern auf die ursprüngliche Bildzeilennummer, so dass immer wieder die Roll Original-Matrix-Format, aber nur mit reduzierten Farben.
Ich würde gerne wissen, was Sie in der Schleife vor der clusterCount-Variablendeklaration tun und auch, was Sie am Ende in der für nach dem Kmeans tun. Denkst du, dass es möglich ist, die Antwort mit diesen Informationen zu aktualisieren? Vielen Dank! –
Die erste Schleife ordnet die Daten aus dem Bild von einer Matrix (Zeilen, Spalten, 3) in eine Matrix (Zeilen * Spalten, 3) um (eine Zeile pro Pixel). Die Schleife am Ende ersetzt jedes Pixel im Bild mit dem entsprechenden Cluster-Zentrum für die Visualisierung. – sietschie
Ist es möglich, 'Mat :: reshape()' anstelle von geschachtelten for-Schleifen zu verwenden? – Jayesh