使用JNI技术实现Java调用dll_java调用dll进行人脸识别(JNI的使用) | 学步园

1.JNI部分

调用JNI基类(JNIBase.java)

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);

}

}

实现基类(JNIOpencv.java)

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);

}

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(添加以下目录)

C:/jdk1.6/INCLUDE //根据具体jdk安装目录确定

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

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

#include

#ifndef _Included_lveyo_bcndyl_jni_opencv_JNIOpencv

#define _Included_lveyo_bcndyl_jni_opencv_JNIOpencv

#ifdef __cplusplus

extern "C" {

#endif

JNIEXPORT jintArray JNICALL Java_lveyo_bcndyl_jni_opencv_JNIOpencv_detectFace

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

#ifdef __cplusplus

}

#endif

#endif

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

//#include "stdafx.h"

#include

#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;

}

然后进行编译、组建

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盘放入人物图片

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);

}

}

}

}

运行程序

0_1289824829As7a.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值