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

小议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程序进行介绍。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# Solidworks二次开发:模型中实体Entity相关操作API详解

大家好&#xff0c;今天要讲的一些API是关于实体的相关API。 在开发的过程&#xff0c;很多地方会涉及到实体的相关操作&#xff0c;比如通过实体选中节点。下面就直接开始介绍API&#xff1a; &#xff08;1&#xff09;第一个API为Select4&#xff0c;这个API的含义为选中一…

编译器领域一些特别好的文章

xz​​​​​​​s​​​​​​​cv_note/cv算法工程师成长路线.md at master HarleysZhang/cv_note GitHub记录cv算法工程师的成长之路&#xff0c;分享计算机视觉和模型压缩部署技术栈笔记。https://harleyszhang.github.io/cv_note/ - cv_note/cv算法工程师成长路线.md at…

Llama2模型本地部署(Mac M1 16G)

环境准备 环境&#xff1a;Mac M1 16G、Conda Conda创建环境配置 使用Anaconda-Navigator创建python 3.8环境 切换到新建的conda环境&#xff1a; conda activate llama38 llama.cpp 找一个目录&#xff0c;下载llama.cpp git clone https://github.com/ggerganov/llama.…

【汇编】计算机系统构成

计算机系统构成 计算机系统包括硬件和软件两部分 硬件 典型的计算机结构包括 中央处理器(CPU)、存储器和输入输出(I/O)子系统 三个主要组成部分&#xff0c;用系统总线把它们连接在一起 计算机硬件组成与各部分之间的联系 软件 计算机软件可以分为系统软件和用户软件两大类 …

​​​​网络编程学习探索系列之——广播原理剖析

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的网络编程系列之广播原理剖析&#xff0c;在这篇文章中&#xff0c; 你将会学习到如何在网络编程中利用广播来与局域网内加入某个特定广播组的主机&#xff01; 希望这篇文章能对你有所帮助&#xff0c;大家要是觉得我写…

集运公司代购系统|轻松为国外客户代购转运中国电商平台货物

做集运的公司会有大量的在国外的客户&#xff0c;客户会有需求购买中国电商平台&#xff0c;如淘宝、1688、京东等的货物。使用代购系统可以实现让客户在系统中搜索查找国内电商平台的货源&#xff0c;自动下单付款&#xff0c;支持多语言多货币支付。 查看演示网站 前台/会员中…

常用组合逻辑电路模块(3):数据选择器

数据选择器概述 数据选择&#xff1a;指经过选择&#xff0c;将多路数据中的某一路数据传到公共数据线上。(相当于多个输入的单刀多掷开关) 数据选择器&#xff1a;能实现数据选择功能的逻辑电路。也称多路选择器或多路开关。如下图为4选1数据选择器&#xff1a; 对于4选1数据…

电大搜题:为您解锁学习的新大门

近年来&#xff0c;随着社会的不断进步和教育的普及化&#xff0c;广大民众对学习的需求也越来越迫切。在这个信息爆炸的时代&#xff0c;大家对于获取准确、可靠学习资料的渴望日益增长。正是基于这样的背景&#xff0c;黑龙江开放大学&#xff08;简称黑开大&#xff09;与广…

Linux学习_进程等待和替换

1.进程等待 概述&#xff1a;父进程通过进程等待的方式&#xff0c;回收子进程资源&#xff0c;获取子进程退出信息 1.1等待方法 wait&#xff1a; #include<sys/types.h> #include<sys/wait.h> pid_t wait(int*status); 返回值&#xff1a; 成功返回被等待进程…

【MATLAB基础】频谱分析

01.引言 频率是单位时间内某事件重复发生的次数,用ω表示,单位是赫兹(Hz)。设m时间内某事件重复发生n次,则此事件发生的频率ω为一。又因为周期定义为重复事件发生的最小时间间隔,故频率也可以表示为周期的倒数:ωn/m,T表示周期。频率是一个很重要的概念,在工程数学中常用于分…

BST:一款功能强大的二进制字符串代码格式转换工具

关于BST BST是一款功能强大的二进制字符串代码格式转换工具&#xff0c;该工具可以将二进制字符串转换为能够兼容不同语言源代码的各种格式&#xff0c;以满足各种安全开发领域中的渗透测试或漏洞利用开发场景。 功能介绍 1、将二进制文件转换并转储为二进制字符串格式的标准输…

leaflet 显示地图加载的瓦片的行列号

背景&#xff1a; 在开发过程中&#xff0c;对接wmts服务的时候&#xff0c;调试参数过程中有时候需要直观看到当前地图加载的瓦片的行列号。 实现原理&#xff1a; 利用Leaflet的L.GridLayer图层&#xff0c;加载一个网格图层&#xff0c;重写其createTile方法&#xff0c;…

开源AI图像识别:支持文件批量识别快速对接数据库存储

随着数字化转型的不断深入&#xff0c;图像识别技术在各行各业中的应用越来越广泛。文件封识别作为图像识别技术的一个分支&#xff0c;能够有效地提高文件处理的自动化程度和准确性。本文将探讨文件封识别技术的原理、应用场景以及如何将识别后的内容批量对应数据库字段进行存…

Blast生态借贷协议Pac Finance陷“清算”风波,兄弟项目ParaSpace曾上演内斗

Blast生态协议又出事了。4月11日晚间&#xff0c;有用户发现借贷协议Pac Finance上出现了大量ezETH清算&#xff0c;涉及金额达2400 万美元。官方回应称&#xff0c;系一位智能合约工程师的操作导致Pac Finance发行清算阈值在没有事先通知团队的情况下被意外更改。 目前社区内…

dPET论文笔记

PBPK论文笔记 题目&#xff1a;Self-supervised Learning for Physiologically-Based Pharmacokinetic Modeling in Dynamic PET 摘要 动态正电子发射断层扫描成像 &#xff08;dPET&#xff09; 提供示踪剂的时间分辨图像。从 dPET 中提取的时间活动曲线 &#xff08;TAC&a…

办公提效-截图录屏

使用感受:滚动截图,目前用着pixpin最方便,简单可控制,有点类似qq截图。faststone容易在长截图出错,显示重复,而share X截不了大模型聊天记录。 我的办公工作流-截图录屏:pixpin截图且识别、录屏gif格式,faststone录屏成mp4格式,截图提取文字技术为OCR文字识别,短截图…

C语言基础:回顾判断素数

什么是素数&#xff08;也称质数&#xff09;&#xff1f;和合数相对。 其特点是只能被 1 和它本身 整除&#xff0c;无法被其他整数整除。或者公因数只有它自己和1两个数的数 怎么求解素数呢&#xff1f;对于求解质数的方法很多&#xff0c;但是有一种专门求解素数的功能&am…

Harmony鸿蒙南向外设驱动开发-Camera

功能简介 OpenHarmony相机驱动框架模型对上实现相机HDI&#xff08;Hardware Device Interface&#xff09;接口&#xff0c;对下实现相机Pipeline模型&#xff0c;管理相机各个硬件设备。 该驱动框架模型内部分为三层&#xff0c;依次为HDI实现层、框架层和设备适配层。各层基…

python--对象序列化和反序列化以及with语句块的使用

1.对象序列化和反序列化 对象序列化&#xff1a;将对象这种抽象概念转化为可以传输存储的物理概念 对象反序列化&#xff1a;将磁盘或者网络间的物理数据转化为对应的编程语言的对象 对象持久化&#xff1a;将对象永久的存储下来 对相反持久化&#xff1a; 将磁盘上永久存储…

Spring启动流程和循环依赖

文章目录 概览对Spring的理解Spring启动流程Spring循环依赖与三级缓存 概览 Spring是一个轻量级的Java开源框架&#xff0c;为了解决企业应用开发的复杂性而创建的。Spring的核心是控制反转&#xff08;IOC&#xff09;和面向切面&#xff08;AOP&#xff09;。 简单来说&…