title: Unable to convert rgb to YCbCr and back without loss
body: <p>I need to write a program that will take pictures, transfer them to YCbCr format, manipulate the picture and then return the result back in RGB format. Before I write the manipulation I wrote the transformation from RGB to YCbCr and back and wanted to test that it works. On most pictures I've tested it on it works, and returns back a picture that is identical to the original. I have problems with 2 pictures, where the transformation seems to change some of the pixels. the pictures are <sup>(cropped areas from larger pictures)</sup>:</p>
  
  <p>The original:</p>
  
  <p><img src="https://i.stack.imgur.com/0K08q.png" alt="enter image description here"></p>
  
  <p>The result:</p>
  
  <p><img src="https://i.stack.imgur.com/6bqDd.png" alt="enter image description here"></p>
  
  <p>The original:</p>
  
  <p><img src="https://i.stack.imgur.com/uya1A.png" alt="enter image description here"></p>
  
  <p>The result:</p>
  
  <p><img src="https://i.stack.imgur.com/Qgmpq.png" alt="enter image description here"></p>
  
  <p>I'm taking the values for the conversion matrices and vectors from <a href="http://www.equasys.de/colorconversion.html" rel="nofollow noreferrer">this site</a>, and I've tried all the 3 available options, all of them give similar "errors".</p>
  
  <p>The code I use:</p>
  
  <pre><code>//transformation matrix from RGB to YCbCr
  const double rgb2YCbCrMatrix[3][3] = {
      { 0.257,  0.504,  0.098},
      {-0.148, -0.291,  0.439},
      { 0.439, -0.368, -0.071}
  };
  //transformation vector from RGB to YcBCr
  const char rgb2YCbCrVector[3] = {
      16,
      128,
      128
  };
  //transformation matrix from YCbCr to RGB
  const double TCbCr2rgbMatrix[3][3] = {
      {1.164,  0.000,  1.596},
      {1.164, -0.392, -0.813},
      {1.164,  2.017,  0.000}
  };
  //transformation vector from RGB to YcBCr
  const char YCbCr2rgbVector[3] = {
      -16,
      -128,
      -128};
  
  //calculate the values of the Y, Cb and Cr channels, used the formula for HDTV, as described at http://www.equasys.de/colorconversion.html
  for (int i = 0; i &lt; height*width; i++) {
      YChannel[i]  = redChannel[i]*rgb2YCbCrMatrix[0][0]+greenChannel[i]*rgb2YCbCrMatrix[0][1]+blueChannel[i]*rgb2YCbCrMatrix[0][2] + rgb2YCbCrVector[0];
      CbChannel[i] = redChannel[i]*rgb2YCbCrMatrix[1][0]+greenChannel[i]*rgb2YCbCrMatrix[1][1]+blueChannel[i]*rgb2YCbCrMatrix[1][2] + rgb2YCbCrVector[1];
      CrChannel[i] = redChannel[i]*rgb2YCbCrMatrix[2][0]+greenChannel[i]*rgb2YCbCrMatrix[2][1]+blueChannel[i]*rgb2YCbCrMatrix[2][2] + rgb2YCbCrVector[2];
  }
  //calculate the values of the RGB channels after the transformation, used the formula for HDTV, as described at http://www.equasys.de/colorconversion.html
  for (int i = 0; i &lt; height*width; i++) {
      redChannel[i]   = (YChannel[i] + YCbCr2rgbVector[0])*TCbCr2rgbMatrix[0][0]+(CbChannel[i] + YCbCr2rgbVector[1])*TCbCr2rgbMatrix[0][1]+(CrChannel[i] + YCbCr2rgbVector[2])*TCbCr2rgbMatrix[0][2];
      greenChannel[i] = (YChannel[i] + YCbCr2rgbVector[0])*TCbCr2rgbMatrix[1][0]+(CbChannel[i] + YCbCr2rgbVector[1])*TCbCr2rgbMatrix[1][1]+(CrChannel[i] + YCbCr2rgbVector[2])*TCbCr2rgbMatrix[1][2];
      blueChannel[i]  = (YChannel[i] + YCbCr2rgbVector[0])*TCbCr2rgbMatrix[2][0]+(CbChannel[i] + YCbCr2rgbVector[1])*TCbCr2rgbMatrix[2][1]+(CrChannel[i] + YCbCr2rgbVector[2])*TCbCr2rgbMatrix[2][2];
  }
  </code></pre>
  
  <p>Where <code>redChannel</code>, <code>greenChannel</code> and <code>blueChannel</code> as well as <code>YChannel</code>, <code>CbChannel</code> and <code>CrChannel</code> are of <code>unsigned char *</code> type, and <code>height</code> and <code>width</code> are the dimensions of the picture. Why doesn't those pictures return the same, while all other tested pictures return perfectly fine.</p>
  
  <p><strong>p.s.</strong></p>
  
  <p>I've tested both pictures in Matlab using the commands <code>rgb2ycbcr</code> and <code>ycbcr2rgb</code>, and rounding them down with <code>uint8</code> and it gave me good results.</p>
  
  <pre><code>in=imread(pic);
  YCbCr = uint8(rgb2ycbcr(in));
  out = uint8(ycbcr2rgb(YCbCr));
  imshow(out);
  </code></pre>