1. 程式人生 > >YUY2(YUV) 與 RGB 格式圖片的相互轉換 以及 基於YUY2(YUV)的blending

YUY2(YUV) 與 RGB 格式圖片的相互轉換 以及 基於YUY2(YUV)的blending

YUY2經常用於電視制式以及許多攝像頭的輸出格式.而我們在處理時經常需要將其轉化為RGB進行處理,這裡簡單介紹下YUY2(YUV)與RGB之間相互轉化的關係:

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資訊。

上述函式的具體實現為:


經測試,功能已經實現,如有錯誤或者不妥的地方,懇請指出。
mosesyuan at gmail dot com