日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 使用OpenCV的三种方式(Android Studio)

發布時間:2025/7/25 Android 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 使用OpenCV的三种方式(Android Studio) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

from: http://blog.csdn.net/sbsujjbcy/article/details/49520791

其實最早接觸OpenCV是很久很久之前的事了,大概在2013年的5,6月份,當時還是個菜逼(雖然現在也是個菜逼),在那一段時間,學了一段時間的Android(并不算學,一個月都不到),之后再也沒接觸android,而是一直在接觸Java Web。那次接觸OpenCV是因為一個學長的畢業設計,這次接觸OpenCV是因為自己的畢業設計。2013年那年技術太菜,ndk環境都搭不好,當初還是eclipse環境,一直按照網上的教程去搭,下什么cygwin,簡直就是個坑,網上的文章轉來轉去,都是過時的。后來一個機會看到了google官方的一個文檔,就像發現了新大陸一樣,發現ndk環境根本不需要裝cygwin,裝了你就坑了,裝這個東西有好多G呢,時間浪費不說,簡直誤人子弟啊。后來在那年7月寫下一篇博客

NDK開發環境

這段時間在填自己畢業設計的坑,要用到OpenCV,首先得下載到sdk吧,這個從官網上下載就好了
OpenCV for Android

注意下載的是OpenCV for android。當前版本是3.0

解壓后,里面的內容如下

samples目錄下是樣例代碼,sdk目錄下是我們需要用到的Java層和jni層的代碼。apk目錄是manager的apk安裝包

其實OpenCV最簡單的使用方式是使用manager,也就是使用apk目錄下的安裝包,安裝對應的apk,將java層代碼導入,使用OpenCVLoader.initAsync()加載庫,之后你就可以直接用java代碼調用Opencv相關的功能了。

但是這種方式除了安裝我們自己的apk還需要安裝上面提到的manager的apk,用戶體驗十分不好,不推薦使用,本文的三種方式將完全脫離這個manager的apk。

本文下面的三種方式的內容參考自文章 OpenCV4Android釋疑: 透析Android以JNI調OpenCV的三種方式(讓OpenCVManager永不困擾)

本篇文章使用android studio作為開發環境,由于實驗性的構建工具對ndk支持還不好,所以使用舊的構建方式,在原來寫的一篇博客基礎上修改即可android studio下ndk開發

這正式介紹三種方式之前,我們需要做一些前期準備。

首先新建一個項目,將OpenCV中sdk目錄下的native目錄拷到項目根目錄

然后新建Jni目錄

在里面新建兩個文件

編輯gradle.properties文件,增加下面的屬性使用舊版的ndk功能(不添加會使用實驗性的ndk構建工具)

<code class="hljs bash has-numbering">android.useDeprecatedNdk=<span class="hljs-literal">true</span></code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>

在local.properties文件中配置ndk目錄

<code class="hljs tex has-numbering">ndk.dir=D<span class="hljs-command">\:</span><span class="hljs-command">\\</span>AndroidSDK<span class="hljs-command">\\</span>sdk<span class="hljs-command">\\</span>ndk-bundle</code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>

編輯build.gradle,在android節點中增加下面的代碼

<code class="hljs makefile has-numbering"><span class="hljs-constant">APP_STL</span> := gnustl_static <span class="hljs-constant">APP_CPPFLAGS</span> := -frtti -fexceptions <span class="hljs-constant">APP_ABI</span> := armeabi armeabi-v7a <span class="hljs-constant">APP_PLATFORM</span> := android-8 </code>

這時候,使用gradle構建一下,如果能成功構建出so,說明配置沒問題,如下圖,點擊as右側的gradle展開,雙擊ndkBuild進行構建

下面開始講第一種方法,純jni層的代碼,該方法基于上面的所有步驟,為靜態鏈接庫

聲明java層的native方法

<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> OpenCVHelper {<span class="hljs-keyword">static</span> {System.loadLibrary(<span class="hljs-string">"OpenCV"</span>);}<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> native <span class="hljs-keyword">int</span>[] <span class="hljs-title">gray</span>(<span class="hljs-keyword">int</span>[] buf, <span class="hljs-keyword">int</span> w, <span class="hljs-keyword">int</span> h); } </code>

注意上面的OPENCV_LIB_TYPE屬性的改動,從STATIC改為了SHARED,這時候再用ndkBuild一下,你會發現會輸出一些警告以及一部分紅色的內容

生成的so庫的大小為310k,小了好幾倍

這時候如果你直接取運行程序,會報錯誤

原因是我們使用的是動態庫加載方式,還需要將依賴的so加進去,這個so就是圖中的libopencv_java3.so,他在我們的最開始加到項目里的native目錄中

將它拷到我們的jniLibs目錄中去,這里只拷貝armeabi和armeabi-v7a中的,至于其他的按需拷貝

這時候運行就不會報錯了。

既然我們使用了動態鏈接庫,那么我們同樣也可以使用java層的接口,優點是java開發速度相對快一點。第三種方法在第二種方法基礎上,使用純java層代碼進行處理。

在此之前,我們需要將sdk目錄中的java代碼拷到項目中去

但是org.opencv.engine包中是一個aidl,我們需要將它剪貼到aidl目錄中去,就像這樣子

最后還有一個資源文件attrs.xml,拷過來

build一下項目,不出意外應該會報錯,這時候找到該類,引入自己的R文件包就可以了

再次build應該就不會有什么問題了。

java層的測試方法

<code class="hljs avrasm has-numbering">OpenCVLoader<span class="hljs-preprocessor">.initDebug</span>()<span class="hljs-comment">;</span> Mat rgbMat = new Mat()<span class="hljs-comment">;</span> Mat grayMat = new Mat()<span class="hljs-comment">;</span> Bitmap srcBitmap = BitmapFactory<span class="hljs-preprocessor">.decodeResource</span>(getResources(), R<span class="hljs-preprocessor">.drawable</span><span class="hljs-preprocessor">.ic</span>)<span class="hljs-comment">;</span> Bitmap grayBitmap = Bitmap<span class="hljs-preprocessor">.createBitmap</span>(srcBitmap<span class="hljs-preprocessor">.getWidth</span>(), srcBitmap<span class="hljs-preprocessor">.getHeight</span>(), Bitmap<span class="hljs-preprocessor">.Config</span><span class="hljs-preprocessor">.RGB</span>_565)<span class="hljs-comment">;</span> Utils<span class="hljs-preprocessor">.bitmapToMat</span>(srcBitmap, rgbMat)<span class="hljs-comment">;//convert original bitmap to Mat, R G B.</span> Imgproc<span class="hljs-preprocessor">.cvtColor</span>(rgbMat, grayMat, Imgproc<span class="hljs-preprocessor">.COLOR</span>_RGB2GRAY)<span class="hljs-comment">;//rgbMat to gray grayMat</span> Utils<span class="hljs-preprocessor">.matToBitmap</span>(grayMat, grayBitmap)<span class="hljs-comment">; //convert mat to bitmap</span> img<span class="hljs-preprocessor">.setImageBitmap</span>(grayBitmap)<span class="hljs-comment">;</span></code>

注意使用OpenCVLoader.initDebug();進行初始化而不是使用OpenCVLoader.initAsync()

這種方法的特點是處理都在java層,不怎么會涉及jni層的代碼,除非java層完成不了的工作會轉移到jni層去。

三種方法各有各的優點,根據自己的情況進行選擇。

  • 如果c++特別好的,建議使用第一種方法
  • 如果更習慣java代碼的,并且java層的函數都能進行處理的,建議選擇第三種方法
  • 第二種方法建議在第三種方法不滿足條件的情況下進行輔助使用,因為使用了第三種方法的前提是使用第二種方法的動態鏈接庫。

最后附上源碼

  • http://download.csdn.net/detail/sbsujjbcy/9275897

總結

以上是生活随笔為你收集整理的Android 使用OpenCV的三种方式(Android Studio)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。