转载请注明 cwyf
身为FAE一直处于什么都要干的情况,开发和客户端支持,一直在做(看着那可怜的薪水心疼).最近做的工作点有点多,所以来写个博记录下一些关键点.自从加入sunny后作了2年的PC端MFC,C# winform,现在开始在领导要求下转行,做数据库,服务器搭建,还有开始尝试Qualcomm底层开发+上层Android JAVA APK应用开发,主要负责camera相机相关和图像算法这块的部分
如有纰漏之处请大家指正
由于领导都奔着商化这个目标去,就不可避免的涉及到了算法以及效率等,所以需要使用OpenCV支持各类算法和OpenCL硬件加速算法这两块,今天就随便记录下相关的需要注意点
在上层Android上使用JAVA进行复杂算法处理大家都知道是很慢的,JAVA和C#虽然有GC机制,帮助了很多新手的,但是这样做代码上的效率就难以上去。
1。在Android studio 使用JNI(个人使用2.2.2版本的studio)
创建工程时钩选“Include C++ Support”,然后在工程目录下可以见到一个默认自动创建的CPP文件夹,里面有一个也是自动创建的“native-lib.cpp”文件,至此一次基础的带JNI调用的工程创建好了,自动创建的MainActivity里面已经自带了引用JNI的so,并且调用了hello JNI的一个方法。
2。添加简单的JNI函数
如果仅仅只是想用C++快速处理一些数据,没有太多逻辑类关联的话,建议直接在官方默认创建的native-lib.cpp文件里面编写函数,这样不用去修改CMakeList.txt。
如果要加复杂的逻辑,生成其他so等,请跳到3
extern“C”
jstring Java_你的包名_JAVA端调用的函数名(JNIEnv *env,jobject /* this */){。。。}
写JNI函数时包名里面的"."用“_”代替,可以参照自动创建的官方示例,传入参数可以自己增加
由于是我主攻camera和图像方向,所以举个示例也是图像方面的3*3sobel模板计算梯度和边缘检测处理
extern "C" void Java_com_example_cwyf_sunnycameradpc_MainPreviewActivity_sobelProcess( JNIEnv *env, jobject, jbyteArray pOriginalImage, //input,JAVA传入的数据,调用地方为camera的onFramePreview(),传入byte data[] jbyteArray pProcessedImage,//output,JAVA端创建的byte[]数组,作为JNI处理好以后的结果值,在JAVA端读取 jint width,//图像长 jint height,//图像宽 jfloat th//sobel的阈值,暂时未使用 ) { jbyte* originalImage = (jbyte*)malloc(sizeof(jbyte) * width * height);//创建输入图像Y值内存区域 memset(originalImage, 0, width * height); env->GetByteArrayRegion(pOriginalImage, 0, width * height, originalImage);//获取原始YUV,Y部分全图,(data[]里面的UV部分没考虑,所以只要提取前长*宽的Y部分即可) jbyte* processImage = (jbyte*)malloc(sizeof(jbyte) * width * height);//创建处理好的Y值内存区域 memset(processImage, 0, width * height); //3 * 3区域sobel //-1 0 +1 -1 -2 -1 //-2 0 +2 0 0 0 //-1 0 +1 +1 +2 +1 float maxVal = 0; for(int r = 1; r < height - 1;r++) { for(int c = 1; c < width - 1;c++) { float tempValueX = - originalImage[(r - 1) * width + (c - 1)] + originalImage[(r - 1) * width + (c + 1)] - 2 * originalImage[(r) * width + (c - 1)] + 2 * originalImage[(r) * width + (c + 1)] - originalImage[(r + 1) * width + (c - 1)] + originalImage[(r + 1) * width + (c + 1)]; float tempValueY = - originalImage[(r - 1) * width + (c - 1)] - 2 * originalImage[(r - 1) * width + (c)] - originalImage[(r - 1) * width + (c + 1)] + originalImage[(r + 1) * width + (c - 1)] + 2 * originalImage[(r + 1) * width + (c)] + originalImage[(r + 1) * width + (c + 1)]; float finalResult = sqrt(tempValueX * tempValueX + tempValueY * tempValueY); if(finalResult > maxVal) maxVal = finalResult; processImage[(r) * width + (c)] = ((int)finalResult & 0xff); } }env->SetByteArrayRegion(pProcessedImage, 0, width * height, processImage);//把处理好的Y图的内存区域拷贝到JAVA端创建的内存中去 free(originalImage)