1. 程式人生 > >顏色空間轉換

顏色空間轉換

BT601和BT709

由於在處理相機實時影象資料時,需要將相機採集的YUV資料轉換為RGB,根據GPUImage的原始碼看到是有三種轉換矩陣用於將YUV資料轉換成RGB資料,分別是

// BT.601, which is the standard for SDTV.
GLfloat kColorConversion601Default[] = {
1.164,  1.164, 1.164,
0.0, -0.392, 2.017,
1.596, -0.813,   0.0,
};
// BT.601 full range (ref:http://www.equasys.de/colorconversion.html)
GLfloat kColorConversion601FullRangeDefault[] = {
1.0,    1.0,    1.0,
0.0,    -0.343, 1.765,
1.4,    -0.711, 0.0,
};

// BT.709, which is the standard for HDTV.
GLfloat kColorConversion709Default[] = {
1.164,  1.164, 1.164,
0.0, -0.213, 2.112,
1.793, -0.533,   0.0,
};

可以看到其中兩個比較奇特的關鍵字即601和709,同時還有FullRange

fullRange和videoRange

在apple關於影象pixelformat的定義中有關於yuv格式的420v和420f的定義

kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v', 
/* Bi-Planar Component Y'CbCr 8-bit 4:2:0, video-range (luma=[16,235] chroma=[16,240]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange  = '420f', 
/* Bi-Planar Component Y'CbCr 8-bit 4:2:0, full-range (luma=[0,255] chroma=[1,255]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct *

而fullRange和videoRange本身的意義是YUV顏色空間中 亮度部分 Y 的取值範圍,fullRange的取值範圍為luma=[0,255] chroma=[1,255],而videoRange是luma=[16,235] chroma=[16,240],另外chroma(Cb,Cr)即色度部分與亮度部分不同,始終為fullRange

YUV

初識顏色空間時,YUV應該是除了大家從小耳濡目染的RGB之外,最讓人不明覺歷的顏色空間了,它高階大氣的名字再加上YUV本身420,422,411這些不同變形 所顯示的複雜度更容易讓人望而卻步。不過本著天下事有難易乎,為之則難者亦易矣,不為則易者亦難矣的態度,我們來對YUV進行一個簡明的學習
YUV是將人眼的感知考慮進來的用於對顏色彩色影象進行編碼的顏色空間,根據

維基百科的說法簡化來說,YUV與YCbCr這兩個概念之間界限比較模糊且是有部分重疊的,因為YUV是用於電視系統中模擬顏色資訊的編碼,而YCbCr適用於對以MPEG及JPEG為代表的視訊及靜態圖片的壓縮及傳輸等場景下對顏色資訊的數字編碼。而現在YUV通常用於計算機工業中稱呼使用YCbCr進行編碼的檔案格式。而一個小常識是YUV3個分量分別都並不是縮寫,而只是對應於xyz的一種座標系代號而已。

YUV和RGB之間的轉換

SDTV with BT601

BT601是用數字格式編碼交錯的模擬視訊訊號的標準,定義於SDTV標準中

//Wr,Wg,Wb,Umax,Vmax均為對應於各BT標準的
Wr = 0.299
Wg = 1 - Wr - Wb = 0.587
Wb = 0.114
Umax = 0.436
Vmax = 0.615

HDTV with BT709

BT 709標準調整了

Wr = 0.2126
Wr = 0.0722

GPUImage框架中同款的YCbCr與RGB轉換規則, 應用於數字顏色資訊編碼的YCbCr應用於SDTV時,標準為BT601

bt601 videorange ycbcr 420v to rgb.png

 

在這種videoRange格式中,亮度和色度空間都留有footroom和headroom,部分原因是為了與模擬視訊裝置結合的場景,而一般典型的比如JPEG影象使用如下的顏色格式full range

 

bt601 fullrange ycbcr 420f to rgb.png

 

而對於HDTV,標準為BT709,由於使用的引數不同,與SDTV一樣留有headroom和footroom,

 

bt709 ycbcr to rgb .png

所以對於videorange和fullrange對應的轉換為RGB的fragmentshader分別為

//fullrange
varying highp vec2 textureCoordinate;

uniform sampler2D luminanceTexture;
uniform sampler2D chrominanceTexture;
uniform mediump mat3 colorConversionMatrix;

void main()
{
 mediump vec3 yuv;
 lowp vec3 rgb;
 
 yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
 yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5);
 rgb = colorConversionMatrix * yuv;
 
 gl_FragColor = vec4(rgb, 1);
}

//video range
varying highp vec2 textureCoordinate;

uniform sampler2D luminanceTexture;
uniform sampler2D chrominanceTexture;
uniform mediump mat3 colorConversionMatrix;

void main()
{
 mediump vec3 yuv;
 lowp vec3 rgb;
 
 yuv.x = texture2D(luminanceTexture, textureCoordinate).r - (16.0/255.0);
 yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5);
 rgb = colorConversionMatrix * yuv;
 
 gl_FragColor = vec4(rgb, 1);
}



作者:縱橫而樂
連結:https://www.jianshu.com/p/5b437c1df48e
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。