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左右的樣子,耐心等待。
觀察下載好的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());
}
}
這樣就能正確讀入圖片了。
再來說說第二個坑(千萬注意):
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());
}
}
沒有任何問題,當運行的時候會出現這樣的錯誤:
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)
。然後當你再次運行的時候錯誤變成了這樣:
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上早就告訴了我們正確的使用姿勢:
網上的都是錯的嗎,並不是,針對於早期的版本這個方案確實是可行的,只不過有太多人都是在粘貼複製到自己的文章中來,根本沒有注意 import
中的內容以及JavaCV的版本號。也算給自己提個醒,多看文檔。