diff --git a/modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java new file mode 100644 index 0000000000000000000000000000000000000000..42433d741320e3928778c5b4851561c76beb8939 --- /dev/null +++ b/modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java @@ -0,0 +1,274 @@ +package org.opencv.test.features2d; + +import org.opencv.core.Core; +import org.opencv.core.CvType; +import org.opencv.core.Mat; +import org.opencv.core.Point; +import org.opencv.core.Scalar; +import org.opencv.features2d.DMatch; +import org.opencv.features2d.DescriptorExtractor; +import org.opencv.features2d.DescriptorMatcher; +import org.opencv.features2d.FeatureDetector; +import org.opencv.features2d.KeyPoint; +import org.opencv.test.OpenCVTestCase; +import org.opencv.test.OpenCVTestRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class BruteForceSL2DescriptorMatcherTest extends OpenCVTestCase { + + DescriptorMatcher matcher; + int matSize; + DMatch[] truth; + + private Mat getMaskImg() { + return new Mat(5, 2, CvType.CV_8U, new Scalar(0)) { + { + put(0, 0, 1, 1, 1, 1); + } + }; + } + + private float sqr(float val){ + return val * val; + } + + private Mat getQueryDescriptors() { + Mat img = getQueryImg(); + List keypoints = new ArrayList(); + Mat descriptors = new Mat(); + + FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF); + DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SURF); + + String filename = OpenCVTestRunner.getTempFileName("yml"); + writeFile(filename, "%YAML:1.0\nhessianThreshold: 8000.\noctaves: 3\noctaveLayers: 4\nupright: 0\n"); + detector.read(filename); + + detector.detect(img, keypoints); + extractor.compute(img, keypoints, descriptors); + + return descriptors; + } + + private Mat getQueryImg() { + Mat cross = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(255)); + Core.line(cross, new Point(30, matSize / 2), new Point(matSize - 31, matSize / 2), new Scalar(100), 3); + Core.line(cross, new Point(matSize / 2, 30), new Point(matSize / 2, matSize - 31), new Scalar(100), 3); + + return cross; + } + + private Mat getTrainDescriptors() { + Mat img = getTrainImg(); + List keypoints = Arrays.asList(new KeyPoint(50, 50, 16, 0, 20000, 1, -1), new KeyPoint(42, 42, 16, 160, 10000, 1, -1)); + Mat descriptors = new Mat(); + + DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SURF); + + extractor.compute(img, keypoints, descriptors); + + return descriptors; + } + + private Mat getTrainImg() { + Mat cross = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(255)); + Core.line(cross, new Point(20, matSize / 2), new Point(matSize - 21, matSize / 2), new Scalar(100), 2); + Core.line(cross, new Point(matSize / 2, 20), new Point(matSize / 2, matSize - 21), new Scalar(100), 2); + + return cross; + } + + protected void setUp() throws Exception { + matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_SL2); + matSize = 100; + + truth = new DMatch[] { + new DMatch(0, 0, 0, sqr(0.643284f)), + new DMatch(1, 1, 0, sqr(0.92945856f)), + new DMatch(2, 1, 0, sqr(0.2841479f)), + new DMatch(3, 1, 0, sqr(0.9194034f)), + new DMatch(4, 1, 0, sqr(0.3006621f)) }; + + super.setUp(); + } + + public void testAdd() { + matcher.add(Arrays.asList(new Mat())); + assertFalse(matcher.empty()); + } + + public void testClear() { + matcher.add(Arrays.asList(new Mat())); + + matcher.clear(); + + assertTrue(matcher.empty()); + } + + public void testClone() { + Mat train = new Mat(1, 1, CvType.CV_8U, new Scalar(123)); + Mat truth = train.clone(); + matcher.add(Arrays.asList(train)); + + DescriptorMatcher cloned = matcher.clone(); + + assertNotNull(cloned); + + List descriptors = cloned.getTrainDescriptors(); + assertEquals(1, descriptors.size()); + assertMatEqual(truth, descriptors.get(0)); + } + + public void testCloneBoolean() { + matcher.add(Arrays.asList(new Mat())); + + DescriptorMatcher cloned = matcher.clone(true); + + assertNotNull(cloned); + assertTrue(cloned.empty()); + } + + public void testCreate() { + assertNotNull(matcher); + } + + public void testEmpty() { + assertTrue(matcher.empty()); + } + + public void testGetTrainDescriptors() { + Mat train = new Mat(1, 1, CvType.CV_8U, new Scalar(123)); + Mat truth = train.clone(); + matcher.add(Arrays.asList(train)); + + List descriptors = matcher.getTrainDescriptors(); + + assertEquals(1, descriptors.size()); + assertMatEqual(truth, descriptors.get(0)); + } + + public void testIsMaskSupported() { + assertTrue(matcher.isMaskSupported()); + } + + public void testKnnMatchMatListOfListOfDMatchInt() { + fail("Not yet implemented"); + } + + public void testKnnMatchMatListOfListOfDMatchIntListOfMat() { + fail("Not yet implemented"); + } + + public void testKnnMatchMatListOfListOfDMatchIntListOfMatBoolean() { + fail("Not yet implemented"); + } + + public void testKnnMatchMatMatListOfListOfDMatchInt() { + fail("Not yet implemented"); + } + + public void testKnnMatchMatMatListOfListOfDMatchIntMat() { + fail("Not yet implemented"); + } + + public void testKnnMatchMatMatListOfListOfDMatchIntMatBoolean() { + fail("Not yet implemented"); + } + + public void testMatchMatListOfDMatch() { + Mat train = getTrainDescriptors(); + Mat query = getQueryDescriptors(); + List matches = new ArrayList(); + matcher.add(Arrays.asList(train)); + + matcher.match(query, matches); + + assertListDMatchEquals(Arrays.asList(truth), matches, EPS); + } + + public void testMatchMatListOfDMatchListOfMat() { + Mat train = getTrainDescriptors(); + Mat query = getQueryDescriptors(); + Mat mask = getMaskImg(); + List matches = new ArrayList(); + matcher.add(Arrays.asList(train)); + + matcher.match(query, matches, Arrays.asList(mask)); + + assertListDMatchEquals(Arrays.asList(truth[0], truth[1]), matches, EPS); + } + + public void testMatchMatMatListOfDMatch() { + Mat train = getTrainDescriptors(); + Mat query = getQueryDescriptors(); + List matches = new ArrayList(); + + matcher.match(query, train, matches); + + assertListDMatchEquals(Arrays.asList(truth), matches, EPS); + + // OpenCVTestRunner.Log("matches found: " + matches.size()); + // for (DMatch m : matches) + // OpenCVTestRunner.Log(m.toString()); + } + + public void testMatchMatMatListOfDMatchMat() { + Mat train = getTrainDescriptors(); + Mat query = getQueryDescriptors(); + Mat mask = getMaskImg(); + List matches = new ArrayList(); + + matcher.match(query, train, matches, mask); + + assertListDMatchEquals(Arrays.asList(truth[0], truth[1]), matches, EPS); + } + + public void testRadiusMatchMatListOfListOfDMatchFloat() { + fail("Not yet implemented"); + } + + public void testRadiusMatchMatListOfListOfDMatchFloatListOfMat() { + fail("Not yet implemented"); + } + + public void testRadiusMatchMatListOfListOfDMatchFloatListOfMatBoolean() { + fail("Not yet implemented"); + } + + public void testRadiusMatchMatMatListOfListOfDMatchFloat() { + fail("Not yet implemented"); + } + + public void testRadiusMatchMatMatListOfListOfDMatchFloatMat() { + fail("Not yet implemented"); + } + + public void testRadiusMatchMatMatListOfListOfDMatchFloatMatBoolean() { + fail("Not yet implemented"); + } + + public void testRead() { + String filename = OpenCVTestRunner.getTempFileName("yml"); + writeFile(filename, "%YAML:1.0\n"); + + matcher.read(filename); + assertTrue(true);// BruteforceMatcher has no settings + } + + public void testTrain() { + matcher.train();// BruteforceMatcher does not need to train + } + + public void testWrite() { + String filename = OpenCVTestRunner.getTempFileName("yml"); + + matcher.write(filename); + + String truth = "%YAML:1.0\n"; + assertEquals(truth, readFile(filename)); + } + +} diff --git a/modules/java/check-tests.py b/modules/java/check-tests.py index b89877229c3b77fd1083dbf4391249eafddfabf7..14b4711402cc1dabe98a7a4c85800220ea97db13 100644 --- a/modules/java/check-tests.py +++ b/modules/java/check-tests.py @@ -75,7 +75,7 @@ class JavaParser: for prefix in ("OneWay", "Fern"): parser.parse_file(path,prefix) elif path.endswith("DescriptorMatcher.java"): - for prefix in ("BruteForce", "BruteForceHamming", "BruteForceHammingLUT", "BruteForceL1", "FlannBased"): + for prefix in ("BruteForce", "BruteForceHamming", "BruteForceHammingLUT", "BruteForceL1", "FlannBased", "BruteForceSL2"): parser.parse_file(path,prefix) else: parser.parse_file(path) diff --git a/modules/java/src/cpp/features2d_manual.hpp b/modules/java/src/cpp/features2d_manual.hpp index 5246fe0ba3ef3808a94e0d74c7c23501acfe552b..028d3fcf8ee1d39df9433e700fb38ec46acb0df0 100644 --- a/modules/java/src/cpp/features2d_manual.hpp +++ b/modules/java/src/cpp/features2d_manual.hpp @@ -166,7 +166,8 @@ public: BRUTEFORCE = 2, BRUTEFORCE_L1 = 3, BRUTEFORCE_HAMMING = 4, - BRUTEFORCE_HAMMINGLUT = 5 + BRUTEFORCE_HAMMINGLUT = 5, + BRUTEFORCE_SL2 = 6 }; CV_WRAP_AS(clone) javaDescriptorMatcher* jclone( bool emptyTrainData=false ) const @@ -198,6 +199,9 @@ public: case BRUTEFORCE_HAMMINGLUT: name = "BruteForce-HammingLUT"; break; + case BRUTEFORCE_SL2: + name = "BruteForce-SL2"; + break; default: CV_Error( CV_StsBadArg, "Specified descriptor matcher type is not supported." ); break; @@ -246,6 +250,7 @@ public: OPPONENTEXTRACTOR = 1000, + OPPONENT_SIFT = OPPONENTEXTRACTOR + SIFT, OPPONENT_SURF = OPPONENTEXTRACTOR + SURF, OPPONENT_ORB = OPPONENTEXTRACTOR + ORB,