|
所谓使用使用jni的开发模式,也就是在开发Android应用的时候部分算法代码是用C/C++写的,这样开发的好处请读者自行了解。下面的代码就是将 JAVA传过来的4通道的图片转换为C/C++ opencv中常见的3通道的图片,再将转换过的图片使用边缘检测函数处理后返回给JAVA调用。
在下面的代码总extern "C" {}的作用是将大括号中的代码使用C的规则编译,但是切记这就需要你放这些的代码的文件是.CPP结尾的C++文件,如果是.C结尾的C文件将会报错。
JNIEXPORT:在Jni编程中所有本地语言实现Jni接口的方法前面都有一个"JNIEXPORT",这个可以看做是Jni的一个标志,至今为止没发现它有什么特殊的用处。
之所以需要将JAVA传过来的图片先转换为3通道是因为,JAVA中图片一般是4通道的,详细的内容请自行了解。
如果你开发过OPENCV 就可以发现这些C/C++代码和在PC机使用vs开发是的那些代码是差不多。
- #include <jni.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <highgui.h>
- #include <opencv2/opencv.hpp>
- using namespace cv;
- IplImage * change4channelTo3InIplImage(IplImage * src);
- extern "C" {
- JNIEXPORT
- jintArray JNICALL Java_com_example_hellojnitest_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h);
- JNIEXPORT
- jintArray JNICALL Java_com_example_hellojnitest_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h)
- {
- jint *cbuf;
- cbuf = env->GetIntArrayElements(buf, NULL);
- if (cbuf == NULL) {
- return 0;
- }
- Mat myimg(h, w, CV_8UC4, (unsigned char*) cbuf);
- IplImage image=IplImage(myimg);
- IplImage* image3channel = change4channelTo3InIplImage(&image);
- IplImage* pCannyImage=cvCreateImage(cvGetSize(image3channel),IPL_DEPTH_8U,1);
- cvCanny(image3channel,pCannyImage,50,150,3);//边缘检测函数
- int* outImage=new int[w*h];
- for(int i=0;i<w*h;i++)
- {
- outImage=(int)pCannyImage->imageData;
- }
- int size = w * h;
- jintArray result = env->NewIntArray(size);
- env->SetIntArrayRegion(result, 0, size, outImage);
- env->ReleaseIntArrayElements(buf, cbuf, 0);
- return result;
- }
- }
- IplImage * change4channelTo3InIplImage(IplImage * src) { //将4通道的图片转换为3通道的图片
- if (src->nChannels != 4) {
- return NULL;
- }
- IplImage * destImg = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);//
- for (int row = 0; row < src->height; row++) {
- for (int col = 0; col < src->width; col++) {
- CvScalar s = cvGet2D(src, row, col);
- cvSet2D(destImg, row, col, s);
- }
- }
- return destImg;
- }
复制代码
将应用安装在PX2开发板,显示在22寸显示器的效果如下:
|
|