Page 1 of 1

[solved] Colorspace YcbCr to RGB

Posted: 2013-05-12T04:18:34-07:00
by thomas12
I have some YCbCr raw binary pictures and the conversion to RGB is too dark.
I was able to isolate the bug:

http://en.wikipedia.org/wiki/YCbCr#JPEG_conversion
Image

a sample with YCbCr(127,127,127)

Code: Select all

     Y      Cb      Cr	
    127  127       127         RGB 255
R   127    0        -1,402	  125,6
G   127    0,34414   0,71414   128,1
B   127   -1,772     0         125,2
a neutral gray tribel YCbCr(127,127,127) goes to RGB(127,128,125)

lets try it with current Windows Version

Code: Select all

>convert xc:rgb(127,127,127) -set colorspace ycbcr -colorspace rgb -format  "rgb(%[fx:round(255*u.r,1)],%[fx:round(255*u.g)],%[fx:round(255*u.b)])" info:
rgb(53,55,53)

>convert -version
Version: ImageMagick 6.8.5-6 2013-05-10 Q16 http://www.imagemagick.org
and here the output from my old convert on my Mac OS

Code: Select all

$ convert xc:rgb\(127,127,127\) -set colorspace YCbCr -colorspace rgb -format  "rgb(%[fx:round(255*u.r,1)],%[fx:round(255*u.g)],%[fx:round(255*u.b)])" info:
rgb(126,128,126)

$ convert -version
Version: ImageMagick 6.7.8-8 2012-08-09 Q16 http://www.imagemagick.org
you see, my old convert is correct, but the current version works wrong

--
in detail: with Chroma Cb=Cr=128 goes the color matrix parts to zero, meaning R=G=B=Y
YCbCr(127,128,128) goes to RGB(127,127,127)
YCbCr(200,128,128) goes to RGB(200,127,127)
...

-------------------------------------------------
I think there is also a bug in documentation:
http://www.imagemagick.org/script/comma ... colorspace


sRGB as function of RGB ( there is shown the wrong direction)
wrong: if R ≤ .04045 then Rs=R/12.92 else Rs=((R+.055)/1.055)^2.4
right: if R ≤ 0.0031308 then Rs=R*12.92 else Rs=1.055 R ^ (1.0 / 2.4) – 0.055
etc.

Re: Colorspace YcbCr to RGB

Posted: 2013-05-12T05:32:25-07:00
by magick
We get the expected results with this command:
  • convert xc:'sRGB(127,127,127)' -set colorspace ycbcr -colorspace srgb -format "rgb(%[fx:round(255*u.r,1)],%[fx:round(255*u.g)],%[fx:round(255*u.b)])" info:
    rgb(126,128,126)
Recent versions of ImageMagick distinguishes linear RGB from non-linear sRGB.

Re: Colorspace YcbCr to RGB

Posted: 2013-05-12T06:05:07-07:00
by thomas12
yes, I know it.
But this conversation is also wrong.

correct is YCbCr(127,128,128) -> RGB(127,127,127) -> sRGB(181,181,181)
with sRGB=1.055 RGB ^ (1.0 / 2.4) – 0.055 (with RGB> 0.0031308)

my old mac version translate this way (nearly) correct with:

Code: Select all

$ convert "xc:rgb(127,128,128)" -set colorspace YCbCr -colorspace srgb -format  "rgb(%[fx:round(255*u.r,1)],%[fx:round(255*u.g)],%[fx:round(255*u.b)])" info:
rgb(188,187,188)

$ convert -version
Version: ImageMagick 6.7.8-8 2012-08-09 Q16 http://www.imagemagick.org

Re: Colorspace YcbCr to RGB

Posted: 2013-05-12T07:17:10-07:00
by magick
  • convert "xc:sRGB(127,128,128)" -set colorspace YCbCr -colorspace srgb -depth 8 -verbose info:
returns
  • (128,126,128) #807E80 srgb(128,126,128)
JPEG Y'CbCr Luma + Chroma operates in the sRGB colorspace so no gamma companding is required. Also note the half interval offset to return unsigned values.

Here is the code we use to facilitate the conversion. If you spot a bug, let us know. We also provide colorspace unit tests in tests/validate.c/ValidateColorspaces(). We only use one sRGB value but the value returned by the YCbCr conversion suggests the conversion is correct.

Code: Select all

static void ConvertsRGBToYPbPr(const double red,const double green,
  const double blue,double *Y,double *Pb,double *Pr)
{
  *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
  *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5;
  *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5;
}

static void ConvertsRGBToYCbCr(const double red,const double green,
  const double blue,double *Y,double *Cb,double *Cr)
{
  ConvertsRGBToYPbPr(red,green,blue,Y,Cb,Cr);
}

static void ConvertYPbPrTosRGB(const double Y,const double Pb,const double Pr,
  double *red,double *green,double *blue)
{
  *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
    1.4019995886561440468*(Pr-0.5));
  *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
    0.71413649331646789076*(Pr-0.5));
  *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
    2.1453384174593273e-06*(Pr-0.5));
}

static void ConvertYCbCrTosRGB(const double Y,const double Cb,
  const double Cr,double *red,double *green,double *blue)
{
  ConvertYPbPrTosRGB(Y,Cb,Cr,red,green,blue);
}

Re: Colorspace YcbCr to RGB

Posted: 2013-05-12T08:17:27-07:00
by thomas12
I'm not a expert of CCIR 601 and can accept, that IM changed the conversion of YCbCr from destination colorspace RGB to sRGB.
(Version 6.7.8-8 to 6.8.5-6)
It's different as described in another public sources (like wikipedia) but I can work with it.

PS: do you have read this?
thomas12 wrote:I think there is also a bug in documentation:
http://www.imagemagick.org/script/comma ... colorspace

sRGB as function of RGB ( there is shown the wrong direction)
wrong: if R ≤ .04045 then Rs=R/12.92 else Rs=((R+.055)/1.055)^2.4
right: if R ≤ 0.0031308 then Rs=R*12.92 else Rs=1.055 R ^ (1.0 / 2.4) – 0.055
etc.

Re: Colorspace YcbCr to RGB

Posted: 2013-05-12T08:32:52-07:00
by magick
We have already corrected the documentation.

Our formulation is the same as Wikipedia. We use 0.99999999999914679361*Y rather than Y because we are working with double precision rather than float (i.e. 0.99999999999914679361=~ 1.0). Our values are normalized whereas the Wikipedia page uses 0 - 255.

Re: Colorspace YcbCr to RGB

Posted: 2013-05-12T08:37:01-07:00
by thomas12
you wrote: ConvertYPbPrTosRGB()
magick wrote:

Code: Select all

static void ConvertYPbPrTosRGB(const double Y,const double Pb,const double Pr,
  double *red,double *green,double *blue)
{
  *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
    1.4019995886561440468*(Pr-0.5));
  *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
    0.71413649331646789076*(Pr-0.5));
  *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
    2.1453384174593273e-06*(Pr-0.5));
}

static void ConvertYCbCrTosRGB(const double Y,const double Cb,
  const double Cr,double *red,double *green,double *blue)
{
  ConvertYPbPrTosRGB(Y,Cb,Cr,red,green,blue);
}
in my ImageMagick-6.8.5-6/tests/validate.c ( http://www.imagemagick.org/download/ImageMagick.tar.gz )
I found the same conversion formula for ConvertYPbPrToRGB()

Code: Select all

static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
  Quantum *red,Quantum *green,Quantum *blue)
{
  *red=ClampToQuantum(QuantumRange*(0.99999999999914679361*Y-
    1.2188941887145875e-06*(Pb-0.5)+1.4019995886561440468*(Pr-0.5)));
  *green=ClampToQuantum(QuantumRange*(0.99999975910502514331*Y-
    0.34413567816504303521*(Pb-0.5)-0.71413649331646789076*(Pr-0.5)));
  *blue=ClampToQuantum(QuantumRange*(1.00000124040004623180*Y+
    1.77200006607230409200*(Pb-0.5)+2.1453384174593273e-06*(Pr-0.5)));
}

static void ConvertYCbCrToRGB(const double Y,const double Cb,
  const double Cr,Quantum *red,Quantum *green,Quantum *blue)
{
  ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
}
anybody has taken some major code changes ...

Re: [solved] Colorspace YcbCr to RGB

Posted: 2013-05-12T08:47:33-07:00
by thomas12
I changed the title to [solved]
thanks for your help