首页 > 图灵资讯 > 技术篇>正文

yuv rgb 互转 公式 及算法

2023-05-04 10:31:54

 

1 前言
2 YUV相关色彩空间模型2.11 YUV 与 YIQ YcrCb
Y=0.30R+0.59G+0.11B , U=0.493(B-Y) , V=0.877(R-Y)
3 YUV2RGB快速算法分析

YUV实际上是YCRCB。YUV2RGB的转换公式本身非常简单,但它涉及到浮点操作。因此,如果要实现快速算法,算法结构本身就没有什么可研究的,主要采用整形操作或检查表来加快计算速度。 首先,可以推导转换公式如下:

R = Y + 1.4075 *(V-128) G = Y – 0.3455 *(U –128) – 0.7169 *(V –128)

3.1 整型算法
u = YUVdata[UPOS] - 128;               rdif = v + ((v * 103) >> 8);         invgdif = ((u * 88) >> 8) +((v * 183) >> 8);              r = YUVdata[YPOS] + rdif;        g = YUVdata[YPOS] - invgdif;

为防止溢出,还需要判断错误计算结果是否在0-255范围内,做出以下类似的判断。

if (r>255)              r=255;        if (r<0)                            RGBdata[1] =( (r & 0xF8) | ( g >> 5) );
3.2 部分查表法
rdif = fac_1_4075[u];         invgdif = fac_m_0_3455[u] + fac_m_0_7169[v];
3.3 完全查表法
y = (YUVdata[Y1POS] >> 2);         u = (YUVdata[UPOS] >> 2);         v = (YUVdata[VPOS] >> 2);         r = yv2r_table[ y ][ v ];         g = yig2g_table[ y ][ uv2ig_table[ u ][ v ] ];         b = yu2b_table[ y ][ u ];        RGBdata[1] =( (r & 0xF8) | ( g >> 5) );
3.4 进一步思考

RGBdata[1] =( (r & 0xF8) | ( g >> 5) );

4 RGB2YUV ?

以下是从DirectShow中提取的相关文章

计算机彩色显示器显示颜色的原理与彩色电视相同,采用R(Red)、G(Green)、B(Blue)混色原理:通过发射三种不同强度的电子束,使屏幕内覆盖的红、绿、蓝磷光材料发光产生颜色。这种颜色表示方法称为RGB颜色空间表示(也是多媒体计算机技术中使用最多的颜色空间表示方法)。 根据三基色原理,任何色光F都可以使用不同重量的R、G、B三色混合而成。

F = r [ R ] + g [ G ] + b [ B ]

其中,r、g、b是三基色参与混合系数。当三基色分量为0(最弱)时,混合为黑光;当三基色分量为k(最强)时,混合为白光。调整r、g、b三个系数的值,可以混合介于黑光和白光之间的各种色光。 那YUV又从何而来?在现代彩色电视系统中,通常使用三管彩色摄像头或彩色CCD摄像头进行摄像头,然后通过分色、放大和校正获得RGB,然后通过矩阵变换电路获得亮度信号Y和两个色差信号R-Y(即U)、B-Y(即V),最后发送端分别编码亮度和色差三个信号,并通过同一信道发送。表示这种颜色的方法是所谓的YUV颜色空间表示。 使用YUV色空间的重要性是其亮度信号Y和色度信号U、V是分离的。如果只有Y信号重量而没有U信号重量、V重量,那么这样表示的图像就是黑白灰度图像。YUV空间用于解决彩色电视与黑白电视的兼容性问题,使黑白电视也能接收彩色电视信号。 YUV与RGB相互转换的公式如下(RGB取值范围为0-255):

Y = 0.299R + 0.587G + 0.114B U = -0.147R - 0.289G + 0.436B V = 0.615R - 0.515G - 0.100B

R = Y + 1.14V G = Y - 0.39U - 0.58V B = Y + 2.03U

在Directshow中,RGB1是RGB1的常见RGB格式、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;YUV的常见格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。作为视频媒体类型的辅助描述类型(Subtype),它们对应的GUID见表2.3。

表2.3 常见的RGB和YUV格式

GUID 格式描述 MEDIASUBTYPE_RGB1 2色,每个像素用1位表示,需要调色板 MEDIASUBTYPE_RGB4 16色,每个像素用4位表示,需要调色板 MEDIASUBTYPE_RGB8 256色,每个像素用8位表示,需要调色板 MEDIASUBTYPE_RGB565 每个像素用16位表示,RGB分别用5位、6位、5位表示 MEDIASUBTYPE_RGB555 每个像素用16位表示,RGB分量用5位(其余1位不用) MEDIASUBTYPE_RGB24 每个像素用24位表示,RGB分量使用8位 MEDIASUBTYPE_RGB32 每个像素用32位表示,RGB分量使用8位(剩下的8位不用) MEDIASUBTYPE_ARGB32 每个像素用32位表示,RGB分量使用8位(剩下的8位用于表示Alpha通道值) MEDIASUBTYPE_YUY2 YUY2格式,以4:2:2方式打包 MEDIASUBTYPE_YUYV YUYV格式(实际格式与YUY2相同) MEDIASUBTYPE_YVYU YVYU格式,4:2:2方式打包 MEDIASUBTYPE_UYVY UYVY格式,以4:2:2方式打包 MEDIASUBTYPE_AYUV 带Alpha通道的4:4:4 YUV格式 MEDIASUBTYPE_Y41P Y41P格式,以4:1:1方式打包 MEDIASUBTYPE_Y411 Y411格式(实际格式与Y41P相同) MEDIASUBTYPE_Y211 Y211格式 MEDIASUBTYPE_IF09 IF09格式 MEDIASUBTYPE_IYUV IYUV格式 MEDIASUBTYPE_YV12 YV12格式 MEDIASUBTYPE_YVU9

以下是各种RGB格式的介绍。

¨ RGB1、RGB4、RGB8是调色板类型的RGB格式。在描述这些媒体类型的格式细节时,通常会在BITMAPINFOHEADER数据结构后面跟随一个调色板(定义一系列颜色)。它们的图像数据不是真正的颜色值,而是当前像素颜色值在调色板中的索引。以RGB1(2色位图)为例。例如,其调色板中定义的两种颜色值依次为0x00000(黑色)和0xffff(白色),因此图像数据001101010111...(每个像素用1位表示)表示相应像素的颜色为:黑、黑、白、黑、白、黑、白、白。

¨ RGB565用16位表示一个像素,其中5位用于R,6位用于G,5位用于B。一个单词通常在程序中使用(WORD,一个字等于两个字节)来操作像素。读完一个像素后,这个词的各位意义如下: 高字节 低字节 R R R R R G G G G G G B B B B B 可结合屏蔽字和移位操作获得RGB各分量的值:

#define RGB565_MASK_RED 0xF800 #define RGB565_MASK_GREEN 0x07E0 #define RGB565_MASK_BLUE 0x001F R = (wPixel & RGB565_MASK_RED) >> 11; // 取值范围0-31 G = (wPixel & RGB565_MASK_GREEN) >> 5; // 取值范围0-63 B = wPixel & RGB565_MASK_BLUE;

¨ RGB555是另一种16位RGB格式,RGB的重量由5位表示(其余1位不使用)。用一个词读出一个像素后,这个词的每个意思如下: 高字节 低字节 X R R R R G G G G G B B B B B (X说不,可以忽略) 可结合屏蔽字和移位操作获得RGB各分量的值:

#define RGB555_MASK_RED 0x7C00 #define RGB555_MASK_GREEN 0x03E0 #define RGB555_MASK_BLUE 0x001F R = (wPixel & RGB555_MASK_RED) >> 10; // 取值范围0-31 G = (wPixel & RGB555_MASK_GREEN) >> 5; // 取值范围0-31 B = wPixel & RGB555_MASK_BLUE;

¨ RGB24使用24位表示一个像素,RGB分量用8位表示,取值范围为0-255。内存中RGB分量的排列顺序如下:BGR BGR BGR...RGBTRIPLE数据结构通常用于操作像素,定义为:

typedef struct tagRGBTRIPLE { BYTE rgbtBlue; // 蓝色分量 BYTE rgbtGreen; // 绿色分量 BYTE rgbtRed; // 红色分量 } RGBTRIPLE;

¨ RGB32使用32位来表示一个像素,RGB分量分别使用8位,其余8位用于Alpha通道或不使用。(ARGB32是带Alpha通道的RGB32。)内存中注意RGB分量的排列顺序如下:BGRA BGRA BGRA...RGBQUAD数据结构通常用于操作像素,其定义为:

typedef struct tagRGBQUAD { BYTE rgbBlue; // 蓝色分量 BYTE rgbGreen; // 绿色分量 BYTE rgbRed; // 红色分量 BYTE rgbReserved; // 保留字节(作为Alpha通道或忽略) } RGBQUAD;

以下是各种YUV格式的介绍。通常有两种类型的YUV格式:包装(packed)格式和平面(planar)格式。前者将YUV的重量存储在同一数组中,通常由几个相邻的像素组成宏像素(macro-pixel);后者用三个数组分别存储YUV的三个重量,就像一个三维平面。表2.3中的YUY2至Y211均为包装格式,而IF09至YVU9均为平面格式。(注:在介绍各种具体格式时,YUV的每个重量都会下标,比如Y0、U0、V0表示YUV的第一像素重量,Y1、U1、V1表示第二像素的YUV重量,以此类推。)

¨ YUY2(和YUYV)格式为每个像素保留Y重量,而UV重量在水平方向上每两个像素采样一次。一个宏像素有四个字节,实际上表示两个像素。(4:2:2是指一个宏像素中有4个Y分量、2个U分量和2个V分量。)图像数据中YUV分量的排列顺序如下: Y0 U0 Y1 V0

¨ YVYU格式与YUY2相似,但YUV分量在图像数据中的排列顺序不同: Y0 V0 Y1 U0

¨ UYVY格式类似于YUY2,但YUV重量在图像数据中的排列顺序不同: U0 Y0 V0 Y1

¨ AYUV格式有Alpha通道,为每个像素提取YUV重量,图像数据格式如下: A0 Y0 U0 V0

¨ Y41P(和Y411)格式为每个像素保留Y重量,而UV重量在水平方向上每四个像素采样一次。一个宏像素有12个字节,实际上表示8个像素。YUV在图像数据中的重量排列顺序如下: U0 Y0 V0 Y1 U4 Y2 V4 Y3

¨ Y211格式在水平方向上每两个像素采样一次,而UV分量每四个像素采样一次。一个宏像素有四个字节,实际上表示四个像素。图像数据中YUV的重量排列顺序如下: Y0 U0 Y2 V0

¨ YVU9格式为每个像素提取Y分量,当提取UV分量时,图像首先被分成几个4 x 4宏块,然后每个宏块提取一个U重量和一个V重量。存储图像数据时,首先是整个图像的Y重量数组,然后是U重量数组和V重量数组。IF09格式类似于YVU9。

¨ IYUV格式为每个像素提取Y分量,当提取UV分量时,图像首先被分成几个2 x 2宏块,然后每个宏块提取一个U分量和一个V分量。YV12格式类似于IYUV。

¨ YUV411、YUV420格式多见于DV数据,前者用于NTSC,后者用于PAL。YUV411为每个像素提取Y分量,而UV分量在水平方向上每四个像素采样一次。YUV420不是V重量采样为0,而是与YUV411相比,水平方向的色差采样频率增加了一倍,垂直方向的色差采样减少了U/V间隔的一半

上一篇 字节面试:项目中,什么地方用到了多线程?
下一篇 LeetCode面试题:反转链表 II

文章素材均来源于网络,如有侵权,请联系管理员删除。