Face Detection using OpenCV Haarcascades in Android
2015-12-22 18:22
435 查看
Face Detection using OpenCV Haarcascades in Android Posted on 22 March 2014 Under Blog Tagged Android Tweet I was working on this app which required face detection and pose estimation. I was already using Native code for some other processes (edge detection, etc) so I figured I’d use Haarcascades in native code only. It was a bit of hassle to configure how to send xml file to JNI or whether it would load the cascade once I pass the filename to the native code. So I looked around a bit. I tried to look into the examples provided with opencv sdk and found out that I had to write the whole xml file to FileOutputStream so that it could be accessed in the native code. Making XML available to the native code First I stored the XML file in assets/ folder. final InputStream is; FileOutputStream os; try { is = getResources().getAssets().open("face_frontal.xml"); File cascadeDir = getDir("cascade", Context.MODE_PRIVATE); mCascadeFile = new File(cascadeDir, "face_frontal.xml"); FileOutputStream os; os = new FileOutputStream(mCascadeFile); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } is.close(); os.close(); } catch (IOException e) { Log.i(TAG, "face cascade not found"); } Once this is done, you can pass the file and relevant Mat objects to the native code. JNI call faceFound = detectFace(mCascadeFile.getAbsolutePath(), mRgba.getNativeObjAddr(), mretVal.getNativeObjAddr()); // Image is loaded in mRgba // mretVal will contain the output Mat // At the end of the class declaring the native function public native int detectFace(String filename, long matAddrRgba, long matAddrRetVal); Native code I’m not editing the native function name here so you need to change it appropriately. JNIEXPORT jint JNICALL Java_com_fenchtose_cardscanner_ScanActivity_detectFace(JNIEnv* jenv, jobject, jstring jFileName, jlong addrRgba, jlong addrRetVal) { const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL); string stdFileName(jnamestr); Mat& mRgba = *(Mat*)addrRgba; Mat& retValMat = *(Mat*)addrRetVal; Mat gray; vector<Rect> faces; jint retVal; int faceFound=0; mRgba.copyTo(retValMat); cvtColor(mRgba, gray, CV_RGBA2GRAY); CascadeClassifier face_cascade; face_cascade.load(stdFileName); LOGD("cascade loaded\n"); face_cascade.detectMultiScale(gray, faces, 2, 1, CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_SCALE_IMAGE, Size(30, 30), Size(900, 900)); LOGD("detectMultiScale\n"); if (faces.size() > 0) { int index; Rect face; for(index=0; index<faces.size(); index++){ face = faces[index]; rectangle(retValMat, face, Scalar(255, 0, 0), 3); } faceFound = 1; LOGD("face found\n"); } else { LOGD("face not found\n"); faceFound = 0; } retVal = (jint)faceFound; return retVal; } This returns if face is found or not. If face is found it draws on the retvalMat. So this was pretty easy to do and return a good output. P.S. Learning more about Android OpenCV. If you have some feedback or questions regarding this post, please add comments. I'd be happy to get some feedback.
相关文章推荐
- Android关闭键盘时的一个小问题
- Android5.0如何监听USB插拔
- Android自定义view控件
- 读Android学Java基础之动机
- Android设置布局背景为白色的三种方法
- viewpager显示多页,左右翻页显示动画
- Android 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚
- Android中Java反射技术的使用示例
- android 自定义组合控件
- Android_xml背景色的值
- Android 动态控制控件的位置
- android proc 虚拟文件系统
- 异常记录之android.content.res.Resources$NotFoundException: String resource ID
- Android开发_关于点击事件
- Android笔记(13) ---布局优化include、merge、ViewStub的使用
- ListView的item点击事件不响应
- ImageView的android:adjustViewBounds属性
- Android中有趣的Demo
- android 9.png图片详解
- Android Canvas的save(),saveLayer()和restore()浅谈