一、實驗原理
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...