1 package org.opencv.test.features2d;
2 
3 import java.util.Arrays;
4 import java.util.List;
5 
6 import org.opencv.core.Core;
7 import org.opencv.core.CvException;
8 import org.opencv.core.CvType;
9 import org.opencv.core.Mat;
10 import org.opencv.core.MatOfDMatch;
11 import org.opencv.core.MatOfKeyPoint;
12 import org.opencv.core.Point;
13 import org.opencv.core.Scalar;
14 import org.opencv.core.DMatch;
15 import org.opencv.features2d.DescriptorExtractor;
16 import org.opencv.features2d.DescriptorMatcher;
17 import org.opencv.features2d.FeatureDetector;
18 import org.opencv.core.KeyPoint;
19 import org.opencv.test.OpenCVTestCase;
20 import org.opencv.test.OpenCVTestRunner;
21 import org.opencv.imgproc.Imgproc;
22 
23 public class FlannBasedDescriptorMatcherTest extends OpenCVTestCase {
24 
25     static final String xmlParamsDefault = "<?xml version=\"1.0\"?>\n"
26             + "<opencv_storage>\n"
27             + "<indexParams>\n"
28             + "  <_>\n"
29             + "    <name>algorithm</name>\n"
30             + "    <type>23</type>\n"
31             + "    <value>1</value></_>\n"
32             + "  <_>\n"
33             + "    <name>trees</name>\n"
34             + "    <type>4</type>\n"
35             + "    <value>4</value></_></indexParams>\n"
36             + "<searchParams>\n"
37             + "  <_>\n"
38             + "    <name>checks</name>\n"
39             + "    <type>4</type>\n"
40             + "    <value>32</value></_>\n"
41             + "  <_>\n"
42             + "    <name>eps</name>\n"
43             + "    <type>5</type>\n"
44             + "    <value>0.</value></_>\n"
45             + "  <_>\n"
46             + "    <name>sorted</name>\n"
47             + "    <type>15</type>\n"
48             + "    <value>1</value></_></searchParams>\n"
49             + "</opencv_storage>\n";
50     static final String ymlParamsDefault = "%YAML:1.0\n"
51             + "indexParams:\n"
52             + "   -\n"
53             + "      name: algorithm\n"
54             + "      type: 23\n"
55             + "      value: 1\n"
56             + "   -\n"
57             + "      name: trees\n"
58             + "      type: 4\n"
59             + "      value: 4\n"
60             + "searchParams:\n"
61             + "   -\n"
62             + "      name: checks\n"
63             + "      type: 4\n"
64             + "      value: 32\n"
65             + "   -\n"
66             + "      name: eps\n"
67             + "      type: 5\n"
68             + "      value: 0.\n"
69             + "   -\n"
70             + "      name: sorted\n"
71             + "      type: 15\n"
72             + "      value: 1\n";
73     static final String ymlParamsModified = "%YAML:1.0\n"
74             + "indexParams:\n"
75             + "   -\n"
76             + "      name: algorithm\n"
77             + "      type: 23\n"
78             + "      value: 6\n"// this line is changed!
79             + "   -\n"
80             + "      name: trees\n"
81             + "      type: 4\n"
82             + "      value: 4\n"
83             + "searchParams:\n"
84             + "   -\n"
85             + "      name: checks\n"
86             + "      type: 4\n"
87             + "      value: 32\n"
88             + "   -\n"
89             + "      name: eps\n"
90             + "      type: 5\n"
91             + "      value: 4.\n"// this line is changed!
92             + "   -\n"
93             + "      name: sorted\n"
94             + "      type: 15\n"
95             + "      value: 1\n";
96 
97     DescriptorMatcher matcher;
98 
99     int matSize;
100 
101     DMatch[] truth;
102 
getMaskImg()103     private Mat getMaskImg() {
104         return new Mat(5, 2, CvType.CV_8U, new Scalar(0)) {
105             {
106                 put(0, 0, 1, 1, 1, 1);
107             }
108         };
109     }
110 
111     private Mat getQueryDescriptors() {
112         Mat img = getQueryImg();
113         MatOfKeyPoint keypoints = new MatOfKeyPoint();
114         Mat descriptors = new Mat();
115 
116         FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
117         DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SURF);
118 
119         String filename = OpenCVTestRunner.getTempFileName("yml");
120         writeFile(filename, "%YAML:1.0\nhessianThreshold: 8000.\noctaves: 3\noctaveLayers: 4\nupright: 0\n");
121         detector.read(filename);
122 
123         detector.detect(img, keypoints);
124         extractor.compute(img, keypoints, descriptors);
125 
126         return descriptors;
127     }
128 
129     private Mat getQueryImg() {
130         Mat cross = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(255));
131         Imgproc.line(cross, new Point(30, matSize / 2), new Point(matSize - 31, matSize / 2), new Scalar(100), 3);
132         Imgproc.line(cross, new Point(matSize / 2, 30), new Point(matSize / 2, matSize - 31), new Scalar(100), 3);
133 
134         return cross;
135     }
136 
137     private Mat getTrainDescriptors() {
138         Mat img = getTrainImg();
139         MatOfKeyPoint keypoints = new MatOfKeyPoint(new KeyPoint(50, 50, 16, 0, 20000, 1, -1), new KeyPoint(42, 42, 16, 160, 10000, 1, -1));
140         Mat descriptors = new Mat();
141 
142         DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SURF);
143 
144         extractor.compute(img, keypoints, descriptors);
145 
146         return descriptors;
147     }
148 
149     private Mat getTrainImg() {
150         Mat cross = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(255));
151         Imgproc.line(cross, new Point(20, matSize / 2), new Point(matSize - 21, matSize / 2), new Scalar(100), 2);
152         Imgproc.line(cross, new Point(matSize / 2, 20), new Point(matSize / 2, matSize - 21), new Scalar(100), 2);
153 
154         return cross;
155     }
156 
157     protected void setUp() throws Exception {
158         super.setUp();
159         matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
160         matSize = 100;
161         truth = new DMatch[] {
162                 new DMatch(0, 0, 0, 0.6211397f),
163                 new DMatch(1, 1, 0, 0.9177120f),
164                 new DMatch(2, 1, 0, 0.3112163f),
165                 new DMatch(3, 1, 0, 0.2925075f),
166                 new DMatch(4, 1, 0, 0.9309179f)
167                 };
168     }
169 
170     public void testAdd() {
171         matcher.add(Arrays.asList(new Mat()));
172         assertFalse(matcher.empty());
173     }
174 
175     public void testClear() {
176         matcher.add(Arrays.asList(new Mat()));
177 
178         matcher.clear();
179 
180         assertTrue(matcher.empty());
181     }
182 
183     public void testClone() {
184         Mat train = new Mat(1, 1, CvType.CV_8U, new Scalar(123));
185         matcher.add(Arrays.asList(train));
186 
187         try {
188             matcher.clone();
189             fail("Expected CvException (CV_StsNotImplemented)");
190         } catch (CvException cverr) {
191             // expected
192         }
193     }
194 
195     public void testCloneBoolean() {
196         matcher.add(Arrays.asList(new Mat()));
197 
198         DescriptorMatcher cloned = matcher.clone(true);
199 
200         assertNotNull(cloned);
201         assertTrue(cloned.empty());
202     }
203 
204     public void testCreate() {
205         assertNotNull(matcher);
206     }
207 
208     public void testEmpty() {
209         assertTrue(matcher.empty());
210     }
211 
212     public void testGetTrainDescriptors() {
213         Mat train = new Mat(1, 1, CvType.CV_8U, new Scalar(123));
214         Mat truth = train.clone();
215         matcher.add(Arrays.asList(train));
216 
217         List<Mat> descriptors = matcher.getTrainDescriptors();
218 
219         assertEquals(1, descriptors.size());
220         assertMatEqual(truth, descriptors.get(0));
221     }
222 
223     public void testIsMaskSupported() {
224         assertFalse(matcher.isMaskSupported());
225     }
226 
227     public void testKnnMatchMatListOfListOfDMatchInt() {
228         fail("Not yet implemented");
229     }
230 
231     public void testKnnMatchMatListOfListOfDMatchIntListOfMat() {
232         fail("Not yet implemented");
233     }
234 
235     public void testKnnMatchMatListOfListOfDMatchIntListOfMatBoolean() {
236         fail("Not yet implemented");
237     }
238 
239     public void testKnnMatchMatMatListOfListOfDMatchInt() {
240         fail("Not yet implemented");
241     }
242 
243     public void testKnnMatchMatMatListOfListOfDMatchIntMat() {
244         fail("Not yet implemented");
245     }
246 
247     public void testKnnMatchMatMatListOfListOfDMatchIntMatBoolean() {
248         fail("Not yet implemented");
249     }
250 
251     public void testMatchMatListOfDMatch() {
252         Mat train = getTrainDescriptors();
253         Mat query = getQueryDescriptors();
254         MatOfDMatch matches = new MatOfDMatch();
255         matcher.add(Arrays.asList(train));
256         matcher.train();
257 
258         matcher.match(query, matches);
259 
260         assertArrayDMatchEquals(truth, matches.toArray(), EPS);
261     }
262 
263     public void testMatchMatListOfDMatchListOfMat() {
264         Mat train = getTrainDescriptors();
265         Mat query = getQueryDescriptors();
266         Mat mask = getMaskImg();
267         MatOfDMatch matches = new MatOfDMatch();
268         matcher.add(Arrays.asList(train));
269         matcher.train();
270 
271         matcher.match(query, matches, Arrays.asList(mask));
272 
273         assertArrayDMatchEquals(truth, matches.toArray(), EPS);
274     }
275 
276     public void testMatchMatMatListOfDMatch() {
277         Mat train = getTrainDescriptors();
278         Mat query = getQueryDescriptors();
279         MatOfDMatch matches = new MatOfDMatch();
280 
281         matcher.match(query, train, matches);
282 
283         assertArrayDMatchEquals(truth, matches.toArray(), EPS);
284 
285         // OpenCVTestRunner.Log(matches.toString());
286         // OpenCVTestRunner.Log(matches);
287     }
288 
289     public void testMatchMatMatListOfDMatchMat() {
290         Mat train = getTrainDescriptors();
291         Mat query = getQueryDescriptors();
292         Mat mask = getMaskImg();
293         MatOfDMatch matches = new MatOfDMatch();
294 
295         matcher.match(query, train, matches, mask);
296 
297         assertListDMatchEquals(Arrays.asList(truth), matches.toList(), EPS);
298     }
299 
300     public void testRadiusMatchMatListOfListOfDMatchFloat() {
301         fail("Not yet implemented");
302     }
303 
304     public void testRadiusMatchMatListOfListOfDMatchFloatListOfMat() {
305         fail("Not yet implemented");
306     }
307 
308     public void testRadiusMatchMatListOfListOfDMatchFloatListOfMatBoolean() {
309         fail("Not yet implemented");
310     }
311 
312     public void testRadiusMatchMatMatListOfListOfDMatchFloat() {
313         fail("Not yet implemented");
314     }
315 
316     public void testRadiusMatchMatMatListOfListOfDMatchFloatMat() {
317         fail("Not yet implemented");
318     }
319 
320     public void testRadiusMatchMatMatListOfListOfDMatchFloatMatBoolean() {
321         fail("Not yet implemented");
322     }
323 
324     public void testRead() {
325         String filenameR = OpenCVTestRunner.getTempFileName("yml");
326         String filenameW = OpenCVTestRunner.getTempFileName("yml");
327         writeFile(filenameR, ymlParamsModified);
328 
329         matcher.read(filenameR);
330         matcher.write(filenameW);
331 
332         assertEquals(ymlParamsModified, readFile(filenameW));
333     }
334 
335     public void testTrain() {
336         Mat train = getTrainDescriptors();
337         matcher.add(Arrays.asList(train));
338         matcher.train();
339     }
340 
341     public void testTrainNoData() {
342         try {
343             matcher.train();
344             fail("Expected CvException - FlannBasedMatcher::train should fail on empty train set");
345         } catch (CvException cverr) {
346             // expected
347         }
348     }
349 
350     public void testWrite() {
351         String filename = OpenCVTestRunner.getTempFileName("xml");
352 
353         matcher.write(filename);
354 
355         assertEquals(xmlParamsDefault, readFile(filename));
356     }
357 
358     public void testWriteYml() {
359         String filename = OpenCVTestRunner.getTempFileName("yml");
360 
361         matcher.write(filename);
362 
363         assertEquals(ymlParamsDefault, readFile(filename));
364     }
365 
366 }
367