2014-02-20 2 views
0

RGB에서 LAB로 다시 변환하는 데 몇 가지 문제가 있습니다. LAB 색상 공간을 실험하면서 손을 잡으려하지만, RGB에서 XYZ로 변환하여 다시 LAB로 변환 할 수 있는지 확인하고 싶습니다.RGB to LAB 및 다시 버그 버그

처음에는 모든 것이 잘 보였지만, 나는 레나 테스트 이미지를 사용하는 경우에만 다른 이미지를 사용하자마자 블루스와 그린이 완전히 끊어져서 오류가 정확히 어디에서 발생했는지 알 수 없었습니다. .

나는 an image with many colors을 테스트했으며 RGB를 LAB로 변환 한 후 distorted colors을 얻었습니다. 여기

내 코드입니다 :

{ 
    double fcolorspace = 255.0f; 

    double* image1temp=new double[nWidth * nHeight * 4]; // this is our tempory buffer to hold image 1 

    // convert to RGB to LAB 
    for (int y = 0; y< nHeight; y++) 
    { 
     for (int x = 0; x< nWidth; x++) 
     { 
      int nIdx = x*4+y*4*nWidth; 

      double red1; 
      double green1; 
      double blue1; 

      double xyzX1; 
      double xyzY1; 
      double xyzZ1; 

      double var_X1; 
      double var_Y1; 
      double var_Z1; 

      double refX; 
      double refY; 
      double refZ; 

      double var_X11; 
      double var_Y12; 
      double var_Z13; 

      //read in image from array 
      red1 = double(pBGRA_in1[nIdx + CHANNEL_R])/fcolorspace; 
      green1 = double(pBGRA_in1[nIdx + CHANNEL_G])/fcolorspace; 
      blue1 = double(pBGRA_in1[nIdx + CHANNEL_B])/fcolorspace; 

      //adjust gamma on image 1 
      if (red1 > 0.04045f) 
      { 
       red1 = powf((red1 + 0.055f)/1.055f, 2.4f); 
      } 
      else 
      { 
       red1 = red1/12.92f; 
      } 
      if (green1 > 0.04045f) 
      { 
       green1 = powf((green1 + 0.055f)/1.055f, 2.4f); 
      } 
      else 
      { 
       green1 = green1/12.92f; 
      } 
      if (blue1 > 0.04045f) 
      { 
       blue1 = powf((blue1 + 0.055f)/1.055f, 2.4f); 
      } 
      else 
      { 
       blue1 = blue1/12.92f; 
      } 

      //scale 
      red1 = red1 * 100.0f; 
      green1 = green1 * 100.0f; 
      blue1 = blue1 * 100.0f; 

      //first we will convert the RGB image to XYZ 
      xyzX1 = (0.4124f * red1) + (0.3576f * green1) + (0.1805f * blue1); 
      xyzY1 = (0.2126f * red1) + (0.7152f * green1) + (0.0722f * blue1); 
      xyzZ1 = (0.0193f * red1) + (0.1192f * green1) + (0.9505f * blue1); 

      //reference white 
      refX = 95.047f; // Observer= 2°, Illuminant= D65 
      refY = 100.000f; 
      refZ = 108.883f; 

      //adjust LAB to reference white 
      var_X1 = xyzX1/refX; 
      var_Y1 = xyzY1/refY; 
      var_Z1 = xyzZ1/refZ; 

      //LAB Conversion 
      if (var_X1 > 0.008856f) 
      { 
       var_X11 = powf(var_X1 , 1.0f/3.0f); 
      } 
      else 
      { 
       var_X11 = (7.787f * var_X1) + (16.0f/116.0f); 
      } 

      if (var_Y1 > 0.008856f) 
      { 
       var_Y12 = powf(var_Y1 , 1.0f/3.0f); 
      } 
      else 
      { 
       var_Y12 = (7.787f * var_Y1) + (16.0f/116.0f); 
      } 

      if (var_Z1 > 0.008856f) 
      { 
       var_Z13 = powf(var_Z1 , 1.0f/3.0f); 
      } 
      else 
      { 
       var_Z13 = (7.787f * var_Z1) + (16.0f/116.0f); 
      } 

      //adjust LAB scale 
      double cieL1 = (116.0f * var_Y12) - 16.0f; 
      double cieA1 = 500.0f * (var_X11 - var_Y12); 
      double cieB1 = 200.0f * (var_Y12 - var_Z13); 

      //we are now in the LAB colorspace 
      f_outred = CLAMP255(cieL1); 
      f_outgreen = CLAMP255(cieA1); 
      f_outblue = CLAMP255(cieB1); 

      //place LAB image in temp array 
      image1temp[nIdx + CHANNEL_R] = int(f_outred); 
      image1temp[nIdx + CHANNEL_G] = int(f_outgreen); 
      image1temp[nIdx + CHANNEL_B] = int(f_outblue); 
     } 
    } 

    //convert from LAB to XYZ 
     for (int x = 0; x< nWidth; x++) 
     { 
      for (int y = 0; y< nHeight; y++) 
      { 
       int nIdx = x * 4 + y * 4 * nWidth; 

       double refX; 
       double refY; 
       double refZ; 

       double var_X; 
       double var_Y; 
       double var_Z; 

       double cieX; 
       double cieY; 
       double cieZ; 

       double red; 
       double green; 
       double blue; 

       //reference white 
       refX = 95.047f; // Observer= 2°, Illuminant= D65 
       refY = 100.000f; 
       refZ = 108.883f; 

       double cieL = image1temp [nIdx + CHANNEL_R]; 
       double cieA = image1temp [nIdx + CHANNEL_G]; 
       double cieB = image1temp [nIdx + CHANNEL_B]; 

       var_Y = (cieL + 16.0f)/116.0f; 
       var_X = cieA/500.0f + var_Y; 
       var_Z = var_Y - cieB/200.0f; 

       if (powf(var_Y, 3.0f) > 0.008856) 
       { 
        var_Y = powf(var_Y, 3.0f); 
       } 
       else 
       { 
        var_Y = (var_Y - 16.0f/116.0f)/7.787f; 
       } 
       if (powf(var_X , 3.0f) > 0.008856f) 
       { 
        var_X = powf(var_X, 3.0f); 
       } 
       else 
       { 
        var_X = (var_X - 16.0f/116.0f)/7.787f; 
       } 
       if (powf(var_Z, 3.0f) > 0.008856) 
       { 
        var_Z = powf(var_Z, 3.0f); 
       } 
       else 
       { 
        var_Z = (var_Z - 16.0f/116.0f)/7.787f; 
       } 

       cieX = refX * var_X; 
       cieY = refY * var_Y; 
       cieZ = refZ * var_Z; 

       var_X = cieX/100.0f; 
       var_Y = cieY/100.0f; 
       var_Z = cieZ/100.0f; 

       red = var_X * 3.2406f + var_Y * -1.5372f + var_Z * -0.4986f; 
       green = var_X * -0.9689f + var_Y * 1.8758f + var_Z * 0.0415f; 
       blue = var_X * 0.0557f + var_Y * -0.2040f + var_Z * 1.0570f; 

       if (red > 0.0031308f) 
       { 
        red = 1.055f * powf(red , (1.0f/2.4f)) - 0.055f; 
       } 
       else 
       { 
        red = 12.92f * red; 
       } 
       if (green > 0.0031308f) 
       { 
        green = 1.055f * powf(green , (1.0f/2.4f)) - 0.055f; 
       } 
       else 
       { 
        green = 12.92f * green; 
       } 
       if (blue > 0.0031308f) 
       { 
        blue = 1.055f * powf(blue , (1.0f/2.4f)) - 0.055f; 
       } 
       else 
       { 
        blue = 12.92f * blue; 
       } 

       red = CLAMP255(red * fcolorspace); 
       green = CLAMP255(green * fcolorspace); 
       blue = CLAMP255(blue * fcolorspace); 

       pBGRA_out[nIdx + CHANNEL_R] = red; 
       pBGRA_out[nIdx + CHANNEL_G] = green; 
       pBGRA_out[nIdx + CHANNEL_B] = blue; 
      } 
     } 

    delete [] image1temp;//delete the array 
    delete [] image2temp;//delete the array 

} 
+0

SSE 최적화 버전을 만드셨습니까? – Royi

답변

1

당신은 CLAMP255 소스를 표시하지 않습니다,하지만 난이 아니라 완전히 잘못된 것 그것은 실험실 출력의 경우 0에서 255 사이에 값을 클램프 같은데요 그들은 다른 범위를 사용합니다; 나는 ab이 0 이하로 떨어지는 것을 안다.

+0

감사합니다. 문제가 정확히 무엇인지, LAB 공식에서 CLAMP255를 제거하면 모든 것이 완벽하게 작동합니다. –