• 生活就是这样,需要去灌溉!
    • 谢谢您的关注,欢迎您的注册与写作!
    • 循环往复,生生不息,或许这就是生命的意义吧!生命是插曲的产品吧!
    • 古今多少事,都付笑言中!
    • 风住尘香花已尽,日晚倦梳头。物是人非事事休,欲语泪先流。
    • 闻说双溪春尚好,也拟泛轻舟,只恐双溪舴艋舟,载不动许多愁。

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

Resources 柳叶扉鸿 来源:CSDN:rabbit729 5年前 (2020-09-18) 3169次浏览 已收录 扫描二维码
内容目录

 *******************************************************

关于 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 每像素位数 Description
AYUV 0x56555941 32 YUV 和 alpha 结合
CLJR 0x524A4C43 8 Cirrus Logic 格式,其中 4 个像素封装在 u_int32 中。

YUV 4:1:1 的形式,每个 Y、U、V 样本的位数少于 8 位。

cyuv 0x76757963 16 本质上是 UYVY 的副本,除了高度感相反-图像

相对于 UYVY 版本而言是上下颠倒的。

GREY 0x59455247 8 显然是 Y800(也可能是“ Y8”)的副本
IRAW 0x57615349 ? 英特尔未压缩的 YUV。
IUYV 0x56595549 16 LEAD Technologies 的 Silviu Brinzei 注册的

UYVY 的隔行版本(行顺序 0\2\4,…,1\3\5 …)。

IY41 0x31345949 12 I 由 LEAD Technologies 的 Silviu Brinzei 注册的

Y41P 的隔行扫描版本(行顺序 0\2\4,…,1\3\5 …)。

IYU1 0x31555949 12 IEEE 1394 数码相机 1.04 规范的模式 2 中使用的 12 位格式。

相当于 Y411

IYU2 0x32555949 24 IEEE 1394 数码相机 1.04 规范的模式 0 中使用的 24 位格式
HDYC 0x43594448 16 YUV 4:2:2(每行 Y 采样,每个像素 U 和 V 在每第二个像素水平采样)。

宏像素在 1 u_int32 中包含 2 个像素。除了颜色分量使用

BT709 色彩空间(用于高清视频)外,这是 UYVY 的一个补充。

UYNV 0x564E5955 16 由 NVidia 注册的 UYVY 的直接副本,

用于解决某些旧编解码器中的问题,

这些编解码器不喜欢提供超过 2 个 UYVY 表面的硬件。

UYVP 0x50565955 24? YCbCr 4:2:2 以 U0Y0V0Y1 的顺序扩展了每个组件的 10 位精度。

由 Evans&Sutherland 的 Rich Ehlers 注册。

UYVY 0x59565955 16 YUV 4:2:2(每行 Y 采样,每个像素 U 和 V 在每第二个像素水平采样)。

宏像素在 1 u_int32 中包含 2 个像素。

V210 0x30313256 32 10 位 4:2:2 YCrCb 等效于同名的 Quicktime 格式。
V422 0x32323456 16 有人告诉我这是 UYVY 的颠倒版本。
V655 0x35353656 16? Vitec Multimedia 注册了 16 位 YUV 4:2:2 格式。

我没有有关组件订购或包装的信息。

VYUY 0x59555956 ? ATI 压缩 YUV 数据(格式未知)
Y422 0x32323459 16 ADS Technologies Pyro WebCam 火线摄像机

使用的 UYVY 的直接副本。

YUY2 0x32595559 16 与 UYVY 相同的 YUV 4:2:2,

但在 u_int32 宏像素内具有不同的组件顺序。

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

This is a 4:4:4 YUV format with 8 bit samples for each component along with an 8 bit alpha blend value per pixel. Component ordering is A Y U V (as the name suggests).

UYVY (and Y422 and UYNV and HDYC)

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)

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

IUYV

IUYV is basically the same as UYVY with the exception that the data is interlaced. Lines are ordered 0,2,4,….,1,3,5…. instead of 0,1,2,3,4,5,….

cyuv

This FOURCC, allegedly registered by Creative Labs, is essentially a duplicate of UYVY. The only difference is that the image is flipped vertically, the first u_int16 in the buffer representing the bottom line of the viewed image. Note that the FOURCC is comprised of lower case characters (so much for the upper case convention !)

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 bottom-up image (botton line first)

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

YUY2 (and YUNV and V422 and YUYV)

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)

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

There is a help page here which contains information on playing AVIs which include video stored in YUY2 format.

YVYU

Despite being a simple byte ordering change from YUY2 or UYVY, YVYU seems to be seen somewhat less often than the other two formats defined above.

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)

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

Y41P

This YUV 4:1:1 format is registered as a PCI standard format. Mediamatics MPEG 1 engine is the only codec (other than a Brooktree internal one) that I know of that can generate it.

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)

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

Y411

I was originally told that this was a duplicate of Y41P however it seems that this is not the case after all. Y411 is a packed YUV 4:1:1 format with a 6 pixel macroblock structure containing 4 pixels. Component packing order is:

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

IY41 is basically the same as Y41P with the exception that the data is interlaced. Lines are ordered 0,2,4,….,1,3,5…. instead of 0,1,2,3,4,5,….

Y211

I have yet to find anything that will output Y211 ! The format looks very much like the missing YUV 4:2:2 ordering but Y samples are only taken on every second pixel. Think of it as a half width 4:2:2 image and double the width on display.

Horizontal Vertical
Y Sample Period 2 1
V Sample Period 4 1
U Sample Period 4 1

Effective bits per pixel : 8

Positive biHeight implies top-down image (top line first)

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

Y41T

This format is identical to Y41P except for the fact that the least significant bit of each Y component forms a chromakey channel. If this bit is set, the YUV image pixel is displayed, if cleared, the pixel is transparent (and the underlying graphics pixel is shown).

Positive biHeight implies top-down image (top line first)

Y42T

This format is identical to UYVY except for the fact that the least significant bit of each Y component forms a chromakey channel. If this bit is set, the YUV image pixel is displayed, if cleared, the pixel is transparent (and the underlying graphics pixel is shown).

Positive biHeight implies top-down image (top line first)

CLJR

Cirrus Logic’s format packs 4 pixel samples into a single u_int32 by sacrificing precision on each sample. Y samples are truncated to 5 bits each, U and V have 6 bits per sample.

Horizontal Vertical
Y Sample Period 1 1
V Sample Period 4 1
U Sample Period 4 1

Effective bits per pixel : 8

Positive biHeight implies top-down image (top line first)

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

IYU1

The IYU1 format is a 12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec (“1394-based Digital Camera Specification, Version 1.04, August 9, 1996”, page 14.). The format, a duplicate of Y411, is YUV (4:1:1) according to the following pattern:

 

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

The IYU2 format is a 24 bit format used in mode 0 of the IEEE 1394 Digital Camera 1.04 spec (ibid.) The format is YUV (4:4:4) according to the following pattern:

 

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

This is another format similar to YUY2 and it’s aliases. The difference here is that each Y, U and V samples is 10 bits rather than 8. I am still waiting to hear how the samples are packed – is a macropixel just 5 bytes long with all the samples packed together or is there more to it than this?

V210

AJA Video Systems have implemented this Quicktime format for Windows. It is a 10 bit per component, YCrCb 4:2:2 format in which samples for 5 pixels are packed into 4 4-byte little endian words. Rather than repeat the details here, I suggest looking at the original definition on the Quicktime web site.

Supposedly there are images described as “YUV10” that are formatted similarly to this aside from the bit ordering (the correspondent mentioned having to run ntoh on the pixel data to reformat from YUV10 to V210. Despite 20 years of C, I’ve not heard of ntoh but I suspect it performs big-endian to little-endian conversion).

Planar YUV Formats

Label FOURCC in Hex Bits per pixel

Description

YVU9 0x39555659 9 8 bit Y plane followed by 8 bit 4×4 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 4×4 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 2×1 subsampled V and U planes.
YV12 0x32315659 12 8 bit Y plane followed by 8 bit 2×2 subsampled V and U planes.
I420 0x30323449 12 8 bit Y plane followed by 8 bit 2×2 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 2×2 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

This format dates back to the days of the ActionMedia II adapter and comprises an NxN plane of Y samples, 8 bits each, followed by (N/4)x(N/4) V and U planes.

Horizontal Vertical
Y Sample Period 1 1
V Sample Period 4 4
U Sample Period 4 4

RGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUV

Positive biHeight implies top-down image (top line first)

ATI has a codec supporting this format that you can download from here.

YUV9

Intel’s web site states that YUV9 is “the color encoding scheme used in Indeo video technology. The YUV9 format stores information in 4×4 pixel blocks. Sixteen bytes of luminance are stored for every 1 byte of chrominance. For example, a 640×480 image will have 307,200 bytes of luminance and 19,200 bytes of chrominance.” This sounds exactly the same as YVU9 to me. Anyone know if there is any difference?

IF09

A derivative of YVU9, IF09 contains the basic 3 planes for Y, V and U followed by an additional (N/4)x(N/4) plane of “skip blocks”. This final plane forms a basic delta encoding scheme which can be used by a displayer to decide which pixels in the image are unchanged from the previous displayed frame. The strange number of bits per pixel listed for the format results from the fact that an NxN image is described using N2+3(N/4)2 bytes.

This format is generated by Intel’s Indeo codecs though users should beware – the original 32 bit Indeo 3.2 shipped with Windows 95 and the beta levels of Indeo 4.1 contain bugs which cause them to generate protection faults when using IF09. Fixed versions of these codecs are available from Intel.

Horizontal Vertical
Y Sample Period 1 1
V Sample Period 4 4
U Sample Period 4 4

RGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUV

Positive biHeight implies top-down image (top line first)

Delta plane definition

To be completed…

YV12

This is the format of choice for many software MPEG codecs. It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.

Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 2
U Sample Period 2 2

RGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUV

Positive biHeight implies top-down image (top line first)

ATI says they have a download which contains this codec but I can’t find it on their site. If you would like something similar for Quicktime, try here.

YV16

This format is basically a version of YV12 with higher chroma resolution. It comprises an NxM Y plane followed by (N/2)xM U and V planes.

Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 1
U Sample Period 2 1

IYUV and I420

These formats are identical to YV12 except that the U and V plane order is reversed. They comprise an NxN Y plane followed by (N/2)x(N/2) U and V planes. Full marks to Intel for registering the same format twice and full marks to Microsoft for not picking up on this and rejecting the second registration.

(Note: There is some confusion over these formats thanks to the definitions on Microsoft’s site which tend to suggest that the two FOURCCs are different. One is described as a 4:2:0 format while the other is described as 4:1:1. Later, however, the same page states that YV12 is the same as both of these with the U and V plane order reversed. I would consider 4:2:0 to imply 1 chroma sample for every 2×2 luma block and 4:1:1 to imply 1 chroma sample for every 4×1 luma block but it seems as if the Microsoft writer may have been using the terms interchangeably. If you know these formats, please could you let me know whether the definition here is correct or whether I need to update one or other?)

Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 2
U Sample Period 2 2

RGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUV

Positive biHeight implies top-down image (top line first)

CLPL

This format introduces an extra level of indirection in the process of accessing YUV pixels in the surface. Locking the DirectDraw or DCI CLPL surface returns a pointer which itself points to three other pointers. These pointers respectively point to an NxN Y plane, an (N/2)x(N/2) U plane and an (N/2)x(N/2) V plane. The Y plane pointer retrieved is (allegedly) valid even when the surface is subsequently unlocked but the U and V pointers can only be used with a lock held (as you should be doing anyway if adhereing to the DirectDraw/DCI spec).

Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 2
U Sample Period 2 2

RGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUVRGB、YUY2、YUYV、YVYU、UYVY与AYUV

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

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

Y16

This format contains only a single, 16 bit Y plane for monochrome images. Each pixel is represented by a 16 bit, little endian luminance sample.

Horizontal Vertical
Y Sample Period 1 1
V Sample Period N/A N/A
U Sample Period N/A N/A

RGB、YUY2、YUYV、YVYU、UYVY与AYUV

NV12

YUV 4:2:0 image with a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2×2 subsampled colour difference samples.

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

YUV 4:2:0 image with a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2×2 subsampled chroma samples. The same as NV12 except the interleave order of U and V is reversed.

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

RGB、YUY2、YUYV、YVYU、UYVY与AYUVSimilar to YV12, this format comprises an NxN Y plane followed by (N/2)x(N/2) U and V planes. The U and V planes have the same stride as the Y plane and are restricted to start on 16 line boundaries.

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

RGB、YUY2、YUYV、YVYU、UYVY与AYUVSimilar to YV12, this format comprises an NxN Y plane followed by “rectangularly adjacent” (N/2)x(N/2) U and V planes. Lines of U and V pixels are interleaved at half stride boundaries below the Y plane.

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

 

YUY2(YUV) To RGB:

C = Y – 16

D = U – 128

E = V – 128

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 之间.

 

RGB To YUY2(YUV):

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


柳叶扉鸿 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明RGB、YUY2、YUYV、YVYU、UYVY与AYUV
相关文章
喜欢 (2)