[FFmpeg-user] origin of those coefficients for rgb-yuv matrix

Andrew Randrianasulu randrianasulu at gmail.com
Fri Sep 13 06:24:08 EEST 2024


Not sure if it was explained to me elsewhere before

https://sites.google.com/view/ananyamukherjeehome/image-processing/color-spaces

====

UV coefficients from Y coefficients

In a 3x3 RGB to YUV matrix, it is enough to know the RGB to Y conversion
coefficients. The coefficients for U and V can be derived from them.


[..]


Often, x and y of red green and blue and a white point (eg D65
<https://www.google.com/url?q=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FIlluminant_D65&sa=D&sntz=1&usg=AOvVaw1bJwIHCrhis7NKs6vy6VKk>)
are specified in specs such as BT 709
<https://www.google.com/url?q=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FRec._709%23Primary_chromaticities&sa=D&sntz=1&usg=AOvVaw3wBydyI2YYVmqxo_GZ-eSM>.
Given the 6 primary chromaticity numbers and the 2 white point numbers, you
can plug them in here
<http://www.google.com/url?q=http%3A%2F%2Fwww.russellcottrell.com%2Fphoto%2FmatrixCalculator.htm&sa=D&sntz=1&usg=AOvVaw3UhBjMsRqOR1VdSDooBpYP>
and get your RGB->XYZ matrix. The mathematical details of the conversion
can be found here
<http://www.google.com/url?q=http%3A%2F%2Fwww.brucelindbloom.com%2Findex.html%3FEqn_RGB_XYZ_Matrix.html&sa=D&sntz=1&usg=AOvVaw05o46rC34j3SnJHd_Mh6no>.
Now the middle row of this matrix converts from RGB to Y, and this Y is the
Y of YUV color space. So you can get the coefficients of Y from here given
primary chromaticities


====

but of course it up to reader to figure out how limited/full range
difference should be used in those calculations ....


from example in

mjpegtools-2.2.1/lavtools/jpeg2yuv.c


/**
                          Rescales the YUV values from the range 0..255 to
the range 16..235

  @param yp: buffer for Y plane of decoded JPEG

  @param up: buffer for U plane of decoded JPEG
                          @param vp: buffer for V plane of decoded JPEG
                                                */

static void rescale_color_vals(int width, int height, uint8_t *yp, uint8_t
*up, uint8_t *vp)       {

  int x,y;
                         for (y = 0; y < height; y++)
                                                   for (x = 0; x < width;
x++)

      yp[x+y*width] = (float)(yp[x+y*width]) * ((235.0 - 16.0)/255.0) +
16.0;


  for (y = 0; y < height/2; y++)
                           for (x = 0; x < width/2; x++)

      {
                                up[x+y*width/2] = (float)(up[x+y*width/2])
* ((240.0 - 16.0)/255.0) + 16.0;

        vp[x+y*width/2] = (float)(vp[x+y*width/2]) * ((240.0 - 16.0)/255.0)
+ 16.0;

      }

}


for 4:2:0 subsampled yuv arrays as far as I understand.


so, this can be simplified to multiplication of chroma and luma values by
their constants? Also matrix, but  2*1 ?

And what to do with two differently sized matrixes?

I am cornered myself .....


More information about the ffmpeg-user mailing list