資料壓縮實驗一 yuv轉rgb格式實驗報告

2021-07-28 14:37:17 字數 4402 閱讀 3263

一:實驗基本原理

yuv轉

rgb格式轉換公式:

r=y+1.4020*(

v-128)

g=y-0.3441*(u-128)-0.7141*(v-128)

b=y+1.7720*(u-128)

分析:

由rgb到

yuv格式的轉換公式: y=

0.2990r+0.5870g+0.1140b

r-y=

0.7010r-0.5870g-0.1140b

b-y=

-0.2990r-0.5870g+0.8860b

為了使色差訊號的動態範圍控制在0.5之間,需要進行歸一化,對色差訊號引入壓縮

係數。b-y和

r-y分別乘以歸一化係數

0.713

和0.564

進行歸一化後得到色度訊號u和

v: u=

-0.1684r-0.3316g+0.5b v=

0.5r-0.4187g-0.0813b

對分量訊號進行8位元量化時,共分為

256個等間隔的量化級。為了防止訊號

變動造成過載,在256級上端留

20級,下端留

16級作為訊號超越動態範圍的保護帶,即色差訊號零電平對應碼電平

128,則由

rgb到

yuv轉換後的實際色差訊號

u』和v』:

u』=u+128

v』=v+128

由上述進行逆向運算得到yuv到

rgb的轉換公式。

二:實驗流程分析

程式設計流程包括下面幾步驟:(基於vc++6.0開發平台)

1,建立乙個工程檔案;

2,建立2個

cpp檔案(

main.c

和yuv2rgb.c

)和乙個標頭檔案(

yuv2rgb.h);

其中標頭檔案放函式的宣告(這裡包括yuv2rgb函式和查詢表函式

initlookuptable

),yuv2rgb

檔案中放兩函式的具體實現。

3,命令列引數的設定:工程

->

設定->

除錯->

設定工作目錄和程式變數;

這裡注意工作目錄設定為需要讀取的yuv檔案所在目錄。

4,主函式中變數的宣告和初始化;

5,主函式讀取

yuv檔案並為變數指標分配記憶體空間;

6,呼叫

yuv2rgb

函式;

7,將轉換後的資料寫入

rgb檔案;

8,關閉檔案,釋放緩衝區;

三:關鍵**及其分析:

/*內部變數初始化 */

char* yuvfilename = null;

char* rgbfilename = null;

file* yuvfile = null;

file* rgbfile = null;

u_int8_t* rgbbuf = null;

u_int8_t* ybuf = null;

u_int8_t* ubuf = null;

u_int8_t* vbuf = null;

u_int32_t videoframeswritten = 0;

yuvfilename = argv[1];

rgbfilename = argv[2];

framewidth = atoi(argv[3]);

frameheight = atoi(argv[4]);

因為yuv是按

4:2:0

的取樣格式由

rgb下取樣得來的,因此u,

v的資料量只有

y的四分之一。

/* 分別為yuv開闢記憶體緩衝區 */

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

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

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

/* 為輸出的rgb檔案開闢乙個緩衝區 */

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

if (rgbbuf == null || ybuf == null || ubuf == null || vbuf == null)

/* 從檔案中讀取資料到三個緩衝區中,並呼叫yuv2rgb轉換函式 */

while (fread(ybuf, 1, framewidth * frameheight , yuvfile)&&fread(ubuf, 1, (unsigned int)(framewidth * frameheight * 0.25), yuvfile)

&&fread(vbuf, 1, (unsigned int)(framewidth * frameheight * 0.25), yuvfile))

/*將緩衝區的資料寫入rgb檔案*/

fwrite(rgbbuf, 1, framewidth * frameheight*3, rgbfile);

printf("\r...%d", ++videoframeswritten);

} printf("\n%u %ux%u video frames written\n", 

videoframeswritten, framewidth, frameheight);

/* 釋放緩衝區並關閉檔案 */

free(ybuf);

free(ubuf);

free(vbuf);

fclose(yuvfile);

fclose(rgbfile);

return(0);

}

/*查詢表函式的實現*/

void initlookuptable()

/*yuv2rgb函式的具體實現*/

int yuv2rgb (int x_dim, int y_dim, void *bmpy,void *bmpu,void *bmpv, void *rgb_out, int flip)

if ((x_dim % 2) || (y_dim % 2)) return 1;

size = x_dim * y_dim;

// 分配記憶體

rgb_buffer = (unsigned char *)rgb_out;

if (!rgb_buffer)

y = (unsigned char *)bmpy;

u = (unsigned char *)bmpu;

v = (unsigned char *)bmpv;

// 關鍵:下取樣

if (!flip) else

u++;

v++;}}

else if(j%2==1)

u++;

v++;}}

}}return 0;

}

四:實驗結果及其分析:

例項檔案對比:

出現的錯誤以及除錯:

錯誤1:影象只出一半;

出錯原因:在進行上取樣的**中,每次迴圈j值誤寫為

j+=2

,導致最後行數隻寫入一半,下半部分沒有影象。

除錯:將迴圈體中的j改為

j++。

錯誤2:影象中藍天變為「紅天」;

出錯原因:rgb在檔案中是以

bgr的順序儲存的,在進行公式帶入時,誤將

r的值賦給

b,誤將

b的值賦給r。

除錯:將賦值公式調換。

錯誤3:影象部分暗處出現彩色噪點

五:結論

可以通過資料上取樣的方法將yuv格式的檔案轉化為

rgb格式,且不會產生較大失真。

資料壓縮實驗 TGA檔案轉YUV檔案

實驗內容 將tga影象檔案轉化為yuv檔案 tga檔案頭有5個字段,共18個位元組 typedef struct tgafileheader tgafileheader tgaheader tga file.read char tgaheader,sizeof tgafileheader int p...

資料壓縮實驗報告2 bmp轉yuv

1 bmp檔案格式 bmp bitmap 是windows作業系統中的標準影象檔案格式,可分為裝置相關位圖 ddb 和裝置無關位圖 dib 使用十分廣泛。它採用位對映存貯格式,除了影象深度可選外,絕大多數無壓縮,因此所佔空間很大。bmp檔案的影象深度可選1bit,4bit,8bit,16bit及24...

資料壓縮實驗報告2 TGA轉YUV

寫在前面 由於大二上學習c 時沒有進行充分的練習,這次的實驗先是自己想了很久但是無果,最後只能參考同學的 看不懂的地方和同學討論並逐漸理解。感覺自己的情況就是知道大概的思路方法,但是不知道如何用 實現。在沒有參考的前提下沒法自己寫出完整的 還是需要多思考多練習。pga struct.h 用來建立pg...