发表于 2016-08-03 | 第1次更新
工程源代码整理中
本文示例OPENCV为3.1.0版本,OpenCV各版本下载地址http://opencv.org/ NDK版本为r10e
前言速记
不用安装manager有三种方法,三种方式的Application.mk内容都一样
三者的Android.mk内容有所不一样,区别如下
1、使用静态的OpenCV库的方式:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OpenCV_INSTALL_MODULES:=on//自动将依赖的OpenCV的so库拷贝到libs目录下
OPENCV_CAMERA_MODULES:=off//on时,会自动将里面的带camera的so拷贝至工程下的libs文件夹下
OPENCV_LIB_TYPE:=STATIC
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include
D:\Android\OpenCV-android-sdk\sdk\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OpenCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=SHARE //注意这里为SHARE,通过动态链接的方式连接OpenCV的so
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include D:\Android\OpenCV-android-sdk\sdk\native\jni\OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)
下面介绍第一种方法,此种方法生成的APK体积较小
配置OpenCV
这一步是必须的,不管想在手机上直接用Java实现,还是通过Jni调用c++实现。
至此OpenCV配置完成。
Java调用Op
编辑gradle.properties文件,增加下面的属性使用旧版的ndk功能(不添加会使用实验性的ndk构建工具)
android.useDeprecatedNdk=true
在Java代码中添加一个静态域
static { |
即可直接调用OpenCV的库函数进行。
配置NDK
NDK全称为Native Development Kit,便于安卓调用底层代码。
主要配置过程如下:
Jni调用OpenCV
在jni文件夹新建Android.mk,添加以下代码:
|
上述的include后接OpenCV目录下的文件。
在jni文件夹新建Application.mk,添加以下代码:
APP\_STL:=gnustl_static
APP\_CPPFLAGS:=-frtti -fexceptions
APP\_ABI:=armeabi armeabi-v7a
在app下的build.gradle下,可以删除上一节中的
ndk{
moduleName “Demo”
},
因为在Android.mk已经定义过了。添加以下代码:
sourceSets.main{
jniLibs.srcDir'src/main/libs' //set .so files directory to libs
jni.srcDirs =[] //disable automatic ndk-build call
}
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
if(Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine'D:\android-ndk-r10e\ndk-build.cmd', '-C',file('src/main').absolutePath//windows系统下的操作
} else {
commandLine'ndk-build', '-C', file('src/main').absolutePath
}//linux,mac系统的操作
}
tasks.withType(JavaCompile) {
compileTask-> compileTask.dependsOn ndkBuild
}
可以直接在cpp文件#include “opencv2/openc.hpp”,如果编译成功会在main文件夹下生成一个obj文件夹,这个文件夹的so文件可以供Java调用。
此,Android Studio下的配置工作基本完成。
详细的源代码见下
jni文件夹下Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=STATIC
ifeq ("$(wildcard$(OPENCV_MK_PATH))","")
includeD:\Android\OpenCV-android-sdk\sdk\native\jni\OpenCV.mk//地址改成自己的
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)
jni文件夹下的Application.mk
APP\_STL:=gnustl_static
APP\_CPPFLAGS:=-frtti -fexceptions
APP\_ABI:= x86 armeabi-v7a
app下的build.gragle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
applicationId "com.study.opencvedge"
minSdkVersion 14
targetSdkVersion 23
versionCode1
versionName"1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
sourceSets.main{
jniLibs.srcDir 'src/main/libs' //set .so files directory to libs
jni.srcDirs= []
}
taskndkBuild(type: Exec) {
commandLine'D:\\Android\\android-ndk-r10e\\ndk-build.cmd', '-C',file('src/main').absolutePath
//windows系统下的操作;将路径替换为自己NDK所在位置;
tasks.withType(JavaCompile) {
compileTask-> compileTask.dependsOn ndkBuild
}
}
}
dependencies {
compilefileTree(include: ['*.jar'], dir: 'libs')
compile'com.android.support:appcompat-v7:22.2.0'
compileproject(':openCVLibrary310')
}
jni下C++源代码
//实现图片的截取
#include
#include
#include
#include
using namespace cv;
IplImage * change4channelTo3InIplImage(IplImage * src);
extern "C" {
JNIEXPORT jintArray JNICALL Java_com_study_opencvedge_MainActivity_ImgFun(
JNIEnv*env, jobject obj, jintArray buf, int w, int h);
JNIEXPORT jintArray JNICALL Java_com_study_opencvedge_MainActivity_ImgFun(
JNIEnv*env, jobject obj, jintArray buf, int w, int h){
jint *cbuf;
cbuf = env->GetIntArrayElements(buf,false);
if(cbuf == NULL)
{
return 0;
}
Mat myimg(h, w, CV_8UC4,(unsigned char*)cbuf);
for(intj=0;j
{
myimg.row(j).setTo(Scalar(0,0,0,0));
}
int size=w * h;
jintArray result= env->NewIntArray(size);
env->SetIntArrayRegion(result, 0, size, cbuf);
env->ReleaseIntArrayElements(buf,cbuf, 0);
return result;
}
}