在Android Studio环境下进行OpenCV开发

来源:互联网 发布:免备案php空间 编辑:程序博客网 时间:2024/06/05 21:09

最近想尝试下OpenCV,但是又不想抛弃外表很美的Android Studio,因此作者简单研究了下怎么在Android Studio下进行OpenCV开发。


一、搭建环境,获取OpenCV SDK

首先我们需要下载安装好Android开发环境包括JDK、SDK、NDK、Android Studio,这里使用AS版本为Ver2.1.2

其次我们需要在OpenCV官网上下载OpenCV For Android ,下载完解压后的文件目录如下:



二、拷贝native文件夹

接下来我们在AS中新建工程OpenCV,将OpenCV For Android中sdk下native文件夹完全复制到项目目录下,效果如下图所示:



三、配置Tools

我们需要配置三个额外的工具,javah、ndk-build 、ndk-build clean。javah用于通过java 类直接生成对应jni的.h文件,ndk-build用于编译C、C++文件,ndk-build clean用于清除生成的obj和lib文件。下面以配置javah为例

打开AS->Preferences->Tools->External Tools->下方加号



命名和描述为javah,分组为NDK,Program为javah(此处为我们在命令行输入的命令),参数为 -d ../jni $FileClass$,工作目录为 $ModuleFileDir$/src/main/java。其中这些带有$符号的部分都可以在旁边的插入宏按钮中找到。



下图为ndk-build、ndk-build clean的配置详情,这里需要注意一点,在配置这两个工具时,Program要在后面的 ... 中选一下执行命令的文件,这样我们就省的配置环境变量了





四、APP目录结构和编码

一个编译过而且运行成功项目的app/src/main文件夹结构应该有如下文件夹,截图一并放上:

java 原本就有

jni  我们自己创建,用于保存C、C++代码、mk文件等

jniLibs  我们自己创建,用于存放一些别人编译好的so文件,这里只放了libopencv_java3.so

libs ndk-build生成

obj ndk-build生成



如果我们在新建的工程下是以怎么样的流程操作呢?

1.我们编写Java文件设计好native方法,我将native方法都放在了OpenCVHelper中,其中写了灰度化处理和腐蚀处理的两个测试方法:

public class OpenCVHelper {    static {        System.loadLibrary("OpenCV");    }    public static native int[] gray(int[] buf, int w, int h);    public static native int[] erode(int[] buf, int w, int h);}


2.在这个类上点击右键,选择NDK,选择javah,可以看到jni文件夹下生成了对应的h文件



3.编写对应cpp文件,这里不赘述代码作用,都是最简单的OpenCV图像处理

#include "yu_myself_opencv_jni_OpenCVHelper.h"#include <stdio.h>#include <stdlib.h>#include "opencv2/opencv.hpp"using namespace cv;extern "C" {JNIEXPORT jintArray JNICALL Java_yu_myself_opencv_jni_OpenCVHelper_gray(        JNIEnv *env, jclass obj, jintArray buf, int w, int h) {    jint *cbuf;    cbuf = env->GetIntArrayElements(buf, JNI_FALSE);    if (cbuf == NULL) {        return 0;    }    Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);    uchar* ptr = imgData.ptr(0);    for(int i = 0; i < w*h; i ++){        //计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B        //对于一个int四字节,其彩色值存储方式为:BGRA        int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);        ptr[4*i+1] = grayScale;        ptr[4*i+2] = grayScale;        ptr[4*i+0] = grayScale;    }    int size = w * h;    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, cbuf);    env->ReleaseIntArrayElements(buf, cbuf, 0);    return result;}JNIEXPORT jintArray JNICALL Java_yu_myself_opencv_jni_OpenCVHelper_erode(        JNIEnv *env, jclass obj, jintArray buf, int w, int h){    jint *cbuf;    cbuf = env->GetIntArrayElements(buf, JNI_FALSE);    if (cbuf == NULL) {        return 0;    }    Mat srcImage(h, w, CV_8UC4, (unsigned char *) cbuf);    //腐蚀算法    Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));    Mat dstImage;    erode(srcImage, dstImage, element);    jint* ptr = (jint*)dstImage.ptr(0);    int size = w * h;    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, ptr);    env->ReleaseIntArrayElements(buf, cbuf, 0);    return result;}}


4.编写Application.mk,APP_ABI为生成这些平台的so文件,通过测试发现x86的so要比arm的大很多

APP_STL := gnustl_staticAPP_CPPFLAGS := -frtti -fexceptionsAPP_ABI := armeabi armeabi-v7a x86APP_PLATFORM := android-8

5.编写Android.mk,其中include使用了相对路径

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)OpenCV_INSTALL_MODULES := onOpenCV_CAMERA_MODULES := onOPENCV_LIB_TYPE :=SHAREDifeq ("$(wildcard $(OPENCV_MK_PATH))","")include ../../../../native/jni/OpenCV.mkelseinclude $(OPENCV_MK_PATH)endifLOCAL_MODULE := OpenCVLOCAL_SRC_FILES := yu_myself_opencv_jni_OpenCVHelper.cppLOCAL_LDLIBS +=  -lm -lloginclude $(BUILD_SHARED_LIBRARY)

6.修改build.gradle文件

apply plugin: 'com.android.application'android {    compileSdkVersion 24    buildToolsVersion "24.0.0"    defaultConfig {        applicationId "yu.myself.opencv"        minSdkVersion 15        targetSdkVersion 24        versionCode 1        versionName "1.0"    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }    //这里是我们添加的jni文件夹配置    sourceSets {        main {            jni.srcDirs = []            jniLibs.srcDirs = ['src/main/libs', 'src/main/jniLibs']        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:24.0.0'}

五、测试效果

我们在cpp文件或者h文件上右键,NDK,ndk-build,如果正常的话会出现libs和obj文件夹,然后我们运行APP,程序编译没有问题,但是在运行的时候会报错,说缺少libopencv_java3.so文件。这个东西在我们拷贝过来的native/libs文件夹下,只拷贝对应的so放到jniLibs的对应平台文件夹下即可。下面放个效果图:












0 0
原创粉丝点击