Java调用OpenCV人脸识别

1.JAVA的JNI部分 

调用JNI的基类 

Java代码  

1. package com;  

2. public class JNIBase

3. {

4.     public JNIBase(){}  

5.       

6.     public JNIBase(String libraryName)

7.     { 

8.         loadLibrary(libraryName); 

9.     } 

10.      

11.    private static void loadLibrary(String libraryName)

12.    {  

13.        System.loadLibrary(libraryName);  

14.    }  

15.}  

 

实现这个基类 

Java代码  

1. package com;  

2.   

3. public class JNIOpencv extends JNIBase

4. {  

5.     public JNIOpencv (String libraryName)

6.     {  

7.         super(libraryName);  

8.     }  

9.       

10.    public JNIOpencv()

11.    {  

12.        System.loadLibrary("jniOpenCV");  

13.    }  

14.  

15.    public native int[] detectFace(int minFaceWidth, int minFaceHeight,  

16.                                   String cascade, String filename);   

17.}  

 

类中定义了一个detectFace方法,是要用C来实现的。 

编译好这个类后,要用在命令行用javah命令生成需要的.h的头文件: 

D:\Develop\Workspace\MyEclipse Professional2014\OpenCVTest\src>javah -jni com.JNIOpencv

其中:

工程路径:D:\Develop\Workspace\MyEclipseProfessional 2014\OpenCVTest\src>

命令:javah

生成文件类型:-jni

类名:com.JNIOpencv

 

会生成一个名为com_JNIOpencv.h的头文件: 

C代码  

1. /* DO NOT EDIT THIS FILE - it is machine generated */  

2. #include <jni.h>  

3. /* Header for class com_JNIOpencv */  

4.   

5. #ifndef _Included_lveyo_bcndyl_jni_opencv_JNIOpencv  

6. #define _Included_lveyo_bcndyl_jni_opencv_JNIOpencv  

7. #ifdef __cplusplus  

8. extern "C" {  

9. #endif  

10./* 

11. * Class:     com_JNIOpencv 

12. * Method:    detectFace 

13. * Signature: (IILjava/lang/String;Ljava/lang/String;)[I 

14. */  

15.JNIEXPORT jintArray JNICALL Java_com_JNIOpencv_detectFace  

16.  (JNIEnv *, jobject, jint, jint, jstring, jstring);  

17.  

18.#ifdef __cplusplus  

19.}  

20.#endif  

21.#endif  

 

2.C程序部分 
在VS2013中配置opencv,同时要将JDK中的include目录和include/win32目录都加入到VS2013的Include Files中。 

VS中在项目上右键打开属性 -> C/C++ -> 常规-> 附加包含目录: 添加jni对应的头文件



新建一个win32 MFC DLL项目jniOpenCV,把刚才生成的com_JNIOpencv.h头文件加入到项目,并且修改jniOpenCV.cpp文件:

C++代码  

1. #include "stdafx.h"  

2. #include <jni.h>  

3. #include "com_JNIOpencv.h"  

4. #include "opencv/cv.h"  

5. #include "opencv/highgui.h"  

6.   

7. JNIEXPORTjintArrayJNICALL Java_com_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 = NULL;  

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.        const int total = faces->total;  

31.  

32.        faceArray = env-> NewIntArray(4*total);  

33.        jint faceBuf[4];  

34.          

35.        forint i = 0; i < total; i++ )  

36.        {  

37.            CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i );  

38.            int pointX = face_rect.x;  

39.            int pointY = face_rect.y;  

40.            int faceWidth = face_rect.width;  

41.            int faceHeight = face_rect.height;  

42.  

43.            //printf("i %d, x %d, y %d, width %d, height %d\n",  

44.                        //        i,pointX,pointY,faceWidth,faceHeight);  

45.  

46.            faceBuf[0] = pointX;  

47.            faceBuf[1] = pointY;  

48.            faceBuf[2] = faceWidth;  

49.            faceBuf[3] = faceHeight;  

50.  

51.            env->SetIntArrayRegion(faceArray,i*4,4,faceBuf);  

52.              

53.        }  

54.          

55.        cvReleaseMemStorage( &storage );  

56.        cvReleaseImage( &image );  

57.    }  

58.    cvReleaseHaarClassifierCascade( &cv_cascade );    

59.  

60.    env->ReleaseStringUTFChars(cascade, str_cascade);  

61.    env->ReleaseStringUTFChars(filename, str_filename);  

62.    return faceArray;  

63.}  

 

编译生成jniOpenCV.dll。此处的检测代码是根据OpenCV的文档和示例程序修改。将生成的jniOpenCV.dll文件复制到%JAVA_HOME%/bin中,如果在没安装OpenCV的机器上运行,还需要将OpenCV安装目录中bin目录下所有dll文件一起复制到%JAVA_HOME%/bin中。

 

3.实现JAVA的调用

其中haarcascade_frontalface_alt2.xml文件在安装的opencv\sources\data\ haarcascades中,将其复制到代码中指定的文件夹中。图片也复制到相应文件夹中。

Java代码  

1. package com;  

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 = "res/image/1.jpg";  

12.  

13.        //OpenCv提供的人间的特征文件  

14.        String cascade = "res/haarcascade_frontalface_alt2.xml"

15.  

16.        //人脸检测,前两个参数为可检测的最小人脸的宽度和高度  

17.        //返回值为人脸在图中的坐标和宽高,{x, y, width, height}  

18.        int[] faces = open.detectFace(4040, 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.             {  

27.                System.out.println(temp);  

28.            }  

29.        }  

30.    }  

31.}  

 

配置JRE环境:

1.      工程名右键 -> Build Path -> Configure Build Path -> Libraries 调整JRE SystemLibrary 为32位的可用Library。

2.      工程名右键 -> Run As -> Run Configurations -> Libraries -> JRE调整Runtime JRE与步骤1中一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值