从 LAB 到 RGB 的颜色转换出现意外结果

问题描述 投票:0回答:2

我的目标是在 LAB 中创建高分辨率的比色图表图像。 我是编程初学者,我使用Processing,因为这是我所知道的最好的方法。但是,它仅适用于 RGB 或 HSB,因此我必须将 LAB 转换为 RGB 才能显示它。

我使用了网上找到的公式(LAB到XYZ和XYZ到RGB) 我将它们包含在我的代码中,然后使用“for”循环来确定每个像素的颜色。

我看到了一些关于颜色转换的主题,但我有点困惑,因为我不知道我的问题来自哪里....

所以这里是:对于固定值 L = 100,一切都运行良好,我得到了预期的图像: https://drive.google.com/file/d/0ByjuuWpChE01X3otSFRQNFUyVjA/edit?usp=sharing

但是当我尝试制作另一张固定值 a = 0 的图像时,我在底部得到一条水平线,就好像 L 值较低时出现问题一样......这里是: https://drive.google.com/file/d/0ByjuuWpChE01RzJWUVZnR2U3VW8/edit?usp=sharing

这是我的代码,希望能清楚,如果需要什么可以问我,非常感谢您的帮助。

// parameters for the code execution
void setup() {
  noLoop();
  size(10,10,P2D);

  nuancier = createGraphics(taille,taille);

}

// final image file and size
PGraphics nuancier ;
int taille = 1000 ;


// Arrays for color values
float[] colorLAB = new float[3];
float[] colorXYZ = new float[3];
float[] colorRGB = new float[3];

// colors
float X;
float Y;
float Z;
float L;
float a;
float b;
float R;
float G;
float B;

// pixels
int x ;
int y ;

// function to convert Lab to XYZ
float[] LABtoXYZ() {

  L = colorLAB[0];
  a = colorLAB[1];
  b = colorLAB[2];


  float ntY = ( L + 16 ) / 116 ;
  float ntX = a / 500 + ntY ;
  float ntZ = ntY - b / 200 ;
  if ( (pow(ntY,3)) > 0.008856 ) {
    ntY = (pow(ntY,3)) ;
  } else { ntY = ( ntY - 16 / 116 ) / 7.787 ; }
  if ( (pow(ntX,3)) > 0.008856 ) {
    ntX = (pow(ntX,3)) ;
  } else { ntX = ( ntX - 16 / 116 ) / 7.787 ; }
  if ( (pow(ntZ,3)) > 0.008856 ) {
    ntZ = (pow(ntZ,3)) ;
  } else { ntZ = ( ntZ - 16 / 116 ) / 7.787 ; }
  X = 95.047 * ntX ;     //ref_X =  95.047      Observateur= 2°, Illuminant= D65
  Y = 100 * ntY ;     //ref_Y = 100.000
  Z = 108.883 * ntZ ;     //ref_Z = 108.883


  colorXYZ[0] = X ;
  colorXYZ[1] = Y ;
  colorXYZ[2] = Z ;
  return colorXYZ ;

}

// function to convert  XYZ to RGB
float[] XYZtoRGB() {

  X = colorXYZ[0];
  Y = colorXYZ[1];
  Z = colorXYZ[2];


  float ntX = X / 100 ;         //X compris entre 0 et  95.047      ( Observateur = 2°, Illuminant = D65 )
  float ntY = Y / 100 ;         //Y compris entre 0 et 100.000
  float ntZ = Z / 100 ;         //Z compris entre 0 et 108.883

  float ntR = ntX *  3.2406 + ntY * (-1.5372) + ntZ * (-0.4986) ;
  float ntG = ntX * (-0.9689) + ntY *  1.8758 + ntZ *  0.0415 ;
  float ntB = ntX *  0.0557 + ntY * (-0.2040) + ntZ *  1.0570 ;

  if ( ntR > 0.0031308 ) {
    ntR = 1.055 * ( pow(ntR,( 1 / 2.4 )) ) - 0.055 ;
  } else { ntR = 12.92 * ntR ; }
  if ( ntG > 0.0031308 ) {
    ntG = 1.055 * ( pow(ntG,( 1 / 2.4 )) ) - 0.055 ;
  } else { ntG = 12.92 * ntG ; }
  if ( ntB > 0.0031308 ) {
    ntB = 1.055 * ( pow(ntB,( 1 / 2.4 )) ) - 0.055 ;
  } else { ntB = 12.92 * ntB ; }

  R = ntR * 255 ;
  G = ntG * 255 ;
  B = ntB * 255 ;

  colorRGB[0] = R ;
  colorRGB[1] = G ;
  colorRGB[2] = B ;
  return colorRGB ;

}

// I know that with RGB, not every visible color is possible
//so I just made this quick function, to bound RGB values between 0 and 255

float[] arrondirRGB () {
  for (int i=0;i<3;i++) {
    if (colorRGB[i]>255) {
      colorRGB[i]=255 ;
    }
    if (colorRGB[i]<0) {
      colorRGB[i]=0 ;
    }
  }
  return colorRGB;
}



// operating section
void draw () {

  nuancier.beginDraw();
  nuancier.noSmooth();
  nuancier.colorMode(RGB, 255);
  nuancier.endDraw();

  for (x=0;x<taille;x++) {
    for (y=0;y<taille;y++) {

      colorLAB[0] = (((taille-y)*100)/taille) ; // --------------------------------------------------------------- valeur 100  // formule ((x*100)/taille)
      colorLAB[1] = 0 ; // ----------------------------------------------------------- valeur 0    // formule ((x*256)/taille)-127
      colorLAB[2] = (((x)*256)/taille)-127 ; // -------------------------------------------------- valeur 0    // (((taille-y)*256)/taille)-127

      println(colorLAB[0]);

      LABtoXYZ () ;
      XYZtoRGB () ;
      arrondirRGB () ;

      nuancier.beginDraw();
      nuancier.stroke (colorRGB[0],colorRGB[1],colorRGB[2]);
      nuancier.point (x,y);
      nuancier.endDraw();


    }
  }

  nuancier.save("nuancier.tiff");
  println("done !");
}
colors processing
2个回答
1
投票

好吧我发现了!

问题是除以整数。

我不知道它是否像其他语言一样工作,但是在处理中如果你写 x = 2/5 结果将是 x = 0 而不是 x = 0.4 ;这是因为分母是整数,结果将始终是整数......所以 x = 2/5.0 将给出 x = 0.4!

我必须在每次整数除法之后加上“.0”,然后将任何要除法的整数数据浮点。

结果很完美,没有更多问题!

https://github.com/processing/processing/wiki/Troubleshooting#Why_does_2_.2F_5_.3D_0_instead_of_0.4.3F


0
投票

XYZtoRGB 函数内计算 RGB 值时使用的值是错误的。这会产生错误的 RGB 值。正确的计算代码是这样的:(用 php 编写,因此请针对任何其他程序语言更改它):

function xyz_to_rgb($X,$Y,$Z){
//X, Y and Z input refer to a D65/2° standard illuminant.
//aR, aG and aB (RGB Adobe 1998) output range = 0 ÷ 255
$var_X = ($X / 100);
$var_Y = ($Y / 100);
$var_Z = ($Z / 100);

$var_R = ($var_X*2.04137)+($var_Y*-0.56495)+($var_Z*-0.34469);
$var_G = ($var_X*-0.96927)+($var_Y*1.87601)+($var_Z*0.04156);
$var_B = ($var_X*0.01345)+($var_Y*-0.11839)+($var_Z*1.01541);
$var_R = pow($var_R,(1/2.19921875));
$var_G = pow($var_G,(1/2.19921875));
$var_B = pow($var_B,(1/2.19921875));

$aR = $var_R * 255;
$aG = $var_G * 255;
$aB = $var_B * 255;
$rgb= sprintf("#%02x%02x%02x;", $aR, $aG, $aB);
return $rgb;
}
© www.soinside.com 2019 - 2024. All rights reserved.