眠いなぁ,寝よう… って思いながら,頭の中で思考してたら,とうとう気になりだしてスマフォ片手に調べだして,挙句の果てに眠れなくなってブログを書き始めた人の文章です。
Twitter でほざいてたのをきれいにまとめておこうかと。間違ってたら指摘してください。色空間に関してはまだまだ知識不足ですね。片手間で書ける記事ではないので,順次追記,公開予定。これがすべての色空間実装への土台になると思うし,集大成だと思っているのでよろしくお願いします。
この資料は適切に加筆修正されると思います。というか,していきます。変換式とかも徐々に増やしていく予定なのでよろしくお願いします。
概要
- 量子化
- YUV⇔RGB変換式
- 色空間
- ガンマ
- 光源変換
- 色空間変換(概論)
1. 量子化 (Quantization levels)
BT.709,BT.2020 ともにほぼ同じ。ただし,BT.709 は 8-bit または 10-bit,BT.2020 は 10-bit または 12-bit のみ定義されている。BT.601 は定義が見つからなかったがあるのだろうか…?
値\ビット数 | 8-bit | 10-bit | 12-bit | ||
---|---|---|---|---|---|
黒レベル (Black level) | 16 | 64 | 256 | ||
Achromatic | 128 | 512 | 2048 | ||
名目ピーク (Nominal Peak) |
R, G, B, Y | 235 | 940 | 3760 | |
CB, CR | min | 16 | 64 | 256 | |
max | 240 | 960 | 3840 | ||
データ*1 (Video Data) |
min | 1 | 4 | 16 | |
max | 254 | 1019 | 4079 | ||
時間参照 (Timing reference) |
0 255 |
0-3 1020-1023 |
0-15 4080-4095 |
※ Achromatic は順応輝度(背景輝度)とか訳す? わかんない
2. YUV⇔RGB変換式 (Color Matrix)
ここが一番目立つところですね。RGB と YUV を変換するために使う式です。言ってただ変換するだけで,色空間やガンマまで変換して sRGB にする,といった魔法は起きません。まずは有名な YCbCr 系について書きます。
2.1 YCbCr
色空間\係数 | Kr | Kg | Kb |
---|---|---|---|
BT.601 | 0.299 | 0.587 | 0.114 |
BT.709 | 0.2126 | 0.7152 | 0.0722 |
BT.2020 | 0.2627 | 0.6780 | 0.0593 |
FCC | 0.30 | 0.59 | 0.11 |
※ Kr,Kb を使うのが一般的…? [要出展]
変換行列を提示します。
……(2.1a) for:
これは,まず YUV の 16-235, 16-240, 16-240 を 0~219, -112~112, -112~112 にします。そして次にフルレンジに戻します。0~255, -128~127,-128~127 にです。そして Yfull,Ufull,Vfull を RGB に変換する行列をかけてやります。
整理した式は割愛します。こっちの式のほうがより理解が深まるでしょう。
逆変換。
……(2.1b)
また,AviSynth や YCbCr の wiki も参照するとよいです。
http://avisynth.nl/index.php/Color_conversions
https://en.wikipedia.org/wiki/YCbCr
これのアナログバージョンを YPbPr って言いますが,まあコンポーネント端子に Y, Pb/Cb, Pr/Cr って書いてあったぐらいですし,実利用ではあんまり言い訳してないですね。
次は YCbCr (YUV) でない色について書きます。
2.2 YCgCo
緑の色差 CG と 橙の色差 CO です。
……(2.2a) ……(2.2b)
https://en.wikipedia.org/wiki/YCgCo
2.3 YDbDr
青の色差 DB と 赤の色差 DR です。SECAM の規格です。
……(2.3a) ……(2.3b) where: R, G, B, Y ∈ [0, 1] Db, Dr ∈ [-1.333, 1.333]
正直なところ,これはアナログフォーマットだし載せる必要ないのですが,x264 で使えるっぽいので,参考までに。
https://en.wikipedia.org/wiki/YDbDr
2.4 YIQ
橙-青 I と 紫-緑 Q です。NTSC の規格です。
……(2.4a) ……(2.4b) where: R, G, B, Y ∈ [0, 1] I ∈ [-0.5957, 0.5957] Q ∈ [-0.5226, 0.5226]
https://en.wikipedia.org/wiki/YIQ
3. 色空間 (Color Primaries)
PC 使ってる人ならよく知っている sRGB,AdobeRGB,DCI-P3 など… 色をきちんと扱う人ならキャリブレーションとかしたことあるのではないのでしょうか?
CIE XYZ 色空間を使って表すので,XYZ 色空間について知らない人は次を一読するとよい。
http://w3.kcua.ac.jp/~fujiwara/infosci/colorspace/colorspace1.html
色空間 | R | G | B | W | ||||
---|---|---|---|---|---|---|---|---|
x | y | x | y | x | y | |||
4 | NTSC (1953) [BT.470-6 System M] |
0.67 | 0.33 | 0.21 | 0.71 | 0.14 | 0.08 | C |
6 | NTSC (1987) [SMPTE 170M] | 0.63 | 0.34 | 0.31 | 0.595 | 0.155 | 0.07 | D65 |
- | NTSC-J (1987) | D93 | ||||||
5 | PAL [BT.470-6 System B, G] | 0.64 | 0.33 | 0.29 | 0.60 | 0.15 | 0.06 | D65 |
1 | sRGB [IEC 61966-2-1] BT.709-5 |
0.640 | 0.330 | 0.300 | 0.600 | 0.150 | 0.060 | D65 |
- | Adobe RGB | 0.6400 | 0.3300 | 0.2100 | 0.7100 | 0.1500 | 0.0600 | D65 |
- | DCI-P3 D65 [SMPTE EG 432-1, RP 431-2] |
0.680 | 0.320 | 0.265 | 0.690 | 0.150 | 0.060 | D65 |
- | DCI-P3 Theater | 0.314, 0.351 | ||||||
9 | BT.2020-2 | 0.708 | 0.292 | 0.170 | 0.797 | 0.131 | 0.046 | D65 |
- | Wide-gamut RGB | 0.7347 | 0.2653 | 0.1152 | 0.8264 | 0.1566 | 0.0177 | 0.3457, 0.3585 |
光源名 | 色温度 | x | y |
---|---|---|---|
A | 0.4476 | 0.4075 | |
B | 0.3486 | 0.3516 | |
C | 6774K | 0.31006 | 0.31616 |
D50 | 0.3457 | 0.3586 | |
D55 | 0.3325 | 0.3475 | |
D60 | 0.3217 | 0.3377 | |
D65 | 6504K | 0.3127 | 0.3290 |
D75 | 0.2991 | 0.3149 | |
D93 | 9305K | 0.2831 | 0.2970 |
RGB 色空間は英語版 wikipedia を参照するといいかも。
https://en.wikipedia.org/wiki/RGB_color_space
RGB⇔XYZ 変換式について記述する。
……(3.1) ……(3.2)
算出については次を見るとよい。
http://vig.is.env.kitakyu-u.ac.jp/Japanese/tutorial/rgb2xyz.html
http://www.ite.or.jp/study/musen/tips/tip07.html
4. ガンマ (Transfer characteristics)
ガンマとはごく一般的に次のような定義です。
……(4.0)
右上の指数の部分だけを取り出して表現されるのが γ です。
γ = 0.45 | γ = 1.0 | γ = 2.2 |
---|---|---|
※ グラフはここで作成 http://keisan.casio.jp/exec/system/1180917567
一般にカメラのガンマ補正が 0.45,ディスプレイガンマが 2.2*2が使われる,が…
ガンマについてもっと詳しいことを知りたいなら,次のサイトを見るとよい。
http://compojigoku.blog.fc2.com/blog-entry-23.html
大雑把な理解はこれでいいんだけど細かな数式が規格によって違うんだよ! って話。
4.1 BT.601 / BT.709 / SMTPE 170M
筆者注釈としては L は Linear な信号 Vlinear。E は γ: BT.709 な信号 Vγ: BT.709。
……(4.1a) where: L: 元の明るさ L (0 ≤ L ≤ 1) (luminance of the image 0 ≤ L ≤ 1) E: 電気信号 (corresponding electrical signal)
逆変換
……(4.1b)
https://en.wikipedia.org/wiki/Rec._709
4.1.1 xvYCC (IEC61966-2-4)
BT.709 でガンマカーブのみ定義を拡張します。リニアなパラメーターが 0~1 に制約されているのを負値を受け入れるようにし,最終的に YUV 1-254 を最大限まで使うようにします。
……(4.1.1a) ……(4.1.1b) where: L: linear L': non-linear
4.2 BT.2020
10-bit と 12-bit で値が違います。12-bit では精度のためか桁が増えています。
……(4.2) where: E: linear (規格はもっとうだうだ書いてます) E´: non-linear signal For practical purpose, the following values can be used: 10-bit: α = 1.099, β = 0.018 12-bit: α = 1.0993, β = 0.0181
4.3 sRGB (IEC 61966-2-1)
……(4.3a) ……(4.3b)
https://en.wikipedia.org/wiki/SRGB
4.4 Adobe RGB (1998)
……(4.4a) ……(4.4b)
https://en.wikipedia.org/wiki/Adobe_RGB_color_space
4.5 DCI-P3
sRGB と同じらしい。D65 規格においては? 詳しいことはわからないです。
4.6 SMTPE 240M
……(4.6a) ……(4.6b)
5. 光源変換 (Bradford 変換)
Bradford 変換のみ取り扱う。
光源における白色点 (White Point) の XYZ を用意する。ぶっちゃけ,D50,D65,D93 光源の 3 つについて考えれば完結するので,用意するのもさほど手間ではないと思う。変換式を用意する手順について説明する。
まず,変換元白色点 (Xs, Ys, Zs) と変換先白色点 (Xd, Yd, Zd) を用意する。これらからそれぞれの値 (L, M, S)*3 を作成する。
……(5.1) ……(5.2)
用意ができたら,次の変換行列を作成。
……(5.3)
単に XYZ 空間から感覚に近い LMS 空間に変換し,そこで波長それぞれの倍率でスケールして,再び XYZ 空間に戻すというだけである。
それぞれの定数は次の通り。
……(5.4) ……(5.5)
より詳しい解説は次を参照するとよい。
http://w3.kcua.ac.jp/~fujiwara/infosci/colorspace/bradford.html
追記: おまけ
ガンマカーブ(OETF)グラフ作った。
6. 色空間変換(概論)
前知識はそろった! いざ色空間変換概論へ。実際に実装する OBS Studio で考える。
OBS Studio は DirectX,OpenGL 上に展開され,その上で演算される。1 回目,YUV である場合 RGB に展開され,処理フローを流れていく。このとき RGB の色空間は全く気にしていない! (てか気にされていない!)
色空間の流れについて書いていく。
5.1 逆ガンマ変換
まずガンマを linear (1.0) に戻す処理を施す。
【format = RGB, cs = NTSC,γ = NTSC, wp = D93】 (NTSC-J) ↓逆ガンマ変換 【format = RGB, cs = NTSC,γ = linear, wp = D93】
5.2 RGB → XYZ 変換
XYZ にすると全色空間を扱うことができる。
【format = RGB, cs = NTSC,γ = linear, wp = D93】 ↓RGB to XYZ変換 【format = XYZ, cs = -,γ = linear, wp = D93】
5.3 光源変換
D93 光源を D65 に変換する
【format = XYZ, cs = -,γ = linear, wp = D93】 ↓XYZ to LMS変換 【format = LMS, cs = -,γ = linear, wp = D93】 ↓光源変換 【format = LMS, cs = -,γ = linear, wp = D65】 ↓LMS to XYZ変換 【format = XYZ, cs = -,γ = linear, wp = D65】
5.4 XYZ → RGB 変換
BT.709 RGB に戻す。
【format = XYZ, cs = -,γ = linear, wp = D65】 ↓XYZ to RGB変換 【format = RGB, cs = BT.709,γ = linear, wp = D65】
5.5 ガンマ変換
ガンマをもとに戻す。
【format = RGB, cs = BT.709,γ = linear, wp = D65】 ↓ガンマ変換 【format = RGB, cs = BT.709,γ = BT.709, wp = D65】
5.6 まとめ
RGB~XYZ~光源変換 (LMS)~XYZ~RGB
は 1 つの行列として演算することができるが,ガンマ変換は無理ぽ(近似すればいけるだろうけど)
したがって,この演算を追加するコストは,GPGPU において,3 回の演算(逆ガンマ変換,行列の掛け算,ガンマ変換)のみである。この程度の変換なら内部でちゃんと情報扱えるようにすればいいのかなーって。整理してて理解したので,あとは実際にコードに落とし込むだけなんだけど,それをどう設計するかが今後の課題…
4/1 ガンマ,光源変換について加筆。