(前言,在配置過程中遇到了不少的bug,本文把bug也列出來。)
基於Android的opencv開發有兩種。 第一種用java形式的OpenCV庫, 第二種用C++形式的OpenCV庫, 這兩種庫都在OpenCV官方提供的SDK中。
- 第一種形式, 需要在開發環境中導入 OpenCV 的 jre包, 還需要安裝 Android OpenCV Manager, 有的書上例子也是用這種方式寫的。 Android OpenCV Manager是用來管理OpenCV 庫的, 減少APP內存佔用, 支持特定硬件優化, 定期更新庫等, 具體看它的介紹(http://docs.OpenCV.org/2.4/platforms/android/service/doc/index.html)。
- 第二種形式, 需要使用C++的OpenCV庫, 以jni的形式來調用。底層NDK的方式開發可以使用這種。
目錄
下載opencv
到opencv官網(https://opencv.org/releases/)去下載opencv(https://sourceforge.net/projects/opencvlibrary/files/4.3.0/opencv-4.3.0-android-sdk.zip/download)
這裏直接下載Opencv4.3.0 android版本(https://sourceforge.net/projects/opencvlibrary/files/4.3.0/opencv-4.3.0-android-sdk.zip/download)
下載後解壓可以看到以下幾個文件
- apk:opencv已經編譯好的Android可執行程序,拷貝到手機上即可運行。
- samples:生成這些apk的Android代碼工程。
- sdk:裏面是opencv的Java的接口和JNI接口等
sample:opencv提供的一些簡單例子。
sdk:目錄即是我們開發opencv所需要的類庫;
在Android studio上配置opencv
1.打開Android studio新建一個新的Android空工程。
2.在Android Studio的菜單選擇File-->New-->Import Module。
3.選擇opencv android pack解壓出來的sdk目錄下的java文件夾,點擊下一步,出現三個複選框,都選上,點擊Finish。
等待導入
4.菜單欄選擇File-->Project Structure。
5.按照如下圖步驟操作,選擇Dependencies-->+-->3 Module dependency,點擊ok退出,然後再點擊ok退出。
然而並不能選擇。。。。
改爲3.4.10試試
先配置AS的SDK Tools
我們選擇CMake和NDK
CMake是一個跨平臺的編譯工具,能夠輸出各種各樣的makefile文件,這個在之後OpenCV編譯階段需要用到
NDK是Android平臺下的一個開發工具包,使用NDK可以快速地開發C、C++的以.so爲後綴的動態庫,並自動將.so動態庫與應用打包成.apk文件,這也是後面需要用到的
選擇好後,點擊Apply應用,即可開始下載
全都不行。。。。。(不得不吐槽一下。網上很多教程,特別是CSDN上,博客裏面寫着圖,一張圖都沒有。。。)
理論上已經成功導入了吖~~~~
也確實是成功導入了
打開下面兩個文件(這裏的小綠點表示這是個原始包,還不是Module或者library)
然後再把你解壓出來的Android-OpenCV-SDK的SDK下面的gradle文件拖入AS,現在你的代碼文件應該有三個,如下圖所示:
sdk\下面的gradle就是用來指導我們gradle該怎麼寫的,一定不要改
首先分屏如下
然後將430的第一句
apply plugin: 'com.android.application'
改爲
apply plugin: 'com.android.library'
這就是爲什麼上面一直import不了module。網上的坑爹教程根本不說有這步!!!!!!!!!!!!!!必須要把application改爲library纔可以當作庫來調用。
其次,把**android標籤開始的內容直到最後一行,複製到430的gradle中,把最後的dependencies刪除(這裏是刪除430的gradle裏面的,千萬別去刪app裏面的),把defalutconfig裏面的applicationId一行也刪除(430裏面的,再次強調不是app)**然後你的430的gradle應該長這樣
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
然後把左邊的選項卡切換到sdk下面的gradle標籤,同樣一比一進行對比改,這裏就不能直接複製了,要對比着改,有些東西必須要有,有些東西我也不知道是不是必須的,有些語句我也看不懂,本着寧多勿少的原則,我會把我能跑通的都複製進去並寫在下面的操作中,現在你的頁面應該是這樣:
將下面這段到的430gradle中(defaultconfig 裏面)
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared"
targets "opencv_jni_shared"
}
}
下面這一段也要複製進去
buildTypes {
debug {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
}
release {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
然後這裏的
sourceSets {
main {
jniLibs.srcDirs = ['native/libs']
java.srcDirs = ['java/src']
aidl.srcDirs = ['java/src']
res.srcDirs = ['java/res']
manifest.srcFile 'java/AndroidManifest.xml'
}
}
只要jniLibs,複製到430中,看到這裏應該明白要把native複製進去,所以把sdk下的native文件夾複製到opencv中src目錄下的main文件夾下,這裏 也可以複製到其他位置按需修改(記得把項目切換到project模式)
然後看到最下面的
externalNativeBuild {
cmake {
path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt')
}
}
就知道要把sdk下面的libcxx_helper複製到430文件夾下,複製進去後你的430文件夾應該是這樣:
gradle(430)文件應該是這樣
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared"
targets "opencv_jni_shared"
}
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
}
release {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['native/libs']
}
}
externalNativeBuild {
cmake {
path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt')
}
}
}
然後點擊sync.同步一下。successful以後,切換回android目錄,發現430下面多了三個柱子如下圖:
這個就表示可以進行模塊導入了。此時找到project struture。點擊它依次選選擇Dependencies,app,+,module Dependency
如果你沒有改成 library,也沒有sync,那麼這裏就是nothing to show,而那些坑爹教程教你Import Moudle以後就去添加依賴,最終你只能得到noting to show,ok之後選擇apply,自動在gradle 裏添加implementation project(path: ‘:opencv430’)
改完了430的gradle,再來改app的gradle.首先是在defalultconfig添加CMAKE語句
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
arguments "-DANDROID_STL=c++_shared"
targets "opencv_jni_shared"
}
}
然後在android括號裏添加sourcsets
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
app的gradle最終是這樣的
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.androidopencvtest"
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
arguments "-DANDROID_STL=c++_shared"
targets "opencv_jni_shared"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation project(path: ':opencv430')
}
這是先不要着急點 sync,先把項目切換到 project目錄,在app-src-main把opencv安卓sdk文件下的 sdk\native\libs裏的東西複製進去,可根據需要酌情刪減,複製的時候順道改名爲jniLibs,如下圖:
進行編譯
然後提醒安裝NDK
應該這就是代表配置成功了嗎
demo測試
首先在java文件中導入opencv頭文件
沒有報錯,證明opencv應該是可以用的了
參考資料
https://blog.csdn.net/u011511601/article/details/80538356
https://blog.csdn.net/KayChanGEEK/article/details/86493632
https://www.pianshen.com/article/4713262635/
https://blog.csdn.net/qq_39321542/article/details/106080136(主要參考資料)