彩色空間轉換(RGB與YUV格式檔案轉換)

2021-07-28 13:03:18 字數 3374 閱讀 2557

一、實驗原理

1.本次實驗是實現yuv格式轉換為rgb格式,這裡的yuv其實是指數字高畫質的ycbcr。

根據亮度和色差計算公式,可以得到:

2.為使色差訊號的動態範圍控制在-0.5~+0.5之間,要對色差訊號進行歸一化處理,得到uv的計算公式:

由上式得到的uv範圍在-128~+127之間,為避免負數,應在u、v之後各加128。

3.yuv在儲存時,為了防止訊號變得造成過載,在對分量訊號進行8位元均勻量化時,y分量256級上端留20級,下端留16級作為訊號超越動態範圍的保護帶,uv分量256級上端留15級,下端留16級作為訊號超越動態範圍

的保護帶。 

4.這裡yuv採用的是420格式,既色度訊號是亮度訊號取樣頻率的四分之一。

5.得到yuv轉換ruv的公式:

注意:這裡在計算rbg時應先將uv的值減128。

二、實驗流程分析

a.首先讀取yuv檔案,新建rgb檔案

b.開闢rgb記憶體陣列和yuv陣列。由於rgb檔案是按照bgrbgrbgr……的順序儲存一幀的,所以rbg開闢乙個3倍畫素數的陣列,而yuv檔案是yyyy……u……v……儲存檔案的,可以開闢乙個畫素數大小的陣列存放y分量和兩個四分之一畫素數大小的陣列存放u和v分量。

c.讀取每一幀的yuv值存在yuv三個快取陣列中

d.因為yuv有動態範圍,先判斷y和uv是否超出要求的範圍。

e.對yuv進行上取樣,恢復出444格式的yuv。

f.按照轉換公式,將每乙個畫素分別轉換為rgb格式存在rgb快取陣列中。

e.重複c操作完成一幀的計算,再將rgb的值寫入rgb檔案。

三、關鍵**及分析

1.本次實驗工程檔案包括兩個原始檔和乙個標頭檔案:

2.main.cpp是主檔案:

a.通過工作引數設定目標檔案和檔案畫素格式:

yuvfilename = argv[1];

rgbfilename = argv[2];

framewidth = atoi(argv[3]);

frameheight = atoi(argv[4]);

b.開闢yuv和rgb的陣列空間:

/* get an input buffer for a frame */

ybuf = (u_int8_t*)malloc(framewidth * frameheight);

ubuf = (u_int8_t*)malloc((framewidth * frameheight) / 4);

vbuf = (u_int8_t*)malloc((framewidth * frameheight) / 4);

/* get the output buffers for a frame */

rgbbuf = (u_int8_t*)malloc(framewidth * frameheight * 3);

c.讀取yuv檔案並判斷是否超出yuv的動態範圍,使用while 函式,可以重複幀操作:

while (fread(ybuf, 1, framewidth * frameheight, yuvfile) && fread(ubuf, 1, framewidth * frameheight /4, yuvfile)

&& fread(vbuf, 1, framewidth * frameheight /4, yuvfile))

for (i = 0; i < framewidth*frameheight / 4; i++)

d.呼叫yuv2rgb函式,使yuv轉換為rgb:

yuv2rgb(framewidth, frameheight, rgbbuf, ybuf, ubuf, vbuf)
e.將rgb資料儲存進rgb檔案:

fwrite(rgbbuf, 1, framewidth * frameheight*3, rgbfile);
3.yuv2rgb.cpp是呼叫的yuv轉換為rgb的函式:

a.對yuv進行上採用,恢復444格式:

//上取樣

for (j = 0; j < y_dim / 2; j++)

}

b.將yuv轉換為rgb,因為rgb採用的unsiged char型,只有一位元組,只能儲存0~255之間的值,如果之間將轉換過來的rgb值存入,可能會存在溢位的現象發生錯誤,所以要先用int型判斷是否溢位,再重新賦給rgb指標:

for (i = 0; i < size ; i++)

c.對uv進行係數計算時,採用查表法可以提高執行速度,因為陣列序號不能為負數,uv之前轉換時為保證取值為正數,加上了128,所以要在計算時先減去128:

void initlookuptable()

d.開闢的陣列要在不需要時及時釋放:

if (u_buffer)

free(u_buffer);

if (v_buffer)

free(v_buffer);

4.yuv2rgb.h宣告了要是有的函式:

int yuv2rgb(int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out);

void initlookuptable();

四、實驗結果及分析第一組例子

左圖是rgb檔案轉換為yuv檔案檢視後,右圖是將yuv檔案轉為rgb,再轉為yuv檢視:

以下三組例子

左圖是yuv420素材,右圖是將yuv檔案轉換為rgb,再轉換為yuv的檔案:

五、結論

通過本次實驗,熟悉了rgb、yuv420、yuv444的儲存格式,熟悉了指標、陣列以及檔案的操作方式。在實驗中應注意正確設定工作路徑和實驗引數。

YUV格式到RGB格式的轉換

yuyv格式到rgb格式的轉換 yuyv格式如下 y0u0y1v0 y2u1y3v1.說明 乙個y代表乙個畫素,而乙個y和uv組合起來構成乙個畫素,所以第0個畫素y0和第乙個畫素y1都是共用第0個畫素的u0和v0。而每個分量y,u,v都是占用乙個位元組的儲存空間。所以y0u0y1v0相當於兩個畫素,...

RGB與YUV格式 四

一 rgb rgb24一幀的大小size width heigth 3 byte,rgb32的size width heigth 4byte.1.rgb為紅綠藍三原色 yuv,rgb是色彩空間模型,而bmp,png,jpeg,gif是影象的檔案儲存格式。影象的每個畫素的三個分量為r g b,每個顏色...

YUV 格式與 RGB 格式的相互轉換公式

cr vcb u 0.257r 0.504g 0.098b 160.439r 0.368g 0.071b 128 0.148r 0.291g 0.439b 128y 0.257r 0.504g 0.098b 16cr v 0.439r 0.368g 0.071b 128cb u 0.148r 0.2...