FlannBasedDescriptorMatcherTest.java 12 KB

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