JAVA应用JNI调用OpenCV实现人脸检测
1.JAVA的JNI部分
调用JNI的基类
package lveyo.bcndyl.jni.opencv; public class JNIBase { public JNIBase(){} public JNIBase(String libraryName){ loadLibrary(libraryName); } private static void loadLibrary(String libraryName){ System.loadLibrary(libraryName); } }
实现这个基类
package lveyo.bcndyl.jni.opencv; public class JNIOpencv extends JNIBase{ public JNIOpencv (String libraryName){ super(libraryName); } public JNIOpencv(){ System.loadLibrary("jniOpenCV"); } public native int[] detectFace(int minFaceWidth, int minFaceHeight, String cascade, String filename); }
类中定义了一个detectFace方法,是要用C来实现的。
编译好这个类后,要用在命令行用javah命令生成需要的.h的头文件:
引用
javahlveyo.bcndyl.jni.opencv.JNIOpencv
会生成一个名为lveyo_bcndyl_jni_opencv_JNIOpencv.h的头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class lveyo_bcndyl_jni_opencv_JNIOpencv */ #ifndef _Included_lveyo_bcndyl_jni_opencv_JNIOpencv #define _Included_lveyo_bcndyl_jni_opencv_JNIOpencv #ifdef __cplusplus extern "C" { #endif /* * Class: lveyo_bcndyl_jni_opencv_JNIOpencv * Method: detectFace * Signature: (IILjava/lang/String;Ljava/lang/String;)[I */ JNIEXPORT jintArray JNICALL Java_lveyo_bcndyl_jni_opencv_JNIOpencv_detectFace (JNIEnv *, jobject, jint, jint, jstring, jstring); #ifdef __cplusplus } #endif #endif
2.C程序部分
按照http://www.opencv.org.cn/index.php/Template:Install安装OpenCV并配置相应的开发环境,我这里用的是VS2005,同时要将JDK中的include目录和include/win32目录都加入到VS2005的IncludeFiles中。
新建一个win32MFCDLL项目jniOpenCV,把刚才生成的lveyo_bcndyl_jni_opencv_JNIOpencv.h头文件加入到项目,并且修改jniOpenCV.cpp文件:
#include "stdafx.h" #include <jni.h> #include "lveyo_bcndyl_jni_opencv_JNIOpencv.h" #include "cv.h" #include "highgui.h" JNIEXPORT jintArray JNICALL Java_lveyo_bcndyl_jni_opencv_JNIOpencv_detectFace (JNIEnv *env, jobject obj, jint width, jint height, jstring cascade, jstring filename) { const char *str_cascade, *str_filename; str_cascade = env->GetStringUTFChars(cascade, false); str_filename = env->GetStringUTFChars(filename, false); jintArray faceArray; CvHaarClassifierCascade *cv_cascade = (CvHaarClassifierCascade*)cvLoad( str_cascade ); IplImage *image = cvLoadImage( str_filename, 1 ); if(image!=0){ CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* faces; //double t = (double)cvGetTickCount(); /* use the fastest variant */ faces = cvHaarDetectObjects( image, cv_cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(width, height) ); //t = (double)cvGetTickCount() - t; //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) ); const int total = faces->total; faceArray = env-> NewIntArray(4*total); jint faceBuf[4]; for( int i = 0; i < total; i++ ) { CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i ); int pointX = face_rect.x; int pointY = face_rect.y; int faceWidth = face_rect.width; int faceHeight = face_rect.height; //printf("i %d, x %d, y %d, width %d, height %d\n", // i,pointX,pointY,faceWidth,faceHeight); faceBuf[0] = pointX; faceBuf[1] = pointY; faceBuf[2] = faceWidth; faceBuf[3] = faceHeight; env->SetIntArrayRegion(faceArray,i*4,4,faceBuf); } cvReleaseMemStorage( &storage ); cvReleaseImage( &image ); } cvReleaseHaarClassifierCascade( &cv_cascade ); env->ReleaseStringUTFChars(cascade, str_cascade); env->ReleaseStringUTFChars(filename, str_filename); return faceArray; }
编译生成jniOpenCV.dll。此处的检测代码是根据OpenCV的文档和示例程序修改,由于本人对c++程序不是很熟练,所以对此段代码是否会有潜在危险和内存泄露不是很肯定,还请熟悉c使用的朋友帮忙检查一下。
别忘记将生成的jniOpenCV.dll文件复制到%JAVA_HOME%/bin中,如果在没安装OpenCV的机器上运行,还需要将OpenCV安装目录中bin目录下所有dll文件一起复制到%JAVA_HOME%/bin中。
3.实现JAVA的调用
package lveyo.bcndyl.jni.opencv; public class Test { public static void main(String[] args) { //初始化JNI调用类JNIOpencv JNIOpencv open = new JNIOpencv("jniOpenCV"); //要检测的图片文件 String filename = "d:/80010.jpg"; //OpenCv提供的人间的特征文件 String cascade = "d:/haarcascade_frontalface_alt2.xml"; //人脸检测,前两个参数为可检测的最小人脸的宽度和高度 //返回值为人脸在图中的坐标和宽高,{x, y, width, height} int[] faces = open.detectFace(40, 40, cascade, filename); if(faces != null && faces.length!=0){ //返回的人脸总数 System.out.println( "faces " + faces.length/4 ); //分别输出每个人脸的坐标信息 for (int temp : faces) { System.out.println(temp); } } } }
相关推荐
learningCV 2020-11-10
learningCV 2020-08-25
huang00 2020-08-21
wangdaren 2020-08-15
BeanJoy 2020-07-28
csdmeb 2020-06-25
wangdaren 2020-06-14
pythonxuexi 2020-06-13
woniulx0 2020-06-13
greent00 2020-06-10
liangzuojiayi 2020-06-09
greent00 2020-06-09
csdmeb 2020-06-08
BeanJoy 2020-06-06
lihuifei 2020-06-05
wangdaren 2020-06-03
wangdaren 2020-05-31
greent00 2020-05-30