一: 开发Android上的OpenCV程序概述
为Android开发OpenCV程序, 有两种方式, 第一种用java形式的OpenCV库, 第二种用C++形式的OpenCV库, 这两种库都在OpenCV官方提供的SDK中。 我们可以从官网下载 http://opencv.org/releases.html。
第一种形式呢, 需要在开发环境中导入 OpenCV 的 jre包, 还需要安装 Android OpenCV Manager, 有的书上例子也是用这种方式写的。 这里要特别说一下 Android OpenCV Manager的作用, 它是用来管理OpenCV 库的, 减少APP内存占用, 支持特定硬件优化, 定期更新库等, 具体看它的介绍(http://docs.opencv.org/2.4/platforms/android/service/doc/index.html)。
第二种形式呢, 需要使用C++的OpenCV库, 以jni的形式来调用。 从C/C++转过来的应该比较喜欢用这种形式吧。
二: 需要准备的工具
1: 需要Android开发环境, 推荐 adt-bundle。
2: 下载 OpenCV Android SDK
3: 如果使用java形式的OpenCV库, 只需从SDK中把库导入到开发环境中。
4:如果使用 c++形式的OpenCV库, 得要要Android.mk 中 指定SDK 中的OpenCV.mk, 并且在开发环境中应用SDK中的 库头文件。
三: 下面以jni形式举一个实例:
1: 首先java创建 一个 native, 显示一副图片。
2: 其次c++ 调用OpenCV函数,让这幅图片灰度化, 并通过jni形式由在native回调显示。
java部分:
package com.example.hellojni;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.widget.TextView;
import android.widget.ImageView;
import android.os.Bundle;
public class HelloJni extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* Create a TextView and set its content.
* the text is retrieved by calling a native
* function.
*/
TextView tv = new TextView(this);
tv.setText( stringFromJNI() );
setContentView(tv);
ImageView iv = new ImageView(this);
Bitmap imgSrc = ((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();
iv.setImageBitmap(imgSrc);
setContentView(iv);
long current = System.currentTimeMillis();
Bitmap img1 = ((BitmapDrawable) getResources().getDrawable(
R.drawable.lena)).getBitmap();
int w = img1.getWidth(), h = img1.getHeight();
int[] pix = new int[w * h];
img1.getPixels(pix, 0, w, 0, 0, w, h);
int[] resultInt = grayImage(pix, w, h);
Bitmap resultImg = Bitmap.createBitmap(w, h, Config.RGB_565);
resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
long performance = System.currentTimeMillis() - current;
iv.setImageBitmap(resultImg);
HelloJni.this.setTitle("NDK consumed: "
+ String.valueOf(performance) + " ms");
}
/* A native method that is implemented by the
* 'hello-jni' native library, which is packaged
* with this application.
*/
public native String stringFromJNI();
public native int[] grayImage(int[] buf, int w, int h);
/* This is another native method declaration that is *not*
* implemented by 'hello-jni'. This is simply to show that
* you can declare as many native methods in your Java code
* as you want, their implementation is searched in the
* currently loaded native libraries only the first time
* you call them.
*
* Trying to call this function will result in a
* java.lang.UnsatisfiedLinkError exception !
*/
public native String unimplementedStringFromJNI();
/* this is used to load the 'hello-jni' library on application
* startup. The library has already been unpacked into
* /data/data/com.example.hellojni/lib/libhello-jni.so at
* installation time by the package manager.
*/
static {
System.loadLibrary("hello-jni");
}
}
C++ 部分:
#include <string.h>
#include <jni.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "com_example_hellojni_HelloJni.h"
extern "C"
{
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI
(JNIEnv *env, jobject thiz)
{
return env->NewStringUTF("Hello OpenCV ! Current Version " CV_VERSION ".");
}
JNIEXPORT jintArray JNICALL Java_com_example_hellojni_HelloJni_grayImage
(JNIEnv *env, jobject obj, jintArray buf, jint w, jint h)
{
jint *cbuf;
cbuf = env->GetIntArrayElements(buf, 0);
if (cbuf == NULL) {
return 0;
}
Mat img(h, w, CV_8UC4, (unsigned char*) cbuf);
Mat gray(h, w, CV_8UC1);
cvtColor(img, gray, CV_RGBA2GRAY);
IplImage pGrayImage = IplImage(gray);
int* outImage = new int[w * h];
for (int i = 0; i < w * h; i++) {
outImage[i] = (int) pGrayImage.imageData[i];
}
int size = w * h;
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result, 0, size, outImage);
env->ReleaseIntArrayElements(buf, cbuf, 0);
return result;
}
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE := STATIC
include ${OPENCV_SDK}/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.cpp
include $(BUILD_SHARED_LIBRARY)
结果: