YUV420笔记

news2025/2/12 10:56:24

YUV420 有YU12、YV12、NV12、NV21

YU12存储格式是

YU12存储格式是YU13中的UV顺序反过来

 

NV12存储格式是 

NV21是NV12数据取反

YUV420_888

是YCbCr的泛化格式,不会具体指明是YU12,YV12,NV12,或是是NV21。它能够表示任何4:2:0的平面和半平面格式.

Image.Plane[] planes = image.getPlanes();

planes[0] 总是Y ,planes[1] 总是U(Cb), planes[2]总是V(Cr)

 pixelStride(通过getPixelStride()获得):像素步长,有可能是1、有可能是2。它代表的是行内连续两个颜色值之间的距离(步长)。

rowStride:(通过getRowStride()获得)“每行数据”的“宽度”,这个跟分辨率的宽度不是同个回事,它是每一行实际存储的宽度

width和height 代表分辨率

buffer size 这个主要就是plane数组的大小,一般就通过plane[i].length获取即可。

(1)、Planar格式(P):
        1、先看一下6*4的假设图片:

         plane[0]的pixelStride是1,说明没有间隔,Y是连续的,rowStride是6,也就是每行6个,length数量是24,24/6 = 4,共4行。

        plane[1]的pixelStride也是1,说明没有间隔,U是连续的,rowStride是3,也就是每行3个,length数量是6,6/3 = 2,共2行,符合YUV420的情况,横纵都是2:1采样。

        plane[2]与plane[1]相同。

        这种其实就是YUV420P的标准格式,跟我们期望的差不多,不用做多解析,直接按照这样将y、u、v分别取出,即是正确的数据。可惜的是,目前测到的手机大部分不是这样的格式,而是下面要介绍的这类SP的情况出现的多一些。

(2)、Semi-Planar格式(SP):
        还是先看一下6*4的假设图片:

        plane[0]的pixelStride是1,说明没有间隔,Y是连续的,rowStride是6,也就是每行6个,length数量是24,24/6 = 4,共4行。这个Y分量跟Planar格式是一样的。

        plane[1]的pixelStride是2,说明有间隔,U是间隔采取的,这里就回到上面我们分析的两个参数的时候,当pixelStride为2的时候,在U分量中,就会间隔插入了V分量,因此每一行由本来是Y的一半也就是3,变成了6(也就是rowStride的值)。同时就像上面分析的一样,会放弃掉最后一个无意义的V分量,所以就lenght会看到是6*2-1=11的,行数还是2,纵向是不变的。

        plane[2]与plane[1]相同。

        对于这种Semi-Planar格式的,安卓提供的这种方式确实就让人很意向不到,在这种格式下,其实我们有几种取数据方式,首先Y是完整的,直接取即可。对于UV分量可以有2种方式:

        I、plane[1]中以索引0,2,4间隔方式去取U分量,plane[2]中以索引0,2,4间隔方式去取V分量,这样就取到了最准确的U和V分量;

        II、我们其实可以看到,在plane[1]中其实就包含了U和V分量了,只不过丢掉了最后一个V,对于人眼来说,少点一个V,是完全没有影响的。因此其实可以直接拿plane[1]的数据,就拿到U和V。plane[2]同理其实也是有V和U,那么这样的话,其实就可以plane[0] + plane[1] 可得NV12格式;或者plane[0] + plane[2] 可得NV21格式。

        Semi-Planar格式在大多数手机中会经常出现,经过上面的分析也能理解为什么U和V的rowStride会和Y一样,而不是一半。以及为什么U和V的数量最后会少一个分量的原因。

(3)、特殊情况:
        rowStride除了有P和SP格式而导致不同之外,它其实还有一个重要的作用,就是在一些特殊的摄像头sensor采集的时候,因为芯片处理器要字节对齐取数据而导致的补齐操作等等原因,可能就有点类似之前的文章中视频相关的一些基本概念的stride。

        我们举个例子,比如还是图像是6*4的,但是由于某些原因,相机输出的时候,假如rowStride+2了,如下:

        plane[0]的pixelStride是1,说明没有间隔,Y是连续的,rowStride本来应该是6,但是这里是8,后面补了两个空的字节,也就是每行8个,length数量是32,32/8 = 4,共4行。这里分析的时候可以这样判断,getWidth()和getHeight()获取到是6和4,6*4是24,发现32与24不对应,就可以初步判断是有补齐的情况了。而Y的rowStride是8,比getWidth()的6多了2,也就可以推测是每行补齐了2个字节。

        这样的话在取数据的时候,就需要每行都去丢弃最后的2个空字节。同理plane[1]和plane[2]也是类似。因此对于这类特殊的camera,我们需要根据pixelStride和rowStride与分辨率的关系,去进行一些特殊的处理才行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/645815.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序实现订阅消息推送的实现步骤

1、准备工作 准备小程序账号、开发环境,我小程序是基于uniapp开发,后台代码基于SpringBoot开发。同时先阅读官方文档,了解小程序订阅消息和后端如何发送订阅消息等相关知识,官方文档地址如下: 《小程序订阅消息》《发…

【C++】4.websocket:websocketpp安装与使用

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍websocketpp的安装与使用。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷…

【Java】《On Java》第12章 集合 读书笔记

结合JavaGuide和《On Java》的集合笔记。 不要使用时代的眼泪Vector、HashTable、Stack。 文章目录 1 泛型与类型安全的集合2 基本概念3 添加一组元素★4 集合的打印5 ListtoArray的使用 ★Collection.sort的使用 6 ArrayList6.1 ArrayList成员变量6.2 ArrayList构造函数6.3 A…

没有公网IP,如何实现数据共享?

数据共享就是让在不同地方使用不同计算机、不同软件的用户能够读取他人数据并进行各种操作、运算和分析。不同层次、不同部门信息系统间,信息和信息产品的交流与共用,就是把信息这一种在互联网时代中重要性越趋明显的资源与其他人共同分享。 数据共享有…

SpeechGen:用提示解锁语音语言模型(Speech LM)的生成能力

论文链接: https://arxiv.org/pdf/2306.02207.pdf Demo: https://ga642381.github.io/SpeechPrompt/speechgen.html Code: https://github.com/ga642381/SpeechGen 引言与动机 大型语言模型 (LLMs)在人工智能生成内容(AIGC…

手动渲染农场和自助云渲染农场的区别

手动渲染农场和自助云渲染农场是两种常见的渲染方式,它们各有优缺点。手动渲染农场指的是在本地使用自己的硬件设备进行渲染,而自助云渲染农场则是利用云服务商提供的计算资源进行渲染。对于需要渲染大规模项目的设计师或工作室来说,选择一种…

网络安全主要学些什么比较重要

网络安全学什么? 第一阶段:基础 入门的第一步是学习当下的一些主流的安全工具和配套的原理基础 第二阶段:学习基础知识 这个阶段的时候对网络安全就有了基本的了解,通过第一步的学习,理论上的知识一定都明白了&…

Python精美图快速上手

seaborn是一个基于Python的数据可视化库,它建立在Matplotlib之上,提供了一种更简单、更美观的方式来创建统计图形。seaborn旨在帮助用户轻松地生成有吸引力和信息丰富的可视化结果。 以下是seaborn库的一些主要特点: 美观的默认样式&#xf…

获取jar包所在路径位置,项目文件夹Path

获取jar包所在路径位置,项目文件夹位置 方法1 new ApplicationHome().getDir().getPath();方法1就是调用了方法2 System.getProperty("user.dir") System.getProperty("user.dir")String源码👇 private File findHomeDir(File source) {File…

Python 标准库 - 并发执行

Python 标准库 - 并发执行 1. 简单介绍2. 程序示例2.1 threading 编程示例2.2 multiprocessing 编程示例2.3 concurrent.futures 编程示例 1. 简单介绍 Python 标准库 非常庞大,所提供的组件涉及范围十分广泛,官方参考链接https://docs.python.org/zh-cn…

【sentinel】令牌桶算法在Sentinel中的应用

令牌桶算法 令牌桶算法介绍 令牌桶算法,又称token bucket。 从图中我们可以看到,令牌桶算法比漏桶算法稍显复杂。首先,我们有一个固定容量的桶,桶里存放着令牌(token)。桶一开始是空的,token以…

【深度学习】0-2 深度学习相关数学概念的简单总结-概率与信息论

样本空间 样本空间是一个实验或随机试验所有可能结果的集合,随机试验中的每个可能结果称为样本点。例如投掷一个骰子,那么样本空间就是{1,2,3,4,5,6}。 随机变量 随机变量,顾名思义…

IDEA全局设置JDK、Maven、编码格式

本机已安装JDK版本: 本机已安装Maven版本: 一、IDEA设置全局JDK设置 File---->New Projects Settings---->Structure for New Projects... 先将本地安装的JDK添加到SDK 将项目SDK设置为刚刚添加的本地JDK版本 File---->New Projects Settings-…

Webstorm 加载vue项目时,特别卡顿,完美解决。觉得有用加好友打赏

觉得有用加好友打赏:QQ:854138497 上图cpu直接干满。 根据上图提示,直接 disable hints,或者到下图的settings里面设置。 Code vision取消后,webstorm 明显就不卡了。记得重启webstorm。 还有一种方式,根…

完美解决MacOS关于ld: library not found for -lnetcdff错误

1. 问题描述 在使用Intel版本的Mac编译某个程序时出现了错误,显示如下图。 说明:libnetcdff是netcdf的Fortran的接口,如下ChatGPT解释。 2. 出现的原因 原因是Makefile中定义的静态库链接并没有在系统默认的库路径下找到,默认…

Jmeter HTTP Cookie管理器的使用

目录 前言: 1、在HTTP信息头管理器组件中添加Cookie信息 (1)测试计划内包含的元件 (2)请求取样器内容 (3)HTTP信息头管理器内容 (4)查看结果 2、使用HTTP Cookie管…

你想知道的 MySQL 性能调优方式,都在这里

前言:对于性能测试来说,数据库的监控是尤为的重要,以及对数据库进行调优,用以提升性能,是能在短期内有显著的效果的,本文针对MySQL数据库进行分析如何定位MySQL数据库的性能问题。 关键 MySQL 统计指标 如…

一张软考系统架构设计师证书到底能证明了什么?

软考证书证明你考过了软考高级架构,拥有了评高级职称的资格! 证书的作用还有: 1、以考代评:软考证书可以用来评职称 2、积分落户:可用于积分落户,加相应的分,软考高级职业资格都几乎可以直接…

Tinker 组件修复,踩坑

1、You need to use a Theme.AppCompat theme (or descendant) with this activity. 复现步骤 补丁加载成功之后重启应用,再退出应用重进闪退 日志 TinkerUncaughtHandler catch exception:java.lang.IllegalStateException: You need to use a Theme.AppCompat th…

Cesium教程(十七):淹没分析

Cesium教程(十七):淹没分析 1、什么是淹没分析 淹没分析是根据某片区域的地形及洪水流量速度,动态模拟该地形区域水位逐渐上涨的淹没过程。该功能可适用于山区、丘陵等地形起伏较大区域,模拟洪水涨到安全限定高度的淹没过程,为防洪水救灾提供一定的参考。此外,还可以为河…