-
Notifications
You must be signed in to change notification settings - Fork 5
/
ImgClass2.java
107 lines (88 loc) · 3.32 KB
/
ImgClass2.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
package org.genericsystem.cv;
import java.util.Iterator;
import java.util.function.Function;
import java.util.stream.Stream;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
public class ImgClass2 {
private final Img classModel;
private SimpleObjectProperty<Img> observableMean = new SimpleObjectProperty<>();
private SimpleObjectProperty<Img> observableVariance = new SimpleObjectProperty<>();
private final String directory;
private final SimpleObjectProperty<Function<Img, Img>> preprocessor = new SimpleObjectProperty<>();
public static ImgClass2 fromDirectory(Img classModel, String bgrDirectory) {
return new ImgClass2(classModel, bgrDirectory);
}
private Img applyPreprocessor(Img img) {
return preprocessor.getValue() != null ? preprocessor.getValue().apply(img) : img;
}
private LongTaskOverrider taskManager = new LongTaskOverrider();
public ImgClass2(Img classModel, String bgrDirectory) {
this.classModel = classModel;
this.directory = bgrDirectory;
computeMeanVariance();
preprocessor.addListener((o, ov, nv) -> {
taskManager.schedule(() -> computeMeanVariance());
});
}
public Stream<Img> classImgsStream() {
return Tools.classImgsStream(directory);
}
private synchronized void computeMeanVariance() {
Img img0 = applyPreprocessor(classImgsStream().iterator().next());
boolean gray = img0.channels() == 1;
int type = gray ? CvType.CV_32S : CvType.CV_32SC3;
Mat mean = new Mat(img0.size(), type, Scalar.all(0));
Mat m2 = new Mat(img0.size(), type, Scalar.all(0));
Mat mask = Mat.ones(img0.size(), CvType.CV_8U);
int count = 1;
Iterator<Img> it = classImgsStream().iterator();
while (it.hasNext()) {
Mat img = new Mat();
applyPreprocessor(it.next()).getSrc().convertTo(img, type);
Mat delta = new Mat(img.size(), type);
Core.subtract(img, mean, delta, mask, type);
Core.addWeighted(mean, 1, delta, 1d / count, 0, mean, type);
Mat delta2 = new Mat(m2.size(), type);
Core.subtract(img, mean, delta2, mask, type);
Mat product = delta.mul(delta2);
Core.add(m2, product, m2);
count++;
}
Mat variance = new Mat(m2.size(), type);
Core.multiply(m2, new Scalar(1d / count, 1d / count, 1d / count), variance);
variance.convertTo(variance, CvType.CV_8U);
mean.convertTo(mean, CvType.CV_8U);
this.observableMean.setValue(new Img(mean));
this.observableVariance.setValue(new Img(variance));
System.gc();
System.runFinalization();
}
public void setPreprocessor(Function<Img, Img> after) {
preprocessor.setValue(after);
}
public Img getClassModel() {
return classModel;
}
public ObservableValue<Img> getObservableMean() {
return observableMean;
}
public ObservableValue<Img> getObservableVariance() {
return observableVariance;
}
public String getDirectory() {
return directory;
}
public Img getClosedMean(Size morphClose) {
return observableMean.getValue().morphologyEx(Imgproc.MORPH_CLOSE, new StructuringElement(Imgproc.MORPH_RECT, morphClose));
}
public Img getClosedVariance(Size morphClose) {
return observableVariance.getValue().morphologyEx(Imgproc.MORPH_CLOSE, new StructuringElement(Imgproc.MORPH_RECT, morphClose));
}
}