Java代码:
public class FindViolajones {
public DET_PARAMS DetParams=new DET_PARAMS();
private native int[] fViolaJonesFindFace1(String sImage,String sDataDir);
private native void CloseViolaJones ();
static {
System.loadLibrary("ViolaJones");
}
}
C++代码:
// ViolaJones.cpp : Defines the entry point for the DLL application.
//
#include "string.h"
#include "stdafx.h"
#include <jni.h>
#include "cv.h"
#include "highgui.h"
#include "com_vio_FindViolajones.h"
// accurate but slow: these values are recommended in opencvref_cv.htm
static const double SCALE_FACTOR = 1.1;
static const int MIN_NEIGHBORS = 3;
static const int DET_FLAGS = 0;
static const char *CASCADE_NAME = "haarcascade_frontalface_alt2.xml";
static CvHaarClassifierCascade *pgCascade;
static CvMemStorage *pgStorage;
/*
* Class: com_vio_FindViolajones
* Method: fViolaJonesFindFace1
* Signature: (Ljava/lang/String;[C)[I
*/
JNIEXPORT jintArray JNICALL Java_com_vio_FindViolajones_fViolaJonesFindFace1
(JNIEnv *env, jobject obj, jstring sImage, jstring sDatadir)
{
const char * str_sImage ,* str_sDatadir;
jintArray faceArray;
str_sImage = env->GetStringUTFChars(sImage, false);
str_sDatadir = env->GetStringUTFChars(sDatadir,false);
jint faceBuf[4];
if (!pgCascade) // first time? if so, must init detector data structures
{
char sCascadePath[256];
strcpy(sCascadePath,str_sDatadir);
strcat(sCascadePath,"//");
strcat(sCascadePath,CASCADE_NAME);
pgCascade = (CvHaarClassifierCascade*)cvLoad(sCascadePath, 0, 0, 0);
if(!pgCascade)
printf("can't load %s", sCascadePath);
pgStorage = cvCreateMemStorage(0);
if (!pgStorage)
printf("out of memory (cvCreateMemStorage failed)");
env->ReleaseStringUTFChars(sDatadir, str_sDatadir);
}
cvClearMemStorage(pgStorage);
IplImage* pImage = cvLoadImage(str_sImage, CV_LOAD_IMAGE_GRAYSCALE);
cvResize(pImage, pImage, CV_INTER_LINEAR);
cvEqualizeHist(pImage, pImage);
CvSeq* pFaces = cvHaarDetectObjects(pImage, pgCascade, pgStorage,
SCALE_FACTOR, MIN_NEIGHBORS, DET_FLAGS,
cvSize((pImage->width)/4,
(pImage->width)/4));
if (pFaces->total) // success?
{
// get most central face
faceArray = env-> NewIntArray(4*pFaces->total);
int iSelectedFace = 0;
double MaxOffset = FLT_MAX; // max abs dist from face center to image center
for (int iFace = 0; iFace < pFaces->total; iFace++)
{
CvRect* r = (CvRect*)cvGetSeqElem(pFaces, iFace);
double Offset = fabs(r->x + r->width/2.0 - pImage->width/2.0);
if (Offset < MaxOffset)
{
MaxOffset = Offset;
iSelectedFace = iFace;
}
}
CvRect* r = (CvRect*)cvGetSeqElem(pFaces, iSelectedFace);
// convert x and y (OpenCV coords at corner of face box) to cartesian
// coords (with x,y at center of face box)
int x = r->x - pImage->width/2 + r->width/2;
int y = pImage->height/2 - r->y - r->height/2;
int width = r->width;
int height = r->height;
faceBuf[0]=x;
faceBuf[1]=y;
faceBuf[2]=width;
faceBuf[3]=height;
env->SetIntArrayRegion(faceArray,0,4,faceBuf);
}
cvReleaseImage(&pImage);
cvReleaseMemStorage( &pgStorage );
env->ReleaseStringUTFChars(sImage, str_sImage);
env->ReleaseStringUTFChars(sDatadir, str_sDatadir);
return faceArray; // return true on success
}
/*
* Class: com_vio_FindViolajones
* Method: CloseViolaJones
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_vio_FindViolajones_CloseViolaJones
(JNIEnv *, jobject)
{
if (pgCascade)
{
cvReleaseHaarClassifierCascade(&pgCascade);
cvReleaseMemStorage(&pgStorage);
pgCascade = NULL;
}
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

这篇博客展示了如何使用Java的JNI技术调用OpenCV库实现人脸检测。通过加载DLL,Java代码与C++代码交互,进行图像处理和面部检测。C++部分涉及到OpenCV的图像加载、灰度化、直方图均衡化以及Haar级联分类器进行对象检测。
1899

被折叠的 条评论
为什么被折叠?



