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的头文件:
引用
javah lveyo.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的Include Files中。
新建一个win32 MFC DLL项目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);
}
}
}
}
分享到:
相关推荐
摘要:针对解决OpenCV人脸检测模块在Android平台编译和移植的问题,提出一种利用JNI技术(JavaNativeInterface)调用 OpenCV
JNI2OpenCV将OpenCV的C/C++程序代码编译成动态链接库文件,Java便可以利用本地方法调用OpenCV的计算机视觉库中的一系列的函数和算法。 JNI2OpenCV中提供了FaceDetection.java的测试程序,程序代码如下:
针对解决OpenCV人脸检测模块在Android平台编译和移植的问题,提出一种利用JNI技术(Java Native Interface)调用OpenCV以及采用Android NDK(Native Development Kit)生成共享库的目标检测方法。文中从分析利用...
人脸检测,检测人睁闭眼睛,可以判断是否疲劳驾驶,代码是androidStudio+opencv工程,并且带android下JNI通过NDK编译so库文件的功能。。
完成 Android 相机预览功能以后,在此基础上我使用 dlib 与 opencv 库做了一个关于人脸检测的 demo。该 demo 在相机预览过程中对人脸进行实时检测,并将检测到的人脸用矩形框描绘出来。具体实现原理如下: 采用双层 ...
java调用dll(使用JNI)进行人脸识别的程序,其中包含使用方法、C++程序、java测试程序(运行成功)
简单介绍了开发环境搭建以及利用Android程序框架实现此应用程序的过程,同时详细阐述了利用JNI( Java Native Interface) 调用OpenCV相关函数的具体步骤,以及采用Android NDK( Native Development Kit)生成共享库的...
人脸识别源代码,希望大家用得上 调用JNI2OpenCV.dll
工作原理:Java加载引入JNI2OpenCV.dll动态链接库,创建对象JNIOpenCV,然后通过调用native方法detectFace,传入参数,通过人脸数据特征比对识别,进行人脸定位
安卓开的人脸识别,Android Studio 3.1编译可通过。NDK通过JNI实现Java调用c++本地代码,检测精度比较高。具有很好的参考价值。