JNI multidimensional Array and OpenCV
843829May 29 2007 — edited May 30 2007Hello everybody,
my first post, so lets go..
At the moment I am writing my thesis in the filed of automatic image classification. The project is written in Java, but I wanna use the OpenCV library from Intel (http://sourceforge.net/projects/opencvlibrary/) for facedetection.
So far I managed to call the native method from Java. What I do I parse the path of the image to be analyzed as a string to my C++ programm. The faces are being detected and written into a so called CvSeq (http://www.comp.leeds.ac.uk/vision/opencv/opencvref_cxcore.htm#cxcore_ds_sequences) which holds the coordinates of the rectangles surrounding the found faces. Until now I can only call cvSeq->total which gives me the total number of faces as ints. That integer I return to my java api.
What I don't know is, how to return a multidimensional array (2 dimensions) where the first dim contains the path as a string to the file and the second dimension 3 integers for x,y coordinates and the lenght of each rectangle.
Or better, I might know how to return that Array, but not how to create it.
I know this is somewht OpenCV specific, but maybe someone knows anything. Any little help would be greatly appreciated. Thanks a lot!!!!
Regards
Carsten
attached: JNI source code
/////////////////////////////////////////// source code ///////////////////////////////////////////////
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cxtypes.h"
#include "cvaux.h"
#include "org_kimm_media_image_data_JNIOpenCV.h"
#include <stdio.h>
JNIEXPORT jint JNICALL
Java_org_kimm_media_image_data_JNIOpenCV_getFaces(JNIEnv *env, jobject object, jstring path)
{
//declarations
CvHaarClassifierCascade *pCascade = 0;
CvMemStorage *pStorage = 0;
CvSeq *pFaceRectSeq;
int scale=1;
jobjectArray recPoints;
const char *str = env->GetStringUTFChars(path, 0);
//initializations
IplImage* pInpImg = cvLoadImage(str, CV_LOAD_IMAGE_COLOR);
IplImage* small_image = pInpImg;
pStorage = cvCreateMemStorage(0);
pCascade = (CvHaarClassifierCascade *)cvLoad
(("C:/OpenCV/data/haarcascades/haarcascade_frontalface_default.xml"),0, 0, 0 );
//validaste that everything initilized properly
if( !pInpImg || !pStorage || !pCascade)
{
printf("Initialization failed: %s \n",
(!pInpImg) ? "didn't load image file" :
(!pCascade) ? "didn't load Haar Cascade --"
"make sure Path is correct" :
"failed to allocate memory for data storage");
exit(-1);
}
//performance boost through reducing image size by factor 2
small_image = cvCreateImage( cvSize(pInpImg->width/2,pInpImg->height/2), IPL_DEPTH_8U, 3 );
cvPyrDown( pInpImg, small_image, CV_GAUSSIAN_5x5 );
scale = 2;
//detect faces in image
pFaceRectSeq = cvHaarDetectObjects(small_image, pCascade, pStorage,
1.1, //increase search scale by 10% each pass
6, //drop group of fewer than three detections
CV_HAAR_DO_CANNY_PRUNING, //skip regions unlikely to contain faces
cvSize(50,50)); //use XML default for smallest search scale
//initialize array for location of the faces (HERE IS WHERE I GET INTO TROUBLE!!!!!)
int x = pFaceRectSeq->total;
jclass intArrCls = env->FindClass ( "[I" ) ;
recPoints = env->NewObjectArray ( x, intArrCls, NULL ) ;
//for(int j = 0; j <= x; j++) {
// recPoints[j] = (jintArray)env->NewIntArray(3);
//}
for(int i=0;i<(pFaceRectSeq ? pFaceRectSeq->total:0); i++)
{
CvRect* r = (CvRect*)cvGetSeqElem(pFaceRectSeq, i);
CvPoint pt1 = {(r->x)*scale, (r->y)*scale};
CvPoint pt2 = {(r->x + r->width)*scale, (r->y + r->height)*scale};
//env->SetObjectArrayElement(recPoints,i, pt1.x);
}
return pFaceRectSeq->total;
}