-
Notifications
You must be signed in to change notification settings - Fork 5
/
CamCropper.java
122 lines (109 loc) · 4.43 KB
/
CamCropper.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
package org.genericsystem.cv;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.DMatch;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Size;
import org.opencv.features2d.DescriptorExtractor;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.FeatureDetector;
import org.opencv.features2d.Features2d;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
public class CamCropper extends AbstractApp {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
private final VideoCapture camera = new VideoCapture(0);
private ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();
public static void main(String[] args) {
launch(args);
}
@Override
protected void fillGrid(GridPane mainGrid) {
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
Mat frame = new Mat();
camera.read(frame);
ImageView src = new ImageView(Tools.mat2jfxImage(frame));
mainGrid.add(src, 0, 0);
ImageView src2 = new ImageView(Tools.mat2jfxImage(frame));
mainGrid.add(src2, 1, 0);
Img[] oldFrame = new Img[] { new Img(frame) };
MatOfKeyPoint[] oldKeypoints = new MatOfKeyPoint[] { new MatOfKeyPoint() };
Mat[] oldDescriptors = new Mat[] { new Mat() };
detector.detect(frame, oldKeypoints[0]);
extractor.compute(frame, oldKeypoints[0], oldDescriptors[0]);
timer.scheduleAtFixedRate(() -> {
camera.read(frame);
Img newFrame = new Img(frame, false);
MatOfKeyPoint newKeypoints = new MatOfKeyPoint();
Mat newDescriptors = new Mat();
detector.detect(frame, newKeypoints);
MatOfDMatch matches = new MatOfDMatch();
extractor.compute(frame, newKeypoints, newDescriptors);
matcher.match(oldDescriptors[0], newDescriptors, matches);
DMatch[] match = matches.toArray();
List<DMatch> goodMatches = new ArrayList<>();
for (DMatch dMatch : match) {
double dist = dMatch.distance;
// System.out.println(dist);
if (dist < 10)
goodMatches.add(dMatch);
}
try {
Mat imgMatches = new Mat();
Features2d.drawMatches(oldFrame[0].getSrc(), oldKeypoints[0], newFrame.getSrc(), newKeypoints, new MatOfDMatch(goodMatches.stream().toArray(DMatch[]::new)), imgMatches);
src.setImage(new Img(imgMatches).toJfxImage());
List<Point> goodNewKeypoints = new ArrayList<>();
List<Point> goodOldKeypoints = new ArrayList<>();
for (DMatch goodMatch : goodMatches) {
goodNewKeypoints.add(newKeypoints.toList().get(goodMatch.trainIdx).pt);
goodOldKeypoints.add(oldKeypoints[0].toList().get(goodMatch.queryIdx).pt);
}
Mat homography = Calib3d.findHomography(new MatOfPoint2f(goodOldKeypoints.stream().toArray(Point[]::new)), new MatOfPoint2f(goodNewKeypoints.stream().toArray(Point[]::new)), Calib3d.RANSAC, 10);
Mat transformedImage = new Mat();
Imgproc.warpPerspective(oldFrame[0].getSrc(), transformedImage, homography, new Size(newFrame.cols(), newFrame.rows()));
Core.subtract(newFrame.getSrc(), transformedImage, transformedImage);
src2.setImage(new Img(transformedImage).toJfxImage());
} catch (Exception e) {
e.printStackTrace();
}
oldFrame[0] = newFrame;
oldDescriptors[0] = newDescriptors;
oldKeypoints[0] = newKeypoints;
}, 0L, 333L, TimeUnit.MILLISECONDS);
}
@Override
public void stop() throws Exception {
timer.shutdown();
camera.release();
super.stop();
}
public Mat copyOver(Img source, Img destination) {
Img result_grey = source.bgr2Gray();
Mat mask = new Mat();
Imgproc.threshold(result_grey.getSrc(), mask, 10, 255, Imgproc.THRESH_BINARY);
Mat mask_inv = new Mat();
Core.bitwise_not(mask, mask_inv);
Mat roi = new Mat();
Core.bitwise_and(source.getSrc(), source.getSrc(), roi, mask);
Mat im2 = new Mat();
Core.bitwise_and(destination.getSrc(), destination.getSrc(), im2, mask_inv);
Mat result = new Mat();
Core.add(im2, roi, result);
return result;
}
}