色温度(K)をRGBに変換:アルゴリズムとサンプルコード





色温度がわからない場合は、 ここから始めてください



PhotoDemonの色温度ツールに取り組んで夜中ずっと温度値(ケルビン)とRGBの間の変換のためのシンプルでわかりやすいアルゴリズムを決定しようとしました。 多くの写真編集者は色温度を補正するツールを備えており、スマートフォンを含む最新のカメラはすべて、照明条件に基づいてホワイトバランスを調整するため、このようなアルゴリズムは簡単に見つかると思いました。





ホワイトバランスが設定されたカメラ画面の例。 出所



温度をRGBに変換するための信頼できる式を見つけることはほとんど不可能であることが判明しました。 もちろん、いくつかのアルゴリズムがありますが、それらのほとんどは温度をXYZ色空間に変換することで機能し、RGB変換を追加できます。 そのようなアルゴリズムはRobertsonメソッドに基づいているようです。その実装の1つはここにあり、もう1つはここにあります



残念ながら、このアプローチは純粋に数学的な公式を提供するものではありません-それは単に変換テーブルに従った補間です。 これは特定の状況では妥当かもしれませんが、追加の変換XYZ→RGBを考慮すると、リアルタイムで色温度を簡単に調整するには遅すぎることがわかります。



だから私は自分のアルゴリズムを書いたが、それはうまく機能している。 これは私がそれを得た方法です。



このアルゴリズムに関する警告



警告1 :私のアルゴリズムは高品質の近似値を提供しますが、科学的な深刻な使用には十分に正確ではありません。 これは主に写真を操作するためのものです-そのため、天文学や医学で使用しないでください。



警告2 :このアルゴリズムは比較的単純であるため、妥当なサイズの画像(12メガピクセルの画像でテストしました)でリアルタイムで動作するのに十分高速ですが、最良の結果を得るには、プログラミング言語に固有の数学的最適化を適用します。 複雑にならないように、数学的最適化なしでアルゴリズムを示します。



警告3 :アルゴリズムは、1000 K〜40,000 Kの範囲でのみ使用できます。これは、写真撮影に適した範囲です。 (実際、ほとんどの状況で必要とされるよりもはるかに大きいです)。 この範囲を超える温度では機能しますが、品質は低下します。



ミッチェルチャリティに感謝



まず、私はこれらのアルゴリズムを作成するために使用した初期データ、つまり未処理の黒体ファイルについて、Mitchell Charityに多くの負債を支払わなければなりません 。 チャリティは2つのデータセットを提供し、私のアルゴリズムはCIE 1964 10度カラーマッチング関数を使用します 。 10度セットと比較したジャッドウォスの修正を伴う2度CIE 1931関数の説明は、この記事の範囲外ですが、興味がある場合は、 このページから包括的な分析を開始できます



アルゴリズム:出力例



1000 K〜40,000 Kの範囲のアルゴリズムの出力を次に示します。





私のアルゴリズムの出力は1000 K〜40,000 Kです。白い点は6500〜6600 Kで、最新のLCDモニターで写真を処理するのに最適です。



1500 Kから15000 Kの写真の興味深い範囲でのアルゴリズムのより詳細なスナップショットは次のとおりです。





同じアルゴリズム、ただし1500 K〜15000 K



ご覧のとおり、バンディングは最小限であり、上記のマッチングテーブルに比べて大幅に改善されています。 このアルゴリズムは、白いドットの近くに明るい黄色の色相を保持するという素晴らしい仕事もします。これは、写真の後処理で日光をシミュレートするために重要です。



このアルゴリズムに至った経緯



信頼できる式を導き出すための最初のステップは、Charityから元の黒体値をプロットすることでした。 LibreOffice / OpenOffice .ods(430 KB)の形式でスプレッドシート全体をダウンロードできます。



プロット後のデータは次のとおりです。





RGB(sRGB)の元の温度データ(K)、LibreOffice Calcグラフ。 この場合も、変換はCIE 1964 10度CMF関数に基づいており、必要に応じて、白色点は6500 K〜6600 K(グラフの左側のピーク)です。 出所



アルゴリズムを単純化するいくつかのセクションがあることは簡単にわかります。 特に:





曲線をデータに適合させるために、緑は2つの別々の曲線として最もよく表示されることに注意することも重要です。



その瞬間から、データ(「常に0」と「常に255」のセグメントなし)を別々の色成分に分割しました。 理想的な世界では、曲線はポイントの各セットに合わせて調整できますが、残念ながら、実際にはそれほど単純ではありません。 グラフのXとYの値には大きな不一致があるため、すべてのx値は1000より大きく、100ドットセグメントで表示されますが、y値は255から0の間です-最適に合わせるためにxデータを転置する必要がありました。 最適化のために、最初にx(温度)の値を各色ごとに100で除算し、グラフへの適合に大いに役立つ場合に必要な量を減算しました。 最適な曲線とそれに対応する決定係数の値(Rの2乗)と同様に、各曲線の結果の図は次のとおりです。



















フォントのひどいカーニングとチャートのヒントをおpoびします。 LibreOfficeには多くの利点がありますが、グラフのフォントをスムーズにできないことは完全に恥ずべきことです。 また、スクリーンショットにはエクスポートオプションがないため、スクリーンショットから図を抽出することは好きではありませんが、後で使用することをお勧めします。



ご覧のとおり、すべての曲線は非常によく整列しており、決定係数の値は0.987を超えています。 曲線の調整にもっと時間をかけることもできますが、写真を処理するにはこれで十分です。 曲線が黒体の最初の理想化された観測に正確に対応していないと言う住民は一人もいませんよね?



アルゴリズム



以下は、その栄光に満ちたアルゴリズムです。



まず、擬似コード:



     -  1000  40000. (   ,             40000 K).  ,             . Set Temperature = Temperature \ 100  : 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  : 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  : 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()は自然対数を意味することに注意してください。 また、温度が常に推奨範囲内にある場合、色が0より小さい場合はチェックを省略できることに注意してください。 (ただし、「色が255より大きい場合」のチェックを残す必要があります)。



実際のコードに関して、ここにPhotoDemonで使用する正確なVisual Basic関数を示します。 まだ最適化されていません(たとえば、対応表を使用すると対数がはるかに高速になります)が、少なくともコードは簡潔で読みやすくなっています。



 '   ( )  RGB- Private Sub getRGBfromTemperature(ByRef r As Long, ByRef g As Long, ByRef b As Long, ByVal tmpKelvin As Long) Static tmpCalc As Double '      1000  40000  If tmpKelvin < 1000 Then tmpKelvin = 1000 If tmpKelvin > 40000 Then tmpKelvin = 40000 '   tmpKelvin \ 100,       tmpKelvin = tmpKelvin \ 100 '     '  If tmpKelvin <= 66 Then r = 255 Else ':  R-    0,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 '  If tmpKelvin <= 66 Then ':  R-    0,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 ':  R-    0,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 ',  If tmpKelvin >= 66 Then b = 255 ElseIf tmpKelvin <= 19 Then b = 0 Else ':  R-    0,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
      
      





この記事は、この記事の冒頭でサンプル出力を生成するために使用されたため、機能することを保証できます。



サンプル画像



色温度調整ができることの良い例がここにあります。 下の画像-HBOのTrue Bloodの広告ポスター-は、色温度を調整する可能性を壮観に示しています。 左側は元のフレームです。 右側-上記のコードを使用して色温度を調整します。 ワンクリックで、夜景を日光に合わせて作り直すことができます。





動作中の色温度調整



PhotoDemonプログラムの実際の色温度ツールは次のとおりです。





PhotoDemon色温度ツール



プログラムをダウンロードして、実際の動作をご覧ください。



2014年10月に更新



Renault Bedarは、このアルゴリズムの優れたオンラインデモを作成しました。 ありがとうルノー!



2015年4月に更新



元のアルゴリズムの改善を提案してくれた皆さんに感謝します。 この記事には多くのコメントがありますが、独自のバージョンを実装する予定がある場合は、読む価値があります。



2つの特定の改善点を強調したいと思います。 まず、Neil Bは元の曲線近似関数に最適なバージョンを提供してくれました。これにより、温度係数がわずかに変化します。 変更点については、 彼の優れた記事で詳しく説明されています



その後、Francis Lochがいくつかのコメントと画像の例を追加しました。これらは写真にこれらの変換を適用したい場合に非常に便利です。 例に見られるように、その修正により、より詳細な画像が生成されます



All Articles