glsl 中使用
Y = 0.299R′ + 0.587G′ + 0.114B′
U = – 0.147R′ – 0.289G′ + 0.436B′= 0.492 (B′ – Y)
V = 0.615R′ – 0.515G′ – 0.100B′ = 0.877(R′ – Y)
R′ = Y + 1.140V
G′ = Y – 0.395U – 0.581V
B′ = Y + 2.032U
这几组公式会产生负数 在shader传出会置为0 影响计算结果
使用以下几组公式可保证数值不会越界
计算机系统中的R'G'B'数值范围为 0-255,使用以下的方程式可能会更加方便:
Y = 0.257R′ + 0.504G′ + 0.098B′ + 16
Cb = –0.148R′ – 0.291G′ + 0.439B′ + 128
Cr = 0.439R′ – 0.368G′ – 0.071B′ + 128
R′ = 1.164(Y – 16) + 1.596(Cr – 128)
G′ = 1.164(Y – 16) – 0.813(Cr – 128) – 0.391(Cb – 128)
B′ = 1.164(Y – 16) + 2.018(Cb – 128)
在shader中使用以下两个矩阵转换yuv与rgb速度不错
需注意第一个矩阵 输入时0到1的数 输出是0到255
第二个矩阵 输入时0到255 输出是0到1的数
const mat4 rgb2yuv = mat4(
65.52255, -37.79398, 111.98732, 0.00000,
128.62729, -74.19334, -93.81088, 0.00000,
24.92233, 111.98732, -18.17644, 0.00000,
16.00000, 128.00000, 128.00000, 1.00000);
gl_FragColor = rgb2yuv * texture2D(texIn, v_texCoord);
const mat4 yuv2rgb = mat4(
0.00456, 0.00456, 0.00456, 0.00000,
0.00000, -0.00153, 0.00791, 0.00000,
0.00626, -0.00319, 0.00000, 0.00000,
-0.87416, 0.53133, -1.08599, 1.00000);
gl_FragColor = yuv2rgb * centerYUV;
The following formulas define the conversion from RGB to YUV:
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16 U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128 V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128
These formulas produce 8-bit results using coefficients that require no more than 8 bits of (unsigned) precision. Intermediate results require up to 16 bits of precision.
The following coefficients are used in conversion process:
C = Y - 16 D = U - 128 E = V - 128
Using the previous coefficients and noting that clip()
denotes clipping a value to the range of 0 to 255, the following formulas provide the conversion from YUV to RGB:
R = clip(( 298 * C + 409 * E + 128) >> 8) G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) B = clip(( 298 * C + 516 * D + 128) >> 8)