Android Studio中集成OpenCV
Posted 粪乧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Studio中集成OpenCV相关的知识,希望对你有一定的参考价值。
Demo 下载地址 :https://github.com/hongyang51/OpenCV
近来公司需求需要对图片进行处理,简单的对OpenCV4android进行集成.首先参考前人经验分为三种方式调用 其中开发方式需要使用到 ndk开发 . 我首先记录一下ndk 环境的配置过程.
Mac下配置Android Studio(AS)NDK环境
- 首先打开
将Android NDK 勾选上 之后 点击Apply 点OK 之后AS会自动下载 (有的时候google会突破墙 ,有时候就不可以了 发帖时可以直接下载) 如果打开这个页面的时候卡死 那就 赶紧挂上梯子再弄吧….. - 下载完成之后创建个项目查看local.properties文件中是否配置ndk目录 一般都是有配置的.
- 打开项目gradle.properties文件, 添加
android.useDeprecatedNdk=true
至此NDK环境已经配置完成.
Mac下Android Studio生成jni调用h文件
- 点击Terminal打开 将终端目录调整到项目的java目录下 例如我的示例目录
需要输入cd app/src/main/java
- 这个时候需要创建一个java文件 进行jni调用 如例子
/**
* Created by xyb on 16/2/26 at UHylab
*
* @version 1.0
*/
public class OpenCVHelper
static
System.loadLibrary("opencv_java3");
System.loadLibrary("OpenCV");
public static native int[] gray(int[] buf, int w, int h);
现在我推荐Clean Project下 之后再 Make Project (哎!挺纠结的一个过程)
- 在Terminal 中输入
javah -jni com.uhylab.opencv.OpenCVHelper
- 查看java目录下生成的.h文件 在main目录下生成jni文件夹将文件放在该目录下
- 之后就可以开始写牛逼闪闪的C++ 代码了.. 这段俺不会 继续学吧…..
此时就要在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', file('src/main/jni').absolutePath
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'
Mac下配置Android Studio(AS)OpenCV环境
首先使用OpenCV需要去下载库文件 OpenCV4Android
将下载的文件解压后 在sdk目录下有个native文件夹 将该文件夹复制到工程的根目录下.如图
在jni文件夹下面创建
Android.mk 与 Application.mk 文件
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 := OpenCV
LOCAL_SRC_FILES := com_uhylab_opencv_OpenCVHelper.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)
Application.mk 内容为
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-15
再创建C++代码文件
我的为com_uhylab_opencv_OpenCVHelper.cpp
//
// Created by xyb on 16/2/26.
//
#include "com_uhylab_opencv_OpenCVHelper.h"
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
using namespace cv;
extern "C"
JNIEXPORT jintArray JNICALL Java_com_uhylab_opencv_OpenCVHelper_gray(
JNIEnv *env, jclass obj, jintArray buf, int w, int h);
JNIEXPORT jintArray JNICALL Java_com_uhylab_opencv_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;
ndkBuild创建so文件
此时 在Activity中调用方式测试成功.
MainActivity.java
package com.uhylab.opencv;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity
private ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = (ImageView) findViewById(R.id.img);
Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(
R.mipmap.ic_launcher)).getBitmap();
int w = bitmap.getWidth(), h = bitmap.getHeight();
int[] pix = new int[w * h];
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
int [] resultPixes=OpenCVHelper.gray(pix,w,h);
Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.RGB_565);
result.setPixels(resultPixes, 0, w, 0, 0,w, h);
img.setImageBitmap(result);
再次 感谢yanzi
http://blog.csdn.net/yanzi1225627/article/details/27863615;
安卓弟 http://blog.csdn.net/sbsujjbcy/article/details/49520791 还有各位大神.!
菜鸟敬上!有错误恳请提醒修正 谢谢!
Demo 下载地址 :https://github.com/hongyang51/OpenCV
以上是关于Android Studio中集成OpenCV的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio 中集成Opencv环境(包含opencv_contrib部分)
如何在 Android App 中集成 OpenCV Manager
为啥使用 Android Studio 在我的应用中集成 AdMob 不起作用?