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

 更新时间:2018年08月04日 15:26:25   作者:BrcLi  
今天小编就为大家分享一篇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方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • android开发教程之时间对话框核心代码

    android开发教程之时间对话框核心代码

    这篇文章主要介绍了android的时间对话框核心代码,需要的朋友可以参考下
    2014-04-04
  • Android基于广播事件机制实现简单定时提醒功能代码

    Android基于广播事件机制实现简单定时提醒功能代码

    这篇文章主要介绍了Android基于广播事件机制实现简单定时提醒功能代码,较为详细的分析了Android广播事件机制及提醒功能的相关实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-10-10
  • Android基础之使用Fragment控制切换多个页面

    Android基础之使用Fragment控制切换多个页面

    Android官方已经提供了Fragment的各种使用的Demo例子,在我们SDK下面的API Demo里面就包含了Fragment的各种使用例子,需要看Demo的朋友,直接看API Demo那个程序就可以了,不用到处去找。里面分开不同功能,实现了不同的类
    2013-07-07
  • Android应用设置独立的多语言实战技巧详解

    Android应用设置独立的多语言实战技巧详解

    这篇文章主要为大家介绍了Android应用设置独立的多语言实战技巧详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 微信Android热更新Tinker使用详解(星空武哥)

    微信Android热更新Tinker使用详解(星空武哥)

    Tinker是微信官方的Android热补丁解决方案,它支持动态下发代码、So库以及资源,让应用能够在不需要重新安装的情况下实现更新。当然,你也可以使用Tinker来更新你的插件
    2017-09-09
  • Android Studio 配置忽略文件的方法实现

    Android Studio 配置忽略文件的方法实现

    这篇文章主要介绍了Android Studio 配置忽略文件的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • 真正的android程序入口

    真正的android程序入口

    android程序的真正入口是Application类的onCreate方法,使用示例如下
    2014-02-02
  • Activity生命周期与启动模式图文解说

    Activity生命周期与启动模式图文解说

    这篇文章主要介绍了Activity生命周期与启动模式图文解说,内容比较详细,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Android实现RecyclerView下拉刷新效果

    Android实现RecyclerView下拉刷新效果

    这篇文章主要为大家详细介绍了Android实现RecyclerView下拉刷新效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • Android项目实现视频播放器

    Android项目实现视频播放器

    这篇文章主要为大家详细介绍了Android项目实现视频播放器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03

最新评论