Color temperature (Kelvin) to RGB conversion: Algorithms and Sample

                         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:

  1. 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.
  2. 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.
  3. 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:

 

从图表可以看出,有一些上限值和下限值,使得我们的算法很容易实现。特别的:

  1. 红色分量在6600K以下的时候总保持255
  2. 蓝色分量在2000K的时候总保持0
  3. 蓝色问了在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/

发布了49 篇原创文章 · 获赞 138 · 访问量 30万+

Guess you like

Origin blog.csdn.net/lz0499/article/details/104088393