線形RGB空間と非線形RGB空間の色を操作する場合の実際的な違いは何ですか?


88

線形RGB空間の基本的な特性と非線形空間の基本的な特性は何ですか?これらの8(またはそれ以上)ビットの各チャネル内の値について話すとき、何が変わりますか?

OpenGLでは、色は3 + 1の値であり、これはRGB +アルファを意味し、各チャネルに8ビットが予約されています。これが明確に得られる部分です。

しかし、ガンマ補正に関しては、非線形RGB空間での作業の効果がわかりません。

グラフィックソフトウェアで曲線を使用して写真編集を行う方法を知っているので、線形RGB空間では、値をそのまま使用し、操作や数学関数を追加せずに、それぞれが非線形の場合に値を取得することを説明します。チャネルは通常、古典的なべき関数の動作に従って進化します。

この説明を実際の説明と見なしても、実際の線形空間が何であるかはわかりません。計算後、すべての非線形RGB空間が線形になり、最も重要なのは、非線形空間が得られないためです。 -線形色空間は、最終的にすべてのRGB空間が私が理解していることに対して線形であるため、人間の目に適しています。


実際には、SVGの色空間として線形または標準RGBのいずれかを指定できますが、これが重要であると思われるという事実を除けば、効果が何であるかは
わかり

@MichaelMullanyこの直線的なものは、実際の独特の品質というよりも、ユーザーにとってのヒントのように見えます。
ケン

私を助けてくれたのは、「線形を聞いたら線を考えなさい」と言ったのは数学の先生だったと思います。これが役立つかどうかはわかりませんが、私にとっては「そうそう」でした。瞬間
ジョープランテ2012年

回答:


229

RGBカラーを使用しているとしましょう。各カラーは3つの強度または明るさで表されます。「リニアRGB」と「sRGB」のどちらかを選択する必要があります。今のところ、3つの異なる強度を無視して物事を単純化し、強度が1つだけであると想定します。つまり、グレーの色合いのみを扱っているということです。

線形色空間では、格納する数値とそれらが表す強度の関係は線形です。実際には、これは、数値を2倍にすると、強度(灰色の明度)が2倍になることを意味します。2つの強度を一緒に追加したい場合(2つの光源の寄与に基づいて強度を計算しているため、または不透明なオブジェクトの上に透明なオブジェクトを追加しているため)、これを行うには、一緒に2つの数字。あらゆる種類の2Dブレンディングや3Dシェーディング、またはほぼすべての画像処理を行っている場合は、線形色空間で強度が必要です。、したがって、数値を加算、減算、乗算、および除算するだけで、強度に同じ影響を与えることができます。ほとんどのカラー処理およびレンダリングアルゴリズムは、すべてに重みを追加しない限り、線形RGBでのみ正しい結果を提供します。

それは本当に簡単に聞こえますが、問題があります。光に対する人間の目の感度は、高強度よりも低強度の方が細かくなります。つまり、区別できるすべての強度のリストを作成すると、明るいものよりも暗いものの方が多くなります。別の言い方をすれば、明るいグレーの色合いよりも暗いグレーの色合いを区別することができます。特に、強度を表すために8ビットを使用していて、これを線形色空間で行うと、明るい色合いが多すぎて、暗い色合いが不十分になります。暗い領域ではバンディングが発生しますが、明るい領域では、ユーザーが区別できない、白に近いさまざまな色合いのビットを無駄にしています。

この問題を回避し、これらの8ビットを最大限に活用するために、sRGBを使用する傾向があります。sRGB規格は、色を非線形にするために使用する曲線を示しています。カーブは下部が浅いため、濃い灰色が多くなり、上部が急になるため、明るい灰色が少なくなります。数値を2倍にすると、強度が2倍以上になります。これは、sRGBカラーを一緒に追加すると、本来よりも明るい結果になることを意味します。最近では、ほとんどのモニターが入力色をsRGBとして解釈します。したがって、画面に色を配置する場合、またはチャネルごとに8ビットのテクスチャで保存する場合は、sRGBとして保存して、これらの8ビットを最大限に活用します。

問題が発生していることに気付くでしょう。色は線形空間で処理されますが、sRGBで保存されます。つまり、読み取り時にsRGBから線形への変換を実行し、書き込み時に線形からsRGBへの変換を実行することになります。線形8ビット強度には十分な暗さがないことをすでに述べたように、これは問題を引き起こす可能性があるため、もう1つの実用的なルールがあります。回避できる場合は、8ビット線形色を使用しないでください。8ビットカラーは常にsRGBであるという規則に従うのが一般的になりつつあるため、強度を8ビットから16ビットに、または整数から浮動小数点に広げると同時に、sRGBから線形への変換を行います。同様に、浮動小数点処理が終了すると、sRGBへの変換と同時に8ビットに絞り込みます。これらのルールに従うと、

sRGB画像を読み取っていて、線形強度が必要な場合は、次の式を各強度に適用します。

float s = read_channel();
float linear;
if (s <= 0.04045) linear = s / 12.92;
else linear = pow((s + 0.055) / 1.055, 2.4);

逆に、画像をsRGBとして記述したい場合は、次の式を各線形強度に適用します。

float linear = do_processing();
float s;
if (linear <= 0.0031308) s = linear * 12.92;
else s = 1.055 * pow(linear, 1.0/2.4) - 0.055; ( Edited: The previous version is -0.55 )

どちらの場合も、浮動小数点の値の範囲は0〜1です。したがって、8ビット整数を読み取る場合は、最初に255で除算し、8ビット整数を書き込む場合は255を乗算します。最後に、通常と同じ方法で。sRGBを使用するために知っておく必要があるのはこれだけです。

これまで、私は1つの強度のみを扱ってきましたが、色に関してはもっと賢いことがあります。人間の目は、さまざまな色合いよりもさまざまな明るさを区別できるため(技術的には、クロミナンスよりも輝度分解能が優れています)、色合いとは別に明るさを保存することで、24ビットをさらに有効に活用できます。これは、YUV、YCrCbなどの表現が行おうとしていることです。Yチャネルは色の全体的な明度であり、他の2つのチャネルよりも多くのビットを使用します(またはより多くの空間解像度を持ちます)。このように、RGB強度の場合のように(常に)曲線を適用する必要はありません。YUVは線形色空間であるため、Yチャネルの数値を2倍にすると、色の明度が2倍になりますが、RGBカラーのようにYUVカラーを加算または乗算することはできないため、

それがあなたの質問に答えると思うので、簡単な歴史的メモで終わります。sRGB以前は、古いCRTには非線形性が組み込まれていました。ピクセルの電圧を2倍にすると、強度は2倍以上になります。モニターごとにどれだけ異なるか、このパラメーターはガンマと呼ばれていました。この動作は、ライトよりも暗くなる可能性があるため便利でしたが、最初にキャリブレーションしない限り、ユーザーのCRTでの色の明るさを判断できないことも意味していました。ガンマ補正開始する色(おそらく線形)を変換し、ユーザーのCRTのガンマに変換することを意味します。OpenGLはこの時代から来ているため、sRGBの動作が少し混乱することがあります。しかし、GPUベンダーは、上記の規則を使用する傾向があります。つまり、8ビットの強度をテクスチャまたはフレームバッファーに格納する場合はsRGBであり、色を処理する場合は線形です。たとえば、OpenGL ES 3.0では、各フレームバッファとテクスチャに「sRGBフラグ」があり、読み取りと書き込みの際に自動変換を有効にすることができます。sRGB変換やガンマ補正を明示的に行う必要はまったくありません。


6
素晴らしい答え、ありがとう、説明されていることを見るのはいつも素晴らしいです、私はあなたの意見でこのトピック、色空間、そして変換sRGBを行うために使用される式に十分である本またはリソースだけを求めます<->線形またはこの動作を近似できる関数は何ですか。
ケン

良い本や資料がわからないのではないかと思います。Wikipediaのページには、包括的である、白点とどのように小さな(ほとんどの人がそれについて知っている必要はありませんように、私が言及していないもの)の色域は約すべてのものが含まれていますが、それはそれビット不可解ます。
Dan Hulme 2012年



1

私は「人間の色検出の専門家」ではありませんが、YUV-> RGB変換で同様のことを経験しました。R / G / Bチャネルにはさまざまな重みがあるため、ソースカラーをxだけ変更すると、RGB値の変更量も異なります。

言ったように、とにかく、私は専門家ではありません、とにかく、色補正変換をしたい場合は、YUV空間でそれを行い、次にそれをRGBに変換する必要があります(またはRGBで数学的に同等の操作を行う必要があります、注意してくださいデータ損失の)。また、YUVが色の最高のネイティブ表現であるかどうかはわかりませんが、ビデオカメラがその形式を提供しているので、そこで問題が発生しました。

これが秘密の数字が含まれている魔法のYUV-> RGB式です:http://www.fourcc.org/fccyvrgb.php


1
RGB <-> YUV変換とその逆に注意してください。これがすべての場合に当てはまるかどうかはわかりませんが、YUV色空間が24ビットRGBの0〜255ではなく16〜235の範囲に変換されることがあります。したがって、色空間変換を行うたびにデータが失われる可能性があります。あなたがそれを助けることができれば、ほとんどの人は同じ色空間内に保つと言う傾向があります。
ジョープランテ2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.