在OpenCV for Android 2.4.5中使用SURF(nonfree module)
http://blog.csdn.net/ruifdu/article/details/9120559
在OpenCV4Android中没有nonfree module,因此也就没有了SURF和SIFT组件。但是我们可以通过OpenCV for Windows的nonfree module开源代码通过NDK将其编译为Android可以使用的.so库文件,然后通过JNI技术,将该.so文件挂载到JNI的库中。
具体实现方法如下:
需要的工具:
- NDK
- OpenCV for Android
- OpenCV for Windows(其实只需要两个头文件)
- Android ADT
电脑操作系统为Windows7 x86,Android开发环境为ADT 20130512。下面说明如何在OpenCV中使用nonfree module:
1.编译nonfree module库
博主OpenCV for Windows安装路径为C:\Program Files\opencv,OpenCV4Android路径为 E:\My Documents\Android\OpenCV-2.4.5-android-sdk。
nonfree module 的源代码存储在C:\Program Files\opencv\modules\nonfree\src中,头文件存储在C:\Program Files\opencv\modules\nonfree\include\opencv2\nonfree中。
编译的过程中需要两个头文件,一个为nonfree.hpp,一个为features2d.hpp,将这两个头文件拷贝至OpenCV4Android SDK的include文件夹下:E:\My Documents\Android\OpenCV-2.4.5-android-sdk\sdk\native\jni\include\opencv2\nonfree文件夹下。
为了编译库文件,我们还需要nonfree module的源代码。源代码为C:\Program Files\opencv\modules\nonfree\src中的nonfree_init.cpp,precomp.cpp,sift.cpp,surf.cpp和precomp.hpp五个文件。为了简单起见,我们需要一个简单的Android JNI的工程来帮我们编译这些源代码。
2.配置NDK环境
在Android中创建JNI工程的方法是在一个已经创建好的Android工程上点击右键,new->Ohter->Convert to a C/C++ Project(Adds C/C++ Nature),并在Android工程目录中创建jni文件夹,将上述5个源代码文件拷贝至jni文件夹中。并在jni文件夹中创建Android.mk和Application.mk文件。此时文件组织如下:
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
这里可能有问题,APP_PLATFORM按照Andoird工程建立时最小SDK填写,否则编译不过。
4. 在Android中使用SURF的例子
- #include "NativeSurf.h"
- #include <opencv2/opencv.hpp>
- #include <stdio.h>
- #include <opencv2/nonfree/features2d.hpp>
- #include <opencv2/nonfree/nonfree.hpp>
- using namespace cv;
- using namespace std;
- void KeyPoint2Mat(vector<KeyPoint>& 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<size;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<KeyPoint> keyPointvec;
- SurfFeatureDetector surfDetector(1000);
- SurfDescriptorExtractor surfExtractor;
- surfDetector.detect(*img,keyPointvec);
- surfExtractor.compute(*img,keyPointvec,*descriptor);
- KeyPoint2Mat(keyPointvec,*keyPointsMat);
- }
编写Android.mk文件如下:
- 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的提示功能,需要对工程进行如下设置。
你会发现所有都正常了,此时工程结构组织如下:
在libs下的libSurf.so库就是我们需要使用的JNI库。
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;
- }
- }
- };
一定要顺序加载,否则会报错。至此就能够在JAVA中使用Native函数了。
在OpenCV for Android 2.4.5中使用SURF(nonfree module)的更多相关文章
- Android studio 一个项目中添加两个module遇到的bug
1.在一个Android studio中,我添加了一个模块,然后就是各种bug 找到到R 是在module 名上面 右键 Make Module '模块名' 经过各种google 的时候发现了 htt ...
- !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
http://hujiaweibujidao.github.io/blog/2013/11/18/android-ndk-and-opencv-development-3/ Android Ndk a ...
- NDk编译opencv for Android,并引用在Unity3d游戏中的一般步骤
本文使用:Unity3d + opencv + Android Unity3d中可以调用opencv 编译好的.so 动态库,在生成Android apk时可以正常运行. 因为Android系统是 ...
- OpenCV在Android平台上的应用
今年8月份, OpenCV 2.3.1发布了. 虽然从2.2开始, OpenCV就号称支持Android平台, 但真正能让OpenCV在Android上运行起来还是在2.3.1版本上. 在这个版本上, ...
- opencv for android sample导入有误
我们下载好opencv for android 后导入eclipse的时候发现人脸检测还有一个sample项目会有小叉,但是好像没有文件有问题.这时我们该怎么办呢? 在window中: 我们右键选择p ...
- 【OpenCV for Android】Android Studio JNI和NDK配置及采坑记录
在配置好Android studio的OpenCV环境后,我们就可以通过Java代码调用OpenCV的API了,但是在通常情况下,用Java代码编写图像处理算法的运行效率是没有C++代码高的,在应用层 ...
- 编译并使用带有OpenCL模块的OpenCV for android SDK
OpenCV Android SDK中提供的静态.动态库是不支持OpenCL加速的,如果在程序中调用OpenCL相关函数,编译时不会报错,但运行时logcat会输出如下信息,提示OpenCL函数不可用 ...
- 交叉编译OpenCV的Android版本
交叉编译OpenCV的Android版本 OpenCV作为一个强大的图像处理库,在Android上也有强大的应用. OpenCV官网提供了SDK的下载,可以直接下载使用 OpenCV官网地址:http ...
- OpenCV 4 Android
OpenCV4Android Want a Quick Start link? Use this tutorial: “OpenCV for Android SDK”. 想要快速开始吗?使用这个教程: ...
随机推荐
- 九度OJ 1094:String Matching(字符串匹配) (计数)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1259 解决:686 题目描述: Finding all occurrences of a pattern in a text is a p ...
- db的操作
'/---------------------------------------------------------------------------------------------- '/ ...
- Linux系统上安装字体
最近项目中需要控制字体类型,然后就上网查了一下在linux系统上安装字体,在window上和linux上,字体要求一样,都是ttf格式,下面这是window上的字体截图 在linux系统中的/usr/ ...
- flex平分测试
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Gym - 101147E E. Jumping —— bfs
题目链接:http://codeforces.com/gym/101147/problem/E 题意:当人在第i个商店时,他可以向左或向右跳di段距离到达另一个商店(在范围之内),一个商店为一段距离. ...
- ios 使用json
1.从https://github.com/stig/json-framework/中下载json框架:json-framework 2.解压下载的包,将class文件夹下的所有文件导入到当前工程下. ...
- bootstrap 学习笔记(2)---- 排版
安装和栅格系统学完,这篇写的是排版手册中排版的目录如下图 <标题,页面主题,内联文本元素,对齐,改变大小写,缩略语,地址,引用,列表>手册中介绍那么多,其实并不是所有的都要去看看.很多都是 ...
- [POI 2000] 病毒
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2938 [算法] 首先建出给定字符串集的AC自动机 存在无限长的代码当且仅当 : AC ...
- AutoIt: 如何使用 AutoIt 解析,修改XML 文件
项目组这次要发布一个项目,需要实施人员根据现场的机器情况,修改项目配置文件的几个节点,为了减轻实施人员的工作负担,我应用AutoIt写了一个小界面,实施人员只需在该界面上点几个按钮,就能够完成文件的配 ...
- windows下多进程加协程并发模式
好久没更新博客了.正好最近要整理一下最近这段时间做过的项目以及学习python的一些心得.如标题所示,今天就来说说windows下多进程加协程并发模式.其实网上还是蛮多在linux下的多进程加协程并发 ...