SURF and SIFT algorithms do not work in OpenCV 3.0 Java

I use OpenCV 3.0 (latest version) in Java, but when I use the SURF algorithm or the SIFT algorithm, it does not work and throws an Exception that says: OpenCV Error: Bad argument (Specified feature detector type is not supported.) in cv::javaFeatureDetector::create

I have googled, but the answers that were given to such questions do not solve my problem. If anyone knows about this issue, please let me know.

Thanks in advance!

Update: The code below in the third line throws an exception.

  Mat img_object = Imgcodecs.imread("data/img_object.jpg"); Mat img_scene = Imgcodecs.imread("data/img_scene.jpg"); FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF); MatOfKeyPoint keypoints_object = new MatOfKeyPoint(); MatOfKeyPoint keypoints_scene = new MatOfKeyPoint(); detector.detect(img_object, keypoints_object); detector.detect(img_scene, keypoints_scene); 
+7
java opencv
source share
3 answers

If you compile OpenCV from source, you can fix the missing bindings by editing opencv / modules / features2d / misc / java / src / cpp / features2d_manual.hpp yourself.

I fixed it by making the following changes:

 (line 6) #ifdef HAVE_OPENCV_FEATURES2D #include "opencv2/features2d.hpp" #include "opencv2/xfeatures2d.hpp" #include "features2d_converters.hpp" ...(line 121) case SIFT: fd = xfeatures2d::SIFT::create(); break; case SURF: fd = xfeatures2d::SURF::create(); break; ...(line 353) case SIFT: de = xfeatures2d::SIFT::create(); break; case SURF: de = xfeatures2d::SURF::create(); break; 

The only requirement is that you create an additional opencv_contrib module along with your sources (you can download the git project from https://github.com/Itseez/opencv_contrib and just set its local path in the opencv ccmake settings.

Oh, and keep in mind that SIFT and SURF are proprietary software ^^;

+9
source share

This is because they are not free in new versions of OpenCV (3+). I ran into this problem a few years ago. You should:

  • Download OpenCV (if you haven’t)
  • Download the non-free part from opencv github repo
  • Generate makefiles using cmake -DBUILD_SHARED_LIBS=OFF , specifying the unoccupied part with the option DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules and create using make -j8 (or any other version of Java).
  • Edit the features2d_manual.hpp file, including opencv2/xfeatures2d.hpp and include the necessary code for SIFT and SURF case , which are commented and undefined: fd=xfeatures2d::SIFT::create(); for the SIFT descriptor and de = xfeatures2d::SIFT::create(); for SIFT extractor. Do the same for SURF if you want to use it too.

I wrote this post explaining step-by-step how to compile the non-free part of OpenCV in order to use common tools like SIFT or SURF. Compile the insecure part of OpenCV

+2
source share

I believe that modifying the features2d module (FeatureDetector class or any other classes from features2d_manual.hpp) to include methods from OpenCV Contrib modules is less attractive because it leads to a cyclical relationship between the OpenCV core and extensions (which may be free or experimental). There is another way to fix this problem without affecting feature2d classes. Making changes to xfeatures2d CMakeLists.txt, as described here , will generate java wrappers for SIFT and SURF - opencv-310.jar now has the org.opencv.xfeatures2d package. Some fixes were needed in / opencv / modules / java / generator / gen _java.py. Namely, insert 2 lines as shown below:

 def addImports(self, ctype): if ctype.startswith('vector_vector'): self.imports.add("org.opencv.core.Mat") self.imports.add("org.opencv.utils.Converters") self.imports.add("java.util.List") self.imports.add("java.util.ArrayList") self.addImports(ctype.replace('vector_vector', 'vector')) elif ctype.startswith('Feature2D'): #added self.imports.add("org.opencv.features2d.Feature2D") #added elif ctype.startswith('vector'): self.imports.add("org.opencv.core.Mat") self.imports.add('java.util.ArrayList') if type_dict[ctype]['j_type'].startswith('MatOf'): self.imports.add("org.opencv.core." + type_dict[ctype]['j_type']) else: self.imports.add("java.util.List") self.imports.add("org.opencv.utils.Converters") self.addImports(ctype.replace('vector_', '')) 

After these changes, wrappers are created successfully. However, the main problem remains how to use these wrappers from Java)). For example, SIFT.create () gives a pointer to a new SIFT class, but a call to any class method (for example, detect ()) will cause Java to crash. I also noticed that using MSER.create () directly from Java results in the same crash.

So, it seems the problem is isolated by how Feature2D.create () methods are wrapped in Java. The solution is as follows (again, by modifying / opencv / modules / java / generator / gen _java.py):

Find the line:

 ret = "%(ctype)s* curval = new %(ctype)s(_retval_);return (jlong)curval->get();" % { 'ctype':fi.ctype } 

Replace it with the following:

 ret = "%(ctype)s* curval = new %(ctype)s(_retval_);return (jlong)curval;" % { 'ctype':fi.ctype } 

Restore opencv. That is, all create () methods will work correctly for all children of the Feature2D class, including experimental and non-free methods. FeatureDescriptor / DescriptorExtractor wrappers may be deprecated. I find Feature2D much easier to use.

BUT! I am not sure if the proposed fix is ​​safe for other OpenCV modules. Is there a scenario where (jlong) curval needs to be dereferenced? It looks like the same fix has already been proposed here .

+1
source share

All Articles