3. 色と視覚

第2章では、画像を数の格子に変えました:各画素はR、G、Bの3つの値を持ちます。
然し、其の3つの数が何を意味するのかはまだ考えていません。
何故3つで、5つや10個ではないのか?
値が128の「50%のグレー」の画素は、何故白の約5分の1の光しか出さないのか?
そして、お店でぴったり合っていた2枚の服が、何故家に帰ると違って見えるのか?

此れらの疑問の答えは全て同じです:色は光だけの性質ではなく、目と脳が光から作り出す物です。
CGは人間の目の為に画像を作るので、此の章では光源から脳までの光の旅を追い、其の各段階がグラフィックスのどこに現れるかを見ていきます:テクスチャのRGB値、動画ファイルの色空間、モニターのガンマカーブ、そしてシェーディングされたポリゴンにあたし達の知覚が仕掛けるいたずらです。

此の章で扱うシラバスの項目:

  • 分野1「ディジタル画像の基礎」:色の表し方、表色系、色空間。
  • 分野9「知覚」:色と視覚の部分(目の仕組み、明るさの知覚、対比の効果、目の解像度、奥行き手がかり)。
  • 分野6「濃淡変換と色変換」(第15章)で画像処理に使う色変換の最初の紹介。

必要な数学は重み付きの和と、行列とベクトルの積が1回だけで、どちらも線型代数シリーズで学んだ物です。

3.1 光とスペクトル

光は電磁波

光は電磁波です。
電波やX線と同じ仲間で、只、波長がずっと短いだけです。
あたし達の目が反応するのは、大体380 nmから780 nmまでの波長です(1 nmは1ミリメートルの100万分の1)。
此の範囲を可視光と呼びます。
其れより短い側が紫外線、長い側が赤外線です。

380 nmから780 nmまでの可視スペクトル。紫、青、緑、黄、橙を経て赤まで

1つの波長だけから成る光を単色光と呼びます。
白い太陽光をプリズムで分けると、単色光の色が紫、青、緑、黄、橙、赤と並んで見えます。
色の名前は大まかなラベルに過ぎません。
色は滑らかに変わり、其の境目は慣習で決めた物です。

注:上の帯は近似です。純粋なスペクトルの色は普通の画面で出せるどの色よりも鮮やかなので、少しだけ薄めて描きました。其の理由は3.4節で分かります。但し、両端が暗いのは本当です:あたし達の目は380 nm付近と780 nm付近ではとても感度が低いのです。

分光分布

現実の光が1つの波長だけである事は殆ど有りません。
ランプも空も1枚の紙も、可視光の全ての波長を其れぞれの強さで混ぜて出しています。
「波長ごとの強さ」のグラフを分光分布(SPD)と呼びます。
物体の表面にも似た曲線があり、其れを分光反射率と呼びます:各波長の光のうち、どれだけの割合を跳ね返すかです。
表面から目に届く光は、波長ごとに「光源の分光分布 × 表面の分光反射率」です。

分光分布は曲線全体なので、場合によっては何百個もの数になります。
其れなのに、画素が持つ数は3つです。
3つで足りる理由は目の中にあります。

3.2 目:桿体・錐体・3つの数

桿体と錐体

目の奥には網膜があり、2種類の光を感じる細胞で覆われています。

  • 桿体:片目に約9千万個以上。感度がとても高く、暗い所で働きます(暗所視)。桿体は1種類しか無いので色を区別出来ません。月明かりの下で世界が灰色に見えるのは其の為です。最も感度が高いのは500 nm付近です。
  • 錐体:片目に約600万個。視野の中心である中心窩に最も密集しています。もっと強い光が必要で(明所視)、S、M、Lの3種類があります。其れぞれ短波長、中波長、長波長に対応します。

3種類の錐体は、其れぞれ広く重なり合った範囲の波長に反応し、ピークは大雑把に420 nm(S)、530 nm(M)、560 nm(L)です。
各錐体は受け取った光を全て感度曲線で重み付けして足し合わせ、1つの数として報告します。
分光分布がどんな形でも、脳が各点から受け取るのはS、M、Lの3つの応答だけです。
此れがRGBの秘密の全てです。

三色説と反対色説

色覚が3種類の受容器に基づくという考えを三色説(ヤング・ヘルムホルツ説)と呼びます。
3つの原色を混ぜると(殆ど)全ての色を真似出来る理由を説明します。
但し、全てを説明出来る訳ではありません:「赤っぽい緑」や「黄色っぽい青」を見た人はいないのに、オレンジ(赤っぽい黄色)は普通に見えます。
此れを説明するのがヘリングの反対色説です:錐体の後で、視覚系は信号を赤–緑、黄–青、明–暗の3つの対立するチャンネルに組み替えます。
現在では、両方が異なる段階で正しいと考えられています:錐体では三色、其の後ろの神経では反対色です(段階説)。
3.6節で見る様に、動画のフォーマットは此の第2段階を真似ています:明暗のチャンネル1つと、色差のチャンネル2つです。

条件等色(メタメリズム)

目は分光分布を捨てて3つの数だけを残すので、異なる2つの分光分布が同じ3つの錐体応答を生む事があります。
其の場合、2つは全く同じに見えます。
此れを条件等色(メタメリズム)と呼び、其の2つの光をメタマーと呼びます。

2つの分光分布:Aは滑らかな曲線、Bは其の周りで大きく波打つ。どちらも同じX、Y、Zになるので、2つの色のパッチは全く同じに見える

上の分光分布Bは、Aに3.4節の標準観測者が全く見えない波(重み付きの和が丁度0になる波)を足して作りました。
其の為、2つのX、Y、Zは完全に同じです。
CGやディスプレイが成り立つのは条件等色のお陰です:モニターは夕焼けの分光分布を再現出来ませんが、其の必要は有りません。
赤・緑・青の光で、夕焼けのメタマーになる分光分布を出せば良いのです。
お店の服の謎も此れで説明出来ます:お店の照明の下でメタマーだった2つの布は、光の分光分布が変わる昼光の下ではメタマーではなくなる事があります。

色覚異常

錐体の1種類が無い、又はずれていると、色覚の独立なチャンネルが3つより少なくなります。
どの錐体かによって、1型(L錐体)、2型(M錐体)、3型(S錐体)の色覚異常と呼びます。
圧倒的に多いのは赤–緑の色覚異常(1型と2型)で、北欧系の男性の約8%、日本人男性の約5%、女性では1%を大きく下回る割合に見られます。
CGやUIのデザインでは、此れが実用的な意味を持ちます:重要な情報を色だけで伝えない事(例えば「赤=敵、緑=味方」だけにしない)。
形、文字、明るさの違いも加えましょう。

3.3 加法混色と減法混色

左:黒の上で赤・緑・青の光の円が重なり、黄・シアン・マゼンタ、中央で白になる。右:白の上でシアン・マゼンタ・イエローのインクが重なり、青・赤・緑、中央で黒になる

加法混色は光を足し合わせます。
原色は赤・緑・青(R、G、B)です。
各光が自分の波長を足すので、混ぜる程明るくなります:赤+緑=黄、緑+青=シアン、青+赤=マゼンタ、3つ全てで白です。
ディスプレイは此の方式です:各画素は3つの小さな光です。

減法混色は白い紙の上にフィルターやインクを重ねます。
各インクは光の一部を吸収します:シアンは赤を、マゼンタは緑を、イエローは青を吸収します。
混ぜる程暗くなります:シアン+マゼンタ=青、マゼンタ+イエロー=赤、イエロー+シアン=緑、3つ全てで(理想的には)黒です。
プリンター、絵の具、写真のフィルムは此の方式です。

一方の方式の二次色は、もう一方の原色です。
値が0から1の範囲なら、変換は簡単です:

C=1−R,M=1−G,Y=1−B

何故プリンターはKを足すのか

現実のインクは理想的なフィルターではないので、C+M+Yを最大にしても黒ではなく濁った焦げ茶色になります。
黒い文字の為に3層のインクをぴったり重ねるのは、インクの無駄で、乾くのも遅く、層が少しずれると滲みます。
其の為プリンターは4つ目のインクとして黒を使い、K(「キープレート」から)と呼びます。
最も簡単な変換は、C、M、Yに共通する灰色の部分を取り出してKで刷ります:

K=min(C,M,Y),C′=C−K1−K,M′=M−K1−K,Y′=Y−K1−K

(K=1なら純粋な黒で、C′=M′=Y′=0とします。)

計算例。RGB (0.2,0.4,0.6)をCMYとCMYKに変換します。

  • CMY:C=1−0.2=0.8、M=1−0.4=0.6、Y=1−0.6=0.4。
  • K=min(0.8,0.6,0.4)=0.4、1−K=0.6。
  • C′=(0.8−0.4)/0.6=0.667、M′=(0.6−0.4)/0.6=0.333、Y′=(0.4−0.4)/0.6=0。
  • 結果:CMYK ≈(0.667,0.333,0,0.4)。此の処理の後は、必ずどれか1つのインクが0になります。

実際の印刷の現場では、インク・紙・印刷機の全てが結果を変えるので、此れらの式ではなく測定したプロファイル(ICCプロファイル)を使います。
其れでも、検定対策として押さえておきたいのは此の式です。

3.4 CIE XYZと色度図

RGBの値は機器に依存します:「R = 1」はモニターごとに違う赤です。
色を正確に表すには、機器に依存しない仕組みが必要です。
其れを1931年に定めたのがCIE(国際照明委員会)です。

等色実験とXYZ表色系

等色実験では、観測者が2つに分かれた視野を見ました:片側には単色のテスト光、もう片側には3つの原色光の混合を表示し、観測者は両側が一致するまで混合を調整します。
結果は表になります:各波長について、各原色がどれだけ必要か。
一部の波長では、正の量の混合ではどうしても一致しませんでした。
其の場合、観測者は原色をテスト光の側に足す必要があり、此れは負の量として数えます。

CIEは此の結果をXYZ表色系に変換しました。
其の3つの原色は架空の物(現実の光では作れない)ですが、全ての現実の色のX、Y、Zが正になる様に選ばれています。
各波長がどれだけ寄与するかを表す3つの曲線が、標準観測者の等色関数x¯(λ)、y¯(λ)、z¯(λ)です:

380 nmから780 nmまでのCIE 1931の等色関数xバー、yバー、zバー。zバーは445 nm付近、yバーは555 nm、xバーは600 nm付近にピークがあり、445 nm付近にも小さな山がある

分光分布S(λ)を持つ光の三刺激値は、其の重み付きの和です:

X=∑λS(λ)x¯(λ)Δλ,Y=∑λS(λ)y¯(λ)Δλ,Z=∑λS(λ)z¯(λ)Δλ

(正式な定義は積分ですが、5 nm又は1 nm刻みの表のデータでは、此の様に積を足し合わせます。此れは2つの長いベクトルの内積に過ぎません。線型代数 第4章を参照して下さい。)

XYZを特に便利にしている選択が1つあります:y¯(λ)は昼間の目の明るさの感度である標準比視感度V(λ)と完全に同じで、555 nmにピークがあります。
従って、Yは其の色の輝度で、XとZが色の情報を持ちます。
同じパワーでも緑が青よりずっと明るく見えるのも此の為です:曲線は555 nmでは高く、450 nmでは低いのです。

XYZからxyへ

「どんな色か」と「どれだけ明るいか」を分ける為に、合計で割ります:

x=XX+Y+Z,y=YX+Y+Z,z=ZX+Y+Z=1−x−y

組(x,y)を其の色の色度と呼びます。
zはxとyから決まるので2つの数で十分で、色全体は色度と輝度を合わせた(x,y,Y)で表す事がよくあります。
光の明るさを2倍にするとX、Y、Zが全て2倍になるので、xとyは変わりません。
其の為、同じ色合いの白と灰色は同じ点に来ます。

色度図の読み方

全ての色を(x,y)で描くと、有名な馬蹄形のxy色度図になります。
下の図はCIE 1931の公式データから計算したので、形も波長の目盛りも正確です。

CIE 1931のxy色度図:380 nmから700 nmまで波長の目盛りが付いた馬蹄形のスペクトル軌跡と、其れを閉じる直線の純紫軌跡。内側にsRGB、DCI-P3、BT.2020の三角形、白色点D65とE、黒体軌跡がある

  • スペクトル軌跡:曲がった縁です。単色光の色が380 nm(左下)から520 nm(上)を通って700 nm(右)まで並んだ道です。存在する中で最も鮮やかな色です。
  • 純紫軌跡:両端を結ぶ直線の縁です。其の色(紫やマゼンタ)は赤と紫の混合で、1つの波長では作れません。
  • 全ての現実の色は此の領域の内側にあり、外側の物は見えません。縁に近い程鮮やか(純粋)で、白色点に近い程淡い色です。
  • 白色点:(1/3,1/3)のEは分光分布が平らな「等エネルギー白色」です。(0.3127,0.3290)のD65はCIEの標準的な平均昼光で、sRGBとHDTVの白です。
  • 混色は直線になります。2つの光を混ぜると2点を結ぶ直線上の色になり、3つを混ぜると其の三角形の内側の色になります。

最後の点が、ディスプレイの色域が三角形である理由です:3つの原色R、G、Bを持つ画面は、其れらが作る三角形の内側の色を丁度表示出来ます。
馬蹄形は曲がっているので、現実の原色で作る三角形が其れを覆う事は出来ません。
従って、3原色のディスプレイで全ての色を表示する事は出来ません。
図では、sRGBの三角形の外側を全て暗くして描きました:普通のsRGBの画面で読んでいるなら、其れらの色は正しく表示出来ないので、雰囲気を示す事しか出来ないのです。

sRGBの原色とRGB → XYZの行列

ウェブ、Windows、殆どの画像の標準の色空間であるsRGB(IEC 61966-2-1)は、HDTV(ITU-R BT.709)と同じ原色と白色を使います:

x y
赤 0.6400 0.3300
緑 0.3000 0.6000
青 0.1500 0.0600
白(D65) 0.3127 0.3290

此の4点から、リニアなsRGBの値(光の量、3.7節)をXYZに変える行列を計算出来ます。
普通の行列とベクトルの積です(線型代数 第6章):

[XYZ]=[0.41240.35760.18050.21260.71520.07220.01930.11920.9505][RGB]

各列は最大の強さの原色1つのXYZで、逆行列(第10章)でXYZからRGBに戻せます。
真ん中の行を見て下さい:Y=0.2126R+0.7152G+0.0722B。
此れがsRGBの色の輝度で、3.6節で全く同じ数にもう一度出会います。

計算例1:sRGBの赤はどこ?(R,G,B)=(1,0,0)とします。

  • 行列は1列目を取り出します:X=0.4124、Y=0.2126、Z=0.0193。
  • 合計:0.4124+0.2126+0.0193=0.6443。
  • x=0.4124/0.6443=0.640、y=0.2126/0.6443=0.330:表の赤の原色と丁度同じで、当然の結果です。

計算例2:白と灰色。(0.5,0.5,0.5)とします。
各行に0.5を掛けて足します:X=0.5⋅0.9505=0.4753、Y=0.5⋅1.0000=0.5、Z=0.5⋅1.0890=0.5445。
合計は1.5198なので、x=0.3127、y=0.3290:D65の白色点です。
黒から白までどの灰色も白色点の色度を持ち、違うのはYだけです。

計算例3:直線上の混色。最大の赤と最大の緑を混ぜます:(1,1,0)、黄色です。

  • 混合のXYZは2つの列の和です:X=0.4124+0.3576=0.7700、Y=0.2126+0.7152=0.9278、Z=0.0193+0.1192=0.1385。
  • 合計は1.8363なので、x=0.7700/1.8363=0.4193、y=0.9278/1.8363=0.5053。
  • 赤の列の合計はSR=0.6443、緑の列の合計はSG=1.1920です。混合は赤から緑への直線上の、t=SG/(SR+SG)=1.1920/1.8363=0.649の位置にあります。
  • 確認:x=0.64+0.649⋅(0.30−0.64)=0.4193、y=0.33+0.649⋅(0.60−0.33)=0.5053。同じ点です。

つまり、混合は直線上にありますが、中点ではありません:各色は輝度やRGBの値ではなく、X+Y+Zの重みで引っ張ります。

もっと広い色域

sRGBの三角形はかなり小さいです。
新しい規格は原色を外側に広げています:

色空間 赤 (x, y) 緑 (x, y) 青 (x, y) 白色 sRGBに対するxyの面積
sRGB / BT.709 0.640, 0.330 0.300, 0.600 0.150, 0.060 D65 1.00
DCI-P3 0.680, 0.320 0.265, 0.690 0.150, 0.060 0.314, 0.351 1.36
BT.2020 0.708, 0.292 0.170, 0.797 0.131, 0.046 D65 1.89

DCI-P3(SMPTE RP 431-2)はデジタルシネマの映写の色域です。
多くのスマートフォンやノートPCが使う「Display P3」は、同じ原色にD65の白とsRGBのカーブを組み合わせた物です。
BT.2020はUHDTV(4K・8K)の色域で、其の原色はスペクトル軌跡の上、630 nm、532 nm、467 nmにあります。
但し、xy色度図は知覚的に均等ではない(同じ距離が同じ違いに見えない。緑の辺りが引き伸ばされている)ので、「面積が1.89倍」は「見える色が1.89倍」という意味ではありません。

知覚に基づく表色系

XYZもxyも均等ではないので、CIEは等しい距離が大体等しい見た目の違いになる様に、CIE 1976 L∗a∗b∗色空間(L*a*b*表色系、CIELAB)も定めました。
其の明度はL∗=116(Y/Yn)1/3−16です(最も暗い値を除く)。
Ynは白の輝度です。
もっと古いマンセル表色系は、塗った色見本を色の三属性で並べた物です:色相、明度、彩度です。
此の3つの属性は、次の話題であるHSVの考え方でもあります。
第15章では、画像処理の色変換で此れらの色空間を使います。

3.5 HSVとHSL

RGBは画面の仕組みですが、人が色を考える方法ではありません。
「もう少しオレンジに」や「鮮やかさを抑えて」をR、G、Bで表すのは難しいです。
HSVは、もっと直感的な3つの値で色を表します:

  • H、色相:どの色か。色相環の上の角度で表します:0°が赤、60°が黄、120°が緑、180°がシアン、240°が青、300°がマゼンタ。
  • S、彩度:どれだけ鮮やかか。0(灰色)から1(純色)まで。
  • V、明度:どれだけ明るいか。0(黒)から1(其の色の最も明るい状態)まで。

左:明度0.8での色相と彩度の色相環。例の色を20度、彩度0.75の位置に示す。右:色相20度での彩度と明度の正方形。例の色を示す

幾何学的には、HSVはRGBの立方体を黒の角で立てて、灰色の対角線の方向から見た物です。
断面が六角形になるので、六角錐モデルと呼ばれる事がよくあります。

RGB → HSV

R,G,B∈[0,1]とし、M=max(R,G,B)、m=min(R,G,B)、Δ=M−mとします:

V=M,S={Δ/MM>00M=0
H=60∘×{(G−BΔ)mod6M=RB−RΔ+2M=GR−GΔ+4M=B

Δ=0の時、其の色は灰色で、色相は定まりません(プログラムでは普通0にします)。

計算例。RGB (0.8,0.4,0.2)、茶色がかったオレンジです。

  • M=0.8(赤)、m=0.2、Δ=0.6。
  • V=0.8、S=0.6/0.8=0.75。
  • 最大はRなので、H=60∘×((0.4−0.2)/0.6)=60∘×0.333=20∘。
  • HSV =(20∘,0.75,0.8):赤寄りのオレンジの色相(赤0°と黄60°の間)で、かなり鮮やか、そこそこ明るい色です。

HSV → RGB

逆向きは、C=V⋅S(「クロマ」)、H′=H/60∘、X=C(1−|H′mod2−1|)、m=V−Cとします。
色相の区間で(R1,G1,B1)を選び、各成分にmを足します:

H (R1, G1, B1)
0°〜60° (C, X, 0)
60°〜120° (X, C, 0)
120°〜180° (0, C, X)
180°〜240° (0, X, C)
240°〜300° (X, 0, C)
300°〜360° (C, 0, X)

計算例。HSV (200∘,0.5,0.6)。
C=0.6⋅0.5=0.3、H′=3.333、H′mod2=1.333なのでX=0.3⋅(1−0.333)=0.2、m=0.6−0.3=0.3。
200°は180°〜240°の区間なので(0,0.2,0.3)、此れにmを足してRGB =(0.3,0.5,0.6)、灰色がかった空色です。

HSL(HLS)

HSL(HLSとも書きます)は明度Vの代わりにL(明度・輝度)を使い、L=(M+m)/2、S=Δ/(1−|2L−1|)です。
HSLでは純色がL=0.5にあり、L=0(黒)もL=1(白)も1点になるので、形は双六角錐です。
例の(0.8,0.4,0.2)では、L=(0.8+0.2)/2=0.5、S=0.6/(1−0)=0.6で、色相は同じ20°です。

実際の使い方

ペイントソフト、3Dツール、ゲームエンジンのカラーピッカーはHSV又はHSLを表示し、「此の敵の色相をずらす」「プレイヤーがダメージを受けたら画面の彩度を下げる」といったシェーダーのエフェクトも此れらで書きます。
但し、HSVはRGBを並べ替えただけの物です:色がどれだけ明るく見えるかについては何も言いません。
純粋な黄色も純粋な青もV=1ですが、黄色の方がずっと明るく見えます。
知覚的な処理には、輝度(Y)又はCIELABの様な色空間を使いましょう。

3.6 ルーマとクロマ:YCbCr

3.2節の反対色のチャンネルを思い出して下さい:視覚系は「明暗」と「色」を分けます。
そして細かい部分は主に明暗のチャンネルで見分けていて、色の違いに対する鋭さはずっと低いです。
動画とJPEGは此れを利用し、RGBを明るさに近いチャンネル1つと、色差のチャンネル2つに変換します。

式

明るさに近いチャンネルはR、G、Bの重み付きの和です。
よく使われる規格が2つあり、どの数がどちらの物かを押さえておくと良いでしょう:

BT.601(SDTV、JPEG):Y′=0.299R′+0.587G′+0.114B′
BT.709(HDTV、sRGB):Y′=0.2126R′+0.7152G′+0.0722B′

BT.709の重みは、3.4節のsRGB → XYZの行列の真ん中の行です:現代のHDTVの原色から来ています。
BT.601の重みはもっと古く、1953年のNTSCカラーテレビ規格の原色から来ていて、其れ以来SDTVとJPEGに残っています。
どちらでも緑が最も重く、青が最も軽いのは、正にy¯の曲線が示す通りです。

2つの色差信号は、−0.5から+0.5の範囲になる様に縮められています:

BT.601:Cb=B′−Y′1.772,Cr=R′−Y′1.402BT.709:Cb=B′−Y′1.8556,Cr=R′−Y′1.5748

(割る数は2(1−0.114)=1.772、2(1−0.299)=1.402で、BT.709も同様です。)

プライム記号には意味があります:此れらの式はリニアな光ではなく、ガンマで符号化された値R′,G′,B′(3.7節)に適用します。
其の為、結果のY′はルーマと呼ばれ、本当の輝度Yの近似に過ぎません。
多くの本やAPIは此の仲間全体を「YUV」と呼びますが、厳密にはYUVはアナログのPAL版、YCbCrがディジタル版です。

計算例。符号化された色(R′,G′,B′)=(0.8,0.4,0.2):

  • BT.601:Y′=0.299⋅0.8+0.587⋅0.4+0.114⋅0.2=0.2392+0.2348+0.0228=0.4968。
  • Cb=(0.2−0.4968)/1.772=−0.2968/1.772=−0.1675、Cr=(0.8−0.4968)/1.402=0.3032/1.402=0.2163。
  • BT.709:Y′=0.17008+0.28608+0.01444=0.4706、Cb=−0.2706/1.8556=−0.1458、Cr=0.3294/1.5748=0.2092。
  • 同じ画素でも、2つの規格でルーマが違います。BT.709の動画をBT.601の数で復号すると(よくあるバグです)、色が少しずれます:肌の色が少し緑っぽく、又は赤っぽくなります。

8ビットの数として保存する時、ディジタル動画は伝統的にY'に16〜235、CbとCrに16〜240の「リミテッドレンジ」を使い、JPEGは0〜255の全範囲を使ってCbとCrに128を足します。

クロマサブサンプリング

ルーマとクロマを分けてしまえば、クロマを低い解像度で保存しても目は殆ど気付きません。
此れがクロマサブサンプリング(色差サブサンプリング、色差間引きとも言います)で、4 × 2画素のブロックについてJ:a:bと書きます:

4×2画素のブロック3つ。4:4:4は全ての画素にCbとCrのサンプルがあり、4:2:2は各行で1画素おき、4:2:0は2×2のブロックに1つだけ。ルーマは全ての画素にある

  • 4:4:4:クロマが完全、1画素あたり3個の値。ハイエンドの制作や、文字やUIの様な画面の内容に使います。
  • 4:2:2:クロマは横の解像度が半分、1画素あたり2個の値。放送や業務用の動画でよく使います。
  • 4:2:0:クロマは縦横とも半分の解像度、1画素あたり1.5個の値。殆ど全ての民生用の動画(Blu-ray、配信)と、殆どのJPEGファイルで使います。

1920 × 1080のフレームを値ごとに8ビットで保存すると、4:4:4は2073600×3=6220800バイト、4:2:2は×2=4147200バイト、4:2:0は×1.5=3110400バイトです。
本格的な圧縮が始まる前に、データが半分になります。
JPEGが其の後で高周波成分をどうするかは第2章で見ました。
代償は、鮮やかでくっきりした境目に現れます。
例えば青い背景の赤い文字は、ぼやけた色の縁取りが付きます。

3.7 ガンマとsRGBの伝達関数

ディスプレイの応答

昔のCRTモニターは、信号に比例した光を出しませんでした。
光の出力は、大体次のべき乗の曲線に従いました:

L=Vγ,γ≈2.2

Vは信号(0から1)、Lは光(0から1)です。
0.5の信号は、最大の光の0.52.2≈0.22しか出しません。
正しい画像にする為、動画の信号は逆のべき乗V=L1/2.2で予め補正して送られていました。
此の予めの補正がガンマ補正です。
現代の液晶や有機ELのパネルには、此の様な曲線になる物理的な理由は有りませんが、わざと真似しています。
そして、其れを残しておく十分な理由があります。

何故カーブが今でも役に立つのか

あたし達の明るさの違いに対する感度は、大体「比」で決まります(ウェーバー・フェヒナーの法則、3.9節):1 cd/m²の差は暗い場面でははっきり分かり、明るい場面では見えません。
8ビットの値を光に比例して保存すると、256個の符号の殆どを区別出来ない明るい階調に無駄遣いし、暗い階調には足りなくなって縞が見えます。
指数1/2.2のべき乗の曲線は、知覚の上でずっと均等に符号を配るので、8ビットで丁度足りる様になります。
ガンマ符号化は目に合わせた圧縮の工夫で、普通の8ビットの画像(PNG、JPEG、スクリーンショット)が全て符号化されて保存されているのは其の為です。

sRGBの符号化の曲線は0付近で急に立ち上がり、復号の曲線は其の鏡像になる。指数1/2.2と2.2の単純なべき乗の破線は殆ど重なる。0.5が0.735に符号化され、0.502が0.216に復号される2つの計算例の点を示す

sRGBの正確なカーブ

sRGBは単純な1/2.2のべき乗を使いません。
単純なべき乗の曲線は0での傾きが無限大になり、一番暗い階調のノイズを増幅してしまうので、sRGBは黒の近くに短い直線を使い、其の他の部分では(ずらして縮めた)2.4のべき乗を使います。
符号化、つまりリニアな光Lから保存する値Vへ(IEC 61966-2-1):

V={12.92LL≤0.00313081.055L1/2.4−0.055L>0.0031308

復号、つまり保存されたVからリニアなLへ:

L={V/12.92V≤0.04045(V+0.0551.055)2.4V>0.04045

2つの部分はL=0.0031308で繋がり、其処で12.92⋅0.0031308=0.04045です。
全体としては、グラフの破線の通り単純な2.2のべき乗にとても近いので、「sRGBはガンマ2.2」と言われます。

計算例1:リニアの0.5 → sRGB。

  • 0.5>0.0031308なので、べき乗の方を使います。
  • 0.51/2.4=0.7492(電卓ではeln0.5/2.4=e−0.2888)。
  • V=1.055⋅0.7492−0.055=0.7904−0.055=0.7354。
  • 8ビットでは0.7354⋅255=187.5で、四捨五入して188です。
  • 単純な2.2のカーブなら0.51/2.2=0.7297、つまり186になります。近いですが同じではありません。

計算例2:8ビットの128 → リニア。

  • V=128/255=0.50196で、0.04045より大きいです。
  • (0.50196+0.055)/1.055=0.52792。
  • L=0.527922.4=0.2159。
  • 「真ん中の灰色」の128は、白の約22%の光しか出しません。光の半分は128ではなく188です。

11個の灰色のパッチが2行。1行目は保存する値で等間隔の0、26、51から255までで、明るさの等しい段に見える。2行目は光の量で等間隔で、sRGBで保存した値は0、89、124から255まで。暗い側の段がずっと大きく見える

上の2つのグラデーションが其れを示しています。
1行目は保存する値で等間隔で、明るさのかなり均等な階段に見えます:符号化が意図通りに働いているのです。
2行目は光の量で等間隔です:光の0から10%への最初の一段で既に符号89になり、残りの9段は明るい側に押し込まれて、段々小さく見えます。

リニア空間とsRGB空間

さて、CGにとって大事な結論です:光はリニア空間で足し算されます。
其れぞれ最大の0.25の光を出す2つのランプは、合わせて0.5の光になります。
物理はリニアな値で起きるので、ライティング、ブレンディング、フィルタリング、平均は全てリニアな値で行い、最後の画像だけをディスプレイの為にsRGBに符号化しなければなりません。

此れを飛ばすとどうなるでしょうか?

  • 光の足し算。各ランプが0.25を出し、sRGBで保存すると0.537(符号137)です。符号化された値を足すと0.537+0.537=1.074で、1.0に切り詰められて真っ白になります。正しい答えはリニアの0.5、符号化して0.735(符号188)です。素朴な方法では明る過ぎます。
  • 平均(アンチエイリアシング、ぼかし、ミップマップ、縮小)。黒の上で白い縁に半分覆われた画素は、半分の光を出すべきです:リニアの0.5、符号188です。符号を平均すると(0+255)/2=128で、光の22%しか出しません:アンチエイリアスされた縁は暗く細く見え、ぼかした画像には暗い縁取りが出来ます。
  • ライティング全般。拡散反射のライティングは、表面の色に光の量を掛けます(第10章)。表面の色が符号化されたままだと、明るい部分から暗い部分への変化がきつく見え、ハイライトの色相が変わります。

実際の使い方

GPUは変換をハードウェアで無料で行います:

  • sRGBのフォーマット(OpenGLではGL_SRGB8_ALPHA8、VulkanではVK_FORMAT_R8G8B8A8_SRGB)のテクスチャは符号化されたバイトを保存し、シェーダーがサンプリングする度に、フィルタリングの前にGPUがリニアに復号します。
  • sRGBのフォーマットのフレームバッファやスワップチェーンの画像は、シェーダーのリニアな出力を書き込む時に符号化します(ブレンディングもリニアで行います)。
  • sRGBなのは色を持つテクスチャ(アルベド、ベースカラー、発光、UIの画像)だけです。法線マップ、ラフネス、メタリック、高さ、マスクのテクスチャは色ではなくデータを持つので、リニアのままにしなければなりません:法線マップをsRGBとして復号すると、全ての法線が曲がります。
  • カラーピッカーで入力した色も普通はsRGBの値なので、光の量として使う前に復号が必要です。
  • HDRレンダリングでは、リニアな値が1を大きく超える事があり、符号化の前にトーンマッピングで0〜1に戻します(第15章と第2部)。

此れはOpenGLシリーズ 第21章で自分で設定し、GLSLシリーズ 第10章ではシェーダーで手作業で行います。

3.8 色温度とホワイトバランス

黒体

鉄を熱すると光ります:最初は暗い赤、次にオレンジ、黄色、とても高い温度では白から青白くなります。
全ての光を吸収し、温度だけで光る理想的な物体を黒体と呼びます。
其の分光分布はケルビン(K)で表した絶対温度Tだけで決まり、プランクの法則で表されます:

M(λ,T)∝1λ5⋅1ec2/(λT)−1,c2=1.4388×10−2m⋅K

ある光と同じ色の黒体の温度を、其の光の色温度と呼びます。
色度図の上では、全ての温度の黒体が1本の曲線、黒体軌跡を作り、低い温度の赤橙色から白を通って水色へと伸びます。
曲線の上に丁度乗っていない光(殆どのランプ、そして曲線の少し上にあるD65自身)には、一番近い点の温度である相関色温度を使います。
D65の相関色温度は約6504 Kです。

1000 Kの濃い橙赤から、4000 K付近の暖かい白、6500 K付近の中性の白を経て12000 Kの水色までの色の帯。約1900 Kのろうそく、約2700 Kの白熱電球、D65、約10000 Kの青空を示す

代表的な値(全て目安):ろうそくは約1900 K、白熱電球は約2700 K、昼間の直射日光は約5000〜5500 K、平均的な昼光は約6500 K(D65)、晴れた青空からの光は10000 K以上です。
紛らわしい呼び方に注意して下さい:色温度が低い光は暖かく(オレンジに)見え、色温度が高い光は冷たく(青っぽく)見えます。

計算例:黒体はどこで一番強く光るか?
ウィーンの変位則がピークの波長を与えます:λmax=b/T、b=2.898×10−3m⋅K。

  • 2700 Kの白熱電球:λmax=2.898×10−3/2700=1.073×10−6 m =1073 nm。可視光の外の赤外線です:電球のエネルギーの殆どは熱になり、此のタイプの電球の効率が悪いのは其の為です。
  • 約5800 Kの太陽の表面:λmax=2.898×10−3/5800=500 nm。可視光の丁度真ん中です。

ホワイトバランス

白い紙は当たった光を其のまま反射するので、2700 Kの電球の下ではオレンジがかった光を出します。
其れでもあたし達には白く見えます:視覚系が光に順応し、其の色を差し引くからです。
此れを色の恒常性と呼びます。
カメラには其の様な本能が無いので、「白」が何かを教える必要があります:其れがホワイトバランスです。
最も簡単な方法は、既知の灰色又は白の物体が中性の色になる様に、各チャンネルを拡大縮小する事です。

計算例。暖かい光の下で、グレーカードがリニアで(0.8,0.6,0.4)と記録されました。

  • 全てのチャンネルを緑の値に揃えるゲインを選びます:gR=0.6/0.8=0.75、gG=1、gB=0.6/0.4=1.5。
  • 全ての画素に掛けます:カードは(0.6,0.6,0.6)、中性の灰色になります。
  • 此れはリニアな値で行う事に注意して下さい:符号化された値を拡大縮小しても同じ操作にはなりません。

もっと丁寧な方法(色順応変換、例えばBradford変換)は、RGBではなく錐体に近いLMS空間で拡大縮小し、人間の順応により近くなります。
CGで色温度に出会うのは、ライトを設定する時(多くのレンダラーやエンジンでは、ライトの色を正に此の黒体の曲線を使ってケルビンで指定出来ます)、シーンの白色点を選ぶ時、そしてCGを実写の映像に合成する時です。
合成では、CGのライトをカメラの映像のホワイトバランスに合わせなければなりません(第14章)。

3.9 CGの為の視覚と知覚

輝度と明るさ

輝度(単位cd/m²)は、測定器で測れる物理量です。
明るさは、物がどれだけ明るく見えるかという感覚です。
2つは関係していますが、比例はしておらず、次の節で見る様に周りの状況で感覚は大きく変わります。

ウェーバー・フェヒナーの法則

19世紀、ウェーバーは、あたし達が気付ける最小の変化(弁別閾)が、元の強さの一定の割合である事を見つけました:

ΔII=k

良い照明の下の輝度では、kは大体1〜2%です。
フェヒナーは、感覚Sが強さの対数で増える、S=k′log(I/I0)と結論しました:光が2倍になる度に、感じる明るさは同じだけ増えます。
合わせてウェーバー・フェヒナーの法則と呼びます。
此れは近似に過ぎません(とても暗い時と明るい時には外れ、後の研究はL∗の立方根の様なべき乗の法則を好みます)が、多くの事を説明します。

計算例。k=0.02とします。

  • 10 cd/m²では0.02⋅10=0.2 cd/m²の変化に気付きます。100 cd/m²では0.02⋅100=2 cd/m²が必要です。
  • 1 cd/m²から100 cd/m²までに、気付ける段は幾つ入るでしょうか?各段で1.02倍になるので1.02n=100、n=ln100/ln1.02=4.605/0.0198≈233。
  • 256より少ないので、符号を比で並べるなら8ビットで足ります。
  • 白が100 cd/m²でリニアな8ビットの符号だと、各段は100/255=0.39 cd/m²です。5 cd/m²では7.8%の跳び(閾値の4倍:縞が見える)、100 cd/m²では0.39%の跳び(必要より5倍細かい:符号の無駄)になります。
  • sRGBの符号化では、段は白の5%で約3.1%、50%で1.2%、白で0.9%と、ずっと均等です。3.7節の「ガンマは圧縮の工夫」を数で表すと此うなります。

コントラスト

コントラストは、明るい所と暗い所の差を表します。
ディスプレイでは普通コントラスト比Lmax/Lminで表します:白が300 cd/m²、黒が0.3 cd/m²のモニターなら300/0.3=1000:1です。
ウェーバー・フェヒナーの法則の為、差よりも比の方が重要です。

マッハバンド

下の帯を見て下さい:平らな暗い部分、滑らかな傾斜、平らな明るい部分です。

灰色の帯:平らな暗い灰色、線型の傾斜、平らな明るい灰色。傾斜の始まりに暗い縞、終わりに明るい縞が見えるが、下に描いた画素値は直線だけ

殆どの人には、傾斜の始まりに細い暗い縞、終わりに明るい縞が見えます。
下のグラフが実際の画素値です:縞は無く、角があるだけです。
此の錯覚の縞がマッハバンドで、1865年にエルンスト・マッハが記述しました。
原因は網膜の側抑制です:隣り合う細胞がお互いを抑え合うので、縁が強調され、明るさの傾きの急な変化が全て誇張されます。

此れはCGに直接関係します。
グーローシェーディング(第10章)は、各ポリゴンの上で明るさを線型に補間します。
明るさは辺を跨いで連続ですが、其の傾きが跳ぶので、目がポリゴンの辺に沿ってマッハバンドを足し、数値には何の問題も無いのにメッシュの構造が見えてしまいます。
もっと滑らかなシェーディング(フォンシェーディング、ポリゴンを増やす)で此の効果は減ります。

同時対比と其の他の錯視

ある領域の明るさの感じ方は、其の周りによって変わります。

2つの同じ中間の灰色の正方形。1つは黒の背景、もう1つは明るい灰色の背景の上にある。下には、黒から明るい灰色に変わる背景の上に、一様な灰色の棒がある

上の2つの正方形は全く同じ画素値(128, 128, 128)で、下の棒も1つの灰色なのに、黒の上の正方形の方が明るく見え、棒は右に行く程暗くなる様に見えます。
此れが同時対比です。
色相でも同じ事が起きます:赤い背景の上の灰色のパッチは、少し緑がかって見えます。
実際の作業では、色は中性の背景の上で判断し、3Dビューポートの周りのUIの色がレンダリングの見え方を変える事を覚えておきましょう。
大きさ、長さ、動きの錯視も他に沢山あります。
知覚については第18章でもっと詳しく扱います。

目はどれだけ細かく、どれだけ速く見えるか

空間の解像度。視力1.0は、1分角(1度の60分の1)離れた細部を見分けられるという意味です。
50 cm離れた画面では、1分角は500mm×tan(1/60∘)=500×0.000291=0.145 mmで、此れは25.4/0.145≈175 ppi(1インチあたりの画素数)です。
其れより画素の密度が高いと、其の距離では1つ1つの画素が見えません。
此れが「Retina」ディスプレイの考え方です。
アンチエイリアシング(第2章)がいつ重要かも此れで分かります:画素が大きく見える程、ジャギーが目立ちます。

時間の解像度。十分速く点滅する光は、点きっぱなしに見えます。
其の周波数が臨界融合周波数(CFF)で、明るい光で大体50〜60 Hzです(光が明るい程、又視野の端程高くなります)。
映画の映写機が1秒24コマの各コマを2回又は3回映す(1秒に48回又は72回の点滅)のも、ディスプレイが60 Hz以上、VRヘッドセットが90 Hz以上で書き換えるのも其の為です。
其れとは別に、少しずつ違う静止画の連続は動きとして見えます:仮現運動こそがアニメーションを成り立たせている物です。
速い動きに対して1秒あたりのコマ数が少な過ぎると、カクつきや時間方向のエイリアシングが起き、モーションブラーで其れを隠します(第2章)。

奥行き手がかり

画面は平らなのに、CGの画像は立体的に見えます。
脳は多くの奥行き手がかりから奥行きを判断し、CGは其れを1つずつ再現します:

奥行き手がかり 目 CGでの作り方
両眼視差 両眼 ステレオレンダリング:目ごとに1枚の画像(第17章)
輻輳 両眼 ステレオディスプレイ。近い物を見ると両目が内側に向く
調節 片眼 目のレンズのピント合わせ。被写界深度で真似する(第2章)
運動視差 片眼 カメラや頭が動くと近い物程速く動く。VRのヘッドトラッキング
重なり(遮蔽) 片眼 隠面消去(第10章)
線遠近法 片眼 透視投影(第5章)
相対的な大きさ・既知の大きさ 片眼 透視投影:遠い物程小さく描かれる
きめの勾配 片眼 透視でのテクスチャマッピング(第11章)
陰影 片眼 シェーディングと影(第10章、第11章)
大気遠近法 片眼 遠くの物を淡く青っぽくするフォグや霞

両眼視差、輻輳、調節は生理的手がかりで、遠近法や陰影の様な絵画的な手がかりは1枚の写真や絵でも働きます。
普通は全ての手がかりが一致しています。
VRヘッドセットでは、両目は例えば50 cm先の仮想の物体に輻輳しますが、ピントはディスプレイの固定された光学的な距離に合わせなければなりません:此れが輻輳調節矛盾で、目の疲れやVR酔いの原因の1つです。
ステレオディスプレイとVRは第17章で再び扱います。

3.10 コード例と検定のポイント

コードは任意です:此の章の内容は全て電卓で出来ます。
以下はsRGBのカーブ、RGB → HSV、ルーマをC++20で書いた物で、線型代数のライブラリのVec3とdotを使っています。
ルーマは重みのベクトルとの内積に過ぎないからです。

C++:sRGB・HSV・ルーマ

#include <algorithm>
#include <cmath>
#include <cstdio>

#include "linalg.hh"

// sRGB(IEC 61966-2-1)の符号化:リニア → sRGB / encode: linear → sRGB
float srgbEncode(float l) {
  l = std::clamp(l, 0.0f, 1.0f);
  if (l <= 0.0031308f) return 12.92f * l;
  return 1.055f * std::pow(l, 1.0f / 2.4f) - 0.055f;
}

// sRGBの復号:sRGB → リニア / decode: sRGB → linear
float srgbDecode(float v) {
  v = std::clamp(v, 0.0f, 1.0f);
  if (v <= 0.04045f) return v / 12.92f;
  return std::pow((v + 0.055f) / 1.055f, 2.4f);
}

// RGB → HSV。戻り値は {H(度), S, V} / returns {H (degrees), S, V}
Vec3 rgbToHsv(Vec3 c) {
  float mx = std::max({c.x, c.y, c.z});
  float mn = std::min({c.x, c.y, c.z});
  float d = mx - mn;
  float h = 0.0f;
  if (d > 0.0f) {
    if (mx == c.x) h = 60.0f * std::fmod((c.y - c.z) / d + 6.0f, 6.0f);
    else if (mx == c.y) h = 60.0f * ((c.z - c.x) / d + 2.0f);
    else h = 60.0f * ((c.x - c.y) / d + 4.0f);
  }
  float s = mx > 0.0f ? d / mx : 0.0f;
  return {h, s, mx};
}

// ルーマは重み付きの和、つまり内積 / luma is a weighted sum, i.e. a dot product
float luma601(Vec3 c) { return dot(c, Vec3{0.299f, 0.587f, 0.114f}); }
float luma709(Vec3 c) { return dot(c, Vec3{0.2126f, 0.7152f, 0.0722f}); }

int main() {
  float e = srgbEncode(0.5f);
  printf("linear 0.5 -> sRGB %.4f -> 8-bit %d\n", e, (int)std::lround(e * 255.0f));
  printf("8-bit 128  -> linear %.4f\n", srgbDecode(128.0f / 255.0f));

  Vec3 c{0.8f, 0.4f, 0.2f};
  Vec3 hsv = rgbToHsv(c);
  printf("HSV of (0.8, 0.4, 0.2) = (%.1f deg, %.2f, %.2f)\n", hsv.x, hsv.y, hsv.z);
  printf("luma BT.601 = %.4f, BT.709 = %.4f\n", luma601(c), luma709(c));
  return 0;
}

出力は上の計算例と一致します:

linear 0.5 -> sRGB 0.7354 -> 8-bit 188
8-bit 128  -> linear 0.2159
HSV of (0.8, 0.4, 0.2) = (20.0 deg, 0.75, 0.80)
luma BT.601 = 0.4968, BT.709 = 0.4706

rgbToHsvでは、fmodの前に6を足して赤の区間の色相を正に保っています(C++のfmodは負の入力の符号を残すからです)。

シェーダー:リニア → sRGB

フレームバッファがsRGBのフォーマットでない時は、ポストプロセスのシェーダーが最後の色を自分で符号化します。
此の版は分岐無しで3つのチャンネルを一度に処理します:stepは値が直線の部分にある所で1になり、ブレンドが其処で其方の式を選びます。

float3 linearToSrgb(float3 c) {
  c = saturate(c);
  float3 lo = 12.92 * c;
  float3 hi = 1.055 * pow(c, float3(1.0 / 2.4)) - 0.055;
  return lerp(hi, lo, step(c, float3(0.0031308)));
}
vec3 linearToSrgb(vec3 c) {
  c = clamp(c, 0.0, 1.0);
  vec3 lo = 12.92 * c;
  vec3 hi = 1.055 * pow(c, vec3(1.0 / 2.4)) - 0.055;
  return mix(hi, lo, step(c, vec3(0.0031308)));
}
float3 linearToSrgb(float3 c) {
  c = saturate(c);
  float3 lo = 12.92 * c;
  float3 hi = 1.055 * pow(c, (float3)(1.0 / 2.4)) - 0.055;
  return lerp(hi, lo, step(c, (float3)0.0031308));
}

フレームバッファがsRGBのフォーマットでない時だけ使って下さい。
sRGBのフレームバッファではハードウェアが符号化してくれるので、2回符号化すると全体が白っぽく褪せます。

検定のポイント

  • 加法混色と減法混色。加法(光、ディスプレイ):原色はR、G、B。R+G=黄、G+B=シアン、B+R=マゼンタ、全てで白。減法(インク、フィルター):原色はC、M、Y。C+M=青、M+Y=赤、Y+C=緑、全てで黒。C=1−R等。
  • 桿体と錐体。桿体:暗い所、色は分からない。錐体:3種類(S、M、L)、色、明るい所、中心窩に集中。
  • 条件等色:分光分布が違っても同じ色に見える。
  • 色度図:軸はx=X/(X+Y+Z)とy=Y/(X+Y+Z)で、RとGではない。曲がった縁がスペクトル軌跡、直線の縁が純紫軌跡。xyでは輝度は分からない。混色は直線上、ディスプレイの色域は三角形。
  • XYZのYは輝度(y¯(λ)=V(λ)だから)。
  • どの係数か:BT.601は0.299、0.587、0.114。BT.709(とsRGB)は0.2126、0.7152、0.0722。どちらも緑が最大。
  • ガンマの向き:ディスプレイはV2.2で信号を光に変える(中間調が暗くなる)。符号化は逆のL1/2.2(中間調を明るくする)。リニアの0.5は8ビットのsRGBで約188、128は光の約22%しかない。
  • 計算はリニア空間で、符号化は最後に。
  • 色温度:低い=赤っぽい(「暖色」)、高い=青っぽい(「寒色」)。D65は約6500 K。
  • ウェーバーの法則:ΔI/Iが一定。マッハバンドは明るさの傾きが変わる所に現れる(グーローシェーディング)。

3.11 まとめ

  • 光は電磁波で、可視光は大体380〜780 nm。光や表面は分光分布で表す。
  • 網膜には桿体(暗い所、色無し)と3種類の錐体(S、M、L)がある。目は全ての分光分布を3つの数にまとめるので、3原色で足り、メタマーが存在する。
  • 加法混色(RGB、光)は明るくなり、減法混色(CMY、インク)は暗くなる。C=1−Rで、プリンターはKを足す。
  • CIE XYZは機器に依存しない表色系で、Yは輝度。xy色度図はスペクトル軌跡、純紫軌跡、白色点、色域の三角形を示す。sRGBはBT.709の原色とD65を使う。
  • HSV・HSLは色相・彩度・明度で色を表し、人には便利だが知覚的には正確ではない。
  • 動画はルーマY′とクロマCb,Crを分け(BT.601:0.299/0.587/0.114、BT.709:0.2126/0.7152/0.0722)、クロマをサブサンプリングする(4:2:2、4:2:0)。
  • 画像はガンマで符号化して保存する(sRGB:直線と2.4のべき乗、ガンマ2.2に近い)。ライティングとブレンディングはリニア空間で行う。
  • 色温度は光を同じ色の黒体で表す。ホワイトバランスは白が白く見える様にチャンネルを拡大縮小する。
  • 知覚:明るさは比に従い(ウェーバー・フェヒナー)、マッハバンドと同時対比は目を騙し、目は約1分角を見分け、大体50〜60 Hz以上の点滅は融合する。CGは奥行き手がかりを1つずつ真似する。

3.12 用語

English 日本語
visible light 可視光
wavelength 波長
spectral distribution 分光分布
retina 網膜
rod / cone 桿体/錐体
photopic / scotopic vision 明所視/暗所視
trichromatic theory 三色説
opponent-process theory 反対色説
metamerism 条件等色(メタメリズム)
color vision deficiency 色覚異常
additive mixing 加法混色
subtractive mixing 減法混色
primary color 原色
color matching function 等色関数
tristimulus values 三刺激値
XYZ color system XYZ表色系
luminous efficiency function 標準比視感度
chromaticity 色度
chromaticity diagram 色度図
spectral locus スペクトル軌跡
purple line 純紫軌跡
white point 白色点
gamut 色域
three attributes of color 色の三属性
hue / saturation / value (lightness) 色相/彩度/明度
luminance 輝度
luma ルーマ
color difference 色差
chroma subsampling クロマサブサンプリング(色差サブサンプリング)
gamma correction ガンマ補正
black body 黒体
color temperature 色温度
correlated color temperature 相関色温度
white balance ホワイトバランス
color constancy 色の恒常性
Weber–Fechner law ウェーバー・フェヒナーの法則
contrast コントラスト
Mach band マッハバンド
lateral inhibition 側抑制
simultaneous contrast 同時対比
visual acuity 視力
critical flicker frequency 臨界融合周波数
apparent motion 仮現運動
depth cue 奥行き手がかり
binocular disparity 両眼視差
convergence / accommodation 輻輳/調節
motion parallax 運動視差

3.13 課題

  1. ★ RGB (0.6,0.3,0.3)をCMYに変換し、更にK=min(C,M,Y)でCMYKに変換して下さい。0になるのはどのインクですか?
  2. ★ リニアの0.18とリニアの0.002を8ビットのsRGBに符号化し(カーブのどちらの部分を使うかに注意)、8ビットの値200をリニアに復号して下さい。
  3. ★ RGB (0.2,0.6,0.4)をHSVとHSLに変換し、HSV (240∘,0.5,0.8)をRGBに戻して下さい。
  4. ★★ sRGBの行列を使って、純粋な緑(0,1,0)、純粋な青(0,0,1)、シアン(0,1,1)のxy色度を計算して下さい。シアンが緑から青への直線上にある事と、其の何割の位置にあるかを示して下さい。
  5. ★★★ ウェーバー比を2%とし、白が400 cd/m²、黒が0.4 cd/m²のディスプレイを考えます。黒から白までに、気付ける段は幾つ入りますか?理想的に並べた符号の8ビットの符号化で足りますか?もっと大きなコントラスト比を持つHDRディスプレイについて、此れは何を示唆しますか?

選択問題

問1 ★ 混色について、次のうち正しい物はどれか。

あ 加法混色の原色はシアン・マゼンタ・イエローである。
い シアンのインクとマゼンタのインクを混ぜると緑になる。
う 減法混色の3原色を最大の強さで混ぜると白になる。
え ディスプレイはシアン・マゼンタ・イエローのサブピクセルの減法混色で色を表示する。
お 赤の光と緑の光を混ぜると黄色の光になる。

問2 ★★ CIE 1931のxy色度図について、次のうち正しい物はどれか。

あ x軸はsRGBの色のRの値、y軸はGの値である。
い 曲がった縁は単色光から成り、其の両端を結ぶ直線の縁の色は、どの1つの波長でも作れない。
う 馬蹄形の領域の内側の色は全て、sRGBの原色を持つディスプレイで表示出来る。
え 色の輝度は、色度図の上の位置から読み取れる。
お 2つの光を混ぜると、必ず2点の丁度中点の色になる。

問3 ★★ レンダラーがある画素についてリニアな光の値0.5(白の半分)を計算し、8ビットのsRGB画像に書き込む。保存される値に最も近い物はどれか。

あ 188
い 64
う 218
え 128
お 160

3.14 実践課題

方眼紙で作る色のカード。
方眼紙(20 × 20 cm以上)、定規、色鉛筆、電卓を用意して下さい。
自分の色度図を描き、其の上に3つの色を置きます。
此の章で行った計算を全て手で行います。

3つの色はリニアなsRGBの値で与えます:P = (1,1,0)、Q = (0.2,0.4,0.8)、R = (0.25,0.25,0.25)。

  • 手順1(軸)。x軸を0から0.8、y軸を0から0.9まで、1 cm = 0.05で描きます(16 cm × 18 cm)。
  • 手順2(スペクトル軌跡)。CIE 1931のスペクトル軌跡の次の点を打ち、滑らかな曲線で結びます:380 nm (0.1741, 0.0050)、460 nm (0.1440, 0.0297)、480 nm (0.0913, 0.1327)、490 nm (0.0454, 0.2950)、500 nm (0.0082, 0.5384)、520 nm (0.0743, 0.8338)、540 nm (0.2296, 0.7543)、560 nm (0.3731, 0.6245)、580 nm (0.5125, 0.4866)、600 nm (0.6270, 0.3725)、700 nm (0.7347, 0.2653)。380 nmから700 nmまでを直線の点線(純紫軌跡)で閉じます。
  • 手順3(色域)。3.4節の表からsRGBの原色とD65を打ち、sRGBの三角形を描きます。
  • 手順4(XYZとxy)。P、Q、Rについて、sRGBの行列でX、Y、Zを計算し、次にxとyを計算します。3つの点を打ってラベルを付けます。
  • 手順5(符号化)。各色について、符号化のカーブで8ビットのsRGBの値を計算し、其の符号化された値(255で割った物)からHSVの値とBT.709のルーマY′を計算します。小さな表にまとめます:リニアなRGB、XYZ、xy、8ビットのsRGB、HSV、Y′、本当の輝度Y。
  • 手順6(混色)。PとQを(リニアな値で、成分ごとに)足し、混合のxyを計算して打ちます。各色のX+Y+ZをSとして割合t=SQ/(SP+SQ)を計算し、混合がPからQへの其の割合の位置にある事を確認します。
  • 手順7(色を塗る)。色鉛筆でsRGBの三角形の内側を大まかに塗り(赤・緑・青の角、D65の近くは白)、三角形とスペクトル軌跡の間の領域を薄い灰色で塗ります:「存在するが、sRGBの画面では表示出来ない色」です。

結果の確かめ方:

  • Rは灰色なので、xyは丁度D65 (0.3127, 0.3290)、HSVの彩度は0、本当の輝度Yは0.25になる筈です。
  • P、Q、RはsRGBの三角形の内側にあり、Pは赤と緑の角を結ぶ辺の上にある筈です。
  • PとQの混合は、PからQへの線分の上の、計算した割合tの位置にある筈です(定規で測って下さい)。
  • QとRでは、Y′(符号化された値から)と本当のY(リニアな値から)は違う筈です:同じ数になったら、2つの空間を取り違えています。(Pでは一致します。Pは0と1だけで出来ていて、符号化しても値が変わらないからです。)


コメント(0)

まだコメントはありません。