這個RGB到XYZ顏色空間轉換演算法有什麼問題?
我的目標是將RGB畫素轉換為CIELab顏色空間,以便在CIELab中進行某些特殊計算.為此,我必須首先將RGB轉換為XYZ,這是非常困難的部分.
我試圖在Objective-C中實現這個演算法(大多數使用普通C,但是結果是錯誤的).
我的程式碼是基於ofollow,noindex" target="_blank">easyrgb.com 提供的偽實現.他們有一個線上顏色轉換器,這是非常有用的.他們說他們的虛擬碼與他們的轉換器中使用的虛擬碼是一樣的.
這是他們的虛擬碼:
var_R = ( R / 255 )//R from 0 to 255 var_G = ( G / 255 )//G from 0 to 255 var_B = ( B / 255 )//B from 0 to 255 if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4 elsevar_R = var_R / 12.92 if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4 elsevar_G = var_G / 12.92 if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4 elsevar_B = var_B / 12.92 var_R = var_R * 100 var_G = var_G * 100 var_B = var_B * 100 //Observer. = 2°, Illuminant = D65 X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805 Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722 Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
這是我在Objective-C/C++中實現它的嘗試:
void convertRGBtoXYZ(NSInteger * inR, NSInteger * inG, NSInteger * inB, CGFloat * outX, CGFloat * outY, CGFloat * outZ) { // http://www.easyrgb.com/index.php?X=MATH&H=02#text2 CGFloat var_R = (*inR / 255); //R from 0 to 255 CGFloat var_G = (*inG / 255); //G from 0 to 255 CGFloat var_B = (*inB / 255); //B from 0 to 255 if (var_R > 0.04045f) { var_R = powf(( (var_R + 0.055f) / 1.055f), 2.4f); } else { var_R = var_R / 12.92f; } if (var_G > 0.04045) { var_G = powf(( (var_G + 0.055f) / 1.055f), 2.4f); } else { var_G = var_G / 12.92f; } if (var_B > 0.04045f) { var_B = powf(( (var_B + 0.055f) / 1.055f), 2.4f); } else { var_B = var_B / 12.92f; } var_R = var_R * 100; var_G = var_G * 100; var_B = var_B * 100; //Observer. = 2°, Illuminant = D65 *outX = var_R * 0.4124f + var_G * 0.3576f + var_B * 0.1805f; *outY = var_R * 0.2126f + var_G * 0.7152f + var_B * 0.0722f; *outZ = var_R * 0.0193f + var_G * 0.1192f + var_B * 0.9505f; }
但是,我沒有得到與他們的工具相同的結果(具有相同的觀察者和照明設定).
在我的測試中,我將這些值輸入到他們的工具中,併為XYZ獲得了這個結果,這與我的實現為RGB值產生了很大的差距.請看截圖:
所得到的Lab顏色值非常接近Photoshop告訴我的,所以轉換器工作很棒.
上面的C程式碼給了我這個結果:
X = 35.76... // should be 42.282 Y = 71.52... // should be 74.129 Z = 11.92... // should be 46.262
任何想法,這個失敗的原因是什麼?我在執行過程中犯了錯誤,還是需要其他常量?
如果你知道一些測試的RGB到XYZ,XYZ到CIELab或RGB到CIELab,XYZ到Lab或RGB到Lab的實現,請不要猶豫,在這裡張貼.
基本上,我想做的就是計算兩種顏色之間的偏差,也稱為Delta-E.這就是為什麼我需要將RGB轉換為XYZ到Lab(或CIELab)…
我相信這是你的問題,這是截斷到一個整數:
CGFloat var_R = (*inR / 255); //R from 0 to 255 CGFloat var_G = (*inG / 255); //G from 0 to 255 CGFloat var_B = (*inB / 255); //B from 0 to 255
嘗試這個:
CGFloat var_R = (*inR / 255.0f); //R from 0 to 255 CGFloat var_G = (*inG / 255.0f); //G from 0 to 255 CGFloat var_B = (*inB / 255.0f); //B from 0 to 255
我沒有檢查其他程式碼的其他問題.
程式碼日誌版權宣告:
翻譯自:http://stackoverflow.com/questions/6629798/whats-wrong-with-this-rgb-to-xyz-color-space-conversion-algorithm