RGB、YUY2、YUYV、YVYU、UYVY与AYUV
最近项目中用到了好多YUV格式相关的东西,在网上找了一些资料,整理如下:
计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用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空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。
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中,常见的RGB格式有RGB1、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 YVU9格式
下面分别介绍各种RGB格式。
¨RGB1、RGB4、RGB8都是调色板类型的RGB格式,在描述这些媒体类型的格式细节时,通常会在BITMAPINFOHEADER数据结构后面跟着一个调色板(定义一系列颜色)。它们的图像数据并不是真正的颜色值,而是当前像素颜色值在调色板中的索引。以RGB1(2色位图)为例,比如它的调色板中定义的两种颜色值依次为0x000000(黑色)和0xFFFFFF(白色),那么图像数据001101010111…(每个像素用1位表示)表示对应各像素的颜色为:黑黑白白黑白黑白黑白白白…。
RGB565使用16位表示一个像素,这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; // 取值范围0-31
¨ 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; // 取值范围0-31
¨ 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 BGRABGRA…。通常可以使用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个像素。(4:2:2的意思为一个宏像素中有4个Y分量、2个U分量和2个V分量。)图像数据中YUV分量排列顺序如下:
Y0 U0 Y1 V0 Y2 U2 Y3 V2 …
¨ YVYU格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
Y0 V0 Y1 U0 Y2 V2 Y3 U2 …
¨ UYVY格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
U0 Y0 V0 Y1 U2 Y2 V2 Y3 …
¨ AYUV格式带有一个Alpha通道,并且为每个像素都提取YUV分量,图像数据格式如下:
A0 Y0 U0 V0 A1 Y1 U1 V1 …
¨ Y41P(和Y411)格式为每个像素保留Y分量,而UV分量在水平方向上每4个像素采样一次。一个宏像素为12个字节,实际表示8个像素。图像数据中YUV分量排列顺序如下:
U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y8 …
¨ Y211格式在水平方向上Y分量每2个像素采样一次,而UV分量每4个像素采样一次。一个宏像素为4个字节,实际表示4个像素。图像数据中YUV分量排列顺序如下:
Y0 U0 Y2 V0 Y4 U4 Y6 V4 …
¨ 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分量在水平方向上每4个像素采样一次。YUV420并非V分量采样为0,而是跟YUV411相比,在水平方向上提高一倍色差采样频率,在垂直方向上以U/V间隔的方式减小一半色差采样。
关于YUV格式的详细介绍及内存排布方式如下:
YUV formats fall into two distinct groups, the packed formats where Y, U (Cb) and V (Cr) samples are packed together into macropixels which are stored in a single array, and the planar formats where each component is stored as a separate array, the final image being a fusing of the three separate planes.
In the diagrams below, the numerical suffix attached to each Y, U or V sample indicates the sampling position across the image line, so, for example, V0 indicates the leftmost V sample and Yn indicates the Y sample at the (n+1)th pixel from the left.
Subsampling intervals in the horizontal and vertical directions may merit some explanation. The horizontal subsampling interval describes how frequently across a line a sample of that component is taken while the vertical interval describes on which lines samples are taken. For example, UYVY format has a horizontal subsampling period of 2 for both the U and V components indicating that U and V samples are taken for every second pixel across a line. Their vertical subsampling period is 1 indicating that U and V samples are taken on each line of the image.
For YVU9, though, the vertical subsampling interval is 4. This indicates that U and V samples are only taken on every fourth line of the original image. Since the horizontal sampling period is also 4, a single U and a single V sample are taken for each square block of 16 image pixels.
Also, if you are interested in YCrCb to RGB conversion, you may find this page helpful.
People reading this page may be interested in a freeware codec from Drastic Technologies which allegedly handles the vast majority of YUV formats listed here. I've not tried it but you can find it here.
Packed YUV Formats
Label | FOURCC in Hex | Bits per pixel | Description |
AYUV | 0x56555941 | 32 | Combined YUV and alpha |
CLJR | 0x524A4C43 | 8 | Cirrus Logic format with 4 pixels packed into a u_int32. A form of YUV 4:1:1 wiht less than 8 bits per Y, U and V sample. |
cyuv | 0x76757963 | 16 | Essentially a copy of UYVY except that the sense of the height is reversed - the image is upside down with respect to the UYVY version. |
GREY | 0x59455247 | 8 | Apparently a duplicate of Y800 (and also, presumably, "Y8 ") |
IRAW | 0x57615349 | ? | Intel uncompressed YUV. I have no information on this format - can you help? |
IUYV | 0x56595549 | 16 | Interlaced version of UYVY (line order 0, 2, 4,....,1, 3, 5....) registered by Silviu Brinzei of LEAD Technologies. |
IY41 | 0x31345949 | 12 | Interlaced version of Y41P (line order 0, 2, 4,....,1, 3, 5....) registered by Silviu Brinzei of LEAD Technologies. |
IYU1 | 0x31555949 | 12 | 12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec. This is equivalent to Y411 |
IYU2 | 0x32555949 | 24 | 24 bit format used in mode 0 of the IEEE 1394 Digital Camera 1.04 spec |
HDYC | 0x43594448 | 16 | YUV 4:2:2 (Y sample at every pixel, U and V sampled at every second pixel horizontally on each line). A macropixel contains 2 pixels in 1 u_int32. This is a suplicate of UYVY except that the color components use the BT709 color space (as used in HD video). |
UYNV | 0x564E5955 | 16 | A direct copy of UYVY registered by NVidia to work around problems in some old codecs which did not like hardware which offered more than 2 UYVY surfaces. |
UYVP | 0x50565955 | 24? | YCbCr 4:2:2 extended precision 10-bits per component in U0Y0V0Y1 order. Registered by Rich Ehlers of Evans & Sutherland.(Awaiting confirmation of component packing structure) |
UYVY | 0x59565955 | 16 | YUV 4:2:2 (Y sample at every pixel, U and V sampled at every second pixel horizontally on each line). A macropixel contains 2 pixels in 1 u_int32. |
V210 | 0x30313256 | 32 | 10-bit 4:2:2 YCrCb equivalent to the Quicktime format of the same name. |
V422 | 0x32323456 | 16 | I am told that this is an upside down version of UYVY. |
V655 | 0x35353656 | 16? | 16 bit YUV 4:2:2 format registered by Vitec Multimedia. I have no information on the component ordering or packing. |
VYUY | 0x59555956 | ? | ATI Packed YUV Data (format unknown but you can get hold of a codec supporting it here) |
Y422 | 0x32323459 | 16 | Direct copy of UYVY as used by ADS Technologies Pyro WebCam firewire camera. |
YUY2 | 0x32595559 | 16 | YUV 4:2:2 as for UYVY but with different component ordering within the u_int32 macropixel. |
YUYV | 0x56595559 | 16 | Duplicate of YUY2 |
YUNV | 0x564E5559 | 16 | A direct copy of YUY2 registered by NVidia to work around problems in some old codecs which did not like hardware which offered more than 2 YUY2 surfaces. |
YVYU | 0x55595659 | 16 | YUV 4:2:2 as for UYVY but with different component ordering within the u_int32 macropixel. |
Y41P | 0x50313459 | 12 | YUV 4:1:1 (Y sample at every pixel, U and V sampled at every fourth pixel horizontally on each line). A macropixel contains 8 pixels in 3 u_int32s. |
Y411 | 0x31313459 | 12 | YUV 4:1:1 with a packed, 6 byte/4 pixel macroblock structure. |
Y211 | 0x31313259 | 8 | Packed YUV format with Y sampled at every second pixel across each line and U and V sampled at every fourth pixel. |
Y41T | 0x54313459 | 12 | Format as for Y41P but the lsb of each Y component is used to signal pixel transparency . |
Y42T | 0x54323459 | 16 | Format as for UYVY but the lsb of each Y component is used to signal pixel transparency . |
YUVP | 0x50565559 | 24? | YCbCr 4:2:2 extended precision 10-bits per component in Y0U0Y1V0 order. Registered by Rich Ehlers of Evans & Sutherland. |
Y800 | 0x30303859 | 8 | Simple, single Y plane for monochrome images. |
Y8 | 0x20203859 | 8 | Duplicate of Y800 as far as I can see. |
Y16 | 0x20363159 | 16 | 16-bit uncompressed greyscale image. |
AYUV
UYVY (and Y422 and UYNV andHDYC)
UYVY is probably the most popular of the various YUV 4:2:2 formats. It is output as the format of choice by the Radius Cinepak codec and is often the second choice of software MPEG codecs after YV12.
Y422 and UYNV appear to be direct equivalents to the original UYVY.
HDYC is equivalent in layout but pixels are described using the BT709 color space as used in HD video systems rather than the BT470 SD video color space typically used. Apparently there is a description in the DeckLink DirectShow SDK documentation at http://blackmagic-design.com/support/software/archive/, find DeckLink SDK 5.6.2 for Windows XP and download http://blackmagic-design.com/support/software/register.asp?softID=108, set product to None, serial no is not required), see "Video Formats" section.
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 1 |
U Sample Period | 2 | 1 |
Effective bits per pixel : 16
Positive biHeight implies top-down imge (top line first)
IUYV
cyuv
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 1 |
U Sample Period | 2 | 1 |
Positive biHeight implies bottom-up image (botton line first)
YUY2 (andYUNV and V422 andYUYV)
YUY2 is another in the family of YUV 4:2:2 formats and appears to be used by all the same codecs as UYVY.
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 1 |
U Sample Period | 2 | 1 |
Effective bits per pixel : 16
Positive biHeight implies top-down image (top line first)
There is a help page here which contains information on playing AVIs which include video stored in YUY2 format.
YVYU
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 1 |
U Sample Period | 2 | 1 |
Positive biHeight implies top-down image (top line first)
Y41P
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 4 | 1 |
U Sample Period | 4 | 1 |
Positive biHeight implies top-down image (top line first)
Y411
U2 Y0 Y1 V2 Y2 Y3
I have not been able to find 100% confirmation of the position for the U and V samples. I suspect that the chroma samples are probably both taken at the position of Y2 but this is a guess just now.
I have recently been informed that this format is identical to IYU1.
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 4 | 1 |
U Sample Period | 4 | 1 |
Effective bits per pixel : 12
Positive biHeight implies top-down image (top line first)
IY41
Y211
Horizontal | Vertical | |
Y Sample Period | 2 | 1 |
V Sample Period | 4 | 1 |
U Sample Period | 4 | 1 |
Positive biHeight implies top-down image (top line first)
Y41T
Positive biHeight implies top-down image (top line first)
Y42T
Positive biHeight implies top-down image (top line first)
CLJR
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 4 | 1 |
U Sample Period | 4 | 1 |
Positive biHeight implies top-down image (top line first)
IYU1
Byte | 0 | 1 | 2 | 3 | 4 | 5 |
Sample | U(K+0) | Y(K+0) | Y(K+1) | V(K+0) | Y(K+2) | Y(K+3) |
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 4 | 1 |
U Sample Period | 4 | 1 |
IYU2
Byte | 0 | 1 | 2 | 3 | 4 | 5 |
Sample | U(K+0) | Y(K+0) | V(K+0) | U(K+1) | Y(K+1) | V(K+1) |
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 1 | 1 |
U Sample Period | 1 | 1 |
YUVP
V210
Planar YUV Formats
Label | FOURCC in Hex | Bits per pixel |
Description |
YVU9 | 0x39555659 | 9 | 8 bit Y plane followed by 8 bit 4x4 subsampled V and U planes. Registered by Intel. |
YUV9 | 0x39565559 | 9? | Registered by Intel., this is the format used internally by Indeo video code |
IF09 | 0x39304649 | 9.5 | As YVU9 but an additional 4x4 subsampled plane is appended containing delta information relative to the last frame. (Bpp is reported as 9) |
YV16 | 0x36315659 | 16 | 8 bit Y plane followed by 8 bit 2x1 subsampled V and U planes. |
YV12 | 0x32315659 | 12 | 8 bit Y plane followed by 8 bit 2x2 subsampled V and U planes. |
I420 | 0x30323449 | 12 | 8 bit Y plane followed by 8 bit 2x2 subsampled U and V planes. |
IYUV | 0x56555949 | 12 | Duplicate FOURCC, identical to I420. |
NV12 | 0x3231564E | 12 | 8-bit Y plane followed by an interleaved U/V plane with 2x2 subsampling |
NV21 | 0x3132564E | 12 | As NV12 with U and V reversed in the interleaved plane |
IMC1 | 0x31434D49 | 12 | As YV12 except the U and V planes each have the same stride as the Y plane |
IMC2 | 0x32434D49 | 12 | Similar to IMC1 except that the U and V lines are interleaved at half stride boundaries |
IMC3 | 0x33434D49 | 12 | As IMC1 except that U and V are swapped |
IMC4 | 0x34434D49 | 12 | As IMC2 except that U and V are swapped |
CLPL | 0x4C504C43 | 12 | Format similar to YV12 but including a level of indirection. |
Y41B | 0x42313459 | 12? | Weitek format listed as "YUV 4:1:1 planar". I have no other information on this format. |
Y42B | 0x42323459 | 16? | Weitek format listed as "YUV 4:2:2 planar". I have no other information on this format. |
Y800 | 0x30303859 | 8 | Simple, single Y plane for monochrome images. |
Y8 | 0x20203859 | 8 | Duplicate of Y800 as far as I can see. |
CXY1 | 0x31595843 | 12 | Awaiting clarification of format. |
CXY2 | 0x32595842 | 16 | Awaiting clarification of format. |
YVU9
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 4 | 4 |
U Sample Period | 4 | 4 |
Positive biHeight implies top-down image (top line first)
ATI has a codec supporting this format that you can download from here.
YUV9
IF09
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 4 | 4 |
U Sample Period | 4 | 4 |
Positive biHeight implies top-down image (top line first)
Delta plane definition
To be completed...
YV12
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 2 |
U Sample Period | 2 | 2 |
Positive biHeight implies top-down image (top line first)
YV16
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 1 |
U Sample Period | 2 | 1 |
IYUV and I420
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 2 |
U Sample Period | 2 | 2 |
Positive biHeight implies top-down image (top line first)
CLPL
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | 2 | 2 |
U Sample Period | 2 | 2 |
Positive biHeight implies top-down image (top line first)
Y800
This format contains only a single, 8 bit Y plane for monochrome images. Apparent duplicate FOURCCs are "Y8" and "GREY".
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | N/A | N/A |
U Sample Period | N/A | N/A |
Y16
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V Sample Period | N/A | N/A |
U Sample Period | N/A | N/A |
NV12
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V (Cr) Sample Period | 2 | 2 |
U (Cb) Sample Period | 2 | 2 |
Microsoft defines this format as follows:
"A format in which all Y samples are found first in memory as an array of unsigned char with an even number of lines (possibly with a larger stride for memory alignment), followed immediately by an array of unsigned char containing interleaved Cb and Cr samples (such that if addressed as a little-endian WORD type, Cb would be in the LSBs and Cr would be in the MSBs) with the same total stride as the Y samples. This is the preferred 4:2:0 pixel format."
NV21
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V (Cr) Sample Period | 2 | 2 |
U (Cb) Sample Period | 2 | 2 |
Microsoft defines this format as follows:
"The same as NV12, except that Cb and Cr samples are swapped so that the chroma array of unsigned char would have Cr followed by Cb for each sample (such that if addressed as a little-endian WORD type, Cr would be in the LSBs and Cb would be in the MSBs)."
IMC1
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V (Cr) Sample Period | 2 | 2 |
U (Cb) Sample Period | 2 | 2 |
Microsoft defines this format as follows:
"The same as YV12, except that the stride of the Cb and Cr planes is the same as the stride in the Y plane. The Cb and Cr planes are also restricted to fall on memory boundaries that are a multiple of 16 lines (a restriction that has no effect on usage for the standard formats, since the standards all use 16×16 macroblocks)."
IMC2
Horizontal | Vertical | |
Y Sample Period | 1 | 1 |
V (Cr) Sample Period | 2 | 2 |
U (Cb) Sample Period | 2 | 2 |
Microsoft defines this format as follows:
"The same as IMC1, except that Cb and Cr lines are interleaved at half-stride boundaries. In other words, each full-stride line in the chrominance area starts with a line of Cr, followed by a line of Cb that starts at the next half-stride boundary. (This is a more address-space-efficient format than IMC1, cutting the chrominance address space in half, and thus cutting the total address space by 25%.) This runs a close second in preference relative to NV12, but NV12 appears to be more popular."
IMC3
The same as IMC1 except for swapping the U and V order.
IMC4
The same as IMC2 except for swapping the U and V order.
CXY1
Planar YUV 4:1:1 format registered by Conexant. Awaiting clarification of pixel component ordering.
CXY2
Planar YUV 4:2:2 format registered by Conexant. Awaiting clarification of pixel component ordering.
*******************************************************
YUY2(YUV) 与 RGB 格式图片的相互转换 以及 基于YUY2(YUV)的blending
YUY2经常用于电视制式以及许多摄像头的输出格式.而我们在处理时经常需要将其转化为RGB进行处理,这里简单介绍下YUY2(YUV)与RGB之间相互转化的关系:
http://msdn2.microsoft.com/en-us/library/ms893078.aspx
R = clip(( 298 * C + 409 * E + 128) >> 8) G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) B = clip(( 298 * C + 516 * D + 128) >> 8)
其中 clip()为限制函数,将其取值限制在0-255之间.
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16 U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128 V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128上述两个公式在代码中的 int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB); int RGB2YUV(void* pRGB, void* pYUVX, int width, int height, bool alphaYUV, bool alphaRGB); 函数中转换。在诸如摄像头的数据获取中,我们往往需要直接在YUY2(YUV)空间上进行一些图象处理,我们希望能够在YUY2 (YUV)进行一些RGB上可以做到的处理。这里已blending为例,将两张带有透明度的YUY2(YUV)图片进行叠加, 以达到在RGB空间进行图像合成的效果。RGB空间进行图像叠加,通常背景(BG)是不透明的,而前景(FG)是带有透明度的。在RGB空间,可以简单表示为: Rdest = Rfg*alpha + Rbg*(1-alpha); Gdest = Gfg*alpha + Gbg*(1-alpha); Bdest = Bfg*alpha + Bbg*(1-alpha); // Rdest、Gdest、Bdest 为最终合成后的像素值考虑到 Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16 U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128 V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128 我们可以推导出(Ydest-16)<<8 = ((Yfg-16)<<8)*alpha + ((Ybg-16)<<8)*(1-alpha); (Udest-128)<<8 = ((Ufg-128)<<8)*alpha + ((Ubg-128)<<8)*(1-alpha); (Vdest-128)<<8 = ((Vfg-128)<<8)*alpha + ((Vbg-128)<<8)*(1-alpha);从而可以得到 Ydest = (Yfg-16)*alpha + (Ybg-16)*(1-alpha) + 16; Udest = (Ufg-128)*alpha + (Ubg-128)*(1-alpha) + 128; Vdest = (Vfg-128)*alpha + (Vbg-128)*(1-alpha) + 128;这个叠加过程在函数 int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG) 中实现。由于本文针对摄像头采集所得的数据进行处理,因此数据为YUY2格式,即4个字节来表示两个像素点的YUV信息, 排列为Y1 U1 Y2 V2, 对于像素点1为(Y1, U1, V1),像素点2为(Y2, U1, V1)。即两个像素点共用U、V信息。这里假设带有alpha透明度的YUV格式用6个字节来表示两个像素点的YUV以及alpha信息,排列为 Y1 U1 Y2 V1 alpha1 alpha2 其中像素点1为(Y1, U1, V1, alpha1),像素点2为(Y2, U1, V1, alpha2)。其中alpha为对应点的透明度信息。而带有alpha透明度RGB格式的图片,假设为32bits的BMP图片,每个像素点用4bytes来表示,分别为B G R alpha信息。上述函数的具体实现为:
- //
- // YUV2RGB
- // pYUV point to the YUV data
- // pRGB point to the RGB data
- // width width of the picture
- // height height of the picture
- // alphaYUV is there an alpha channel in YUV
- // alphaRGB is there an alpha channel in RGB
- //
- int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB)
- {
- if (NULL == pYUV)
- {
- return -1;
- }
- unsigned char* pYUVData = (unsigned char *)pYUV;
- unsigned char* pRGBData = (unsigned char *)pRGB;
- if (NULL == pRGBData)
- {
- if (alphaRGB)
- {
- pRGBData = new unsigned char[width*height*4];
- }
- else
- pRGBData = new unsigned char[width*height*3];
- }
- int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2;
- int C1, D1, E1, C2;
- if (alphaRGB)
- {
- if (alphaYUV)
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- Y1 = *(pYUVData+i*width*3+j*6); //i*width*3 = i*(width/2)*6
- U1 = *(pYUVData+i*width*3+j*6+1);
- Y2 = *(pYUVData+i*width*3+j*6+2);
- V1 = *(pYUVData+i*width*3+j*6+3);
- alpha1 = *(pYUVData+i*width*3+j*6+4);
- alpha2 = *(pYUVData+i*width*3+j*6+5);
- C1 = Y1-16;
- C2 = Y2-16;
- D1 = U1-128;
- E1 = V1-128;
- R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
- G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
- B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
- R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
- G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
- B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
- *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
- *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
- *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
- *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha1;
- *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
- *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
- *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
- *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha2;
- }
- }
- }
- else
- {
- int alpha = 255;
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- Y1 = *(pYUVData+i*width*2+j*4);
- U1 = *(pYUVData+i*width*2+j*4+1);
- Y2 = *(pYUVData+i*width*2+j*4+2);
- V1 = *(pYUVData+i*width*2+j*4+3);
- C1 = Y1-16;
- C2 = Y2-16;
- D1 = U1-128;
- E1 = V1-128;
- R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
- G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
- B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
- R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
- G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
- B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
- *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
- *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
- *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
- *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha;
- *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
- *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
- *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
- *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha;
- }
- }
- }
- }
- else
- {
- if (alphaYUV)
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- Y1 = *(pYUVData+i*width*3+j*4);
- U1 = *(pYUVData+i*width*3+j*4+1);
- Y2 = *(pYUVData+i*width*3+j*4+2);
- V1 = *(pYUVData+i*width*3+j*4+3);
- C1 = Y1-16;
- C2 = Y2-16;
- D1 = U1-128;
- E1 = V1-128;
- R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
- G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
- B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
- R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
- G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
- B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
- *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
- *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
- *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
- *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
- *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
- *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
- }
- }
- }
- else
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- Y1 = *(pYUVData+i*width*2+j*4);
- U1 = *(pYUVData+i*width*2+j*4+1);
- Y2 = *(pYUVData+i*width*2+j*4+2);
- V1 = *(pYUVData+i*width*2+j*4+3);
- C1 = Y1-16;
- C2 = Y2-16;
- D1 = U1-128;
- E1 = V1-128;
- R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
- G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
- B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
- R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
- G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
- B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
- *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
- *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
- *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
- *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
- *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
- *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
- }
- }
- }
- }
- return 0;
- }
- //
- // RGB2YUV
- // pRGB point to the RGB data
- // pYUV point to the YUV data
- // width width of the picture
- // height height of the picture
- // alphaYUV is there an alpha channel in YUV
- // alphaRGB is there an alpha channel in RGB
- //
- int RGB2YUV(void* pRGB, void* pYUV, int width, int height, bool alphaYUV, bool alphaRGB)
- {
- if (NULL == pRGB)
- {
- return -1;
- }
- unsigned char* pRGBData = (unsigned char *)pRGB;
- unsigned char* pYUVData = (unsigned char *)pYUV;
- if (NULL == pYUVData)
- {
- if (alphaYUV)
- {
- pYUVData = new unsigned char[width*height*3];
- }
- else
- pYUVData = new unsigned char[width*height*2];
- }
- int R1, G1, B1, R2, G2, B2, Y1, U1, Y2, V1;
- int alpha1, alpha2;
- if (alphaYUV)
- {
- if (alphaRGB)
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- B1 = *(pRGBData+(height-i-1)*width*4+j*8);
- G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
- R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
- alpha1 = *(pRGBData+(height-i-1)*width*4+j*8+3);
- B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
- G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
- R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
- alpha2 = *(pRGBData+(height-i-1)*width*4+j*8+7);
- Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
- U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
- Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
- V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
- *(pYUVData+i*width*3+j*6) = Y1;
- *(pYUVData+i*width*3+j*6+1) = U1;
- *(pYUVData+i*width*3+j*6+2) = Y2;
- *(pYUVData+i*width*3+j*6+3) = V1;
- *(pYUVData+i*width*3+j*6+4) = alpha1;
- *(pYUVData+i*width*3+j*6+5) = alpha2;
- }
- }
- }
- else
- {
- unsigned char alpha = 255;
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- B1 = *(pRGBData+(height-i-1)*width*3+j*6);
- G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
- R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
- B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
- G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
- R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
- Y1 = ((66*R1+129*G1+25*B1+128)>>8) + 16;
- U1 = ((-38*R1-74*G1+112*B1+128)>>8+(-38*R2-74*G2+112*B2+128)>>8)/2 + 128;
- Y2 = ((66*R2+129*G2+25*B2+128)>>8) + 16;
- V1 = ((112*R1-94*G1-18*B1+128)>>8 + (112*R2-94*G2-18*B2+128)>>8)/2 + 128;
- Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
- U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
- Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
- V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
- *(pYUVData+i*width*3+j*6) = Y1;
- *(pYUVData+i*width*3+j*6+1) = U1;
- *(pYUVData+i*width*3+j*6+2) = Y2;
- *(pYUVData+i*width*3+j*6+3) = V1;
- *(pYUVData+i*width*3+j*6+4) = alpha;
- *(pYUVData+i*width*3+j*6+5) = alpha;
- }
- }
- }
- }
- else
- {
- if (alphaRGB)
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- B1 = *(pRGBData+(height-i-1)*width*4+j*8);
- G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
- R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
- B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
- G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
- R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
- Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
- U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
- Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
- V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
- *(pYUVData+i*width*2+j*4) = Y1;
- *(pYUVData+i*width*2+j*4+1) = U1;
- *(pYUVData+i*width*2+j*4+2) = Y2;
- *(pYUVData+i*width*2+j*4+3) = V1;
- }
- }
- }
- else
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- B1 = *(pRGBData+(height-i-1)*width*3+j*6);
- G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
- R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
- B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
- G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
- R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
- Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
- U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
- Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
- V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
- *(pYUVData+i*width*2+j*4) = Y1;
- *(pYUVData+i*width*2+j*4+1) = U1;
- *(pYUVData+i*width*2+j*4+2) = Y2;
- *(pYUVData+i*width*2+j*4+3) = V1;
- }
- }
- }
- }
- return 0;
- }
- //
- // pGBYUV point to the background YUV data
- // pFGYUV point to the foreground YUV data
- // width width of the picture
- // height height of the picture
- // alphaBG is there an alpha channel in background YUV data
- // alphaFG is there an alpha channel in fourground YUV data
- //
- int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG)
- {
- if (NULL == pBGYUV || NULL == pFGYUV)
- {
- return -1;
- }
- unsigned char* pBGData = (unsigned char*)pBGYUV;
- unsigned char* pFGData = (unsigned char*)pFGYUV;
- if (!alphaFG)
- {
- if (!alphaBG)
- {
- memcpy(pBGData, pFGData, width*height*2);
- }
- else
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- *(pBGData+i*width*2+j*4) = *(pFGData+i*width*2+j*4);
- *(pBGData+i*width*2+j*4+1) = *(pFGData+i*width*2+j*4+1);
- *(pBGData+i*width*2+j*4+2) = *(pFGData+i*width*2+j*4+2);
- *(pBGData+i*width*2+j*4+3) = *(pFGData+i*width*2+j*4+3);
- }
- }
- }
- }
- int Y11, U11, V11, Y12, Y21, U21, V21, Y22;
- int alpha1, alpha2;
- if (!alphaBG)
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- Y11 = *(pBGData+i*width*2+j*4);
- U11 = *(pBGData+i*width*2+j*4+1);
- Y12 = *(pBGData+i*width*2+j*4+2);
- V11 = *(pBGData+i*width*2+j*4+3);
- Y21 = *(pFGData+i*width*3+j*6);
- U21 = *(pFGData+i*width*3+j*6+1);
- Y22 = *(pFGData+i*width*3+j*6+2);
- V21 = *(pFGData+i*width*3+j*6+3);
- alpha1 = *(pFGData+i*width*3+j*6+4);
- alpha2 = *(pFGData+i*width*3+j*6+5);
- *(pBGData+i*width*2+j*4) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
- *(pBGData+i*width*2+j*4+1) = ((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255 + (U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*2+j*4+3) = ((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255 + (V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*2+j*4+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
- }
- }
- }
- else
- {
- for (int i=0; i<height; ++i)
- {
- for (int j=0; j<width/2; ++j)
- {
- Y11 = *(pBGData+i*width*3+j*6);
- U11 = *(pBGData+i*width*3+j*6+1);
- Y12 = *(pBGData+i*width*3+j*6+2);
- V11 = *(pBGData+i*width*3+j*6+3);
- Y21 = *(pFGData+i*width*3+j*6);
- U21 = *(pFGData+i*width*3+j*6+1);
- Y22 = *(pFGData+i*width*3+j*6+2);
- V21 = *(pFGData+i*width*3+j*6+3);
- alpha1 = *(pFGData+i*width*3+j*6+4);
- alpha2 = *(pFGData+i*width*3+j*6+5);
- *(pBGData+i*width*3+j*6) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
- *(pBGData+i*width*3+j*6+1) = ((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255 + (U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*3+j*6+3) = ((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255 + (V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*3+j*6+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
- }
- }
- }
- return 0;
- }
参考网址:
http://www.cppblog.com/bangle/archive/2009/07/07/89475.html
http://www.fourcc.org/yuv.php
http://blog.csdn.net/jtujtujtu/article/details/3874621
RGB、YUY2、YUYV、YVYU、UYVY与AYUV相关推荐
- RGB、YUY2、YUYV、YVYU、UYVY、AYUV、YUV444、YUV422、YUV420、YUV411
1) YUV 4:4:4YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节.下面的四个像素为: [Y0 ...
- 谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV
计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红.绿.蓝磷光材料发光而产生色彩. ...
- RGB、YUY2、YUYV、YVYU、UYVY、AYUV
小知识:RGB与YUV----摘自<DirectShow实务精选> 作者:陆其明 计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加 ...
- 谈谈“色彩空间表示方法”——RGB、YUY2、YUYV、YVYU、UYVY、AYUV
转自:http://bbs.chinavideo.org/viewthread.php?tid=4143 还可参考http://www.fourcc.org/yuv.php 小知识:RGB与YUV-- ...
- RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解
计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红.绿.蓝磷光材料发光而产生色彩. ...
- matlab yuy2转rgb,YUY2/RGB转换公式
YUY2/RGB转换公式 Y = 0.299 R + 0.587 G + 0.114 B Cb = - 0.1687 R - 0.3313 G + 0.5 B + 128 Cr = 0.5 R - 0 ...
- matlab yuy2转rgb,YUY2转RGB(或BGR)
//YUY2视频转化RGB格式 inline void YUY2_RGB(BYTE *YUY2buff,BYTE *RGBbuff,int dwSize) { //B = 1.164(Y - 16) ...
- YUY2(YUYV)转YUV420源码分析
视频监控,用到ARM11的H.264硬件编码器,由于其要求输入的视频为YUV420格式,所以需要对自己USB摄像头输出的YUY2格式进行转换. YUY2与YUV422内部排列形式一样!理论性分析,可参 ...
- 完成一个YUV文件播放器
前面匆忙写了很多篇文章,虽然都很简单,但着实花了不少时间去研究的.几年前写了YUV转换RGB的代码,当时只限于转换成BMP来测试正确性.后来一直使用YUV Player Deluxe来看YUV文件,但 ...
最新文章
- spring-session用redis实现session共享实践
- voc_eval.py:41: RuntimeWarning: invalid value encountered in greater_equal if np.sum(rec = t) ==
- mysql 5.7.23要钱吗_最新mysql 5.7.23安装配置图文教程
- 【渝粤教育】国家开放大学2018年春季 0034-22T现代管理原理 参考试题
- chart.js x轴显示不全_机床大讲堂第67讲——基于FANUC系统的数控铣床增加第四轴的方法...
- 编程到底该用 Tab 还是 Space?比尔·盖茨也来挑事儿
- ef6 mysql code first_使用EntityFramework6连接MySql数据库(code first方式)
- jquery替换节点
- 网络编程基础知识之单线程与多线程
- ubuntu facebook/C3D视频特征提取
- c语言程序设计实验第二版答案,C语言程序设计实验指导及习题答案
- BeanUtils与PropertyUtils的copyProperties方法的差别
- 1024程序节|Android框架之一 BRVAH【BaseRecyclerViewAdapterHelper】使用demo
- JavaFX的webview下载文件的一种实现思路
- 甲乙丙丁四个人去商店每人买了一台计算机,2016国考行测备考:巧用矛盾速解题...
- springboot自定义启动logo
- 20行Python代码开发植物识别 app
- 学习图神经网络相关内容
- python框架Django数据库类型
- HTML5期末大作业:音乐网站设计——html5在线音乐新闻发布会网站模板(滚动页) HTML+CSS+JavaScript
热门文章
- 计算机桌面开辟一个小桌面,电脑桌面图标异常怎么办,那就自己动手做一个小工具快速修复吧...
- JS案例-仿京东放大镜效果
- 设计模式(10)----策略模式
- Google 的秘密- PageRank 彻底解说 中文版
- Windows ,
- 01背包问题的动态规划求解及其C++实现
- ios触摸超出_iOS开发笔记之多点触控(一)处理触摸的4个方法
- 顾维灏谈百度地图数据采集:POI自动处理率达90%
- 【UE4基础】蓝图使用Media Player播放自定义文件路径的Mp3文件
- python subprocess参数shell=True踩到的坑