OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)

OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)

http://blog.csdn.net/yanzi1225627/article/details/27863615

前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平。但不断有人反应依然配不好OpenCV4Android,不能得心应手的在Android上使用OpenCV,大量的精力都浪费在摸索配置上。尤其是OpenCVManager诞生之后,更让人无语,大家第一个反应就是如何才能不安装OpenCVManager,因为要多安装这个东西对客户来说体验太不好了。咱家昨夜研究至两点,今早七点起床,终于把头绪理清了。下面咱家以之前做过的一个基于OpenCV2.3.1,android通过jni调用opencv实现人脸检测的实例来逐个回答,如何在Android上使用Java接口而不安装OpenCVManager,及通过jni方式使用OpenCV的三种方式。

先来看JNI调OpenCV的三种方式。很多人会吃惊肿么JNI调OpenCV还会有3种方式,长久以来大量网上教程都说在Android上只有Java和JNI两种方式使用OpenCV,怎么又冒出来3种使用JNI的方式。经本人研究,确实有3种调JNI的方式,就连官网指导文档都模棱两可,所以让很多人不知所措。这三种方式分别是:

1、使用静态的OpenCV库的方式;

2、使用动态的OpenCV库的方式;

3、同时使用Java的API又使用JNI的接口的方式,此时编译时一般使用的是动态链接OpenCV库的方式。

要说明的是,这三种方式均无需安装OpenCVManager,区别在于mk文件的不同。个人最推崇的就是第一种方式,第一种方式也是和OpenCV2.3.1在JNI调OpenCV使用完全吻合的一种方式。本文是以windows平台最新的OpenCV-2.4.9-android-sdk为基础,使用2.4.9的OpenCV4Android需要使用NDK版本为r9,本人使用的是android-ndk-r9d的版本。之所以昨晚捣腾到2点,就是因为之前使用的ndk r7的版本,怎么编都编不过,因少东西报上千行错误。android-ndk-r9d安装十分简单,只需要解压缩配置一个环境变量即可。

一、Android以JNI调OpenCV的第一种配置方法:

Application.mk文件里的内容如下:

APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions 
APP_ABI:= armeabi-v7a 

这三种方式的Application.mk都一样,所以往后不说了。在Application.mk里还可以配置APP_PLATFORM=17类似这种,当然不配置完全可以。

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 D:\ProgramFile\OpenCV-2.4.9-android-sdk\sdk\native\jni\OpenCV.mk
else  
include $(OPENCV_MK_PATH)  
endif 


LOCAL_MODULE    := ProcessImg 
LOCAL_SRC_FILES := DetectFace_JNI.cpp \
src/copyToAssets.cpp \
src/detectFace.cpp
LOCAL_LDLIBS    += -lm -llog 

include $(BUILD_SHARED_LIBRARY) 

逐一解释下,OpenCV_INSTALL_MODULES:=on的意思是自动将依赖的OpenCV的so库拷贝到libs目录下,但很遗憾的是,这个命令只对OPENCV_CAMERA_MODULES有效。只有当OPENCV_CAMERA_MODULES:=on时,可以看到他会自动将里面的带camera的so拷贝至工程下的libs文件夹下。include D:\ProgramFile\OpenCV-2.4.9-android-sdk\sdk\native\jni\OpenCV.mk这句话比较关键,这是我安装OpenCV-2.4.9-android-sdk的地方,我将其安装到了D盘。而我的工作空间在E盘也是ok的。而不用像OpenCV2.3.1使用时,限制这个解压缩包的位置了。LOCAL_MODULE    是要生成的库的名字,LOCAL_SRC_FILES 是jni文件夹下的cpp文件,其中的src说明我的jni下还有个子文件夹名字是“src”,这块替换成自己的源码文件就ok了。

为了测试的严谨性,在工程里将libs文件夹的东西,和obj文件夹下的东西全删了。用cygwin进到工程,输入ndk-build,看到如下信息:

[plain]  view plain   copy
  print ? 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-family: 'Comic Sans MS';"><span style="font-size:18px;">Administrator@yanzi /cygdrive/e/WorkSpaces/OpenCV4Android/FaceDetectLiu2  
  2. $ ndk-build  
  3. Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 16 in ./AndroidManifest.xml  
  4. [armeabi-v7a] Cygwin         : Generating dependency file converter script  
  5. [armeabi-v7a] Compile++ thumb: ProcessImg <= DetectFace_JNI.cpp  
  6. jni/DetectFace_JNI.cpp: In function '_jstring* Java_org_yan_processlib_LibProcessImg_processIplImg(JNIEnv*, jobject, jintArray, int, int)':  
  7. jni/DetectFace_JNI.cpp:99:44: warning: converting 'false' to pointer type for argument 2 of 'jint* _JNIEnv::GetIntArrayElements(jintArray, jboolean*)' [-Wconversion-null]  
  8. jni/DetectFace_JNI.cpp: In function '_jstring* Java_org_yan_processlib_LibProcessImg_processStaticImg(JNIEnv*, jobject, jintArray, int, int)':  
  9. jni/DetectFace_JNI.cpp:133:44: warning: converting 'false' to pointer type for argument 2 of 'jint* _JNIEnv::GetIntArrayElements(jintArray, jboolean*)' [-Wconversion-null]  
  10. [armeabi-v7a] Compile++ thumb: ProcessImg <= copyToAssets.cpp  
  11. [armeabi-v7a] Compile++ thumb: ProcessImg <= detectFace.cpp  
  12. [armeabi-v7a] SharedLibrary  : libProcessImg.so  
  13. [armeabi-v7a] Install        : libProcessImg.so => libs/armeabi-v7a/libProcessImg.so  
  14. </span></span>  
上面两个警告么有关系,编译成功。生成的libProcessImg.so的大小为4M,整个apk大小为1.99M。

注意,如果将mk里的LOCAL_LDLIBS    += -lm -llog这一句错误的写为:LOCAL_LDLIBS    := -lm -llog,即将“+=”错写成了“:=”将会看到如下大量错误:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值