本人菜鸟一枚,对Android开发更是知之甚少。
但是,最近由于项目需要,研究了一下Andorid平台下调用OpenCV的方法,现将其总结如下。
1.开发环境。
- 操作系统:Mac OS Yosemite
- 开发工具:Eclipse
2.准备工作。
- 下载并安装Android NDK,假设其路径为NDK_PATH。
- 下载并安装Android SDK。
- Eclipse的Android开发环境及NDK环境已经配置OK,具体怎么配置的,记不清了。回头想起来再补吧。
3.下载OpenCV Android SDK,下载好后,将其解压出来,为了后面便于使用,将其解压后的文件夹重命名为OpenCV-android-sdk。
https://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.9/OpenCV-2.4.9-android-sdk.zip/download
5.点击OpenCVTest,右键->Android Tools->Add Native Support.在弹出的对话框中名称默认为OpenCVTest,点击Finish,之后,会看到OpenCVTest目录下多了一个jni文件夹,展开会发现多了两个文件OpenCVTest.cpp和Android.mk.如下图所示:
6.右键点击jni->New->File,创建一个Application.mk文件。然后在将之前下载好的OpenCV-android-sdk拷贝到jni目录下,右键OpenCVTest->Refresh,结果如下图所示:
7.引入头文件,右键OpenCVTest->Properties->C/C++ General->Paths and Symbols,在弹出的页面中点Add,分别将以下头文件引入:
- jni.h,路径为$(NDK_PATH)/platforms/android-14/arch-arm/usr/include.
- 如果有报错,提示找不到OpenCV的头文件,则需要再引入OpenCV-android-sdk的头文件,路径为OpenCVTest/jni/OpenCV-android-sdk/sdk/native/jni/include.
8.头文件引入OK后,下面开始写测试代码。打开OpenCVTest.cpp,敲入以下代码:
#include <jni.h>
#include <android/log.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/stitching/stitcher.hpp>
#define LOGD(Key,...) __android_log_print(ANDROID_LOG_DEBUG, Key, __VA_ARGS__)
extern "C"
{
jint Java_com_yourname_opencvtest_MainActivity_CreateStitcher(JNIEnv *env);
}
using namespace cv;
jint Java_com_yourname_opencvtest_MainActivity_CreateStitcher(JNIEnv *env)
{
cv::Stitcher stitcher = Stitcher::createDefault();
if(&stitcher==NULL)
{
LOGD("CreateStitcher","Stitcher created failed!\n");
return -1;
}
else
{
LOGD("CreateStitcher","Stitcher created successfully!\n");
return 0;
}
}
这里大概介绍一下,该代码定义了一个方法
jint Java_com_yourname_opencvtest_MainActivity_CreateStitcher(JNIEnv *env);
该方法的作用是,初始化一个OpenCV中的Stitcher类,初始化成功返回0,失败返回-1;
到此,测试代码就写完了。下面开始写NDK 的Make file.
9.分别将如下代码copy到Android.mk和Application.mk中:
Android.mk
LOCAL_PATH := $(call my-dir)
OPENCV_A_SDK_JNI_PATH := $(LOCAL_PATH)/OpenCV-android-sdk/sdk/native/jni
include $(call all-subdir-makefiles)
include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
include $(OPENCV_A_SDK_JNI_PATH)/OpenCV.mk
LOCAL_ARM_NEON := true
include $(CLEAR_VARS)
LOCAL_LDLIBS += -ldl -llog
LOCAL_C_INCLUDES := $(OPENCV_A_SDK_JNI_PATH)/include/
LOCAL_SHARED_LIBRARIES := opencv_java
LOCAL_MODULE := OpenCVTest
LOCAL_SRC_FILES := OpenCVTest.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-14
到此,Make file文件就OK了,下来开始在Java层写调用的代码。
10.打开MainActivity.java,将如下代码copy进去:
package com.yourname.opencvtest;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
CreateStitcher(); //1
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
static //2
{
System.loadLibrary("opencv_java");
System.loadLibrary("OpenCVTest");
}
public native int CreateStitcher(); //3
}
下面就修改部分简单做一下介绍:
- 调用CreateSticher.
- 告诉Java加载"opencv_java"和"OpenCVTest"库。这两个库,在NDK编译时会自动生成。
- 声明CreateStitcher为native的方法。
11.到此就大功告成,保存->Build->Run之后,应该会在LogCat中看到相应的打印,如下图所示: