forward from:
1. Formula: Based on BT.601-6
BT601 UV coordinate map (after quantization): (the abscissa is u, the ordinate is v, the lower left corner is the origin)
Through the coordinate graph, we can see that the UV does not contain the entire coordinate system, but is an octagonal rotated at a certain angle. The larger U is, the bluer the blue, the larger the V, the more red the red.
Glossary:
After quantization: Y~[16,235] U ~[16-240] V~[16-240] Quantization is to make Y or U or V within a certain range through linear transformation, for example, let Y [0,1] change to Y'(16,235) is implemented like this: Y'= Y* (235-16)/(1-0) + 16 that is, Y'= 219*Y + 16
Unquantified: Y~ [0,1] U,V~[-0.5,0.5]
YUV: YCbCr Both are equivalent
About why quantify? To
1. As we all know, the range of RGB is [0,255]. If R=0, G=0, B=255 is put into the formula U = -0.169*R-0.331*G + 0.5 *B ;, U=127.5, The range of char is [-128,127], which cannot be expressed to 127.5.
Then, we need to quantify the YU V data;
2. After quantization, when we convert RGB to YUV, if we need to make boundary judgments, similar to Y=Y_int <0?0: (Y_int>255?255:Y_int); This statement consumes a lot of CPU, if YUV performs After quantization, there is no need to make boundary judgments when converting RGB to YUV;
3. Some bandwidth will be saved after quantization.
How to judge whether the image is quantified?
Print out the Y data of the image when the screen is completely black. If Y=16, it means that Y is quantized, if Y=0, it means that Y is not quantified.
1. Decimal form, not quantified (U~[-0.5-0.5], R~[0,1])
R = Y + 1.4075 * V;
G = Y - 0.3455 * U - 0.7169*V;
B = Y + 1.779 * U;
Y = 0.299*R + 0.587*G + 0.114*B;
U = (B-Y)/1.772;
V = (R-Y)/1.402;
or written as:
Y = 0.299*R + 0.587*G + 0.114*B;
U = -0.169*R - 0.331*G + 0.5 *B ;
V = 0.5 *R - 0.419*G - 0.081*B;
2. Integer form (reduce the amount of calculation) not quantified R, G, B~[0,255] U, V~[-128,128]
R= Y + ((360 * (V - 128))>>8) ;
G= Y - (( ( 88 * (U - 128) + 184 * (V - 128)) )>>8) ;
B= Y +((455 * (U - 128))>>8) ;
Y = (77*R + 150*G + 29*B)>>8;
U = ((-44*R - 87*G + 131*B)>>8) + 128;
V = ((131*R - 110*G - 21*B)>>8) + 128 ;
3. Quantified formula (Y~(16,235) U/V ~(16,240)) Quantification
[Y,U,V,1]T = M[R,G,B,1]T where M =
[ 0.2568, 0.5041, 0.0979, 16
-0.1479, -0.2896, 0.4375, 128
0.4375, -0.3666, -0.0709, 128,
0, 0, 0, 1 ]
[R,G,B,1]T = M[Y,U,V,1]T M =
1.1644 0 1.6019 -223.5521
1.1644 -0.3928 -0.8163 136.1381
1.1644 2.0253 0 -278.0291
0.0000 0.0000 0.0000 1.0000
This can get the red YUV component
YUV = ( 81,91,240 )
The following picture is a screenshot on the bt601 document: Screenshot 1 Screenshot 2
4 The quantified formula is written as an integer (reduce the amount of calculation) (Y~(16,235) U/V ~(16,240))
yuv --> rgb
R = (298*Y + 411 * V - 57344)>>8
G= (298*Y - 101* U- 211* V+ 34739)>>8
B= (298*Y + 519* U- 71117)>>8
rgb --> yuv
Y= ( 66*R + 129*G + 25*B)>>8 + 16
U= (-38*R - 74*G + 112*B)>>8 +128
V= (112*R - 94*G - 18*B)>>8 + 128
5. YUV quantization and non-quantization conversion
YUV quantized to non-quantized
Y=(Y'-16 )*255/219 ;
U=(U'-128)*128/112;
V=(V'-128)*128/112;
YUV quantified to non-quantified U~(-128-127) -----> U~(16-240)
Y' = ((219*Y)>>8) + 16;
U' = ((219*U)>>8) + 128;
V' =((219*V)>>8) + 128;
6. YV12 to RGB (this is to be verified...)
R = Y + 1.370705 * (V-128); // r component value
G = Y-0.698001 * (U-128)-0.703125 * (V-128) // g component value
B = Y + 1.732446 * (U-128 ); // b component value
7. Matrix form (BT601):
Matrix form
Before quantification
[Y,U,V]T = M[R,G,B]T where M = 0.299, 0.587, 0.114, -0.169,-0.331, 0.5, 0.5,-0.419,-0.081
[R,G,B]T = M[Y,U,V]T where M = 1 0 1.4017 1 -0.3437 -0.7142 1 1 1.7722 0
After quantification
[Y,U,V,1]T = M[R,G,B,1]T where M = [0.2568, 0.5041, 0.0979, 16 -0.1479, -0.2896, 0.4375, 128 0.4375, -0.3666, -0.0709, 128, 0, 0, 0, 1]
[R,G,B,1]T = M[Y,U,V,1]T M = 1.1644 0 1.6019 -223.5521 1.1644 -0.3928 -0.8163 136.1381 1.1644 2.0253 0 -278.0291 0.0000 0.0000 0.0000 1.0000
The quantized formula is written in integer form
[Y,U,V,1]T = (M[R,G,B,1]T)>>8 where M = 66, 129, 25, 4096, -38, -74, 112, 32768, 112, -94, -18, 32768, 0, 0, 0, 256
[R,G,B,1]T = (M[Y,U,V,1]T)>>8 M = 298, 0, 410, -57229, 298, -101, -209, 34851, 298, 518, 0, -71175, 0, 0, 0, 256
2. The conversion formula of YUV and RGB under Rec2020 (BT2020) (I think it is more unified and coordinated to write in matrix form)
The coordinate map of BT2020 UV (after quantization): (the abscissa is u, the ordinate is v, the lower left corner is the origin)
Through the coordinate graph, we can see that UV is different from the BT601 protocol. The uv represents a larger color range, and the color range is an irregular octagon.
1. full range
which is:
Y = 0.2627*R + 0.6780*G + 0.0593*B;
U = -0.1396*R - 0.3604*G + 0.5*B;
V = 0.5*R - 0.4598*G -0.0402*B;
Matrix form
Before quantification
[Y,U,V]T = M[R,G,B]T where M = 0.2627 0.6780 0.0593, -0.1396 -0.3604 0.5000, 0.5000 -0.4598 -0.0402
[R,G,B]T = M[Y,U,V]T where M = 1.000 -0.0000 1.4746 1.0000 -0.1645 -0.5713 1.0000 1.8814 -0.0001
After quantification
[Y,U,V,1]T = M[R,G,B,1]T where M = 0.2256, 0.5823, 0.05093, 16, -0.1222, -0.3154, 0.4375, 128, 0.4375, -0.4023, -0.0352 , 128, 0,0,0,1
[R,G,B,1]T =M[Y,U,V,1]T M =1.1644, 0, 1.6853, -234.3559, 1.1644, -0.1881, -0.6529, 89.0206, 1.1646, 2.1501, 0.0000, -293.8542, 0.0000, 0.0000, 0.0000, 1.0000
The quantized formula is written in integer form
[Y,U,V,1]T = (M[R,G,B,1]T)>>8 where M =58, 149, 13, 4096, -31, -81, 112, 32768, 112, -103, -9, 32768, 0, 0, 0, 256
[R,G,B,1]T = (M[Y,U,V,1]T)>>8 M = 298, 0, 431, -59995, 298, -48, -167, 22789, 298, 550, 0, -75227, 0, 0, 0, 256
2. BT601 to BT2020
_Y = (256*Y - 32*U -30*V+ 7826)>>8;
_U = (258*U +17*V - 2208)>>8;
_V = (22*U + 264*V - 3369)>>8;
3. bt2020 to bt601
YUV_601 = M*[Y,U,V,1]T
M=[
1.0000 0.1157 0.1037 -28.0756
0.0000 0.9951 -0.0602 8.3197
-0.0000 -0.0835 0.9767 13.6686
0.0000 0.0000 0.0000 1.0000
]
RGB and HSV conversion
1. RGB to HSV
1: max=max(R,G,B) 2: min=min(R,G,B) 3: if R = max, H = (G-B)/(max-min) 4: if G = max, H = 2 + (B-R)/(max-min) 5: if B = max, H = 4 + (R-G)/(max-min) 6: 7: H = H * 60 8: if H < 0, H = H + 360 9: 10: V=max(R,G,B) 11: S=(max-min)/max
2. HSV to RGB
1: if s = 0 2: R=G=B=V 3: else 4: H /= 60; 5: i = INTEGER(H) 6: 7: f = H - i 8: a = V * ( 1 - s ) 9: b = V * ( 1 - s * f ) 10: c = V * ( 1 - s * (1 - f ) ) 11: 12: switch(i) 13: case 0: R = V; G = c; B = a; 14: case 1: R = b; G = v; B = a; 15: case 2: R = a; G = v; B = c; 16: case 3: R = a; G = b; B = v; 17: case 4: R = c; G = a; B = v; 18: case 5: R = v; G = a; B = b;