顏色空間轉換
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和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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。