java调用dll进行人脸识别(JNI的使用)

来源:互联网 发布:淘宝数据魔方下线 编辑:程序博客网 时间:2024/05/22 05:29

http://blog.csdn.net/jiben071/article/details/6011019

1.JNI部分

调用JNI基类(JNIBase.java)

 

[c-sharp] view plaincopy
  1. package lveyo.bcndyl.jni.opencv;     
  2. public class JNIBase {     
  3.          
  4.     public JNIBase(){}     
  5.          
  6.     public JNIBase(String libraryName){     
  7.         loadLibrary(libraryName);     
  8.     }     
  9.          
  10.     private static void loadLibrary(String libraryName){     
  11.         System.loadLibrary(libraryName);     
  12.     }     
  13.     
  14. }    

实现基类(JNIOpencv.java)

[c-sharp] view plaincopy
  1. package lveyo.bcndyl.jni.opencv;     
  2.     
  3. public class JNIOpencv extends JNIBase{     
  4.          
  5.     public JNIOpencv (String libraryName){     
  6.         super(libraryName);     
  7.     }     
  8.          
  9.     public JNIOpencv(){     
  10.         System.loadLibrary("jniOpenCV");     
  11.     }     
  12.     
  13.     public native int[] detectFace(int minFaceWidth, int minFaceHeight,     
  14.                                    String cascade, String filename);     
  15.     
  16. }  

 

2.编译文件

运行——>cmd——>进入java源文件夹

javac -d . JNIBase.java

javac -d . JNIOpencv.java

javah lveyo.bcndyl.jni.opencv.JNIOpencv //生成lveyo_bcndyl_jni_opencv_JNIOpencv.h头文件

 

二、visual C++6.0

3.建立工程(选择win32 Dynamic-Link Library)

tools---->Options---->Drectories(添加以下目录)

[java] view plaincopy
  1. C:/jdk1.6/INCLUDE        //根据具体jdk安装目录确定  
  2. C:/jdk1.6/INCLUDE/WIN32  

4.点击工程右键(先确定自己已经安装和配置好OpenCV,可以到OpenCV中文官网参考visualC++6.0配置安装opencv步骤)

选择“设置”,下拉选择“所有配置”,在右方区域点击连接,在对象/库模块下添加

cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib

5.新建头文件veyo_bcndyl_jni_opencv_JNIOpencv.h

添加在编译时生成的头文件代码:

[c-sharp] view plaincopy
  1. #include <jni.h>  
  2.  
  3. #ifndef _Included_lveyo_bcndyl_jni_opencv_JNIOpencv  
  4. #define _Included_lveyo_bcndyl_jni_opencv_JNIOpencv  
  5. #ifdef __cplusplus  
  6. extern "C" {  
  7. #endif  
  8. JNIEXPORT jintArray JNICALL Java_lveyo_bcndyl_jni_opencv_JNIOpencv_detectFace  
  9.   (JNIEnv *, jobject, jint, jint, jstring, jstring);  
  10.  
  11. #ifdef __cplusplus  
  12. }  
  13. #endif  
  14. #endif  

6.新建jniOpenCV.cpp程序文件(检测主程序)

[cpp] view plaincopy
  1. //#include "stdafx.h"     
  2. #include <jni.h>     
  3. #include "lveyo_bcndyl_jni_opencv_JNIOpencv.h"     
  4. #include "cv.h"     
  5. #include "highgui.h"     
  6.     
  7. JNIEXPORT jintArray JNICALL Java_lveyo_bcndyl_jni_opencv_JNIOpencv_detectFace     
  8.   (JNIEnv *env, jobject obj, jint width, jint height, jstring cascade, jstring filename)     
  9. {     
  10.     const char *str_cascade, *str_filename;     
  11.     str_cascade = env->GetStringUTFChars(cascade, false);     
  12.     str_filename = env->GetStringUTFChars(filename, false);     
  13.     
  14.     jintArray faceArray;     
  15.     CvHaarClassifierCascade *cv_cascade = (CvHaarClassifierCascade*)cvLoad( str_cascade );     
  16.     IplImage *image = cvLoadImage( str_filename, 1 );     
  17.          
  18.     if(image!=0){     
  19.     
  20.         CvMemStorage* storage = cvCreateMemStorage(0);     
  21.         CvSeq* faces;     
  22.     
  23.         //double t = (double)cvGetTickCount();     
  24.         /* use the fastest variant */    
  25.         faces = cvHaarDetectObjects( image, cv_cascade, storage, 1.2, 2,     
  26.                                    CV_HAAR_DO_CANNY_PRUNING, cvSize(width, height) );     
  27.         //t = (double)cvGetTickCount() - t;     
  28.         //printf( "detection time = %gms/n", t/((double)cvGetTickFrequency()*1000.) );     
  29.              
  30.     
  31.         const int total = faces->total;     
  32.     
  33.         faceArray = env-> NewIntArray(4*total);     
  34.         jint faceBuf[4];     
  35.              
  36.         forint i = 0; i < total; i++ )     
  37.         {     
  38.             CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i );     
  39.             int pointX = face_rect.x;     
  40.             int pointY = face_rect.y;     
  41.             int faceWidth = face_rect.width;     
  42.             int faceHeight = face_rect.height;     
  43.     
  44.             //printf("i %d, x %d, y %d, width %d, height %d/n",     
  45.                         //        i,pointX,pointY,faceWidth,faceHeight);     
  46.     
  47.     
  48.             faceBuf[0] = pointX;     
  49.             faceBuf[1] = pointY;     
  50.             faceBuf[2] = faceWidth;     
  51.             faceBuf[3] = faceHeight;     
  52.     
  53.     
  54.             env->SetIntArrayRegion(faceArray,i*4,4,faceBuf);     
  55.                  
  56.         }     
  57.              
  58.         cvReleaseMemStorage( &storage );     
  59.         cvReleaseImage( &image );     
  60.     }     
  61.     cvReleaseHaarClassifierCascade( &cv_cascade );     
  62.          
  63.     
  64.     env->ReleaseStringUTFChars(cascade, str_cascade);     
  65.     env->ReleaseStringUTFChars(filename, str_filename);     
  66.     return faceArray;     
  67. }    

然后进行编译、组建

7.进入c++源文件夹把DEBUG里生成的jniOpenCV.dll拖入D:/mylib里(具体原因参考我的另一篇文章《java调用dll(JNI的使用)》)同时把Opencv的C:/Program Files/OpenCV/bin目录下的所有dll文件拖入D:/mylib中(java程序调用需要)

 

8.D:/mylib中需要拖入haarcascade_frontalface_alt2.xml文件(OpenCV提供的人脸特征文件)

 

 

三、回到java部分

9.新建Test.java(进行程序测试)

注意先在D盘放入人物图片

[c-sharp] view plaincopy
  1. package lveyo.bcndyl.jni.opencv;     
  2.     
  3. public class Test {     
  4.     
  5.     public static void main(String[] args) {     
  6.              
  7.         //初始化JNI调用类JNIOpencv     
  8.         JNIOpencv open = new JNIOpencv("jniOpenCV");     
  9.     
  10.         //要检测的图片文件     
  11.         String filename = "d:/80010.jpg";     
  12.     
  13.         //OpenCv提供的人间的特征文件     
  14.         String cascade = "d:/haarcascade_frontalface_alt2.xml";     
  15.     
  16.         //人脸检测,前两个参数为可检测的最小人脸的宽度和高度     
  17.         //返回值为人脸在图中的坐标和宽高,{x, y, width, height}     
  18.         int[] faces = open.detectFace(40, 40, cascade, filename);     
  19.         if(faces != null && faces.length!=0){     
  20.     
  21.             //返回的人脸总数     
  22.             System.out.println( "faces " + faces.length/4 );     
  23.     
  24.             //分别输出每个人脸的坐标信息     
  25.             for (int temp : faces) {     
  26.                 System.out.println(temp);     
  27.             }     
  28.         }     
  29.     }     
  30. }    

运行程序

0 0
原创粉丝点击