为了在eclipse-java里用surf和sift进行图片特征提取、描述和匹配,搜了好久、下载了好几个别人编译的库,要么没有java用的jar和dll,要么一用surf.create()就弹出"This algorithm is patented and is excluded in this configuration; " "Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library")。没有可用的,只能自己弄一个了。文章上讲的都挺简单,自己下载OpenCV和OpenCV-contrib源码,重新Cmake配置,选上OPENCV_ENABLE_NONFREE,然后编译出来就行了。实际上做起来好多坑,下面就来一一吐槽!
刚开始的时候想用mingw做编译器来编译,后来发现是个巨大的坑,尝试了不下十遍,都无法完成mingw32-make。可能和我没有安装Ant和Python有关,不管怎么样,这个编译起来太麻烦了,不建议用。我没有成功,也就不吐槽过程中的一堆问题了。
下载安装了Visual Studio 2019社区版(免费),又安装了Cmake,按照网上帖子用Cmake来configure然后generate(不帮别人卖广告,自己搜一下吧,很多的,我不重复。后面会讲关键的Configrue选项)。然后编译,顺利进行了ALL_BUILD和INSTALL的生成。打开build目录一看,找不到opencv-410的jar和dll。郁闷!
注意事项1:要安装Ant和Python
上网搜了一大通,终于发现打包jar需要用Apache_Ant,好吧,下载Ant,解压,设置系统环境变量里面的Path,开始设了不行,来回折腾几回才设好了Ant(不会设环境变量就自己上网搜吧,抓重点,我就不重复这些基本操作了)。装完了再试,还是不行。看到好多Python的字眼,估计还要Python,不管那么多还是下载装上吧。由于过程中没有一一记录,我也不知道最终是否一定需要用Python,但还是建议装上吧。
注意事项2:要用Java,Java编程环境是要的,但是还要把Java编译器的环境变量设对
编译的时候出现:
4>Buildfile: C:\opencv4\build\modules\java\jar\opencv\build.xml
4>
4>jar:
4>Target 'jar' failed with message 'Unable to find a javac compiler;
4>com.sun.tools.javac.Main is not on the classpath.
4>Perhaps JAVA_HOME does not point to the JDK.
4>It is currently set to "C:\Program Files (x86)\Java\jre1.8.0_31"'.
怎么办?上网又搜一大通,发现原因是Cmake里Java编译程序所在路径是错的,我已经用到java 1.12.01了,Cmake却找到了旧路径!又去设置环境变量里面的Path,再到注册表里删旧键值。折腾一大通,还不行。后来把Cmake的Cashe 删掉,重头开始进行设置和Confiure、Generate,行了!
注意事项3:修改源码,在surf.cpp,sift.cpp里面加上#include "opencv2/xfeatures2d.hpp"
终于生成了Eclipse-java可以用的Jar和dll了。写个程序一试,还是出现"This algorithm is patented and is excluded in this configuration; "。又上网搜一通,发现有人通过修改surf.cpp代码来解决问题。那就改代码吧。按别人方法改了,不行,ALL_BUILD生成出错,INSTALL生成出错!折腾了几回,想去掉Opencv_congtrible里面的#ifdef OPENCV_ENABLE_NONFREE等语句是不行的,也不知道别人怎么成功的!?最后我想了很久,终于想起去看surf.cpp在哪里define的 OPENCV_ENABLE_NONFREE。在Visual Studio里一路追下去,发现原来在opencv_modules.hpp文件里做的define,然后precomp.hpp里面有#include "opencv2/xfeatures2d.hpp",而surf.cpp只有#include "precomp.hpp",我也搞不懂为什么编译surf.cpp的时候就不能转到#ifdef OPENCV_ENABLE_NONFREE里面去!?难道是在Cmake里面没有选上ENABLE_PRECOMPILED_HEADERS?我没有去研究这个问题了,我在surf.cpp,sift.cpp里面加上#include "opencv2/xfeatures2d.hpp",让它能找到OPENCV_ENABLE_NONFREE已经define;也在Cmake里面选上了ENABLE_PRECOMPILED_HEADERS。
注意事项4:去掉BUILD_SHARED_LIBS选项的勾勾
好了,不会出现"This algorithm is patented and is excluded in this configuration"了,这次是"……UnsatisfiedLinkError:……install\java\opencv_java410.dll: Can't find dependent libraries." 哎!继续上网搜答案,搜了后,发现是生成的opencv_java410.dll没有把依赖的其他库打包进去。怎么打包进去呢?后来有人说,build with BUILD_SHARED_LIBS=OFF,怎么让它off?把Cmake里面confiure时的BUILD_SHARED_LIBS选项的勾勾去掉。好了,又重新弄一遍,编译出来,终于可以用了!
注意事项5:Cmake里进行Confiure的选项设置
要勾选上
BUILD_JAVA
BUILD_opencv_java
BUILD_opencv_java_bingdings_generator
OPENCV_ENABLE_NONFREE
ENABLE_PRECOMPILED_HEADERS
要设置好OPENCV_EXTRA_MODULES_PATH ,路径是opencv_contrib源码所在路径下的modules文件夹的路径
BUILD_SHARED_LIBS不选
BUILD_opencv_world不选
其它的默认。如果有什么选项你明白用来做什么的,你自己考虑选不选了。
为了用surf、sift,搞了一个星期!哎!
吐槽主要是为了让初学者不再浪费时间,也为了不让初学者倒在Java调用OpenCV的门槛前。感觉在Java里用Opencv的人少,很多问题很难有直接答案,需要很大的耐心,烧很久的脑子!路漫漫其修远兮……
编译出来的库放在https://download.csdn.net/download/netscaner/11460982