1. 程式人生 > >YUV 格式與 RGB 格式的相互轉換公式及C++ 程式碼

YUV 格式與 RGB 格式的相互轉換公式及C++ 程式碼

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

最近在用的一個工業相機,輸出的影象格式是 YUY2 格式。而在電腦上顯示時需要 RGB 格式,所以就花了些時間在網上查了些相關的資料。說實話,網上關於 YUV 與 RGB 格式變換的文章挺多的,本來不需要我再多寫這麼一篇。但是網上那些文章中給出了各種各樣的變換公式,公式的係數又各不相同,讓人看了之後越看越糊塗。其實那些文章的公式基本都是對的,只不過因為作者忘記給出變換公式的定義域與值域,所以給讀者使用造成了很大的麻煩。

為此我就寫了這篇文章,來梳理一下各種網文中的各種公式。

在 Keith Jack’s 的書 “Video Demystified” (ISBN 1-878707-09-4) 給出的公式是這樣的。

RGB to YUV

YCr=VCb=U===0.257R+0.504G+0.098B+160.439R0.368G0.071B+1280.148R0.291G+0.439B+128

YUV to RGB

BGR===1.164(Y16)+2.018(U128)1.164(Y16)0.813(V128)0.391(U128)1.164(Y16)+1.596(V128)

注意在上面的式子中,RGB 的範圍是 [0,255],Y 的範圍是 [16,235] ,UV 的範圍是 [16,239]。 如果計算結果超出這個範圍就截斷處理。

CCIR 601 定義的轉換公式是:

YCr=VCb=
U
===0.299R+0.587G+0.114B0.713(RY)=0.500R0.419G0.081B0.564(BY)=0.169R0.331G+0.500B
RGB===Y+1.403VY0.344U0.714VY+1.770U

這裡 RGB 的取值範圍是 [0,1]。 Y 的範圍是 [0,1], Cr 和 Cb 的範圍是 [0.5,0.5]

大家仔細看,這兩個來源給出的公式係數有些細微的差別,如果將公式中的 YUV 和 RGB 的取值範圍統一成相同的,計算出的結果也略有不同,但是差異很小,基本上眼睛看不出區別來。所以大家不用計較這兩個公式的區別。

如果把 RGB 和YUV 的範圍都放縮到 [0,255]

,那麼常用的轉換公式是這樣的。

RGB===Y+1.403×(V128)Y0.343×(U128)0.714×(V128)Y+1.770×(U128)

RGB 到 YUV 的轉換公式變化很小,只是VU 的值做了個平移。

YCr=VCb=U===0.299R+0.587G+0.114B0.500R0.419G0.081B+1280.169R0.331G+0.500B+128

上面的公式涉及到浮點運算,可以轉換成整數運算來加速:

u = U - 128; 
v = V - 128;
R = qRound(0, Y + v + (v * 103) >> 8, 255);
G = qRound(0, Y – (u * 88) >> 8 – (v * 183) >> 8, 255);
B = qRound(0, Y + u + (u * 198) >> 8, 255);

這裡的 qRound 是 Qt 裡的函式,作用是將值域限制到 [0,255]

上面的公式用 C++ 來實現可以寫成這樣:

/**
 * @brief yuv2rgb
 * @param y [0, 255]
 * @param u [0, 255]
 * @param v [0, 255]
 * @return #ABGR
 */
inline QRgb yuv2rgb(uint8_t y, uint8_t u, uint8_t v)
{
    int R = qRound(y + 1.403 * (v - 128)); // 四捨五入到最近的整數
    int G = qRound( - 0.343 * (u - 128) - 0.714 * (v - 128));
    int B = qRound(y + 1.770 * (u - 128));

    R = qBound(0, R, 255);
    G = qBound(0, y + G, 255);
    B = qBound(0, B, 255);

    return qRgb(R, G, B);
}

/**
 * @brief rgb2yuv
 * @param rgb [0, 255]
 * @param y [0, 255]
 * @param u [0, 255]
 * @param v [0, 255]
 */
inline void rgb2yuv(QRgb rgb, uint8_t &y, uint8_t &u, uint8_t &v)
{
    int R = qRed(rgb);
    int B = qBlue(rgb);
    int G = qGreen(rgb);

    int Y, U, V;
    Y = 0.299 * R + 0.587 * G + 0.114 * B;
    U = -0.169 * R - 0.331 * G + 0.500 * B + 128;
    V = 0.500 * R - 0.419 * G - 0.081 * B + 128;

    y = qBound(0, Y, 255);
    u = qBound(0, U, 255);
    v = qBound(0, V, 255);
}

inline QRgb yuv2rgb_fast(uint8_t y, uint8_t u, uint8_t v)
{
    u = u - 128;
    v = v - 128;

    int r_dif = v + ((v * 103) >> 8);
    int g_dif = -((u * 88) >> 8) - ((v * 183) >> 8);
    int b_dif = u +((u * 198) >> 8);

    int R = y + r_dif;
    int G = y + g_dif;
    int B = y + b_dif;

    R = qBound(0, R, 255);
    G = qBound(0, G, 255);
    B = qBound(0, B, 255);

    return qRgb(R, G, B);
}

用移位運算代替浮點數乘法確實可以算的快一些。但是要求更高速度時還是略顯的有點慢。這時可以用查表法。

RGB===Y

相關推薦

YUV 格式 RGB 格式相互轉換公式C++ 程式碼

YUV 格式與 RGB 格式的相互轉換公式 最近在用的一個工業相機,輸出的影象格式是 YUY2 格式。而在電腦上顯示時需要 RGB 格式,所以就花了些時間在網上查了些相關的資料。說實話,網上關於 YUV 與 RGB 格式變換的文章挺多的,本來不需要我再多寫這麼

YUV格式RGB格式

YUV420介紹: YUV420格式是指,每個畫素都保留一個Y(亮度)分量,而在水平方向上,不是每行都取U和V分量,而是一行只取U分量,則其接著一行就只取V分量,以此重複(即4:2:0, 4:0:2, 4:2:0, 4:0:2 .......),所以420不是指沒有V,而是指一行取樣只取U,另一行取樣只取V

RGBHSV之間的轉換公式顏色表

bsp 公式 blog log b- size 分享 ont idt RGB & HSV 英文全稱  RGB - Red, Green, Blue  HSV - Hue, Saturation, Value HSV --> RGB 轉換公式 HSV --&g

計算機顏色程式碼RGB相互轉換

在24位彩色裡,藍、綠、紅各佔8位(8bits),正好可以用兩位十六進位制數表示,最大的是0xFF,也就是十進位制的255。 24位彩色的排列順序是8位藍、8位綠、8位紅。 純紅色表示為0x0000FF,也就是255 純綠色表示為0x00FF00,也就是65280 純藍色表示為0xFF0000,也就

YUY2(YUV) RGB 格式圖片的相互轉換 以及 基於YUY2(YUV)的blending

YUY2經常用於電視制式以及許多攝像頭的輸出格式.而我們在處理時經常需要將其轉化為RGB進行處理,這裡簡單介紹下YUY2(YUV)與RGB之間相互轉化的關係: YUY2(YUV) To RGB: C = Y - 16 D = U - 128 E = V - 128 R =

YUVRGB格式轉換

原文:http://www.cnblogs.com/dwdxdy/p/3713990.html YUV格式具有亮度資訊和色彩資訊分離的特點,但大多數影象處理操作都是基於RGB格式。 因此當要對影象進行後期處理顯示時,需要把YUV格式轉換成RGB格式。 RGB與YUV的變換公式如下:   YU

YUVRGB互轉各種公式 (YUVRGB轉換公式有很多種,請注意區別!!!)

一、 公式:基於BT.601-6       BT601 UV 的座標圖(量化後): (橫座標為u,縱座標為v,左下角為原點)           通過座標圖我們可以看到UV並不會包含整個座標系,而是呈一個旋轉了一

Oracle和Sql 日期格式字串格式相互轉換

日期格式轉換為字元型別 Oracle 型別日期格式轉換字串型別 1.date 轉換為 字串 to_char(日期,”轉換格式” ) 即把給定的日期按照“轉換格式”轉換。 轉換的格式: 表示year的:y 表示年的最後一位 yy 表示年的最後2位 y

\u格式 unicode漢字的相互轉換

直接上程式碼 using System; using System.Text; using System.Text.RegularExpressions; namespace UnicodeConvertDemo { class Program

RGBHSB之間的轉換公式

sse 亮度 顏色模型 csdn compare 特定 概念 col 將不 先來了解一些概念: 1.RGB是一種加色模型,就是將不同比例的Red/Green/Blue混合在一起得到新顏色.通常RGB顏色模型表示為: 2.HSB(HSV) 通過色相/飽和度/亮度三要素來表達

JavaScript JSON的key 下劃線格式駝峰格式互相轉換

我們編碼的格式是使用駝峰式還是下劃線格式,這個爭論由來已久,這不,我負責的vue.js前端剛剛做好,發現後臺介面是使用Python寫的,導致介面的所有欄位都是下劃線格式的,而我又希望介面改成駝峰格式,後

日期格式和時間戳相互轉換 外帶一個獲取當前程式根目錄

/* * 函式: * CTimeConvertCString(時間戳轉字串日期格式) * 引數: * tm:時間戳 * 返回值: * 返回對應的日期格式字串 * ssdwuj

YUYRGB格式區別

YUV   做視訊採集與處理,自然少不了要學會分析YUV資料。因為從採集的角度來說,一般的視訊採集晶片輸出的碼流一般都是YUV資料流的形式,而從視訊處理(例如H.264、MPEG視訊編解碼)的角度來說,也是在原始YUV碼流進行編碼和解析,所以,瞭解如何分析YUV資料流對

C++ vector知識點、cout輸出bool格式int格式轉換

一、vector 的初始化:可以有五種方式,舉例說明如下 (1) vector<int> a(10); //定義了10個整型元素的向量(尖括號中為元素型別名,它可以是任何合法的資料型別),但沒有給出初值,其值是不確定的。 (2)vector<int&

關於YUVRGB之間的轉換公式

轉載地址:http://blog.sina.com.cn/s/blog_5713096b0100059i.html 總結了一下網上關於YUV的一些東西 先區分一下YUV和YCbCr YUV色彩模型來源於RGB模型, 該模型的特點是將亮度和色度分離開,從而適合於影象處理領域。

最精簡的XML格式陣列的互相轉換

1.陣列轉XML格式 /** * 陣列轉XML格式 * @param array $arr * @return string XML * @author mosishu */ functio

YUVRGB相互轉換實驗報告

1、彩色空間轉換基本原理 1)彩色空間轉換公式: 為了實現格式轉換,我們首先要明確待轉換格式和目標格式的特點和相互轉換關係,這是程式設計實現轉換的核心。對於RGB轉YUV的過程,我們要首先拿到RG

Android中system.img的兩種格式raw,sparse及其相互轉換方法

搞Android的同學經常會接觸到system.img。但是該檔案經常以兩種格式出現:raw和sparse。 一種是raw ext4 image,即經常說的raw image,使用file觀察它: 其特點是完整的ext4分割槽映象(包含很多全零的無效填充區),可以直接使用mo

CMYKRGB引數轉換公式轉換方法

1. RGB色彩模式  自然界中絕大部分的可見光譜可以用紅、綠和藍三色光按不同比例和強度的混合來表示。RGB分別代表著3種顏色:R代表紅色,G代表綠色、B代表藍色。RGB模型也稱為加色模型,如圖5所示。RGB模型通常用於光照、視訊和螢幕影象編輯。 RGB色彩模式使用RGB模型為影象中每一個畫素的RGB分量分

【VirtualBox】虛擬硬碟格式vdi和vmdk相互轉換方法

以Windows為例,假設VirtualBox安裝在D:\Program Files\Oracle\VirtualBox\ 進入 source.vdi 或 source.vmdk 所在的資料夾,然後執行以下命令: #  將vdi轉化為vmdk "D:\Program Fi