添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
火爆的罐头  ·  Hive ...·  2 月前    · 
文雅的海龟  ·  My Oppo Findx is ...·  1 年前    · 


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左右的样子,耐心等待。

javacv函数关系opencv javacv与opencv的关系_OpenCV


观察下载好的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());
}

这样就能正确读入图片了。


再来说说第二个坑( 千万注意 ):

javacv函数关系opencv javacv与opencv的关系_OpenCV_02


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());
}

没有任何问题,当运行的时候会出现这样的错误:

javacv函数关系opencv javacv与opencv的关系_UnsatisfiedLinkError_03

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) 。然后当你再次运行的时候错误变成了这样:

javacv函数关系opencv javacv与opencv的关系_UnsatisfiedLinkError_04

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上早就告诉了我们正确的使用姿势:

javacv函数关系opencv javacv与opencv的关系_javacv函数关系opencv_05


网上的都是错的吗,并不是,针对于早期的版本这个方案确实是可行的,只不过有太多人都是在粘贴复制到自己的文章中来,根本没有注意 import 中的内容以及JavaCV的版本号。也算给自己提个醒,多看文档。