首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

施用Android NDK编译OpenCV应用

2012-06-26 
使用Android NDK编译OpenCV应用#include cv.h#include highgui.h#include stdio.h#include stdlib.

使用Android NDK编译OpenCV应用
#include "cv.h"#include "highgui.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <math.h>#include <float.h>#include <limits.h>#include <time.h>#include <ctype.h>#include <android/log.h>#include <study_opencv_FaceRec.h>#include <jni.h>#define LOG_TAG "opencv_face_detect"#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)static CvMemStorage* storage = 0;static CvHaarClassifierCascade* cascade = 0;void detect_and_draw( IplImage* image );const char* cascade_name = "haarcascade_frontalface_alt.xml";/* "haarcascade_profileface.xml";*//*int captureFromImage(char* xml, char* filename);*/char* jstring2String(JNIEnv*, jstring);int captureFromImage(char* xml, char* filename, char* outfile){LOGI("begin: ");// we just detect image// CvCapture* capture = 0; IplImage *frame, *frame_copy = 0; const char* input_name = "lina.png";if(xml != NULL){cascade_name = xml;}if(filename != NULL){input_name = filename;}LOGI("xml=%s,filename=%s", cascade_name, input_name);// load xml cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );LOGI("load cascade ok ? %d", cascade != NULL ? 1 : 0);if( !cascade ) { LOGI("ERROR: Could not load classifier cascade\n" );// I just won't write long full file path, to instead of relative path, but I failed.FILE * fp = fopen(input_name,"w");if(fp == NULL){LOGE("create failed");} return -1; }storage = cvCreateMemStorage(0);// cvNamedWindow( "result", 1 ); IplImage* image = cvLoadImage( input_name, 1 ); if( image ) {LOGI("load image successfully"); detect_and_draw( image ); // cvWaitKey(0);if(outfile != NULL){LOGI("after detected save image file");cvSaveImage(outfile, image);//把图像写入文件} cvReleaseImage( &image ); }else{LOGE("can't load image from : %s ", input_name);}}void detect_and_draw( IplImage* img ){ static CvScalar colors[] = { {{0,0,255}}, {{0,128,255}}, {{0,255,255}}, {{0,255,0}}, {{255,128,0}}, {{255,255,0}}, {{255,0,0}}, {{255,0,255}} }; double scale = 1.3; IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 ); IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale), cvRound (img->height/scale)), 8, 1 ); int i; cvCvtColor( img, gray, CV_BGR2GRAY ); cvResize( gray, small_img, CV_INTER_LINEAR ); cvEqualizeHist( small_img, small_img ); cvClearMemStorage( storage ); if( cascade ) { double t = (double)cvGetTickCount(); CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/, cvSize(30, 30) ); t = (double)cvGetTickCount() - t; LOGI( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) ); for( i = 0; i < (faces ? faces->total : 0); i++ ) { CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); CvPoint center; int radius; center.x = cvRound((r->x + r->width*0.5)*scale); center.y = cvRound((r->y + r->height*0.5)*scale); radius = cvRound((r->width + r->height)*0.25*scale); cvCircle( img, center, radius, colors[i%8], 3, 8, 0 ); } } // cvShowImage( "result", img ); cvReleaseImage( &gray ); cvReleaseImage( &small_img );}JNIEXPORT void JNICALL Java_study_opencv_FaceRec_detect (JNIEnv * env, jobject obj, jstring xml, jstring filename, jstring outfile){LOGI("top method invoked! ");/*LOGI("1");char * c_xml = (char *)env->GetStringUTFChars(xml, JNI_FALSE);LOGI("char * = %s", c_xml);if(c_xml == NULL){LOGI("error in get char*");return;}char * c_file = env->GetStringCritical(env, filename, 0);if(c_xml == NULL){LOGI("error in get char*");return;}captureFromImage(c_xml, c_file);env->ReleaseStringCritical(env, xml, c_xml);env->ReleaseStringCritical(env, file_name, c_file);*/captureFromImage(jstring2String(env,xml), jstring2String(env,filename), jstring2String(env,outfile));}//jstring to char*char* jstring2String(JNIEnv* env, jstring jstr){if(jstr == NULL){LOGI("NullPointerException!");return NULL;}char* rtn = NULL;jclass clsstring = env->FindClass("java/lang/String");jstring strencode = env->NewStringUTF("utf-8");jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);jsize alen = env->GetArrayLength(barr);jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);if (alen > 0){rtn = (char*)malloc(alen + 1);memcpy(rtn, ba, alen);rtn[alen] = 0;}env->ReleaseByteArrayElements(barr, ba, 0);LOGI("char*=%s",rtn);return rtn;}

人脸检测? http://www.opencv.org.cn/index.php/%E4%BA%BA%E8%84%B8%E6%A3%80%E6%B5%8B


1 楼 ihopethatwell 2012-01-05   楼主您好,请问:OpenCV 设置,从网站上下载 OpenCV 2.3.0 for Android 后,解压到某个目录,如 ~/ 目录下

设置 OPENCV_PACKAGE_DIR 环境变量

  $ export OPENCV_PACKAGE_DIR=~/enCV-2.3.0/

在这里 $ export OPENCV_PACKAGE_DIR=~/enCV-2.3.0/ 是添加到那个环境变量里?是我的电脑 -》高级-path,还是 cygwin中? 2 楼 melord 2012-01-12   ihopethatwell 写道楼主您好,请问:OpenCV 设置,从网站上下载 OpenCV 2.3.0 for Android 后,解压到某个目录,如 ~/ 目录下

设置 OPENCV_PACKAGE_DIR 环境变量

  $ export OPENCV_PACKAGE_DIR=~/enCV-2.3.0/

在这里 $ export OPENCV_PACKAGE_DIR=~/enCV-2.3.0/ 是添加到那个环境变量里?是我的电脑 -》高级-path,还是 cygwin中?
添加到环境变量. 我的是Linux系统,你的是XP系统, 如果不行,也添加到cygwin中吧. 3 楼 ihopethatwell 2012-01-16   我知道怎么设置了,是我自己路径存放有问题,已经解决了,对了楼主有没有使用过OpenCV2.0?如果使用过能介绍一下2.0中Android.mk应该如何导入哪些库? 4 楼 melord 2012-01-19   ihopethatwell 写道我知道怎么设置了,是我自己路径存放有问题,已经解决了,对了楼主有没有使用过OpenCV2.0?如果使用过能介绍一下2.0中Android.mk应该如何导入哪些库?
没有哦, 我当初只是简单的用OpenCV实现人脸识别而已,不过,你可以去openCV wiki上查看一下, 我也是按照官网上给的指导 配置mk文件的. 5 楼 xiongjian007 2012-02-27   02-27 11:12:35.965: ERROR/AndroidRuntime(1755): java.lang.UnsatisfiedLinkError: detect

楼主啊,log里面我每次运行都出这个提示,????求解 6 楼 melord 2012-03-31   xiongjian007 写道02-27 11:12:35.965: ERROR/AndroidRuntime(1755): java.lang.UnsatisfiedLinkError: detect

楼主啊,log里面我每次运行都出这个提示,????求解
请确认是你否生成了so库,so库有没有放到指定目录?java代码中是否有loadLibrary()来加载? 7 楼 ihopethatwell 2012-04-06   嗯,已经解决了,每次用jni生成的头文件 导入不能去掉,去掉了,即使打包成功了,加载后调用就会报上面的错 8 楼 xinrui0754 2012-05-16   楼主您好!我目前卡在ndk-build这一项,出错内容是这样的:
$ $NDK/ndk-build
Compile++ thumb: ImgFun <= /cygdrive/f/Eclipse-IDE-for-Java-EE-Developers/TestOp
enCV/HaveImgFun/jni/ImgFun.cpp
make: *** No rule to make target `/cygdrive/f/Eclipse-IDE-for-Java-EE-Developers
/TestOpenCV/HaveImgFun/obj/local/armeabi/libopencv_contrib.a', needed by `/cygdr
ive/f/Eclipse-IDE-for-Java-EE-Developers/TestOpenCV/HaveImgFun/obj/local/armeabi
/libImgFun.so'. Stop.
之前看了一些网上的评论,说是是要把Android.mk文件中多余的空格去掉,可是去掉之后还是出现了这种问题,请问要如何解决,谢谢!另外,我用这个命令去编译crystax ndk r4下自带的sample文件夹下的文件是可以得到.so文件的,但是一涉及到OpenCV的就无法编译通过,我的Android.mk文件是这样的,不知道有什么错误,请指教,谢谢!
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include ../includeOpenCV.mk
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
#try to load OpenCV.mk from default install location
include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_CPP_EXTENSION := cpp
LOCAL_MODULE    := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
include $(BUILD_SHARED_LIBRARY)

热点排行