专栏首页恩蓝脚本Android将camera获取到的YuvData在jni中转化为Mat方法

Android将camera获取到的YuvData在jni中转化为Mat方法

Android中可以通过camera获取图像,并实时处理,不同的手机camera支持的的图像格式不同,可以采用getCameraPreviewFormat来得到preview支持的图像编码格式,Android默认使用NV21(yuv420sp)的图像格式,因为大部分手机都支持。

为了达到实时处理的目的,很多时候我们将得到的yuv数据直接传入jni中的c++使用,减少上层转化图像格式的过程yuv420本身属于单通道图像,若图像处理中只需要获取灰度图像,可以在c++中直接通过Mat构造函数构造生成灰度图像,代码如下:

/*
* ImageProcessing.cpp
*  实时显示canny算子结果
*/
#include <jni.h 
 
#include <opencv2/core/core.hpp 
#include <opencv2/imgproc/imgproc_c.h 
#include <opencv2/opencv.hpp 
 
 
using namespace std;
using namespace cv;
 
 
Mat * mCanny = NULL;
 
extern "C"
jboolean
Java_my_project_MyRealTimeImageProcessing_CameraPreview_ImageProcessing(
		JNIEnv* env, jobject thiz,
		jint width, jint height,
		jbyteArray NV21FrameData, jintArray outPixels)
{
	jbyte * pNV21FrameData = env- GetByteArrayElements(NV21FrameData, 0); //输入yuv数据 
	jint * poutPixels = env- GetIntArrayElements(outPixels, 0);	//输出结果的int数据
	if ( mCanny == NULL )
	{
		mCanny = new Mat(height, width, CV_8UC1);
	}
	Mat mGray(height, width, CV_8UC1, (unsigned char *)pNV21FrameData);	//构建灰度图时构造函数
	Mat mResult(height, width, CV_8UC4, (unsigned char *)poutPixels);
	IplImage srcImg = mGray;
	IplImage CannyImg = *mCanny;
	IplImage ResultImg = mResult;
 
	cvCanny(&srcImg, &CannyImg, 80, 100, 3);
	cvCvtColor(&CannyImg, &ResultImg, CV_GRAY2BGRA);
	env- ReleaseByteArrayElements(NV21FrameData, pNV21FrameData, 0);
	env- ReleaseIntArrayElements(outPixels, poutPixels, 0);
	return true;
}

若图像处理时需要彩色图像,则需要先将nv21类型的数据转化为yuv格式,再将yuv转化为BGR彩色图像,构造yuv时的构造函数和直接构造灰度图有些不同,在YUV420中一个像素对应一个Y,一个2*2的小方块对应一个UV,对于所有YUV420图像,它们的Y值排列是完全相同的,因为只有Y的图像就是灰度图像。YUV420sp与YUV420p的数据格式它们的UV排列在原理上是完全不同的。420p它是先把U存放完后,再存放V,也就是说UV它们是连续的。而420sp它是UV、UV这样交替存放的。对于一个YUV420在内存中存放的大小:

Y = width*height

U = Y/4

v = Y/4

所以获取灰度图只需要Y的数据大小就可以,所以构造函数中宽高都是图像的宽高,而要获取YUV彩色图像则需要获取的内存长度为width*height*3/2

构造函数中图像高度需再加上1/2*height,代码如下:

JNIEXPORT int JNICALL Java_com_ProjectName_nativecaller_ClassName_readYUV420SP(JNIEnv *env, jclass clz, jbyteArray yuv,jint len,jint height,jint width)
{
 
	jbyte * pBuf = (jbyte*)env- GetByteArrayElements(yuv, 0);
 
	Mat image(height + height/2,width,CV_8UC1,(unsigned char *)pBuf);	//注意这里是height+height/2
	Mat mBgr;
	cvtColor(image, mBgr, CV_YUV2BGR_NV21);
	imwrite("/mnt/sdcard/readYuv.jpg",mBgr);
	env- ReleaseByteArrayElements(yuv, pBuf, 0);  
	return 0;
}

以上这篇Android将camera获取到的YuvData在jni中转化为Mat方法就是小编分享给大家的全部内容了,希望能给大家一个参考。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • php异常处理捕获错误整理

    为了让用户得到更好的体验,我们屏蔽所有错误的输出,是输出,而不是显示。但这样的话,管理员也看不到错误了。页面上不显示错

    砸漏
  • 利用OPENCV为android开发畸变校正的JNI库方法

    需要为项目提供一套畸变校正的算法,由于需要大量的矩阵运算,考虑到效率和适时性,使用JNI开发,希望把有关数组短阵的处理的变换全部放入C语言中处理。

    砸漏
  • 解决nginx/apache静态资源跨域访问问题详解

    #LoadModule headers_module modules/mod_headers.so

    砸漏
  • 融合之下的想象:影视众筹的未来在哪?

    孟永辉
  • 微信小程序引用we-cropper裁切图片

    文档地址 github下载源码直达链接 复制dist文件夹中的 .min.js 和 .wxml文件到项目中

    wePanda
  • 0819-使用CDP7.1.3的Atlas采集CDH5.15.1的元数据和血缘

    基于以上框架,使用CDP的Atlas采集CDH5的元数据和血缘,理论上只需要将相应的Atlas Hook正确部署到CDH5对应的服务上即可。本文以采集Hive元...

    Fayson
  • SQL练习之不反复执行相同的计算

    下面是Demo所需要的代码: CREATE TABLE Fee ( Income decimal(10,1), overhead decimal(10,1) )...

    郑小超.
  • RecyclerView 刷新闪烁

    code_horse
  • vue的seo问题

    参考 https://www.npmjs.com/package/prerender-spa-plugin https://www.npmjs.com/pack...

    似水的流年
  • iOS开发CoreGraphics核心图形框架之八——层聚合

        正常情况下,在使用CoreGraphics框架中的方法进行图形绘制时,每一闭合的图形都是一个独立的层,如果在绘制时添加了阴影效果,则通过阴影可以很明显的...

    珲少

扫码关注云+社区

领取腾讯云代金券