Color temperature (Kelvin) to RGB conversion: Algorithms and Sample
As far as I know, it is unlikely to find a reliable formula for converting from the color temperature to RGB. Although, there are many algorithms to achieve similar functionality, however, are mostly converted from the color temperature to XYZ color space. After that you can re-needed space in the conversion from XYZ to RGB color space. One implementation of this algorithm you can find here.
Unfortunately, this approach is not a mathematical formula in the true sense, but a way to achieve the look-up table landscaping. In some cases, this is a reliable implementation. However, when it comes to XYZ-> RGB conversion time, for simple adjustment of the color temperature in real time, in this way too slow.
So, I set the color temperature to achieve the RGB conversion algorithm. The conversion algorithm is quite good. The following are some of my ideas.
Use some of the limitations of this algorithm:
- My algorithm is a highly accurate estimate. However, in terms of scientific accuracy is not enough. This algorithm is mainly used in the treatment of some photos, so do not try to use this algorithm in astronomy and medical image processing.
- Since the algorithm is relatively simple, the image processing algorithm suitable size, real time has rapidly enough. However, in order to obtain better real-time performance, you must implement the programming language you are using this algorithm and then do some optimization.
- This algorithm applies only to convert 1000K to 40000K color temperature of. For photography for such a large spectral range is sufficient. When using the color temperature exceeds this range, the accuracy will decrease.
Algorithm: Sample output
FIG algorithm output is the image of 1000K to 40000K.
FIG lower color temperature range of interest in photography: from 1500K to 15000K
Algorithm thinking
My first step is to work from the Charity's original blackbody values to achieve a reliable formula for reverse engineering method.
Charity's original blackbody values of the data represented graphically as:
从图表可以看出,有一些上限值和下限值,使得我们的算法很容易实现。特别的:
- 红色分量在6600K以下的时候总保持255
- 蓝色分量在2000K的时候总保持0
- 蓝色问了在6500K以上总保持255
为了更好地拟合这些数据,绿色分量被划分为两部分进行拟合。一部分是低于6600K;另一部分是高于6600K。
之后,我把数据分成独立的颜色分量进行拟合。(不包括那些总是为0和255的数据)。理想状态下,有一条曲线将经过每一个数据点。但现实情况,往往没这么理想。因为对于上图中X轴和Y轴的数据而言,它们的数值相差太大。X轴的数值都大于1000,对于Y轴而言,其数值范围在0到255之间。我们必须对X轴的数据做相应的转换才能更好的进行曲线拟合。为了达到最优拟合的目的,我对X轴的数据做了除100处理,并进行了相应的偏移。以下是每个分量的数据分布和最优的拟合曲线:
如上图所述,其曲线拟合的很好。
算法实现
以下是算法实现的伪代码:
输入:1000K到40000K的色温;色温和颜色分量的变量必须是双精度
Set Temperature = Temperature \ 100
Calculate Red:
If Temperature <= 66 Then
Red = 255
Else
Red = Temperature - 60
Red = 329.698727446 * (Red ^ -0.1332047592)
If Red < 0 Then Red = 0
If Red > 255 Then Red = 255
End If
Calculate Green:
If Temperature <= 66 Then
Green = Temperature
Green = 99.4708025861 * Ln(Green) - 161.1195681661
If Green < 0 Then Green = 0
If Green > 255 Then Green = 255
Else
Green = Temperature - 60
Green = 288.1221695283 * (Green ^ -0.0755148492)
If Green < 0 Then Green = 0
If Green > 255 Then Green = 255
End If
Calculate Blue:
If Temperature >= 66 Then
Blue = 255
Else
If Temperature <= 19 Then
Blue = 0
Else
Blue = Temperature - 10
Blue = 138.5177312231 * Ln(Blue) - 305.0447927307
If Blue < 0 Then Blue = 0
If Blue > 255 Then Blue = 255
End If
End If
上述伪代码中,Ln()表示的是自然对数。
以下是VB的代码实现。以下代码未做优化,但是代码简短可读性好。
Static tmpCalc As Double
'Temperature must fall between 1000 and 40000 degrees
If tmpKelvin < 1000 Then tmpKelvin = 1000
If tmpKelvin > 40000 Then tmpKelvin = 40000
'All calculations require tmpKelvin \ 100, so only do the conversion once
tmpKelvin = tmpKelvin \ 100
'Calculate each color in turn
'First: red
If tmpKelvin <= 66 Then
r = 255
Else
'Note: the R-squared value for this approximation is .988
tmpCalc = tmpKelvin - 60
tmpCalc = 329.698727446 * (tmpCalc ^ -0.1332047592)
r = tmpCalc
If r < 0 Then r = 0
If r > 255 Then r = 255
End If
'Second: green
If tmpKelvin <= 66 Then
'Note: the R-squared value for this approximation is .996
tmpCalc = tmpKelvin
tmpCalc = 99.4708025861 * Log(tmpCalc) - 161.1195681661
g = tmpCalc
If g < 0 Then g = 0
If g > 255 Then g = 255
Else
'Note: the R-squared value for this approximation is .987
tmpCalc = tmpKelvin - 60
tmpCalc = 288.1221695283 * (tmpCalc ^ -0.0755148492)
g = tmpCalc
If g < 0 Then g = 0
If g > 255 Then g = 255
End If
'Third: blue
If tmpKelvin >= 66 Then
b = 255
ElseIf tmpKelvin <= 19 Then
b = 0
Else
'Note: the R-squared value for this approximation is .998
tmpCalc = tmpKelvin - 10
tmpCalc = 138.5177312231 * Log(tmpCalc) - 305.0447927307
b = tmpCalc
If b < 0 Then b = 0
If b > 255 Then b = 255
End If
End Sub
算法效果:
下图是色温调整算法实现的效果图。左侧是原始图像,有测试经过上述色温调整算法后的图像。
实际在工具中实现的效果如下图所示:
有选择的翻译至:http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/