web-dev-qa-db-ja.com

RGBをグレースケール/強度に変換する

RGBからグレースケールに変換する場合、チャネルR、G、およびBに特定の重みを適用する必要があると言われています。これらの重みは、0.2989、0.5870、0.1140です。

その理由は、これら3色に対する人間の知覚/感性が異なるためと言われています。これらはNTSC信号の計算に使用される値であるとも言われます。

ただし、Webでこれに関する適切なリファレンスが見つかりませんでした。これらの値のソースは何ですか?

これらの以前の質問も参照してください: here および here

113
ypnos

質問の具体的な番号はCCIR 601からのものです(以下のWikipediaリンクを参照)。

RGB->グレースケールをわずかに異なる数値/異なる方法で変換する場合、通常の照明条件の下で通常のコンピューター画面に大きな違いは見られません-それを試してください。

一般的な色に関するリンクを次に示します。

ウィキペディア ルマ

Bruce Lindbloom の傑出したWebサイト

colin Ware著の本の「Color」に関する第4章「Information Visualization」、isbn 1-55860-819-2。 books.google.com のウェアへのこの長いリンクは機能する場合と機能しない場合があります

cambridgeincolor :優れた、よく書かれた「手順よりも概念を強調する視覚指向のアプローチを使用してデジタル写真を取得、解釈、処理する方法に関するチュートリアル」

「リニア」対「ノンリニア」RGBに遭遇した場合、これに関する古いメモの一部を以下に示します。繰り返しますが、実際には大きな違いは見られません。


RGB-> ^ gamma-> Y-> L *

カラーサイエンスでは、html rgb(10%、20%、30%)のような一般的なRGB値は、「非線形」または ガンマ補正 と呼ばれます。 「線形」値は次のように定義されます

Rlin = R^gamma,  Glin = G^gamma,  Blin = B^gamma

多くのPCのガンマは2.2です。通常のR G Bは、R 'G' B '(R' = Rlin ^(1/gamma))(純粋主義者の舌クリック)と表記されることもありますが、ここでは 'をドロップします。

CRTディスプレイの明るさはRGBlin = RGB ^ガンマに比例するため、CRTの50%グレーは非常に暗くなります:.5 ^ 2.2 =最大明るさの22%。 (LCDディスプレイはより複雑です;さらに、一部のグラフィックカードはガンマを補正します。)

RGBからL*と呼ばれる明度の尺度を取得するには、最初にR G Bを255で割り、計算します

Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma

これは、XYZ色空間ではYです。それは色の「輝度」の尺度です。 (実際の式は厳密にはx ^ gammaではありませんが、厳密です。最初のパスではx ^ gammaを使用します。)

最後に、

L* = 116 * Y ^ 1/3 - 16

「...知覚の均一性を目指して(そして]明るさの人間の知覚と密接に一致します。」 -ウィキペディア ラボの色空間

79
denis

この出版物は、以前の同様の質問への回答で参照されていることがわかりました。それは非常に役立ちます:

http://cadik.posvete.cz/color_to_gray_evaluation/

結果が異なるグレースケール画像を生成するさまざまな方法の「トン」を示しています!

11
ypnos

Rgbをグレースケールに変換するcのコードをいくつか示します。 RGBからグレースケールへの変換に使用される実際の重み付けは、0.3R + 0.6G + 0.11Bです。これらの重みは絶対に重要ではないので、一緒に遊ぶことができます。 0.25R + 0.5G + 0.25Bにしました。わずかに暗い画像を生成します。

注:次のコードはxRGB 32ビットピクセル形式を想定しています

unsigned int *pntrBWImage=(unsigned int*)..data pointer..;  //assumes 4*width*height bytes with 32 bits i.e. 4 bytes per pixel
unsigned int fourBytes;
        unsigned char r,g,b;
        for (int index=0;index<width*height;index++)
        {
            fourBytes=pntrBWImage[index];//caches 4 bytes at a time
            r=(fourBytes>>16);
            g=(fourBytes>>8);
            b=fourBytes;

            I_Out[index] = (r >>2)+ (g>>1) + (b>>2); //This runs in 0.00065s on my pc and produces slightly darker results
            //I_Out[index]=((unsigned int)(r+g+b))/3;     //This runs in 0.0011s on my pc and produces a pure average
        }
9
twerdster

これらの数値(または類似の数値)がどのように導出されたかについての論文を次に示します。

https://web.archive.org/web/20160303201512/http://www.cis.rit.edu/mcsl/research/broadbent/CIE1931_RGB.pdf

6
rmmh

これについての情報は Color FAQ をご覧ください。これらの値は、ディスプレイで使用するRGB値の標準化に基づいています。実際、Color FAQによれば、使用している値は古いものであり、元のNTSC標準に使用される値であり、最新のモニターではありません。

6
Brian Campbell

これらの値のソースは何ですか?

投稿された係数の「ソース」はNTSC仕様であり、 Rec601 および テレビの特性 で確認できます。

「究極のソース」は、1931年頃の人間の色知覚に関するCIE実験です。人間の視覚のスペクトル応答は均一ではありません。実験により、知覚に基づく三刺激値の重み付けが行われました。 L、M、Sコーン1 「赤」、「緑」、「青」(それぞれ)として識別される光の波長に敏感であり、三刺激値の原色が得られます。2

リニアライト3 sRGB(およびRec709)のスペクトルの重み付けは次のとおりです。

R * 0.2126 + G * 0.7152 + B * 0.0722 = Y

これらは、コンピューターモニター(sRGB)またはHDTVモニター(Rec709)を表すことを目的としたsRGBおよびRec709色空間に固有のものであり、 Rec709 および BT .2380-2(10/2018)

脚注(1)コーンは目の網膜の細胞を検出する色です。
(2)ただし、選択した三刺激値の波長は各コーンタイプの「ピーク」ではありません。代わりに、三刺激値は、特定のコーンタイプで他よりもかなり刺激するように選択します。
(3)係数を適用する前に、sRGB値を線形化する必要があります。これについては 別の回答をここで で説明します。

2
Myndex