SpringBoot使用OpenCV总结

前言

最近有个项目需要对图片图像进行处理,使用到了开源框架OpenCV全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库;而现在的项目都是基于SpringBoot,需要把OpenCv整合进去,下面把在使用中遇到的问题进行一个汇总整理。

下载安装

Opencv官网提供了一个多个平台的版本包括:Windows,IOS,Android,地址如下:https://opencv.org/releases/;因为开发在Windows平台,发布在Linux平台,所以我们这里至少需要两个版本;

windows平台

直接可以在官网下载opencv-3.4.10-vc14_vc15.exe安装即可,安装完会出现opencv文件夹在buildjava目录下有我们需要的opencv-3410.jar,x64/opencv_java3410.dll,x86/opencv_java3410.dll文件;

Linux平台

Linux平台需要我们手动编译,下载opencv-3.4.10.zip,解压到/user/local目录下,然后编译安装,执行如下命令:

1cd /usr/local/opencv-3.4.10 2mkdir build 3cd build 4cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF .. 5make -j8 6sudo make install

安装完之后可以在build/bin目录下找到opencv-3410.jar,在build/lib目录下找到libopencv_java3410.so

整合使用

两个平台分别安装完之后,获取了对应的dll和so文件;两个平台获取到的jar都是一样的,随便用哪个都可以,下面看看如何使用

外部引用方式

通过把应用jar与本地库文件进行分隔开,然后在项目中进行引用

相对路径方式

可以通过System.loadLibrary来指定本地库文件,但是这种方式需要在运行时指定-Djava.library.path,具体可以提供配置类:

1@Configuration 2public class NativeConfig { 3 static { 4 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 5 } 6}

运行时需要在VM arguments中添加-Djava.library.path=对应dll存放的路径,不然会出现如下错误:

1Caused by: java.lang.UnsatisfiedLinkError: no opencv_java3410 in java.library.path 2 at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860) ~[na:1.8.0_251] 3 at java.lang.Runtime.loadLibrary0(Runtime.java:870) ~[na:1.8.0_251] 4 at java.lang.System.loadLibrary(System.java:1122) ~[na:1.8.0_251] 5 at com.springboot.opencv.NativeConfig.<clinit>(NativeConfig.java:10) ~[classes/:na]

绝对路径方式

可以通过System.load来指定本地库函数的绝对路径:

1@Configuration 2public class NativeConfig { 3 static { 4 System.load("C:\\Users\\opencv\\build\\java\\x64\\opencv_java3410.dll"); 5 } 6}

踩坑1

在IDE中运行使用Opencv功能的时候,出现如下错误:

1java.lang.UnsatisfiedLinkError: org.opencv.imgcodecs.Imgcodecs.imread_1(Ljava/lang/String;)J 2 at org.opencv.imgcodecs.Imgcodecs.imread_1(Native Method) ~[opencv-3.4.10.jar:unknown] 3 at org.opencv.imgcodecs.Imgcodecs.imread(Imgcodecs.java:332) ~[opencv-3.4.10.jar:unknown] 4 at com.springboot.opencv.OpenCVController.testOpenCV(OpenCVController.java:13) ~[classes/:na]

很明显是在使用jar包里面的方法时没有找到对应的本地库函数,也就是说loadLibrary没有成功,但是之前其实在本地Java项目中是有进行测试的,可以通过的,猜测是不是使用了什么工具导致加载失败,最终锁定在spring-boot-devtools工具包,提供了动态加载等功能,直接移除此工具包,或者配置如下开关:

System.setProperty("spring.devtools.restart.enabled", "false");

内部引用方式

为了更加简单部署,可以把本地库文件和项目文件打成一个jar包,可以把本地库文件放在resources目录下,这样可以打成一个jar包,现在的主要问题就是如何加载jar包里面的本地库文件,通过测试发现可以读取到resources目录下的库文件,但是通过system.load并不能去加载成功,对应的是一个类似如下的路径:

1file:/C:/Users/Administrator.SKY-20170404CXG/Desktop/springboot-0.0.1-SNAPSHOT.j 2ar!/BOOT-INF/classes!/opencv

最后采用的方式是把读取的库文件,存放到系统的一个临时文件夹下,然后拿到库文件的绝对路径,这样就可以通过system.load直接去加载,具体实现代码可以参考Github

踩坑2

在执行maven编译打包的时候,发现本地库文件(dll或者so文件)体积会变大,猜测maven在编译的时候对本地库文件也进行了编译,具体如何禁用指定的文件格式编译,而只需要拷贝即可:

1<plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-resources-plugin</artifactId> 4 <configuration> 5 <encoding>UTF-8</encoding> 6 <!-- maven编译下面扩展类型文件的时候直接复制原文件,而不会进行二次编码--> 7 <nonFilteredFileExtensions>dll,so</nonFilteredFileExtensions> 8 </configuration> 9</plugin>

第三方Jar包

除了以上两种需要我们自己去实现加载的方式,其实还可以直接使用第三方提供的jar包OpenPnp,里面包含了OpenCV.jar,对应各个平台的本地库,以及加载本地库的封装类;查看其源码可以发现,其实也是通过判断当前系统,然后将对应的本地库文件拷贝到系统的临时文件夹下,最后通过system.load去加载:

Files.createTempDirectory(`opencv_openpnp`);

因为此包兼顾了所有平台,所以整个包有点大,一百多M,如果部署的系统确定,其实可以自己去加载指定库文件就可以了,然后以相同的方式打成一个公共包供各个系统使用;

总结

本文虽然介绍的是在项目中使用OpenCV的一些总结,但其实其他的本地库也可以使用相同的方式;本文重点记录一下在使用过程中遇到的那些坑,以及加载库文件的方式。

代码地址

Github

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Opencv中Mat矩阵相乘——点乘、dot、mul运算详解

Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593