前言
众所周知OpenCV是一个基于C/C++开发的功能强大的计算机视觉开源框架,官方提供了Windows(含Java封装库)、Android、iOS这几种环境下的已编译好的库。 一般情况下如果想在桌面操作系统中使用OpenCV,可以直接使用C/C++调用编译好的动态/静态库。 如果想要通过Java来使用OpenCV,可以先将相关功能用C/C++开发后编译为JNI库、再由Java程序调用(IPC、RPC方式在此不讨论)。 也可以直接使用OpenCV的Java封装库(封装了对OpenCV的JNI调用),这样可以直接用Java进行OpenCV相关的开发,后面这种方式对于大多数Java开发同学来说更为友好,效率上也没有太大的差别。
但官方只提供了Windows下的Java封装库,Linux、MacOS下的Java封装库就要自己动手丰衣足食了,想要在Java后端开发中使用OpenCV,就得自己编译下Linux(服务器使用)、MacOS(本机开发使用)下的Java封装库和对应的OpenCV动态链接库了。
编译及结果
OpenCV 2.4.x 版本的Java封装库编译官方文档在:https://docs.opencv.org/2.4/doc/tutorials/introduction/desktop_java/java_dev_intro.html 。
编译过程也比较简单不再赘述,这里直接提供编译好的Jar包和动态库。 注意编译机器上的Java版本都是Java8,编出来的Jar包低版本的Java可能不能使用(没有测试过)。
Linux版本
如果应用要部署到服务器上,那当然只能用Linux版本的动态库和Jar包了。Jar包可以通过该url获取(尽量保证长期有效):http://cdn.spirithy.com/code/opencv2413-java/linux/opencv-2413.jar。
so动态链接库可以通过该url获取(尽量保证长期有效,方便直接用Docker的ADD指令):http://cdn.spirithy.com/code/opencv2413-java/linux/libopencv_java2413.so。
MacOS
Mac下是使用的XCode自带的CLang来编译的,Jar包可以通过该url获取(尽量保证长期有效):http://cdn.spirithy.com/code/opencv2413-java/macos/opencv-2413.jar。 但请注意,经测试MacOS下直接用Linux的Jar包也是完全OK的、证明两个平台下的Jar包其实是没有区别的,所以直接用opencv-java-x86_64-linux的Jar包更方便。
dylib动态链接库可以通过该url获取(尽量保证长期有效):http://cdn.spirithy.com/code/opencv2413-java/macos/libopencv_java2413.dylib 。
使用
上面编译出来的动态链接库中已经包含了OpenCV的所有函数,所以Java应用在使用时只需要依赖这一个动态链接库、及Java封装库即可,非常的方便。
在项目中引入jar包
直接引入上述的Maven依赖即可,MacOS、Linux下都可以用opencv-java-x86_64-linux的Jar包。
依赖动态库
需要在Java参数中指定OpenCV动态库所在的目录的路径,这样才能加载到动态链接库。
本机环境(MacOS)
例如在MacOS下进行开发,在Idea中,“Run”-“Edit Configurations”-“VM options”,加入以下参数即可指定动态库的目录。 1
-Djava.library.path=/Users/xxxx/opencv2413-java/macos
服务器环境
需要将动态库部署到服务器上,或者添加到Docker镜像中,然后需要在启动Java应用时用"-Djava.library.path"指定动态库目录。 具体实现这里也没有实践过需要读者自行尝试。
代码编写
Java使用OpenCV的封装库,和在C/C++中使用OpenCV,在代码上是稍有不同的,但基本可以把代码“平移过来”。 需要额外注意的只有一点:在Java进程中、使用OpenCV之前需要显式地加载动态库。 所以如果是Spring boot应用可以在Application.java的静态代码块中执行加载。示例如下: 1
2
3
4
5
6
7
8
9
10
11public class Application {
//加载OpenCV动态链接库
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args)...
}
}
代码示例
下面提供一个从C++代码人工转换过来的Java使用OpenCV的示例,功能为“从一张白底图片中抠出包含主要内容的最小图片”,也就是“抠图片中的物体”,代码比较简单而且应该还有需要调优的地方。
1 | package com.xxxx; |