Android Studio 2.2 NDK开发 opencv 人脸识别
2016-11-17 15:13
525 查看
一、开发环境准备
1、Android Studio到 2.2版本,在sdk Manager中下载 ndk-bundle 和 cmake
2、下载OpenCV for Android 下载地址:http://opencv.org/downloads.html
二、搭建环境
1、使用Android Studio 新建一个项目(在c++ suport 上打上对勾)
2、带项目创建好之后,将opencv中的头文件,和动态链接库copy到项目中,并在CMakeLists.txt中引入他们。
最后我们的目录大致如下:
三、编码
1、新建jni类
对应的cpp文件
四、遇到的坑
1、在编写项目时,我发现ndk-bundle更新了,于是我点了一下更新,满怀激动的心情等到下载完(更新到了ndk 13),但在我编译的时候蛋疼的事情发生了,编译不通过了,搞得我很焦灼。最后静下心来看log 其中报错的信息中有这么一段话:
What!!! 真是蛋疼~ ,说明:升级有风险,更新需谨慎啊!,但最后终于找到了一个方法来fix它,打开android_sdk/cmke/3.6.xxxxx/android.toolchain.cake文件,找到报错的那一行:
错误正式从这里出来的。
最后们只需要吧ANDROID_NDK_REVISION 改成13就行了,也就是位于android.toolchain.cmake的 第43行左右 改为 set(ANDROID_NDK_REVISION 13) 好了。
2、在 build.gradle 要引入opencv的动态库文件目录
其中 opencv/prebuilt为opencv动态库的目录
3、设置 abi类型
这里只能设置一种ABI类型,设置2个以上就会报错,目前我也不知道什么情况~,有知道的朋友留言哈~
旨在体验Android 2.2 使用NDK开发,代码中若是有不严谨的地方,还望大神勿喷
最后完整项目的地址: https://github.com/blueberryCoder/FaceRecognition
1、Android Studio到 2.2版本,在sdk Manager中下载 ndk-bundle 和 cmake
2、下载OpenCV for Android 下载地址:http://opencv.org/downloads.html
二、搭建环境
1、使用Android Studio 新建一个项目(在c++ suport 上打上对勾)
2、带项目创建好之后,将opencv中的头文件,和动态链接库copy到项目中,并在CMakeLists.txt中引入他们。
最后我们的目录大致如下:
三、编码
1、新建jni类
package com.blueberry.facerec; /** * Created by blueberry on 11/16/2016. * <p> * 人脸检测 */ public class FaceDetector { static { System.loadLibrary("face_detect"); } private long cPtr; public FaceDetector(String path) { cPtr = init(path); } /** * 初始化CascadeClassifier,需要传入xml文件的路径,CascadeClassifier会根据这个xml文件进行识别。 * * @param path xml文件的路径 * @return CascadeClassifier的路径 */ public final native long init(String path); /** * 人脸检测 * * @param path 人脸图片文件的路径 * @return 检测到人脸数据的集合 */ public final native Face[] detect(String path); /** * 删除CascadeClassifier * * @param cPtr CascadeClassifier的指针 */ private final native void delete(long cPtr); @Override protected void finalize() throws Throwable { delete(cPtr); } }
package com.blueberry.facerec; /** * Created by blueberry on 11/17/2016. * <p> * 检测到人脸的坐标 */ public class Face { private int x; private int y; private int width; private int height; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } @Override public String toString() { return "Face{" + "x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + '}'; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } }
对应的cpp文件
// // Created by Administrator on 11/16/2016. // #ifndef FACERECOGNITION_FACE_DETECT_CPP #define FACERECOGNITION_FACE_DETECT_CPP #include "face_detect.h" using namespace cv; using namespace std; CascadeClassifier *g_CascadeClassifier; JNIEXPORT jlong JNICALL Java_com_blueberry_facerec_FaceDetector_init(JNIEnv *env, jobject instance, jstring path_) { const char *path = env->GetStringUTFChars(path_, NULL); g_CascadeClassifier = new CascadeClassifier(path); long ptr = reinterpret_cast<long>(g_CascadeClassifier); env->ReleaseStringUTFChars(path_, path); LOGD("cascadeClassifier initialized"); return ptr; } JNIEXPORT jobjectArray JNICALL Java_com_blueberry_facerec_FaceDetector_detect(JNIEnv *env, jobject instance, jstring path_) { if (!g_CascadeClassifier) { jclass je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, "CascadeClassifier not initialized!"); } // 图片的路径 const char *path = env->GetStringUTFChars(path_, 0); //单通道模式,读取图片 Mat srcImage = imread(path, IMREAD_GRAYSCALE); //直方图均值化 equalizeHist(srcImage, srcImage); vector<Rect> vectors; g_CascadeClassifier->detectMultiScale(srcImage, vectors); LOGD("detected."); jclass objectClass = env->FindClass("com/blueberry/facerec/Face"); // 返回的人脸数组 jobjectArray result = env->NewObjectArray(vectors.size(), objectClass, NULL); jmethodID cId = env->GetMethodID(objectClass, "<init>", "()V"); jfieldID xId = env->GetFieldID(objectClass, "x", "I"); jfieldID yId = env->GetFieldID(objectClass, "y", "I"); jfieldID widthId = env->GetFieldID(objectClass, "width", "I"); jfieldID heightId = env->GetFieldID(objectClass, "height", "I"); for (int i = 0; i < vectors.size(); i++) { jobject obj = env->NewObject(objectClass, cId); env->SetIntField(obj, xId, vectors[i].x); env->SetIntField(obj, yId, vectors[i].y); env->SetIntField(obj, widthId, vectors[i].width); env->SetIntField(obj, heightId, vectors[i].height); env->SetObjectArrayElement(result, i, obj); } env->ReleaseStringUTFChars(path_, path); return result; } JNIEXPORT void JNICALL Java_com_blueberry_facerec_FaceDetector_delete(JNIEnv *env, jobject instance, jlong cptr) { cv::CascadeClassifier *cascadeClassifier = reinterpret_cast<cv::CascadeClassifier *>(cptr); delete cascadeClassifier; return; } #endif //FACERECOGNITION_FACE_DETECT_CPP
四、遇到的坑
1、在编写项目时,我发现ndk-bundle更新了,于是我点了一下更新,满怀激动的心情等到下载完(更新到了ndk 13),但在我编译的时候蛋疼的事情发生了,编译不通过了,搞得我很焦灼。最后静下心来看log 其中报错的信息中有这么一段话:
..... Invalid Android NDK revision (should be 12):
What!!! 真是蛋疼~ ,说明:升级有风险,更新需谨慎啊!,但最后终于找到了一个方法来fix它,打开android_sdk/cmke/3.6.xxxxx/android.toolchain.cake文件,找到报错的那一行:
if(NOT ANDROID_NDK_PACKAGE_REVISION MATCHES "^${ANDROID_NDK_REVISION}\\.") message(FATAL_ERROR "Invalid Android NDK revision (should be ${ANDROID_NDK_REVISION}): ${ANDROID_NDK_PACKAGE_REVISION}.") endif()
错误正式从这里出来的。
最后们只需要吧ANDROID_NDK_REVISION 改成13就行了,也就是位于android.toolchain.cmake的 第43行左右 改为 set(ANDROID_NDK_REVISION 13) 好了。
2、在 build.gradle 要引入opencv的动态库文件目录
sourceSets { main { java.srcDirs 'src/main/java' jniLibs.srcDirs 'opencv/prebuilt', 'lib' }}
其中 opencv/prebuilt为opencv动态库的目录
3、设置 abi类型
ndk { //打包进APK的ABI类型 abiFilters 'x86' }
这里只能设置一种ABI类型,设置2个以上就会报错,目前我也不知道什么情况~,有知道的朋友留言哈~
旨在体验Android 2.2 使用NDK开发,代码中若是有不严谨的地方,还望大神勿喷
最后完整项目的地址: https://github.com/blueberryCoder/FaceRecognition
相关文章推荐
- Android Studio 2.2 中利用CAMKE进行OpenCV的NDK开发
- 使用OpenCV开发人脸识别及相关注意事项
- Android Studio 2.2 NDK开发环境搭建
- Android Studio 2.2 之 NDK开发
- android studio 2.2 ndk jni 开发 调试 hello world
- Android Studio2.2 CMAKE高效NDK开发
- 人脸识别系统开发(8) -- OpenCV人脸检测
- android studio导入opencv人脸识别案例的一些报错
- android studio 2.2中进行ndk(c/c++)开发
- C++开发人脸性别识别教程(3)——OpenCv配置和ImageWatch插件介绍
- NDK开发 从入门到放弃(七:Android Studio 2.2 CMAKE 高效NDK开发)
- 【Android】Android Studio 2上利用NDK进行OpenCV 3.1开发(注意点)
- Android Studio 2.3利用CMAKE进行OpenCV 3.2的NDK开发
- HMM人脸识别用OpenCV2.2
- android studio2.2初探ndk jni开发
- Face++人脸识别 android studio开发集成
- 在Android studio 2.2中配置NDK和开发
- 人脸识别系统开发(8) -- OpenCV人脸检测
- Android Studio 2.2 NDK 开发 之 cMake 方式