日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实验一:彩色空间转换(YUV2RGB)

發(fā)布時間:2024/3/13 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实验一:彩色空间转换(YUV2RGB) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
實驗一:彩色空間轉(zhuǎn)換

#ifndef/#define/#endif?使用詳解:http://blog.csdn.net/abc5382334/article/details/18052757

Debug與Release版本的區(qū)別詳解:http://blog.csdn.net/ithzhang/article/details/7575483#comments

VS中Release和Debug模式的區(qū)別:http://blog.csdn.net/eric491179912/article/details/6154375

YUV格式分析:http://www.cnblogs.com/armlinux/archive/2012/02/15/2396763.html

一、實驗基本原理

1.????彩色空間轉(zhuǎn)換的基本思想及轉(zhuǎn)換公式

(1)???YUVRGB空間的相互轉(zhuǎn)換

RGB格式轉(zhuǎn)YUV格式:

由電視原理知識,

Y = 0.2990 R + 0.5870 G + 0.1140 B

R-Y=0.7010 R - 0.5870 G - 0.1140 B

B-Y=-0.2990 R-0.5870 G + 0.8860 B

為了使色差信號的動態(tài)范圍控制在-0.50.5之間,需要進行歸一化,對色差信號引入壓縮系數(shù),歸一化后的色差信號為:

U = - 0.1684 R - 0.3316 G + 0.5 B

V = 0.5 R - 0.4187 G - 0.0813 B

(2)???碼電平分配及數(shù)字表達(dá)式

亮電平信號:在對分量信號進行8比特均勻量化時,共分為256個等間隔的量化級。為了防止信號變動造成過載,在256級上端留20級,下端留16級作為信號超越動態(tài)范圍的保護帶。

色差信號:量化后碼電平分配色差信號經(jīng)過歸一化處理后,動態(tài)范圍為-0.50.5,讓色差零電平對應(yīng)碼電平128,色差信號總共占225個量化級。在256級上端留15級,下端留16級作為信號超越動態(tài)范圍的保護帶。

由此可知,YUV轉(zhuǎn)RGB公式為:

??????????????????????????R = Y + 1.4075 *V-128

G = Y 0.3455 *U128) – 0.7169 *V128

B = Y + 1.779 *U128

(3)???色度格式

4:2:0格式:色差信號UV的取樣頻率為亮度信號取樣頻率的四分之一,在水平方向和垂直方向上的取樣點數(shù)均為Y的一半。

所以:

RGB轉(zhuǎn)換YUV格式時,根據(jù)公式計算得到一幀YUV數(shù)據(jù)后,要對色差信號UV進行下采樣。

YUV轉(zhuǎn)換RGB格式時,在利用公式進行計算之前首先要對色差信號UV進行上采樣。(下面是兩張丑丑的圖示~)




?

二、實驗流程

1.????建立工程,C相關(guān)知識回顧(養(yǎng)成良好代碼書寫習(xí)慣)

1)?????程序文件一般分為三部分:

(1)頭文件:包括與結(jié)構(gòu)(類)的聲明和使用這些結(jié)構(gòu)(類)的函數(shù)的原型,不要將函數(shù)的定義或變量的聲明放在頭文件中,#ifndef/#define/#endif?防止頭文件被多次引用,詳解見文章頭部鏈接。

(2)源代碼文件:包含與結(jié)構(gòu)(類)有關(guān)的函數(shù)的代碼,即函數(shù)的定義

(3)源代碼文件(main.c/cpp):包含調(diào)用這些函數(shù)的代碼

2)?????學(xué)會使用帶參主函數(shù)定義以及命令參數(shù)、可執(zhí)行文件工作路徑的設(shè)置

VS2013步驟為:項目項目屬性配置屬性調(diào)試命令參數(shù)(編輯)/工作目錄(編輯:絕對路徑/瀏覽:找到具體文件夾目錄)如下圖:


??????

??????? 關(guān)于參數(shù)設(shè)置過程中DebugRelease版本的區(qū)別詳解鏈接見文章頭部鏈接。


2.????調(diào)試RGB轉(zhuǎn)換YUV程序

理解課上所給例程,尤其對色差信號進行4:2:0下采樣部分,妙用指針可以很容易實現(xiàn),在課程作業(yè)編寫YUV轉(zhuǎn)換RGB程序中對UV數(shù)據(jù)進行上采樣也是借鑒了例程的指針用法。

3.????編寫YUV轉(zhuǎn)換RGB程序,具體見下一部分。

三、關(guān)鍵代碼

#include "stdlib.h" #include "yuv2rgb.h" /*YUV->RGB 轉(zhuǎn)換公式 R = Y + 1.4075 *(V-128) G = Y – 0.3455 *(U –128) – 0.7169 *(V –128) B = Y + 1.779 *(U – 128) */ static float YUV2RGB14075[256]; static float YUV2RGB03455[256], YUV2RGB07169[256]; static float YUV2RGB1779[256];/************************************************************************ * * int YUV2RGB (int x_dim, int y_dim, void *ychunk, void *uchunk, void *vchunk, void *rgb_out, int flip) * * Purpose : It takes a YUV (4:2:0) format and convert it into * a 24-bit RGB bitmap. * * Input : x_dim the x dimension of the bitmap * y_dim the y dimension of the bitmap* * yuv chunk pointer to the YUV structurergb_out pointer to the buffer of the bitmap * * Output : 0 OK * 1 wrong dimension * 2 memory allocation error * * Side Effect : * None * * Date : 03/11/2017 * ************************************************************************/int YUV2RGB(int x_dim, int y_dim, void *ychunk, void *uchunk, void *vchunk, void *rgb_out, int flip) { static int init_done = 0;long i, j, size;unsigned char *r, *g, *b;unsigned char *y, *u, *v;unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv; unsigned char *addu_buffer, *addv_buffer;unsigned char *addu_buf, *addv_buf;if (init_done == 0){InitLookupTable();init_done = 1;}// check to see if x_dim and y_dim are divisible by 2if ((x_dim % 2) || (y_dim % 2)) return 1;size = x_dim * y_dim;// allocate memory addu_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));addv_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));b = (unsigned char *)rgb_out;y = (unsigned char *)ychunk; u = (unsigned char*)uchunk;v = (unsigned char*)vchunk;addu_buf = (unsigned char *)addu_buffer;addv_buf = (unsigned char *)addv_buffer;// 對UV塊進行上采樣for (j = 0; j < y_dim/2; j++){psu = u + j * x_dim / 2;//原始數(shù)據(jù)U塊指針psv = v + j * x_dim / 2;//原始數(shù)據(jù)V塊指針pu1 = addu_buf + 2 * j * x_dim; //U塊奇數(shù)行首地址pu2 = addu_buf + (2 * j + 1) * x_dim;//U塊偶數(shù)行首地址pv1 = addv_buf + 2 * j * x_dim; //V塊奇數(shù)行首地址pv2 = addv_buf + (2 * j + 1) * x_dim;//V塊偶數(shù)行首地址for (i = 0; i < x_dim/2; i++){*pu1 = *psu;*pu2 = *psu;pu1++;pu2++;*pu1 = *psu;*pu2 = *psu; //U塊上采樣:“以1作4”*pv1 = *psv;*pv2 = *psv; pv1++;pv2++; *pv1 = *psv;*pv2 = *psv; //V塊上采樣:“以1作4”pu1++;pu2++;pv1++;pv2++;psu++;psv++; }} // convert YUV to RGBif (!flip) {for (j = 0; j < y_dim; j++){y = y + (y_dim - j - 1) * x_dim;addu_buf = addu_buf + (y_dim - j - 1) * x_dim;addv_buf = addv_buf + (y_dim - j - 1) * x_dim;for (i = 0; i < x_dim; i++) {g = b + 1;r = b + 2;adjust(b, g, r, y, addu_buf, addv_buf);b += 3;y++;addu_buf++;addv_buf++;}}}else { for (i = 0; i < size; i++){g = b + 1;r = b + 2;adjust(b, g, r, y, addu_buf, addv_buf);//對變量范圍作適應(yīng)性調(diào)整b += 3;y++;addu_buf++;addv_buf++;}}free(addu_buffer);free(addv_buffer);return 0; } void InitLookupTable() {int i;for (i = 16; i < 240; i++) YUV2RGB14075[i] = (float)1.4075 * (i-128);for (i = 16; i < 240; i++) YUV2RGB03455[i] = (float)0.3455 * (i - 128);for (i = 16; i < 240; i++) YUV2RGB07169[i] = (float)0.7169 * (i - 128);//for (i = 16; i < 240; i++) YUV2RGB1779[i] = (float)1.779 * (i-128); } void adjust(unsigned char *b, unsigned char *g, unsigned char *r, unsigned char *y, unsigned char *u, unsigned char *v) {float temp = 0;temp = (float)(*y + YUV2RGB1779[*u]);temp = temp>255 ? 255 : temp;temp = temp<0 ? 0 : temp;*b = (unsigned char)temp;temp = (float)(*y - YUV2RGB03455[*u] - YUV2RGB07169[*v]);temp = temp>255 ? 255 : temp;temp = temp<0 ? 0 : temp;*g = (unsigned char)temp;temp = (float)(*y + YUV2RGB14075[*v]);temp = temp>255 ? 255 : temp;temp = temp<0 ? 0 : temp;*r = (unsigned char)temp; }

四、程序分析

RGB格式裸數(shù)據(jù)部分,三通道的排列順序依次是B\G\R,所以一個像素點有三個分別表示顏色的數(shù)據(jù)。

?YUV格式通常有兩大類:

打包(packed)格式:將YUV分量存放在同一個數(shù)組中,通常是幾個相鄰的像素組成一個宏像素(macro-pixel);

平面(planar)格式:使用三個數(shù)組分開存放YUV三個分量,就像是一個三維平面一樣。

下面是我們測試所用RGBYUV文件的兩張丑丑的排列簡示圖~

依次是B G R B G R.........

每幀數(shù)據(jù)Y U V分塊排列......


程序?qū)崿F(xiàn)過程:

1.? 主程序?qū)崿F(xiàn)對YUV視頻逐幀讀取數(shù)據(jù)分別處理,根據(jù)格式特點,開辟三個緩存分別存放YUV三個分量各自的數(shù)據(jù)。

2.? 關(guān)鍵函數(shù)首先對U\V色差信號作上采樣,下采樣過程中相鄰四個數(shù)據(jù)取平均得到一個U/V,所以上采樣我們這里相應(yīng)地就可以->以1代4。

3.? 接著就是帶入公式計算,依然使用查找表的方法,重點注意強制類型轉(zhuǎn)換過程,在void adjust(~~~)函數(shù)中實現(xiàn),超出0~255范圍內(nèi)的rgb值, 負(fù)數(shù)取0,大于255的取255。

4.? 最后按照存儲格式寫入文件。

五、實驗結(jié)果

(所有YUV測試文件均來自網(wǎng)站:http://trace.eas.asu.edu/yuv/index.html)

1.? 如何檢驗程序結(jié)果是否正確:

由于RGB的裸數(shù)據(jù)并不構(gòu)成文件格式,所以我們的YUV視頻通過程序轉(zhuǎn)換成RGB文件以后,再用RGB2YUV程序轉(zhuǎn)換成YUV格式文件,用YUV播放 器查看,對比前后兩個視頻圖像畫面,若有明顯色調(diào)失真或不明色塊之類則表明程序出錯。

2.? 下面是這次實驗程序編寫過程中出現(xiàn)的錯誤整理:

①程序結(jié)果出錯:

測試得到上圖結(jié)果時,首先注意到明顯的藍(lán)紅色塊,猜測是公式計算過程中強制類型轉(zhuǎn)換錯誤,老師上課也提醒過,查閱相關(guān)書籍得到C語言各種數(shù)據(jù)類型大小范圍如下圖:

改正: 將公式計算和強制類型轉(zhuǎn)換過程另寫函數(shù),將計算所得結(jié)果在unsignedchar類型 0~255范圍之外的再次處理。

②程序運行報錯:program received signal SIGSEGV,Segmentationfault.

通過相關(guān)搜索以及不斷改正調(diào)試發(fā)現(xiàn),出現(xiàn)這種錯誤的原因是因為聲明指針后沒有初始化,指針指向地址為未知,未初始化指針直接執(zhí)行運算就會出錯。

改正:程序中聲明的指針初始化。

③程序本身錯誤:對比差錯圖像與原圖像具體差異:

??????? 下面是一組結(jié)果圖:

藍(lán)紅色塊錯誤處理完之后,得到的圖像還是不對,但對于錯誤原因不是很清楚,于是再次進行各種測試。

看上去好像是色調(diào)改變了

繼續(xù)測試


。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

還好找到了這個顏色豐富亮麗的YUV,幫了大忙

似曾相識的豎條色彩分界

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

所以這應(yīng)該是發(fā)生了某部分?jǐn)?shù)據(jù)的位置偏移,問題應(yīng)該出現(xiàn)在有關(guān)數(shù)據(jù)計算部分。

??????? 于是重新查看程序,在直接得到數(shù)據(jù)的計算過程和U/V色差信號的上采樣兩部分仔細(xì)排查,最終發(fā)現(xiàn)錯誤出現(xiàn)采樣程序部分的指針使用。

??????? 錯誤:程序中指針psu\psv多進行了一次偏移超出數(shù)據(jù)范圍。

上采樣部分正確代碼已經(jīng)在上面程序部分給出,指針使用圖示如下:

指針簡圖(V同理):

以上錯誤改正以后再次進行多次測試,結(jié)果表明程序運行結(jié)果正確。

test 1----


test 2----


test 3----

五、結(jié)論

掌握指針運算很重要,會使程序變的簡單。




tips/2017/04/30:對于人眼來說,亮度信號是最敏感的,如果將彩色圖像轉(zhuǎn)換為灰度圖像,僅僅需要轉(zhuǎn)換保存亮度信號就可以。

?

YUV官方播放器的注冊方法:

官方提供注冊碼:

REGEDIT4

?

[HKEY_CURRENT_USER\Software\tihohod.com\YUVPlayer\RegistrationInfo]

"RegistrationName"="Peace on Earth -Goodwill to Men"

"RegistrationKey"="JxsQHEseR43VXvp6kCV8w5ACtqNVJ11LhOAE4Pztk+Ksw211wohNjsR78XHoGajwlqIOU6gVz0zipwkJCfdvIqyAJrEgJLYB+NKwPGaD+OqbJD+oe+5xixyIKc7tT0ecQjNER47sA3HsUUhRl3LmKozxS2nH233WNPpJwoF4rL1Bjm5OfcM/jiixF/By85wQTdzSwAehjfvB7iO9tCaI9A=="

把上面key的內(nèi)容復(fù)制到一個編輯器,另存為key.reg,點擊運行這個文件會自動注冊,就OK了





總結(jié)

以上是生活随笔為你收集整理的实验一:彩色空间转换(YUV2RGB)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。