日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

一種簡(jiǎn)單的YUV轉(zhuǎn)RGB的優(yōu)化算法

 taotao_2016 2019-07-12


YUV與RGB的相互轉(zhuǎn)換一直以來(lái)都是非常常用的基礎(chǔ)算法,如何才能最高效的轉(zhuǎn)換,成為一個(gè)難點(diǎn)問(wèn)題,尤其是目前視頻直播火熱的時(shí)候,這些算法的優(yōu)化也越發(fā)重要。

首先,我們看下最常用的YUV與RGB相互轉(zhuǎn)換的算法公式,如下所示:

注意,RGB取值范圍均為0-255:

1,RGB轉(zhuǎn)YUV

Y = 0.299R + 0.587G + 0.114B

U = -0.147R - 0.289G + 0.436B

V = 0.615R - 0.515G - 0.100B

2,YUV轉(zhuǎn)RGB

R = Y + 1.14V

G = Y - 0.39U - 0.58V

B = Y + 2.03U

我的優(yōu)化方案如下:

優(yōu)化1:看到上述算法,從算法優(yōu)化角度來(lái)看,算法計(jì)算中,最好不要出現(xiàn)浮點(diǎn)運(yùn)算,浮點(diǎn)運(yùn)算比較耗時(shí);

基于這一點(diǎn),我們做如下操作:

Y * 256 = 0.299 * 256R + 0.587 * 256G + 0.114 * 256B

U * 256 = -0.147 * 256R - 0.289 * 256G + 0.436 * 256B

V * 256 = 0.615 * 256R - 0.515 * 256G - 0.100 * 256B

R * 256 = Y * 256 + 1.14 * 256V

G * 256 = Y * 256 - 0.39 * 256U - 0.58 * 256V

B * 256 = Y * 256 + 2.03 * 256U

簡(jiǎn)化上面的公式如下:

256Y = 76.544R + 150.272G + 29.184B

256U = -37.632R - 73.984G + 111.616B

256V = 157.44R - 131.84G - 25.6B

256R = 256Y + 291.84V

256G = 256Y - 99.84U - 148.48V

256B = 256Y + 519.68U

做到這一步,我這里要說(shuō)明一下:我們這里的轉(zhuǎn)換是有損的,適用于追求速度,而對(duì)效果要求不是100%準(zhǔn)確的情況。

然后,我們就可以對(duì)上述公式進(jìn)一步優(yōu)化,徹底干掉小數(shù):

256Y = 77R + 150G + 29B

256U = -38R - 74G + 112B

256V = 158R - 132G - 26B

256R = 256Y + 292V

256G = 256Y - 100U - 149V

256B = 256Y + 520U

實(shí)際上就是四舍五入,為什么要乘以256,這是實(shí)際上是為了縮小誤差,當(dāng)然你這個(gè)地方乘數(shù)越大,誤差越小。

優(yōu)化2:干掉所有乘法,用移位運(yùn)算表示;

上述公式,我們可以用移位進(jìn)行簡(jiǎn)單優(yōu)化:

Y = (77R + 150G + 29B) >> 8

U = (-38R - 74G + 112B) >> 8

V = (158R - 132G - 26B) >> 8

R = (256Y + 292V) >> 8

G = (256Y - 100U - 149V) >> 8

B = (256Y + 520U) >> 8

做到此處,已經(jīng)沒(méi)有了浮點(diǎn)運(yùn)算量了,但是我們發(fā)現(xiàn)雖然采用了移位運(yùn)算,但是,公式中還有很多乘法運(yùn)算,乘法跟移位運(yùn)算相比,還是效率太低了,因此,我們將把所有乘法都改成移位運(yùn)算。

如何將常數(shù)乘法改成移位運(yùn)算?

這里給個(gè)例子:

                      Y=Y*9可以改為:Y=(Y<<3)+Y

因此,我們可以講YUV的公式繼續(xù)改為最簡(jiǎn):

RGB轉(zhuǎn)YUV:

Y = ((R << 6) + (R << 3) + (R << 2) + R + (G << 7) + (G << 4) + (G << 2) + (G << 1) + (B << 4) + (B << 3) + (B << 2) + B) >> 8;

U = (-((R << 5) + (R << 2) + (R << 1)) - ((G << 6) + (G << 3) + (G << 1)) + ((B << 6) + (B << 5) + (B << 4))) >> 8;

V = ((R << 7) + (R << 4) + (R << 3) + (R << 2) + (R << 1) - ((G << 7) + (G << 2)) - ((B << 4) + (B << 3) + (B << 1))) >> 8;

YUV轉(zhuǎn)RGB:

R   = ((Y << 8) + ((V << 8) + (V << 5) + (V << 2))) >> 8;

G = ((Y << 8) - ((U << 6) + (U << 5) + (U << 2)) - ((V << 7) + (V << 4) + (V << 2) + V)) >> 8;  

B = ((Y << 8) + (U << 9) + (U << 3)) >> 8;

至此,YUV與RGB的相互轉(zhuǎn)換公式就優(yōu)化完畢了,這個(gè)優(yōu)化,在移動(dòng)端,速度會(huì)有很大的提高,至于一些測(cè)試數(shù)據(jù),我就不列舉了,只給個(gè)效果圖吧,大家可以直接試一下就知道了,最后,給出C的代碼如下:

static void RGBToYUV(int Red, int Green, int Blue, int* Y,int* U,int* V)

{

*Y = ((Red << 6) + (Red << 3) + (Red << 2) + Red + (Green << 7) + (Green << 4) + (Green << 2) + (Green << 1) + (Blue << 4) + (Blue << 3) + (Blue << 2) + Blue) >> 8;

*U = (-((Red << 5) + (Red << 2) + (Red << 1)) - ((Green << 6) + (Green << 3) + (Green << 1)) + ((Blue << 6) + (Blue << 5) + (Blue << 4))) >> 8;

*V = ((Red << 7) + (Red << 4) + (Red << 3) + (Red << 2) + (Red << 1) - ((Green << 7) + (Green << 2)) - ((Blue << 4) + (Blue << 3) + (Blue << 1))) >> 8;

};

static void YUVToRGB(int Y, int U, int V, int* Red, int* Green, int* Blue)

{

*Red   = ((Y << 8) + ((V << 8) + (V << 5) + (V << 2))) >> 8;

*Green = ((Y << 8) - ((U << 6) + (U << 5) + (U << 2)) - ((V << 7) + (V << 4) + (V << 2) + V)) >> 8;  

*Blue = ((Y << 8) + (U << 9) + (U << 3)) >> 8;

};

效果圖:

原圖

使用浮點(diǎn)型RGB-YUV-RGB結(jié)果圖

使用優(yōu)化版RGB-YUV-RGB結(jié)果圖

在說(shuō)一下,這個(gè)優(yōu)化純粹是追求速度,當(dāng)然,效果差異很小,如果你需要的是100%的準(zhǔn)確,最好還是要使用浮點(diǎn)計(jì)算。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多