You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
342 lines
9.8 KiB
342 lines
9.8 KiB
/* |
|
OpenCV for Android NDK |
|
Copyright (c) 2006-2009 SIProp Project http://www.siprop.org/ |
|
|
|
This software is provided 'as-is', without any express or implied warranty. |
|
In no event will the authors be held liable for any damages arising from the use of this software. |
|
Permission is granted to anyone to use this software for any purpose, |
|
including commercial applications, and to alter it and redistribute it freely, |
|
subject to the following restrictions: |
|
|
|
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. |
|
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. |
|
3. This notice may not be removed or altered from any source distribution. |
|
*/ |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <jni.h> |
|
#include <android/log.h> |
|
|
|
#include "cv.h" |
|
#include "cxcore.h" |
|
#include "cvaux.h" |
|
#include "highgui.h" |
|
#include "ml.h" |
|
#include "utils.h" |
|
#include "WLNonFileByteStream.h" |
|
#include "grfmt_bmp.h" |
|
|
|
#define LOGV(...) __android_log_print(ANDROID_LOG_SILENT, LOG_TAG, __VA_ARGS__) |
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) |
|
//ANDROID_LOG_UNKNOWN, ANDROID_LOG_DEFAULT, ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_SILENT |
|
//LOGV(ANDROID_LOG_DEBUG, "JNI", ""); |
|
|
|
#define ANDROID_LOG_VERBOSE ANDROID_LOG_DEBUG |
|
#define LOG_TAG "CVJNI" |
|
#define INVALID_ARGUMENT -18456 |
|
|
|
#define SAFE_DELETE(p) { if(p){ delete (p); (p)=0; } } |
|
#define SAFE_DELETE_ARRAY(p) { if(p){ delete [](p); (p)=0; } } |
|
|
|
|
|
#define IMAGE( i, x, y, n ) *(( unsigned char * )(( i )->imageData \ |
|
+ ( x ) * sizeof( unsigned char ) * 3 \ |
|
+ ( y ) * ( i )->widthStep ) + ( n )) |
|
|
|
// CV Objects |
|
static const char* fmtSignBmp = "BM"; |
|
|
|
CvCapture *m_capture = 0; |
|
CvHaarClassifierCascade *m_cascade = 0; |
|
IplImage *m_sourceImage = 0; |
|
IplImage *m_grayImage = 0; |
|
IplImage *m_smallImage = 0; |
|
CvMemStorage *m_storage = 0; |
|
CvSeq *m_facesFound = 0; |
|
CvRect m_faceCropArea; |
|
CvSize m_smallestFaceSize; |
|
|
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
JNIEXPORT |
|
jboolean |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_createSocketCapture(JNIEnv* env, |
|
jobject thiz, |
|
jstring address_str, |
|
jstring port_str, |
|
jint width, |
|
jint height); |
|
|
|
JNIEXPORT |
|
void |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_releaseSocketCapture(JNIEnv* env, |
|
jobject thiz); |
|
|
|
JNIEXPORT |
|
jboolean |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_grabSourceImageFromCapture(JNIEnv* env, |
|
jobject thiz); |
|
|
|
JNIEXPORT |
|
jbooleanArray |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_getSourceImage(JNIEnv* env, |
|
jobject thiz); |
|
|
|
JNIEXPORT |
|
jboolean |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_setSourceImage(JNIEnv* env, |
|
jobject thiz, |
|
jintArray photo_data, |
|
jint width, |
|
jint height); |
|
|
|
JNIEXPORT |
|
jbooleanArray |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_findContours(JNIEnv* env, |
|
jobject thiz, |
|
jint width, |
|
jint height); |
|
|
|
JNIEXPORT |
|
jboolean |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_initFaceDetection(JNIEnv* env, |
|
jobject thiz, |
|
jstring cascade_path_str); |
|
|
|
JNIEXPORT |
|
void |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_releaseFaceDetection(JNIEnv* env, |
|
jobject thiz); |
|
|
|
JNIEXPORT |
|
jboolean |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_highlightFaces(JNIEnv* env, |
|
jobject thiz); |
|
|
|
JNIEXPORT |
|
jobjectArray |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_findAllFaces(JNIEnv* env, |
|
jobject thiz); |
|
|
|
JNIEXPORT |
|
jobject |
|
JNICALL |
|
Java_org_siprop_opencv_OpenCV_findSingleFace(JNIEnv* env, |
|
jobject thiz); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
|
|
|
|
IplImage* loadPixels(int* pixels, int width, int height) { |
|
|
|
int x, y; |
|
IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); |
|
|
|
for ( y = 0; y < height; y++ ) { |
|
for ( x = 0; x < width; x++ ) { |
|
// blue |
|
IMAGE( img, x, y, 0 ) = pixels[x+y*width] & 0xFF; |
|
// green |
|
IMAGE( img, x, y, 1 ) = pixels[x+y*width] >> 8 & 0xFF; |
|
// red |
|
IMAGE( img, x, y, 2 ) = pixels[x+y*width] >> 16 & 0xFF; |
|
} |
|
} |
|
|
|
return img; |
|
} |
|
|
|
|
|
void loadImageBytes(const uchar* data, |
|
int step, |
|
int width, |
|
int height, |
|
int depth, |
|
int channels, |
|
WLNonFileByteStream* m_strm) { |
|
|
|
int fileStep = (width*channels + 3) & -4; |
|
uchar zeropad[] = "\0\0\0\0"; |
|
char log_str[100]; |
|
|
|
|
|
assert( data && width > 0 && height > 0 && step >= fileStep ); |
|
|
|
int bitmapHeaderSize = 40; |
|
int paletteSize = channels > 1 ? 0 : 1024; |
|
int headerSize = 14 /* fileheader */ + bitmapHeaderSize + paletteSize; |
|
PaletteEntry palette[256]; |
|
|
|
int testSize = fileStep*height + headerSize; |
|
m_strm->Open(testSize); |
|
sprintf(log_str, "fileStep*height + headerSize=%i", testSize); |
|
LOGV(log_str); |
|
|
|
// write signature 'BM' |
|
m_strm->PutBytes( fmtSignBmp, (int)strlen(fmtSignBmp) ); |
|
|
|
// write file header |
|
m_strm->PutDWord( fileStep*height + headerSize ); // file size |
|
m_strm->PutDWord( 0 ); |
|
m_strm->PutDWord( headerSize ); |
|
|
|
// write bitmap header |
|
m_strm->PutDWord( bitmapHeaderSize ); |
|
m_strm->PutDWord( width ); |
|
m_strm->PutDWord( height ); |
|
m_strm->PutWord( 1 ); |
|
m_strm->PutWord( channels << 3 ); |
|
m_strm->PutDWord( BMP_RGB ); |
|
m_strm->PutDWord( 0 ); |
|
m_strm->PutDWord( 0 ); |
|
m_strm->PutDWord( 0 ); |
|
m_strm->PutDWord( 0 ); |
|
m_strm->PutDWord( 0 ); |
|
|
|
if( channels == 1 ) |
|
{ |
|
FillGrayPalette( palette, 8 ); |
|
m_strm->PutBytes( palette, sizeof(palette)); |
|
} |
|
|
|
width *= channels; |
|
data += step*(height - 1); |
|
for( ; height--; data -= step ) |
|
{ |
|
m_strm->PutBytes( data, width ); |
|
if( fileStep > width ) |
|
m_strm->PutBytes( zeropad, fileStep - width ); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
bool is_NULL_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name, const char* field_type) { |
|
|
|
|
|
LOGV("in is_NULL_field_JavaObj!"); |
|
jclass clazz = env->GetObjectClass(java_obj); |
|
|
|
|
|
// get field |
|
jfieldID fid = env->GetFieldID(clazz, field_name, field_type); |
|
|
|
jobject obj = env->GetObjectField(java_obj, fid); |
|
if(obj == 0) { |
|
LOGV("Object is NULL!"); |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
bool is_NULL_vec_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
return is_NULL_field_JavaObj(env, java_obj, field_name, "Lorg/siprop/opencv/util/Vector3;"); |
|
} |
|
|
|
bool is_NULL_point_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
return is_NULL_field_JavaObj(env, java_obj, field_name, "Lorg/siprop/opencv/util/Point3;"); |
|
} |
|
|
|
bool is_NULL_axis_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
return is_NULL_field_JavaObj(env, java_obj, field_name, "Lorg/siprop/opencv/util/Axis;"); |
|
} |
|
|
|
bool is_NULL_pivot_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
return is_NULL_field_JavaObj(env, java_obj, field_name, "Lorg/siprop/opencv/util/Pivot3;"); |
|
} |
|
|
|
bool is_NULL_quat_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
return is_NULL_field_JavaObj(env, java_obj, field_name, "Lorg/siprop/opencv/util/Quaternion;"); |
|
} |
|
|
|
bool is_NULL_mat3x3_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
return is_NULL_field_JavaObj(env, java_obj, field_name, "Lorg/siprop/opencv/util/Matrix3x3;"); |
|
} |
|
bool is_NULL_mat3x1_field_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
return is_NULL_field_JavaObj(env, java_obj, field_name, "Lorg/siprop/opencv/util/Matrix3x1;"); |
|
} |
|
|
|
|
|
|
|
|
|
void set_JavaObj_int(JNIEnv* env, jobject java_obj, const char* field_name, jint val) { |
|
|
|
LOGV("in set_JavaObj_int!"); |
|
|
|
jclass clazz = env->GetObjectClass(java_obj); |
|
jfieldID fid = env->GetFieldID(clazz, field_name, "I"); |
|
|
|
env->SetIntField(java_obj, fid, val); |
|
|
|
} |
|
|
|
int get_id_by_JavaObj(JNIEnv* env, jobject java_obj) { |
|
|
|
LOGV("in get_id_by_JavaObj!"); |
|
|
|
jclass method_clazz = env->GetObjectClass(java_obj); |
|
jmethodID get_type_mid = env->GetMethodID(method_clazz, "getID", "()I"); |
|
return env->CallIntMethod(java_obj, get_type_mid); |
|
|
|
} |
|
|
|
int get_type_by_JavaObj(JNIEnv* env, jobject java_obj) { |
|
|
|
LOGV("in get_type_by_JavaObj!"); |
|
|
|
jclass method_clazz = env->GetObjectClass(java_obj); |
|
jmethodID get_type_mid = env->GetMethodID(method_clazz, "getType", "()I"); |
|
return env->CallIntMethod(java_obj, get_type_mid); |
|
|
|
} |
|
|
|
|
|
int get_int_by_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
|
|
LOGV("in get_int_by_JavaObj!"); |
|
|
|
jclass clazz = env->GetObjectClass(java_obj); |
|
jfieldID int_fid = env->GetFieldID(clazz, field_name, "I"); |
|
return env->GetIntField(java_obj, int_fid); |
|
|
|
} |
|
|
|
|
|
float get_float_by_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name) { |
|
|
|
LOGV("in get_float_by_JavaObj!"); |
|
|
|
jclass clazz = env->GetObjectClass(java_obj); |
|
jfieldID float_fid = env->GetFieldID(clazz, field_name, "F"); |
|
return env->GetFloatField(java_obj, float_fid); |
|
|
|
} |
|
|
|
|
|
jobject get_obj_by_JavaObj(JNIEnv* env, jobject java_obj, const char* field_name, const char* obj_type) { |
|
|
|
LOGV("in get_obj_by_JavaObj!"); |
|
|
|
jclass clazz = env->GetObjectClass(java_obj); |
|
jfieldID obj_fid = env->GetFieldID(clazz, field_name, obj_type); |
|
return env->GetObjectField(java_obj, obj_fid); |
|
|
|
} |
|
|
|
|