159 lines
5.9 KiB
Java
159 lines
5.9 KiB
Java
package de.wwwu.awolf.presenter.evaluation.measures;
|
|
|
|
import de.wwwu.awolf.model.Line;
|
|
import de.wwwu.awolf.model.communication.Data;
|
|
import de.wwwu.awolf.model.communication.SubscriberType;
|
|
import de.wwwu.awolf.model.communication.TypeData;
|
|
import de.wwwu.awolf.presenter.Presenter;
|
|
import de.wwwu.awolf.presenter.util.Logging;
|
|
import org.opencv.core.*;
|
|
import org.opencv.imgcodecs.Imgcodecs;
|
|
import org.opencv.imgproc.Imgproc;
|
|
|
|
import javax.swing.*;
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.DataBufferByte;
|
|
import java.io.File;
|
|
import java.util.ArrayList;
|
|
import java.util.concurrent.Flow;
|
|
|
|
/**
|
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
*
|
|
* @Author: Armin Wolf
|
|
* @Email: a_wolf28@uni-muenster.de
|
|
* @Date: 17.09.2017.
|
|
*/
|
|
public class PictureProcessor implements Flow.Publisher<Data> {
|
|
|
|
private Mat image;
|
|
private Mat contour;
|
|
private Presenter presenter;
|
|
private File file;
|
|
private ArrayList<MatOfPoint> contours;
|
|
private double contourLength;
|
|
private Flow.Subscriber<? super Data> subscriber;
|
|
|
|
/**
|
|
* Konstruktor
|
|
*
|
|
* @param presenter Presenter
|
|
* @param file Bilddatei
|
|
*/
|
|
public PictureProcessor(Presenter presenter, File file) {
|
|
this.file = file;
|
|
this.presenter = presenter;
|
|
subscribe(presenter);
|
|
}
|
|
|
|
/**
|
|
* startet den Import des Bild und die Vorverarbeitung
|
|
*/
|
|
public void run() {
|
|
image = Imgcodecs.imread(file.getAbsolutePath());
|
|
contour = process(image);
|
|
contourLength = image.width() * 0.3;
|
|
createInputData();
|
|
}
|
|
|
|
/**
|
|
* Vorverarbeitung des Eingabebilds. Dabei wird auf verschiedene OpenCV Methoden zurückgegriffen.
|
|
*
|
|
* @param image Eingabebild
|
|
* @return Matrix representation des Bilds
|
|
*/
|
|
private Mat process(Mat image) {
|
|
Mat threshold = new Mat(image.width(), image.height(), CvType.CV_8UC1);
|
|
Mat source = new Mat(image.width(), image.height(), CvType.CV_8UC1);
|
|
Imgcodecs.imwrite(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + "-orig.png", image);
|
|
Imgproc.cvtColor(image, source, Imgproc.COLOR_BGR2GRAY);
|
|
Imgcodecs.imwrite(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + "-Greyscale.png", source);
|
|
Imgproc.GaussianBlur(source, threshold, new Size(3, 3), 0, 0);
|
|
Imgproc.Canny(threshold, source, 300, 600, 5, true);
|
|
Imgcodecs.imwrite(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + "-Canny.png", source);
|
|
//Konturen berechnen und filtern
|
|
contours = new ArrayList<>();
|
|
Imgproc.findContours(source, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
|
|
Mat viscont = new Mat(source.size(), source.type());
|
|
double minArea = 50;
|
|
double maxArea = 0.2 * image.cols() * image.rows();
|
|
for (int i = 0; i < contours.size(); i++) {
|
|
double acutualArea = Imgproc.contourArea(contours.get(i));
|
|
if (minArea < acutualArea && maxArea > acutualArea) {
|
|
Imgproc.drawContours(viscont, contours, i, new Scalar(255, 0, 0), 1);
|
|
}
|
|
}
|
|
Imgcodecs.imwrite(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + "-Contour.png", viscont);
|
|
Mat resized = new Mat();
|
|
Imgproc.resize(viscont, resized, new Size(560, 560));
|
|
SwingUtilities.invokeLater(() -> {
|
|
JDialog dialog = new JDialog();
|
|
dialog.setSize(560, 560);
|
|
JLabel label = new JLabel();
|
|
label.setSize(560, 560);
|
|
label.setIcon(new ImageIcon(toBufferedImage(resized)));
|
|
dialog.add(label);
|
|
dialog.setVisible(true);
|
|
});
|
|
return viscont;
|
|
}
|
|
|
|
/**
|
|
* Das Bild wird passend umgewandelt, um im nächsten Schritt visualisiert werden zu können.
|
|
*
|
|
* @param m Matrix representation des Bilds
|
|
* @return visualisierbares Bild
|
|
*/
|
|
private BufferedImage toBufferedImage(Mat m) {
|
|
int type = BufferedImage.TYPE_BYTE_GRAY;
|
|
if (m.channels() > 1) {
|
|
type = BufferedImage.TYPE_3BYTE_BGR;
|
|
}
|
|
int bufferSize = m.channels() * m.cols() * m.rows();
|
|
byte[] b = new byte[bufferSize];
|
|
m.get(0, 0, b); // get all the pixels
|
|
BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
|
|
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
|
|
System.arraycopy(b, 0, targetPixels, 0, b.length);
|
|
return image;
|
|
|
|
}
|
|
|
|
/**
|
|
* Das gefilerte Bild ist bereit ins Modell aufgenommen zu werden um darauf dann die Algorithmen laufen zu lassen.
|
|
*/
|
|
private void createInputData() {
|
|
Thread t = new Thread(() -> {
|
|
double minArea = 50;
|
|
double maxArea = 0.2 * image.cols() * image.rows();
|
|
int id = 0;
|
|
for (int j = 0; j < contours.size(); j++) {
|
|
Point[] p = contours.get(j).toArray();
|
|
double acutualArea = Imgproc.contourArea(contours.get(j));
|
|
if (minArea < acutualArea && maxArea > acutualArea) {
|
|
for (int i = 0; i < p.length; i++) {
|
|
Line line = new Line(-1 * (500 - p[i].x), p[i].y);
|
|
line.setId("" + id++);
|
|
presenter.getModel().getLines().add(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
TypeData data = new TypeData();
|
|
data.setType(SubscriberType.PICTURE);
|
|
this.subscriber.onNext(data);
|
|
});
|
|
t.start();
|
|
try {
|
|
t.join();
|
|
} catch (InterruptedException e) {
|
|
Logging.logError(e.getMessage(), e);
|
|
Thread.currentThread().interrupt();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
|
this.subscriber = subscriber;
|
|
}
|
|
} |