这个RGB到XYZ颜色空间转换算法有什么问题?

前端之家收集整理的这篇文章主要介绍了这个RGB到XYZ颜色空间转换算法有什么问题?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的目标是将RGB像素转换为CIELab颜色空间,以便在CIELab中进行某些特殊计算.为此,我必须首先将RGB转换为XYZ,这是非常困难的部分.

我试图在Objective-C中实现这个算法(大多数使用普通C,但是结果是错误的).

我的代码是基于easyrgb.com提供的伪实现.他们有一个在线颜色转换器,这是非常有用的.他们说他们的伪代码与他们的转换器中使用的伪代码是一样的.

这是他们的伪代码

  1. var_R = ( R / 255 ) //R from 0 to 255
  2. var_G = ( G / 255 ) //G from 0 to 255
  3. var_B = ( B / 255 ) //B from 0 to 255
  4.  
  5. if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
  6. else var_R = var_R / 12.92
  7. if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
  8. else var_G = var_G / 12.92
  9. if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
  10. else var_B = var_B / 12.92
  11.  
  12. var_R = var_R * 100
  13. var_G = var_G * 100
  14. var_B = var_B * 100
  15.  
  16. //Observer. = 2°,Illuminant = D65
  17. X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
  18. Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
  19. Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505

这是我在Objective-C/C++中实现它的尝试:

  1. void convertRGBtoXYZ(NSInteger * inR,NSInteger * inG,NSInteger * inB,CGFloat * outX,CGFloat * outY,CGFloat * outZ) {
  2. // http://www.easyrgb.com/index.PHP?X=MATH&H=02#text2
  3.  
  4. CGFloat var_R = (*inR / 255); //R from 0 to 255
  5. CGFloat var_G = (*inG / 255); //G from 0 to 255
  6. CGFloat var_B = (*inB / 255); //B from 0 to 255
  7.  
  8. if (var_R > 0.04045f) {
  9. var_R = powf(( (var_R + 0.055f) / 1.055f),2.4f);
  10. } else {
  11. var_R = var_R / 12.92f;
  12. }
  13.  
  14. if (var_G > 0.04045) {
  15. var_G = powf(( (var_G + 0.055f) / 1.055f),2.4f);
  16. } else {
  17. var_G = var_G / 12.92f;
  18. }
  19.  
  20. if (var_B > 0.04045f) {
  21. var_B = powf(( (var_B + 0.055f) / 1.055f),2.4f);
  22. } else {
  23. var_B = var_B / 12.92f;
  24. }
  25.  
  26. var_R = var_R * 100;
  27. var_G = var_G * 100;
  28. var_B = var_B * 100;
  29.  
  30. //Observer. = 2°,Illuminant = D65
  31. *outX = var_R * 0.4124f + var_G * 0.3576f + var_B * 0.1805f;
  32. *outY = var_R * 0.2126f + var_G * 0.7152f + var_B * 0.0722f;
  33. *outZ = var_R * 0.0193f + var_G * 0.1192f + var_B * 0.9505f;
  34. }

但是,我没有得到与他们的工具相同的结果(具有相同的观察者和照明设置).

在我的测试中,我将这些值输入到他们的工具中,并为XYZ获得了这个结果,这与我的实现为RGB值产生了很大的差距.请看截图:

所得到的Lab颜色值非常接近Photoshop告诉我的,所以转换器工作很棒.

上面的C代码给了我这个结果:

  1. X = 35.76... // should be 42.282
  2. Y = 71.52... // should be 74.129
  3. Z = 11.92... // should be 46.262

任何想法,这个失败的原因是什么?我在执行过程中犯了错误,还是需要其他常量?

如果你知道一些测试的RGB到XYZ,XYZ到CIELab或RGB到CIELab,XYZ到Lab或RGB到Lab的实现,请不要犹豫,在这里张贴.

基本上,我想做的就是计算两种颜色之间的偏差,也称为Delta-E.这就是为什么我需要将RGB转换为XYZ到Lab(或CIELab)…

解决方法

我相信这是你的问题,这是截断到一个整数:
  1. CGFloat var_R = (*inR / 255); //R from 0 to 255
  2. CGFloat var_G = (*inG / 255); //G from 0 to 255
  3. CGFloat var_B = (*inB / 255); //B from 0 to 255

尝试这个:

  1. CGFloat var_R = (*inR / 255.0f); //R from 0 to 255
  2. CGFloat var_G = (*inG / 255.0f); //G from 0 to 255
  3. CGFloat var_B = (*inB / 255.0f); //B from 0 to 255

我没有检查其他代码的其他问题.

猜你在找的CSS相关文章