`
lveyo
  • 浏览: 915420 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAVA应用JNI调用OpenCV实现人脸检测

    博客分类:
  • JAVA
阅读更多
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);
			}
		}
	}
}

3
1
分享到:
评论
11 楼 shun1 2012-09-24  
您好啊,您能把邮箱给我吗?我有问题可以请教你啊。
10 楼 lithens2015 2012-04-24  
                  
9 楼 lveyo 2010-07-08  
a78027a78027 写道
我想知道
为什么这程式如果写成无限回圈
记忆体会一直上升
而不会释放
当程式关闭后
记忆体才释放掉
平均执行900多次就会挑出错误

我循环运行了几十万次都没有出现问题
8 楼 a78027a78027 2010-07-07  
我想知道
为什么这程式如果写成无限回圈
记忆体会一直上升
而不会释放
当程式关闭后
记忆体才释放掉
平均执行900多次就会挑出错误
7 楼 lveyo 2010-05-14  
loven_11 写道
不错的介绍啊,我按照做下来还是碰到个问题,不过都是些低级问题,分享下:
我的操作环境介绍: Opencv2.0, Visual Studio2008.

  2008创建的是win dll工程, 需要手工删除掉jniOpenCV.h头文件的Using System; 这句话折腾了我一个多小时悲剧.(主要是因为,framework跟2008 window sdk里面都存在一个相同的类);


我那会用的还是VS2005呢
6 楼 loven_11 2010-05-06  
不错的介绍啊,我按照做下来还是碰到个问题,不过都是些低级问题,分享下:
我的操作环境介绍: Opencv2.0, Visual Studio2008.

  2008创建的是win dll工程, 需要手工删除掉jniOpenCV.h头文件的Using System; 这句话折腾了我一个多小时悲剧.(主要是因为,framework跟2008 window sdk里面都存在一个相同的类);
5 楼 westice 2010-04-28  
物体识别还真是复杂! OpenCV识别的关键是那个xml文件.官网提供的xml文件说是经过了三天三夜的训练才能用来识别人脸.要拿来识别自己的东东成本太高了吧,不说电费,几天几夜下来如果没成功那还不晕倒.有没有专门的机构去做这种训练的事啊.纠结中...
4 楼 lveyo 2010-04-07  
yifzeng 写道
问题:
在jniOpenCV.cpp中
detectFace方法的参数有6个:  
(JNIEnv *env, jobject obj, jint width, jint height, jstring cascade, jstring filename)

为什么在Test的时候
只用了这个detectFace(40, 40, cascade, filename) ?


前两个参数是JNI调用的必要参数,传递的是JNI参数,和应用方法没有关系。而且这个h头文件是由JNI根据JAVA方法自动生成的。
3 楼 yifzeng 2010-04-02  
问题:
在jniOpenCV.cpp中
detectFace方法的参数有6个:  
(JNIEnv *env, jobject obj, jint width, jint height, jstring cascade, jstring filename)

为什么在Test的时候
只用了这个detectFace(40, 40, cascade, filename) ?
2 楼 crazier9527 2009-12-02  
好文,收藏
1 楼 chenmin 2009-08-18  
好文章 ,收藏

相关推荐

    JAVA调用OpenCV人脸检测

    本教程将详细讲解如何在Java环境中调用OpenCV来实现人脸检测。 首先,我们需要理解OpenCV的基本概念。OpenCV是一个跨平台的计算机视觉库,它包含了众多用于图像处理、特征检测、机器学习等功能的C++接口。为了在...

    android opencv人脸检测

    总的来说,"android opencv人脸检测"项目涉及到了Android应用开发、NDK编程、OpenCV库的集成以及计算机视觉中的特征检测技术。通过这样的项目,开发者不仅可以提升Android原生开发能力,还能深入理解计算机视觉领域...

    java结合opencv人脸检测.zip

    Java 结合 OpenCV 进行人脸检测是一种常见的计算机视觉应用场景,尤其在开发基于图像处理的系统时。OpenCV 是一个强大的开源计算机视觉库,它提供了丰富的功能,包括图像处理、特征检测、对象识别等。而Java,作为一...

    Android系统下OpenCV的人脸检测模块的设计_公衍宇1

    4. **实现本地代码**:在C/C++层实现JNI函数,直接调用OpenCV的人脸检测算法,如Haar特征级联分类器或者LBP特征级联分类器。 5. **链接库文件**:在Android.mk或CMakeLists.txt文件中,指定链接OpenCV库的路径和...

    java与opencv结合,进行人脸检测

    Java是编程语言,通过Java Native Interface (JNI) 或者 JavaCPP库可以方便地调用OpenCV的C++接口,使得在Java环境中也能高效地应用OpenCV。 首先,让我们了解人脸检测的基本原理。OpenCV中的人脸检测主要基于Haar...

    java结合opencv人脸检测识别.zip

    总结,"java结合opencv人脸检测识别.zip"的项目内容涵盖了如何在Java环境下集成和使用OpenCV进行人脸检测和识别的技术,涉及到的步骤包括环境配置、人脸检测算法应用、人脸识别模型建立和优化等。通过这个项目,...

    java 人脸检测

    在Java中使用OpenCV进行人脸检测,通常需要通过JNI来实现,因为OpenCV的核心算法是用C++编写的。JNI2OpenCV项目就是这样一个桥梁,它将OpenCV的C/C++代码编译为动态链接库,使得Java程序能够通过本地方法调用这些...

    JNI-OpenCV-Face-Detection:JNI OpenCV 人脸检测

    Java部分则通过JNI调用这个本地库,实现人脸检测功能。这样做的好处是可以在保持Java的跨平台性的同时,利用OpenCV的高性能。 ### 开发步骤 1. **配置OpenCV**: 首先需要安装OpenCV库,并确保开发环境(如Android ...

    Android通过Java接口调用OpenCV2.4示例

    本文将深入探讨如何在Android应用中通过Java接口调用OpenCV 2.4版本,以实现将图片转换为灰度图的功能。 首先,我们需要理解OpenCV的基本概念。OpenCV(Open Source Computer Vision Library)是一个跨平台的计算机...

    opencv实现人脸识别.zip

    开发过程中,可以使用Java或C++ API,通过JNI(Java Native Interface)进行调用。OpenCV的Android样例代码通常会包含一个初始化步骤,加载OpenCV库并设置相应的回调函数。 在实现人脸识别时,需要注意性能优化,...

    JavaOpenCV246人脸识别

    它通过JNI(Java Native Interface)将Java代码与OpenCV的C++核心库连接起来,使得Java开发者也能便捷地调用OpenCV的底层算法。 **3. 人脸识别** 人脸识别是计算机视觉领域中的一个重要课题,它涉及人脸检测、特征...

    人脸检测,检测人睁闭眼睛,可以判断是否疲劳驾驶,代码是androidStudio+opencv工程 带android下JNI通过NDK编译so库文件。

    在Android开发中,JNI被用来调用C/C++代码,以实现高性能或低级别的功能,例如本项目中的人脸检测算法可能就是用C++实现的。通过JNI,开发者可以将OpenCV的C++库封装成Android可以调用的.so动态链接库。 接着,我们...

    openCv+java+spring boot

    在这个项目中,Java用于编写后端代码,处理来自前端的请求,调用OpenCV库进行人脸识别,并将结果返回。Java的多线程能力使得处理多个并发请求成为可能,提高了系统的响应速度。 Spring Boot简化了Spring框架的使用...

    java人脸识别在项目中的应用(一)

    这篇博客“java人脸识别在项目中的应用(一)”将介绍如何在Java项目中集成和使用人脸识别功能,特别是通过JNI(Java Native Interface)调用OpenCV库来实现这一目标。OpenCV是一个强大的计算机视觉库,支持多种编程...

    FaceDetectAndroid2:基于Android+OpenCV人脸检测,采用jni NDK实现人脸检测

    【FaceDetectAndroid2】是一个基于Android平台的人脸检测应用程序,它利用了OpenCV库的强大功能,特别是其Cascade Classifier模块,来实现在实时摄像头预览中检测人脸。OpenCV是一个开源的计算机视觉库,广泛用于...

    人脸识别java(调用dll实现).rar

    此外,Java测试程序表明了整个流程的正确性,这可能是一个简单的Java应用,通过JNI调用C++编写的DLL,传入测试图像,然后接收并解析返回的人脸识别结果。测试程序的存在对于验证算法的准确性和性能至关重要,确保在...

    opencv4.5.1-java-jar dll.zip

    Java程序在导入此jar包后,可以通过Java代码调用OpenCV的功能。 4. **x86和x64**:这两个文件夹分别对应32位(x86)和64位(x64)的系统环境。OpenCV的动态链接库(dll)文件需要与运行环境匹配,否则可能会导致...

    android opencv 实现项目

    5. **OpenCV人脸检测步骤**: - 加载预训练的Haar级联分类器XML文件。 - 对输入图像或视频帧进行灰度处理,以减少计算复杂性。 - 应用级联分类器在灰度图像上滑动窗口进行检测,寻找符合人脸特征的区域。 - 返回...

Global site tag (gtag.js) - Google Analytics