热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

SpringBoot使用OpenCV示例总结

前言 最近有个项目需要对图片图像进行处理,使用到了开源框架OpenCV全称是Open Source Computer Vision L

前言

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

下载安装

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

windows平台

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

Linux平台

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

cd /usr/local/opencv-3.4.10
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF ..
make -j8
sudo make install

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

整合使用

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

外部引用方式

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

相对路径方式

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

@Configuration
public class NativeConfig {
 static {
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
 }
}

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

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

绝对路径方式

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

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

踩坑1

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

java.lang.UnsatisfiedLinkError: org.opencv.imgcodecs.Imgcodecs.imread_1(Ljava/lang/String;)J
    at org.opencv.imgcodecs.Imgcodecs.imread_1(Native Method) ~[opencv-3.4.10.jar:unknown]
    at org.opencv.imgcodecs.Imgcodecs.imread(Imgcodecs.java:332) ~[opencv-3.4.10.jar:unknown]
    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并不能去加载成功,对应的是一个类似如下的路径:

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

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

踩坑2

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


 org.apache.maven.plugins
 maven-resources-plugin
 
  UTF-8
       
  dll,so
 


第三方Jar包

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

Files.createTempDirectory(`opencv_openpnp`);

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

总结

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

到此这篇关于SpringBoot使用OpenCV示例总结的文章就介绍到这了,更多相关SpringBoot使用OpenCV内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
author-avatar
DLDLBABY1_182
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有