Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java
16354 views
1
import java.io.File;
2
import java.io.IOException;
3
import java.util.ArrayList;
4
import java.util.List;
5
6
import javax.xml.parsers.DocumentBuilder;
7
import javax.xml.parsers.DocumentBuilderFactory;
8
import javax.xml.parsers.ParserConfigurationException;
9
10
import org.opencv.core.Core;
11
import org.opencv.core.CvType;
12
import org.opencv.core.DMatch;
13
import org.opencv.core.KeyPoint;
14
import org.opencv.core.Mat;
15
import org.opencv.core.MatOfDMatch;
16
import org.opencv.core.MatOfKeyPoint;
17
import org.opencv.core.Scalar;
18
import org.opencv.features2d.AKAZE;
19
import org.opencv.features2d.DescriptorMatcher;
20
import org.opencv.features2d.Features2d;
21
import org.opencv.highgui.HighGui;
22
import org.opencv.imgcodecs.Imgcodecs;
23
import org.w3c.dom.Document;
24
import org.xml.sax.SAXException;
25
26
class AKAZEMatch {
27
public void run(String[] args) {
28
//! [load]
29
String filename1 = args.length > 2 ? args[0] : "../data/graf1.png";
30
String filename2 = args.length > 2 ? args[1] : "../data/graf3.png";
31
String filename3 = args.length > 2 ? args[2] : "../data/H1to3p.xml";
32
Mat img1 = Imgcodecs.imread(filename1, Imgcodecs.IMREAD_GRAYSCALE);
33
Mat img2 = Imgcodecs.imread(filename2, Imgcodecs.IMREAD_GRAYSCALE);
34
if (img1.empty() || img2.empty()) {
35
System.err.println("Cannot read images!");
36
System.exit(0);
37
}
38
39
File file = new File(filename3);
40
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
41
DocumentBuilder documentBuilder;
42
Document document;
43
Mat homography = new Mat(3, 3, CvType.CV_64F);
44
double[] homographyData = new double[(int) (homography.total()*homography.channels())];
45
try {
46
documentBuilder = documentBuilderFactory.newDocumentBuilder();
47
document = documentBuilder.parse(file);
48
String homographyStr = document.getElementsByTagName("data").item(0).getTextContent();
49
String[] splited = homographyStr.split("\\s+");
50
int idx = 0;
51
for (String s : splited) {
52
if (!s.isEmpty()) {
53
homographyData[idx] = Double.parseDouble(s);
54
idx++;
55
}
56
}
57
} catch (ParserConfigurationException e) {
58
e.printStackTrace();
59
System.exit(0);
60
} catch (SAXException e) {
61
e.printStackTrace();
62
System.exit(0);
63
} catch (IOException e) {
64
e.printStackTrace();
65
System.exit(0);
66
}
67
homography.put(0, 0, homographyData);
68
//! [load]
69
70
//! [AKAZE]
71
AKAZE akaze = AKAZE.create();
72
MatOfKeyPoint kpts1 = new MatOfKeyPoint(), kpts2 = new MatOfKeyPoint();
73
Mat desc1 = new Mat(), desc2 = new Mat();
74
akaze.detectAndCompute(img1, new Mat(), kpts1, desc1);
75
akaze.detectAndCompute(img2, new Mat(), kpts2, desc2);
76
//! [AKAZE]
77
78
//! [2-nn matching]
79
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
80
List<MatOfDMatch> knnMatches = new ArrayList<>();
81
matcher.knnMatch(desc1, desc2, knnMatches, 2);
82
//! [2-nn matching]
83
84
//! [ratio test filtering]
85
float ratioThreshold = 0.8f; // Nearest neighbor matching ratio
86
List<KeyPoint> listOfMatched1 = new ArrayList<>();
87
List<KeyPoint> listOfMatched2 = new ArrayList<>();
88
List<KeyPoint> listOfKeypoints1 = kpts1.toList();
89
List<KeyPoint> listOfKeypoints2 = kpts2.toList();
90
for (int i = 0; i < knnMatches.size(); i++) {
91
DMatch[] matches = knnMatches.get(i).toArray();
92
float dist1 = matches[0].distance;
93
float dist2 = matches[1].distance;
94
if (dist1 < ratioThreshold * dist2) {
95
listOfMatched1.add(listOfKeypoints1.get(matches[0].queryIdx));
96
listOfMatched2.add(listOfKeypoints2.get(matches[0].trainIdx));
97
}
98
}
99
//! [ratio test filtering]
100
101
//! [homography check]
102
double inlierThreshold = 2.5; // Distance threshold to identify inliers with homography check
103
List<KeyPoint> listOfInliers1 = new ArrayList<>();
104
List<KeyPoint> listOfInliers2 = new ArrayList<>();
105
List<DMatch> listOfGoodMatches = new ArrayList<>();
106
for (int i = 0; i < listOfMatched1.size(); i++) {
107
Mat col = new Mat(3, 1, CvType.CV_64F);
108
double[] colData = new double[(int) (col.total() * col.channels())];
109
colData[0] = listOfMatched1.get(i).pt.x;
110
colData[1] = listOfMatched1.get(i).pt.y;
111
colData[2] = 1.0;
112
col.put(0, 0, colData);
113
114
Mat colRes = new Mat();
115
Core.gemm(homography, col, 1.0, new Mat(), 0.0, colRes);
116
colRes.get(0, 0, colData);
117
Core.multiply(colRes, new Scalar(1.0 / colData[2]), col);
118
col.get(0, 0, colData);
119
120
double dist = Math.sqrt(Math.pow(colData[0] - listOfMatched2.get(i).pt.x, 2) +
121
Math.pow(colData[1] - listOfMatched2.get(i).pt.y, 2));
122
123
if (dist < inlierThreshold) {
124
listOfGoodMatches.add(new DMatch(listOfInliers1.size(), listOfInliers2.size(), 0));
125
listOfInliers1.add(listOfMatched1.get(i));
126
listOfInliers2.add(listOfMatched2.get(i));
127
}
128
}
129
//! [homography check]
130
131
//! [draw final matches]
132
Mat res = new Mat();
133
MatOfKeyPoint inliers1 = new MatOfKeyPoint(listOfInliers1.toArray(new KeyPoint[listOfInliers1.size()]));
134
MatOfKeyPoint inliers2 = new MatOfKeyPoint(listOfInliers2.toArray(new KeyPoint[listOfInliers2.size()]));
135
MatOfDMatch goodMatches = new MatOfDMatch(listOfGoodMatches.toArray(new DMatch[listOfGoodMatches.size()]));
136
Features2d.drawMatches(img1, inliers1, img2, inliers2, goodMatches, res);
137
Imgcodecs.imwrite("akaze_result.png", res);
138
139
double inlierRatio = listOfInliers1.size() / (double) listOfMatched1.size();
140
System.out.println("A-KAZE Matching Results");
141
System.out.println("*******************************");
142
System.out.println("# Keypoints 1: \t" + listOfKeypoints1.size());
143
System.out.println("# Keypoints 2: \t" + listOfKeypoints2.size());
144
System.out.println("# Matches: \t" + listOfMatched1.size());
145
System.out.println("# Inliers: \t" + listOfInliers1.size());
146
System.out.println("# Inliers Ratio: \t" + inlierRatio);
147
148
HighGui.imshow("result", res);
149
HighGui.waitKey();
150
//! [draw final matches]
151
152
System.exit(0);
153
}
154
}
155
156
public class AKAZEMatchDemo {
157
public static void main(String[] args) {
158
// Load the native OpenCV library
159
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
160
161
new AKAZEMatch().run(args);
162
}
163
}
164
165