1. 程式人生 > 程式設計 >SpringBoot使用OpenCV示例總結

SpringBoot使用OpenCV示例總結

前言

最近有個專案需要對圖片影象進行處理,使用到了開源框架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.<clinit>(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在編譯的時候對本地庫檔案也進行了編譯,具體如何禁用指定的檔案格式編譯,而只需要拷貝即可:

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-resources-plugin</artifactId>
 <configuration>
  <encoding>UTF-8</encoding>
  <!-- maven編譯下面擴充套件型別檔案的時候直接複製原檔案,而不會進行二次編碼-->     
  <nonFilteredFileExtensions>dll,so</nonFilteredFileExtensions>
 </configuration>
</plugin>

第三方Jar包

除了以上兩種需要我們自己去實現載入的方式,其實還可以直接使用第三方提供的jar包OpenPnp,裡面包含了OpenCV.jar,對應各個平臺的本地庫,以及載入本地庫的封裝類;檢視其原始碼可以發現,其實也是通過判斷當前系統,然後將對應的本地庫檔案拷貝到系統的臨時資料夾下,最後通過system.load去載入:

Files.createTempDirectory(`opencv_openpnp`);

因為此包兼顧了所有平臺,所以整個包有點大,一百多M,如果部署的系統確定,其實可以自己去載入指定庫檔案就可以了,然後以相同的方式打成一個公共包供各個系統使用;

總結

本文雖然介紹的是在專案中使用OpenCV的一些總結,但其實其他的本地庫也可以使用相同的方式;本文重點記錄一下在使用過程中遇到的那些坑,以及載入庫檔案的方式。

到此這篇關於SpringBoot使用OpenCV示例總結的文章就介紹到這了,更多相關SpringBoot使用OpenCV內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!