【图像处理】-小议YUV色彩空间-YUV和RGB格式的来由,相互关系以及转换方式,并对编程实现的YUV转为RGB程序进行介绍

news2024/11/24 3:23:29

小议YUV色彩空间
摘要:
在视频图像处理等相关相关领域,YUV是一个经常出现的格式。本文主要以图解的资料形式详细描述YUV和RGB格式的来由,相互关系以及转换方式,并对编程实现的YUV转为RGB程序进行介绍。
1 引言
自然界的颜色千变万化,为了给颜色一个量化的衡量标准,就需要建立色彩空间模型来描述各种各样的颜色,由于人对色彩的感知是一个复杂的生理和心理联合作用的过程,所以在不同的应用领域中为了更好更准确的满足各自的需求,就出现了各种各样的色彩空间模型来量化的描述颜色。我们比较常接触到的就包括 RGB / CMYK / YCbCr/ YUV / HSI等等。
即使只是RGB、 YUV这两大类色彩空间,所涉及到的知识也是十分丰富复杂的,自知具备的相关专业知识有限,所以本文主要针对自己所了解的相关知识以及项目开发中遇到的相关问题对YUV色彩空间相关进行讨论。

2 理论分析
2.1 RGB、YUV色彩空间模型介绍
RGB与YUV有着千丝万缕的联系与区别,其中RGB是按三基色加光系统的原理来描述颜色,而YUV则是按照亮度、色差的原理来描述颜色。
2.1.1 RGB 颜色空间
RGB 颜色空间是我们最常见的颜色空间,是一种简单鲁棒性较好的定义颜色的空间。RGB 颜色空间由红、绿、蓝三个基本颜色通道组成,由这些颜色通道组合代表一种颜色。RGB 颜色模型可以通过一个立方体颜色模型,如图 1 表示,其三个轴分别代表红、绿、蓝 3 个颜色分量。对于一张 24 位真彩色的图片,R、G、B 三个通道各自具有 8 位宽,像素的取值范围为0-255,红色为(255,0,0),绿色为(0,255,0),蓝色为(0,0,255)。
在这里插入图片描述

图 1 RGB颜色模型
2.1.2 YUV颜色空间
在现代彩色电视系统中,通常采用三管彩色摄像机或彩色CCD(点耦合器件)摄像机,它把摄得的彩色图像信号,经分色、分别放大校正得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y、B-Y,最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这就是我们常用的YUV色彩空间。

2.1.2.1 RGB 颜色空间过渡到YUV色彩空间
对于视频捕获和编解码等应用来讲,RGB这样的表示方式数据量太大了。需要想办法在不太影响感觉的情况下,对原始数据的表示方法进行更改,减少数据量。
在RGB色彩空间中,三个颜色的重要程度相同,所以需要使用相同的分辨率进行存储, 3个颜色通道需要按照相同的分辨率进行存储,数据量还是很大的。所以,利用人眼睛对亮度比对颜色更加敏感,将图像的亮度信息和颜色信息分离,并使用不同的分辨率进行存储,这样可以在对主观感觉影响很小的前提下,更加有效的存储图像数据。
YCbCr色彩空间和它的变形(也就是YUV)是最常用的有效的表示彩色图像的方法。Y是图像的亮度(luminance/luma)分量,使用以下公式计算,为R,G,B分量的加权平均值:
Y = kr R + kgG + kbB,其中k是权重因数。
上面的公式计算出了亮度信息,还有颜色信息,使用色差(color difference/chrominance或chroma)来表示,其中每个色差分量为R,G,B值和亮度Y的差值:
  Cb = B -Y Cr = R -Y Cg = G- Y
其中,Cb+Cr+Cg是一个常数(其实是一个关于Y的表达式),所以,只需要其中两个数值结合Y值就能够计算出原来的RGB值。所以,我们仅保存亮度和蓝色、红色的色差值,这就是(Y,Cb,Cr)。
相比RGB色彩空间,YCbCr色彩空间有一个显著的优点。Y的存储可以采用和原来画面一样的分辨率,但是Cb,Cr的存储可以使用更低的分辨率。这样可以占用更少的数据量,并且在图像质量上没有明显的下降。所以,将色彩信息以低于量度信息的分辨率来保存是一个简单有效的图像压缩方法。
注释:YCbCr进行不同的取样就是所谓的YUV了。

2.1.2.2 YUV与RGB相互转换
YUV 空间和RGB空间存在如下转换关系:
在这里插入图片描述

注释:
1、从公式中,我们关键要理解的一点是,UV / CbCr信号实际上就是蓝色差信号和红色差信号,进而言之,实际上一定程度上间接的代表了蓝色和红色的强度,理解这一点对于我们理解各种颜色变换处理的过程会有很大的帮助。
2、我们在数字电子多媒体领域所谈到的YUV格式,实际上准确的说,是以YcrCb色彩空间模型为基础的具有多种存储格式的一类颜色模型的家族(包括YUV444 / YUV422 / YUV420 / YUV420P等等)。并不是传统意义上用于PAL制模拟电视的YUV模型。这些YUV模型的区别主要在于UV数据的采样方式和存储方式

2.2 RGB、YUV色彩空间模型内存分布
在RGB24格式中,对于宽度为w,高度为h的画面,需要wh3个字节来存储其每个像素的rgb信息,画面的像素数据是连续排列的。按照r(0,0),g(0,0),b(0,0);r(0,1),g(0,1),b(0,1);…;r(w-1,0),g(w-1,0),b(w-1,0);…;r(w-1,h-1),g(w-1,h-1),b(w-1,h-1)这样的顺序存放起来。
在YUV格式中,以YUV420格式为例。宽度为w高度为h的画面,其亮度Y数据需要wh个字节来表示(每个像素点一个亮度)。而Cb和Cr数据则是画面中4个像素共享一个Cb,Cr值。这样Cb用wh/4个字节,Cr用wh/4个字节。
YUV文件中,把多个帧的画面连续存放。就是YUV YUV YUV……这样的不断连续的形式,而其中每个YUV,就是一幅画面。
在这单个YUV中,前w
h个字节是Y数据,接着的wh/4个字节是Cb数据,再接着的wh/4个字节为Cr数据。

2.3 RGB、YUV色彩空间模型数据表达方式
以320240的一帧图像为例RGB24的排列方式如下图所示:
每个像素点有三个字节组成分别表示R,G,B分量上的颜色值。在数据中的表示方式为一个像素 一个像素表示。字节流可以表述如下:
BGRBGRBGRBGRBGR……
|---------------320
2403-------|
每一个字母表示一个字节,也就是该颜色分量的数值,相邻的三个BGR字节表示一个像素点。在我们做计算时,通常一次取三个字节,也就是一个像素点。
相应的YV12的排列方式如下图所示:
每个像素点都有一个Y分量,每隔一列就有一个U或者V分量,U和V交替出现。YV12的字节流表示方式和RGB24有很大区别,YV12并不是按照像素依次排列的,而是先放置Y空间,然后放置整个V空间,最后放置U空间,那么字节流如下所示:
YYYYYYY……VVVV……UUUU……
|-----320
240----|-320240/4-|-320240/4-|
在320240个字节的Y后,紧跟着320240/4个V和320240/4个U。
YV12和RGB24同样都有320
240个像素点,但是在数据结构和字节流上有着很大区别。单纯从数据大小来看,RGB24的数据大小为3202403Bytes,而YV12为3202401.5Bytes,可见YV12的数据量为RGB24的一半。

2.4 YCbCr色彩空间模型取样格式
对YCbCr色彩空间,进行不同格式的取样就得到不同的YUV格式了,如下图3所示。
在这里插入图片描述

2.5 RGB、YUV色彩空间模型转换示例
核心编程示例
//RGB转YUV
bool RGB2YUV(byte* RgbBuf,int nWidth,int nHeight,byte* yuvBuf,unsigned long len)
{
int i, j;
byte
bufY, *bufU, *bufV, *bufRGB,bufYuv;
memset(yuvBuf,0,(unsigned int )len);//len表示yuvBuf长度(WH3/2)
bufY = yuvBuf;//Y首址
bufV = yuvBuf + nWidth * nHeight;//V首址
bufU = bufV + (nWidth * nHeight
1/4);//U首址
*len = 0;
byte y, u, v, r, g, b,testu,testv;
unsigned int ylen = nWidth * nHeight; //Y长度
unsigned int ulen = (nWidth * nHeight)/4;//U长度
unsigned int vlen = (nWidth * nHeight)/4; //V长度

for (j = 0; j < nHeight;j++)
{
	bufRGB = RgbBuf + nWidth * (nHeight - 1 - j) * 3 ;
	for (i = 0;i < nWidth;i++)
	{
		int pos = nWidth * i + j;
		r = *(bufRGB++);
		g = *(bufRGB++);
		b = *(bufRGB++);

		y = (byte)( ( 66 * r + 129 * g +  25 * b + 128) >> 8) + 16  ;          
		u = (byte)( ( -38 * r -  74 * g + 112 * b + 128) >> 8) + 128 ;          
		v = (byte)( ( 112 * r -  94 * g -  18 * b + 128) >> 8) + 128 ;
		*(bufY++) = max( 0, min(y, 255 ));
		if (j%2==0&&i%2 ==0)
		{	//存u分量
			if (u>255){u=255;}
			if (u<0){u = 0;}
			*(bufU++) =u;
		}
		else
		{
			//存v分量
			if (i%2==0)
			{ if (v>255){v = 255;}
			  if (v<0){v = 0;}

*(bufV++) =v;
}
}
}
}
*len = nWidth * nHeight+(nWidth * nHeight)/2;
return true;
}

//YUV4转RGB
static void YUV420p_to_RGB24(unsigned char *yuv420[3], unsigned char *rgb24, int width, int height)
{
int R,G,B,Y,U,V,x,y;
int nWidth = width>>1; //色度信号宽度
for (y=0;y<height;y++)
{
for (x=0;x<width;x++)
{
Y = (yuv420[0] + ywidth + x);
U = (yuv420[1] + ((y>>1)nWidth) + (x>>1));
V = (yuv420[2] + ((y>>1)nWidth) + (x>>1));
R = Y + 1.402
(V-128);
G = Y - 0.34414
(U-128) - 0.71414
(V-128);
B = Y + 1.772
(U-128);
//防止越界
if (R>255)R=255;if (R<0)R=0;
if (G>255)G=255;if (G<0)G=0;
if (B>255)B=255;if (B<0)B=0;
*(rgb24 + ((height-y-1)*width + x)*3) = B;
*(rgb24 + ((height-y-1)*width + x)*3 + 1) = G;
*(rgb24 + ((height-y-1)*width + x)*3 + 2) = R;
}
}
}

2.4 RGB、YUV色彩空间模型转换示例实验结果
为了验证转换的效果,从RGB色彩空间转换到YUV420色彩空间再转换到RGB色彩空间,结果如下图4所示。

在这里插入图片描述

                      图4 RGB与YUV转换结果图

从上图看出,转换的效果还是可以的,部分地方出现色彩失真,算法还需优化。
3 结语
在视频监控领域,YUV是一个经常出现的格式。本文主要以图解的资料形式详细描述YUV和RGB格式的来由,相互关系以及转换方式,并对编程实现的YUV转为RGB程序进行介绍。

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

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

相关文章

AI算力报告:算力大时代,AI算力产业链全景梳理

今天分享的是AI算力专题系列深度研究报告&#xff1a;《算力大时代&#xff0c;AI算力产业链全景梳理》。 &#xff08;报告出品方&#xff1a;中信建投证券&#xff09; 报告共计&#xff1a;98页 核心观点 生成式 AI取得突破&#xff0c;我们对生成式 A 带来的算力需求做…

AI预测体彩排3第1弹【2024年4月12日预测--第1套算法开始计算第1次测试】

前面经过多个模型几十次对福彩3D的预测&#xff0c;积累了一定的经验&#xff0c;摸索了一些稳定的规律&#xff0c;有很多彩友让我也出一下排列3的预测结果&#xff0c;我认为目前时机已成熟&#xff0c;且由于福彩3D和体彩排列3的玩法完全一样&#xff0c;我认为3D的规律和模…

6.基础乐理-升降号、黑键的音名

首先需要先了解音乐中的两个符号&#xff0c;升号和降号&#xff0c;升号的符号像#&#xff0c;降号的符号像b&#xff0c;如下图&#xff1a; 升号表示升高到相邻的音&#xff0c;降号表示降低到相邻的音&#xff0c;现在首先要知道音是有高低的&#xff0c;在钢琴键盘上从左到…

ZGC的介绍

背景 在jdk17中已经将ZGC从实验性产品升级到正式产品功能&#xff0c;达到亚毫秒级停顿&#xff0c;毫不留情地将parallel和G1拉开了数量级的差别&#xff0c;无论是平均停顿还是最大停顿时间都能毫不费劲地控制在10ms内。 《深入理解Java虚拟机》在书中这样定义&#xff1a;Z…

String类(2)

❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&…

【日常记录】【JS】使用Number.prototype.toLocaleString 对 数字做 格式化

文章目录 1、引言2、语法参数3、常见案例4、参考链接 1、引言 在目前的项目中&#xff0c;经常需要给数字做格式化处理&#xff0c;特别是财务方面&#xff0c;比如分割成千分位&#xff0c;保留小数&#xff0c;增加符号等 &#xff0c;这些都需要我们手写一些函数来处理。 但…

Vue.js组件精讲 第2章 基础:Vue.js组件的三个API:prop、event、slot

如果您已经对 Vue.js 组件的基础用法了如指掌&#xff0c;可以跳过本小节&#xff0c;不过当做复习稍读一下也无妨。 组件的构成 一个再复杂的组件&#xff0c;都是由三部分组成的&#xff1a;prop、event、slot&#xff0c;它们构成了 Vue.js 组件的 API。如果你开发的是一个…

TechTool Pro for Mac v19.0.3中文激活版 硬件监测和系统维护工具

TechTool Pro for Mac是一款专为Mac用户设计的强大系统维护和故障排除工具。它凭借全面的功能、高效的性能以及友好的操作界面&#xff0c;赢得了广大用户的信赖和好评。 软件下载&#xff1a;TechTool Pro for Mac v19.0.3中文激活版 作为一款专业的磁盘和系统维护工具&#x…

大数据入门之如何利用Phoenix访问Hbase

在大数据的世界里&#xff0c;HBase和Phoenix可谓是一对黄金搭档。HBase以其高效的列式存储和强大的数据扩展能力&#xff0c;成为大数据存储领域的佼佼者&#xff1b;而Phoenix则以其SQL化的操作方式&#xff0c;简化了对HBase的访问过程。今天&#xff0c;就让我们一起看看如…

哲学家带你实现单链表

最近本哲♂学家学习了链表这一新的数据结构&#xff0c;接下来由我带领大家实现链表&#xff1a; 一 、头文件 注&#xff1a;本写法是无头的单链表&#xff0c;所以传参为二级指针。 我们事先写好所要完成的函数&#xff0c;在 .c文件中进一步去完成。 typedef int SLTData…

19(20)-1(3)-CSS3 平面 2D 变换+CSS3 过渡

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍一、CSS3 平面 2D 变换&#x1f48e;1 坐标轴&#x1f48e;2 transform 语法…

云原生数据库海山(He3DB)PostgreSQL版核心设计理念

本期深入解析云原生数据库海山PostgreSQL版&#xff08;以下简称“He3DB”&#xff09;的设计理念&#xff0c;探讨在设计云原生数据库过程中遇到的工程挑战&#xff0c;并展示He3DB如何有效地解决这些问题。 He3DB是移动云受到 Amazon Aurora 论文启发而独立自主设计的云原生数…

【学习】Spring IoCDI

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 Spring 是什么&#xff1f; 什么是 IoC容器&#xff1f; 传统开发模式 loC开发模式 IoC的优势 IoC 的使用 Bean的…

策略为王股票软件源代码-----如何修改为自己软件04

上面是如何打开-------类---------函数 1. 数据结构 1) 股票数据结构的定义在头文件Src\StkLib\Include\Stock.h中,主要的几个结构定义为: KDATA K线数据结构 DRDATA 除权数据结构 REPORT 交易所在交易时间内不断发送的报价信息 MINUTE 分钟成交…

最大连续1的个数 III

题目链接 最大连续1的个数 III 题目描述 注意点 nums[i] 不是 0 就是 10 < k < nums.length 解答思路 创建一个滑动窗口&#xff0c;保证窗口内翻转0的个数始终不大于k&#xff0c;不断移动窗口的右边界&#xff0c;有以下三种情况&#xff1a; 当右边界的值为1&…

Java基础第十课——类与对象(1)

前面二白的九讲属于Java基础方面的内容&#xff0c;总体来说偏基础和简单&#xff0c;能完成的操作也有限&#xff0c;有兴趣的同学可以写一写相关的管理系统&#xff0c;后面二白也会上传一些自己敲的小系统&#xff0c;下面就要开始Java面对对象的知识内容了&#xff0c;从这…

【年度典型案例】扫码就能领补贴?通知社保在线速办?当心是钓鱼骗局!

随着我们生活的数字化程度越来越高&#xff0c;完成各种业务和服务变得前所未有的便捷。只需轻轻一点手机屏幕&#xff0c;我们办事儿变得飞快又方便。然而&#xff0c;正当我们享受这种数字化带来的便捷时&#xff0c;一些不法分子也在暗中伺机而动&#xff0c;利用各种手段制…

c# refc# substring c# 反射c# split c# websocket c# datatable使用

在C#编程中&#xff0c;ref关键字、Substring方法、反射&#xff08;Reflection&#xff09;、Split方法、WebSocket通信以及DataTable的使用都是常见的技术和方法。下面我将逐一为您详解这些内容。 1. C# ref关键字 ref关键字在C#中用于按引用传递参数。这意味着当您将变量作…

PC-lint 学习之配置方法

1. 下载PC-lint 9.0后&#xff0c;点击pclint9setup.exe进行安装&#xff08;我只安装了C/C语言&#xff0c;其他语言可安装时选择&#xff09; 2.安装完成后&#xff0c;打开keil5&#xff0c;选择配置 3. 配置选项 &#xff08;1&#xff09;Lint Executable&#xff1a;在第…

基于SpringBoot+Vue+Mysql的图书管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…