JavaCV可以认为是OpenCV的Java版,其本质上是一个Java Interface,是一个联结Java与OpenCV的桥梁,所以它本质上是依赖OpenCV的。关于这东西能查到的文档和资料实在是太少了,这个过程中着实踩了不少坑,记录一下以便帮助以后的人。
先说第一个坑,从JavaCV 0.8版本开始,OpenCV被完整地集成进了JavaCV的依赖中,也就是说从这个版本以后不需要在环境中配置任何关于OpenCV的东西,包括什么加载dll,配置环境变量,加载jar什么的,完全不需要!!! 网上搜到的相当多的博客都说什么加载dll,都是没用的,新版本完全不需要。不要在错误的方向上一再尝试了。
下面开始第一个demo程序。工程采用gradle进行管理,与maven基本一致,换汤不换药的东西,没什么特别的。依赖项如下:
compile group: 'org.bytedeco', name: 'javacv-platform', version: '1.5'
依赖比较大,目测下载完会有400M左右的样子,耐心等待。
观察下载好的jar会发现JavaCV似乎是将OpenCV在各个平台编译之后的产物都添加了进来,不仅仅是OpenCV,还有ffmpeg等,连macos、arm、android啥的都在这里面,所以导致了依赖项如此之大。后期我们会进行一些筛选,剔除掉用不到的依赖。
程序如下:
import org.bytedeco.opencv.opencv_core.Mat;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
public class DemoApplication {
public static void main(String[] args) {
//千万不要用成这个方法,这是OpenCV的,用错了会出现各种错误
//Mat image = Imgcodecs.imread()
Mat image = imread("/root/test.png"); //可使用相对路径
System.out.println("width:" + image.cols());
System.out.println("height:" + image.rows());
}
}
这样就能正确读入图片了。
再来说说第二个坑(千万注意):
Mat
类有两个包,一个是 opencv
下面的,一个是 bytedeco
的,注意不要选错,选错了会导致后面的 imread
都指向错误的包。见下面的代码:
import org.opencv.core.Mat;
//注意这一行
import static org.opencv.imgcodecs.Imgcodecs.imread;
public class DemoApplication {
//这是错误的代码,看清楚!
public static void main(String[] args) {
Mat image = imread("/root/test.png");
System.out.println("width:" + image.cols());
System.out.println("height:" + image.rows());
}
}
没有任何问题,当运行的时候会出现这样的错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.imgcodecs.Imgcodecs.imread_1(Ljava/lang/String;)J
at org.opencv.imgcodecs.Imgcodecs.imread_1(Native Method)
at org.opencv.imgcodecs.Imgcodecs.imread(Imgcodecs.java:112)
at com.example.demo.DemoApplication.main(DemoApplication.java:8)
怎么办?当你使用 UnsatisfiedLinkError
和 javacv
作为关键字去搜索的时候,就已经深深的陷在这个坑里再也出不来了,因为得到的答案全都是要你加上这一句话:System.load(Core.NATIVE_LIBRARY_NAME)
。然后当你再次运行的时候错误变成了这样:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: opencv_java401
at java.lang.Runtime.load0(Runtime.java:806)
at java.lang.System.load(System.java:1086)
at com.example.demo.DemoApplication.main(DemoApplication.java:9)
opencv_java401
后面的数字指示的是版本,版本不同这个数字也不同,但错误都是一样的:找不到库。然后继续搜索,答案清一水的都是各种配置环境,配置IDE,安装OpenCV什么的…
然后不管你如何努力,程序就是跑不起来,因为从第一次搜索开始就已经走上了错误的方向。
其实在GitHub上早就告诉了我们正确的使用姿势:
网上的都是错的吗,并不是,针对于早期的版本这个方案确实是可行的,只不过有太多人都是在粘贴复制到自己的文章中来,根本没有注意 import
中的内容以及JavaCV的版本号。也算给自己提个醒,多看文档。