opencv官網上關於Android的大多是在eclipse下運行的,網上關於在Android studio中運行的博客都比較少,大多數是灰度化等比較簡單的例子,如何在android studio 中運行成功人臉識別的例子?過程如下:
1.在官網上下載opencv的SDK,把opencv的SDK下的native 文件夾都拷到項目文件夾下
2. 新建一個jni目錄,在main包下
3. 在jni目錄下,新建兩個文件,分別爲Android.mk和Application.mk,如圖
4. 在gradle.properties文件裏面添加這樣一句話
android.useDeprecatedNdk=true
5. 配置好ndk目錄,在Android studio中使用NDK不用在系統中配置環境變量
如果不清楚怎麼配置NDK,可以在網上隨便找找,網上這方面資料挺多
6. 在app的build.gradle中,在Android節點下添加下面這段話
sourceSets.main.jni.srcDirs = []
//禁止自帶的ndk功能
sourceSets.main.jniLibs.srcDirs = ['src/main/libs','src/main/jniLibs']
//重定向so目錄爲src/main/libs和src/main/jniLibs,原來爲src/main/jniLibs
task ndkBuild(type: Exec, description: 'Compile JNI source with NDK') {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkDir = properties.getProperty('ndk.dir')
if (org.apache.tools.ant.taskdefs.condition.Os.isFamily(org.apache.tools.ant.taskdefs.condition.Os.FAMILY_WINDOWS)) {
commandLine "$ndkDir/ndk-build.cmd", '-C', }
else {
commandLine "$ndkDir/ndk-build", '-C', file('src/main/jni').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task ndkClean(type: Exec, description: 'Clean NDK Binaries') {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkDir = properties.getProperty('ndk.dir')
if (org.apache.tools.ant.taskdefs.condition.Os.isFamily(org.apache.tools.ant.taskdefs.condition.Os.FAMILY_WINDOWS)) {
commandLine "$ndkDir/ndk-build.cmd",'clean', '-C', file('src/main/jni').absolutePath
} else {
commandLine "$ndkDir/ndk-build",'clean', '-C', file('src/main/jni').absolutePath
}
}
clean.dependsOn 'ndkClean'
7.在Application.mk和Android.mk中分別添加下面內容,注意不要講兩個填反了
在Application.mk中:
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8
在Android.mk中:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := off
OPENCV_LIB_TYPE :=STATIC
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include ..\..\..\..\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := detection_based_tracker
LOCAL_SRC_FILES :=com_example_facetest_DetectionBasedTracker.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)
8.Ndk build一下,展開右方gradle,找到ndkbuild,雙擊,如圖所示:
成功後,會如圖顯示:
能成功build出so說明沒有問題,並且如下圖所示會多兩個文件夾:
10.把opencv下org文件夾拷到項目main/java目錄下,Value下的attr.xml也拷進來res/value下
11.build一下
這時可能會報這個錯誤
解決辦法:
在main下新建一個aidl文件夾
把org.opencv.engine拷入這個文件夾下
如果報錯說aidl.exe錯誤,把這個包名改一下,注意光標處
12.Rebuild一下,沒有報其他錯誤,這時可以把opencv sample中人臉識別的例子拷進來包括Java代碼,佈局文件,raw文件夾
再次rebuild
13.在terminal下cd到這個文件夾下
運行命令 Javah 包名+DetectionBasedTracker
此時生成了一個.h頭文件,把它拷到jni目錄下
14.(1)新建一個和頭文件同樣文件名的cpp文件
(2)把原示例項目face-detection中jni目錄下cpp文件的內容拷入你的cpp文件中 (3)注意紅色箭頭的地方將.h文件include進去
15.下面用Java開頭的方法即是Java代碼可能調用的方法,這個地方的方法名需要修改爲頭文件中對應的方法名,因爲從樣本中拷入的代碼的包名是樣本的包名,應該是你自己的包名,這些包名在頭文件中已經聲明瞭,所以只需要一一複製過來
16.在Android.mk裏面把這個cpp加進去
LOCAL_SRC_FILES :=com_example_facetest_DetectionBasedTracker.cpp
改一下生成的so文件的名字
17.此時,可以ndkbuild一下,生成出來的so文件如果只有幾k,說明C++文件沒有編進去
18.新建一個文件夾,命名爲jniLibs將native/libs下的armeabi和armeabi-v7a拷過來,如圖
如果此時報錯
是因爲這個terminal下正在佔用,cd出去就行了
19.把這幾句畫複製到你的項目中
然後應該就可以了