具体实现方法如下:
需要的工具:
- NDK
- OpenCV for Android
- OpenCV for Windows(其实只需要两个头文件)
- Android ADT
1.编译nonfree module库
2.配置NDK环境
3.编写makefile文件
- LOCAL_PATH:=
$(call my-dir) - include
$(CLEAR_VARS) - OPENCV_INSTALL_MODULES:=on
- OPENCV_CAMERA_MODULES:=off
- include
..\OpenCV-2.4.5-android-sdk\sdk\native\jni\OpenCV.mk -
- LOCAL_C_INCLUDES:=
../OpenCV-2.4.5-android-sdk/sdk/native/jni/include - LOCAL_MODULE
:= nonfree - LOCAL_CFLAGS
:= -Werror -O3 -ffast-math - LOCAL_LDLIBS
+= -llog - LOCAL_SRC_FILES
:= nonfree_init.cpp \ -
precomp.cpp \ -
sift.cpp \ -
surf.cpp - include
$(BUILD_SHARED_LIBRARY)
在Application.mk中代码如下
- #APP_ABI
:= armeabi - APP_ABI
:= armeabi-v7a - APP_STL
:= gnustl_static - APP_CPPFLAGS
:= -frtti -fexceptions - APP_PLATFORM
:= android-8
4. 在Android中使用SURF的例子
- #include
"NativeSurf.h" - #include
- #include
- #include
- #include
-
- using
namespace cv; - using
namespace std; -
- void
KeyPoint2Mat(vector& keypoints, Mat& mat) - {
-
int i = 0; -
int size = keypoints.size(); -
mat.create(size,1,CV_32FC(7)); -
float* buff = (float*)mat.data; -
for(i=0;i -
{ -
KeyPoint kp = keypoints[i]; -
buff[7*i+0] = kp.pt.x; -
buff[7*i+1] = kp.pt.y; -
buff[7*i+2] = kp.size; -
buff[7*i+3] = kp.angle; -
buff[7*i+4] = kp.response; -
buff[7*i+5] = kp.octave; -
buff[7*i+6] = kp.class_id; -
} - }
-
- JNIEXPORT
void JNICALL Java_com_ruif_nativeSurf_NativeSurf_SurfDetect -
(JNIEnv *, jclass, jlong imgObj, jlong keyPointsObj, jlong descriptorObj) - {
-
//Create Mats -
Mat* img = (Mat*)imgObj; //img -
Mat* descriptor = (Mat*)descriptorObj; //Descriptor -
-
Mat* keyPointsMat = (Mat*)keyPointsObj; -
vector keyPointvec; -
SurfFeatureDetector surfDetector(1000); -
SurfDescriptorExtractor surfExtractor; -
surfDetector.detect(*img,keyPointvec); -
surfExtractor.compute(*img,keyPointvec,*descriptor); -
KeyPoint2Mat(keyPointvec,*keyPointsMat); - }
- LOCAL_PATH
:= $(call my-dir) - include
$(CLEAR_VARS) - LOCAL_MODULE
:= nonfree - LOCAL_SRC_FILES
:= libnonfree.so - include
$(PREBUILT_SHARED_LIBRARY) -
- include
$(CLEAR_VARS) - LOCAL_MODULE
:= opencv_java_prebuilt - LOCAL_SRC_FILES
:= libopencv_java.so - include
$(PREBUILT_SHARED_LIBRARY) -
- include
$(CLEAR_VARS) - include
../OpenCV-2.4.5-android-sdk/sdk/native/jni/OpenCV.mk - LOCAL_MODULE
:= Surf - LOCAL_CFLAGS
:= -Werror -O3 -ffast-math - LOCAL_LDLIBS
+= -llog -ldl - LOCAL_SHARED_LIBRARIES
:= nonfree opencv_java_prebuilt - LOCAL_SRC_FILES
:= Surf.cpp - include
$(BUILD_SHARED_LIBRARY)
编写Application.mk文件如下:
- APP_ABI
:= armeabi-v7a - APP_STL
:= gnustl_static - APP_CPPFLAGS
:= -frtti -fexceptions - APP_PLATFORM
:= android-8
此时你会发现各种语法错误和不能解析的变量。其实他们并不影响编译,所有的头文件在Android.mk和Application.mk中已经声明,编译仍然会成功,但是自己编写程序时为了使用Eclipse的提示功能,需要对工程进行如下设置。
5.使用JNI库
- private
BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { -
@Override -
public void onManagerConnected(int status) { -
switch (status) { -
case LoaderCallbackInterface.SUCCESS: -
{ -
Log.i(Unity.TAG,"OpenCV loaded successfully"); -
System.loadLibrary("nonfree"); -
System.loadLibrary("opencv_java"); -
System.loadLibrary("Surf"); -
isOpenCVLoad = true; -
} break; -
default: -
{ -
Log.i(Unity.TAG,"OpenCV loaded Failed!"); -
super.onManagerConnected(status); -
} break; -
} -
} -
};