2017年11月29日水曜日

rawの線形変換と色再現

 一般的なカメラでは正確な色は出せないがRawデータに一次変換を行いどの程度色が合わせられるのかを検証した。

colorCheckerの撮影とraw現像を行い、そこからXYZ色空間への変換マトリクスを算出し、この変換マトリクスを適用して色を正しいものに近づけた。
これをカメラごとに行い差がどれだけあるかを確認した。
  1. カラーチェッカーの撮影とRaw現像
    現像時に露光量とWBを合わせ、カラープロファイルは無効にする(Raw空間の現像)
  2. Raw_to_XYZマトリクス作成
    Raw空間のRGB値がリファレンスのXYZ色空間にフィットするようなマトリクスを作成
  3. マトリクス適用とsRGB変換
    XYZ空間への変換が出来たら任意の色空間への変換は容易となる。今回はsRGBに変換した
raw現像はRawTherapeeを使用
マトリクスの作成と適用はpythonとOpenCVで作成

RGB色空間とXYZ色空間について
  • 下図の点群は人が認識可能な物体色を表している
  • RGB色空間では表せない物体色がある。立方体からはみ出た点がそれのこと
  • sRGB色空間を立方体で表したが、はみ出た点は1.0を超えていたりマイナスにいる
  • X軸、Y軸、Z軸それぞれの軸を傾けたり伸縮させたりして空間をゆがませ、はみ出ていた物体色が立方体に収まるようにする。この変換のことをRGBからXYZに変換すると言い、3x3マトリクスを掛けることで変換できる
  • ついでにXYZのほかにxyzやxyYへの変換イメージも記載した
 

Luther-Ives条件
本来はセンサーにLuther-Ives条件が満たされたものでないと色は一致しない。
これは人の色の感じ方と同じになるようなフィルタをカメラに備える必要があるということでかなり難しいみたい。(たぶんモニタのキャリブレーションの計測器とかがそうだと思う)

正確な色が出せるカメラ
ここによると価格は100万以上とのこと
 4Gamer.net ― [SIGGRAPH]「Emerging Technologies」展示セクションレポート(3) 液晶や有機ELの先にある「未来のディスプレイ」とは?

colorCheckerPassportを使ったカメラキャリブレーションについて

今回は使わないが検証した。
colorCheckerのクラシックターゲットの写真(.dng)をドラッグするだけで、24個のパッチを自動認識してdcpファイルを作ってくれるもの。
dcpファイルとはDNG Camera Profileの略。
dcpはLightRoomやRawTherapeeでも読み込める

dcpプロファイルの中はマトリクスのほかにテーブルを持つことも可能。
このツールで作られたdcpの中身を見るとマトリクス以外に6*6*3のHSVの補正テーブルが存在していた。

カメラごとにdcpの作成を行い、RawTherapeeでdcpを適用しsRGBで現像したもの
左から6D、α6300、K52s
   
思ったよりばらついている

dcpについて詳細は Color Management/jp - RawPedia
dcpToolを使えばdcpの中を見たり直接編集できる Lightroomのカメラプロファイルを偽装して増やす方法

線形変換だけにしたい理由

LUTを含めたキャリブレーションは一枚の絵としては問題ないが、露出の異なる複数の写真を合成するようなHDR現像等では色が綺麗につながらなくなる可能性があると思う。
LUTは明るさや色を3次元で細かく分割してそれらが別々の向きに補正をしていることから、ところどころ空間をゆがめて補正していると考えられる。
例えば、ある色を2倍の明るさで撮影した場合2倍のRGB値になるはずがそうならない可能性がある。これはLUTにより線形性が崩れるため。

カメラRaw色空間の現像

比較したカメラは以下
  • SONY ILCE6300 + sony E PZ16-50mm f/3.5-5.6 OSS
  • Canon EOS 6D + Canon EF50mm f/1.8 STM
  • PENTAX K-5IIs + Tamron AF 17-50mm f/2.8 XR Di-II LD(Model A16)
撮影条件
  • 午後の日陰。色温度は9000ケルビンくらいはありそう
  • 中心付近に小さめに写るように撮影(周辺減光の影響を避けるため)
  • 白が現像時に白飛びしていないように気を付けて撮影
現像(RawTherapee)

 どの現像ソフトでもよいけどニュートラルな状態にすることが重要
  • 処理プロファイルをニュートラル設定にする
  • ホワイトバランスを合わせる(下段右から3個目をスポイトでクリック)
  • 露光量を合わせる。下段のグレーのあかるさが理論値になるようにする
  • 場合によっては黒レベルを調整。レンズによってはハレーションが起きたりして黒浮きすることもあるかも。なぜか6Dが本来より少し黒が締まっていたので黒レベルを少しだけマイナスにした
  • プロファイルを無しにする。デフォで使われているプロファイルを外すこと。ホワイトバランスと露光調整以外の余計な色補正をさせないため
  • 作業プロファイルと出力プロファイルはともにsRGB。余計なデータ補正や見た目の補正をさせないため
 こんな感じに現像される。プロファイル無しのrawデータのため低コントラスト且つ低彩度な見え方になる
 
 RAW現像結果の色。左から6D、α6300、K5IIs
    

マトリクス適用

理想的なカメラなら任意の3点を一致させる変換マトリクスを適用すると、他の色も一致することになる。
また、光源が変わるとたとえホワイトバランスを合わせたとはいえ、変換マトリクスは違うものになる。

変換先はXYZ色空間とする。後から他の色空間への変換が容易になるため。

canon6Dの日陰撮影のRawデータで検証
RawデータのRGBをYu'v'空間にプロットした
  • 色付きの24個のポイントがRaw現像後の位置
  • その中で赤、青、緑、を大きな丸で囲った
  • 小さな点がリファレンスの位置(リファレンスはbeforeNov2014_D65とした)
  • グレーの三角形はsRGB領域
 Yu'v'を真上から見たもの (u'v'平面)
 

横のほうから見たもの (高さは視感反射率Yとした。明るさのこと)
  

赤、青、緑の3色が一致する変換マトリクスを適用(canon6D)

  • 3つの未知数を持つ連立方程式を解いてマトリクスを適用
  • 3点が完全に一致していることがわかる
  • 全体的にリファレンスに近いが黄色やオレンジが大きくずれている
   

変換マトリクスと変換後の色差DE2000
toXYZ_Mat
[ 0.89835441 -0.17661714  0.21551421]
[ 0.31729395  0.82602992 -0.15964913]
[ 0.01397038 -0.34370169  1.39592   ]
ΔE00
[ 9.38996824e-01  1.08310822e+00  7.85876988e-01  2.41646509e+00   1.31960531e+00  9.10994244e-01]
[ 4.03237985e+00  7.20378675e-01  5.64588810e-01  1.43603546e+00   2.07556347e+00  4.43399649e+00]
[ 3.02228672e-06  1.39560170e-06  2.91851177e-07  3.69368659e+00   1.46170962e+00  3.78619604e+00]
[ 4.60377270e+00  1.54580962e+00  5.78651985e-01  2.43207497e+00   1.50993729e+00  3.91870255e+00]
ΔE00_ave :  1.84368897906

調整した変換マトリクスを適用(canon6D)

  • 3機種の傾向も考慮して手動で微調整した
    ターゲット3点のYu'v'の座標を少しずらして試行錯誤した。
    できればL*a*b*やL*u*v*で誤差が最小になるような計算ができればよいのだが難しそうなのでやめた
  • オレンジや黄色が改善された
  
変換マトリクスと変換後の色差DE2000
toXYZ_Mat
[ 0.86985374 -0.11609804  0.20381344]
[ 0.30761041  0.9124425  -0.20011322]
[ 0.00506413 -0.30798665  1.41722922]
ΔE00
[ 1.06833092  1.2581274   0.36424489  0.86918975  0.90505062  0.79224334]
[ 2.06356919  0.1082458   0.48136401  1.25677744  0.88228887  2.12901974]
[ 1.33289029  1.37997964  0.89330811  1.25032554  1.17798868  3.62548714]
[ 0.99368582  1.6426019   2.47002297  0.43946784  1.44493901  2.8286171 ]
ΔE00_ave :  1.31907358332

調整した変換マトリクスを適用(α6300)

α6300での結果
  
toXYZ_Mat
[ 0.82079626  0.0782833   0.03976358]
[ 0.27049007  1.04623496 -0.31998426]
[ 0.04249192 -0.32674336  1.3431005 ]
ΔE00
[ 1.10702662  2.58816693  1.00386873  0.53055415  0.95530419  0.23357595]
[ 1.62771004  0.94036273  1.26947082  1.1245529   1.43463378  1.90325408]
[ 0.72444967  1.07176911  1.03303373  2.62862239  0.86314914  1.73175871]
[ 3.30977831  0.72365459  1.21562373  1.59332979  0.91186525  0.43170746]
ΔE00_ave :  1.28988428371

調整した変換マトリクスを適用(k5Ⅱs)

K5Ⅱsでの結果
  
toXYZ_Mat
[ 0.72176424  0.18613429  0.04197106]
[ 0.26178377  1.05924103 -0.31321469]
[ 0.00864767 -0.31876012  1.44011637]
ΔE00
[ 1.50517607  3.43638754  0.76003805  0.90319897  1.4062553   1.24471321]
[ 2.04390155  0.64819104  1.2938633   2.08423349  1.72452133  2.82271584]
[ 1.29717256  1.56150571  2.03697617  3.38381743  0.46752731  2.11843823]
[ 0.87083697  1.49841186  1.92799113  0.73928252  1.03020498  1.95780584]
ΔE00_ave :  1.61513193227


カラーチェッカーの比較

左からリファレンス、6D、α6300、K5Ⅱs
    
  •  多少ばらつきはあるがなぜかcolorCheckerPassportのキャリブレーションより結果はよい。
  •  マトリクスの影響で下段のグレーに多少色のばらつきが発生

写真で比較

それぞれホワイトバランスを合わせてRaw現像したものに対して、上記マトリクスを適用してからsRGBに変換したもの

左から6D、α6300、K5Ⅱs
  
  
多少ばらつきはあるがこんなものかもしれない

現像時に3機種のホワイトバランスを合わせているためある程度ばらつきは抑えられているが、ホワイトバランスを固定して、光源の色を重視した現像をする場合はもっとばらついてしまう

dxomarkにも変換マトリクスが載っている

今回はマトリクスを自前で用意したが、ここのを使用してもいいかも。

dxomark.comというカメラの機種ごとの評価や詳細なデータを公開しているすごいところがある。
ここに記載されてるマトリクスはRawからsRGBへの変換。光源はたぶんD50
下記ページのColorResponseタブに記載されている

Canon EOS 6D : Measurements - DxOMark
Raw_to_sRGB_Mat
[ 2.29 -1.44  0.15]
[-0.27  1.63 -0.36]
[ 0.05 -0.75  1.70]
これをXYZへの変換に直すと
Raw_to_XYZ_Mat
[ 0.85700156 -0.14641637  0.23988479]
[ 0.29753848  0.80531788 -0.10285635]
[ 0.059608   -0.54628587  1.57550788]
Raw_to_sRGB_Mat
[ 2.04 -0.91 -0.13]
[-0.24  1.65 -0.41]
[ 0.06 -0.49  1.44]
これをXYZへの変換に直すと
Raw_to_XYZ_Mat
[ 0.76641911  0.12625081  0.05960444]
[ 0.26654659  0.95110304 -0.21692786]
[ 0.06785332 -0.286576    1.31705573]
Pentax K-5 IIs : Measurements - DxOMark
Raw_to_sRGB_Mat
[ 1.69 -0.57 -0.12]                    
[-0.14  1.49 -0.35]
[ 0.07 -0.49  1.43]
これをXYZへの変換に直すと
Raw_to_XYZ_Mat
[ 0.65962134  0.20927382  0.0833792 ]
[ 0.26434806  0.90898746 -0.17261375]
[ 0.0825087  -0.2990732   1.31489755]

XDOのマトリクスを使ってみたところ6Dに関しては日向で撮影したカラーチェッカーがいい感じになった
ΔE00_ave :  1.69791451803


α6300やk52sはそこまで一致はしなかった

参考

Nikon D610で同じような検証をしている。ΔE00平均は1.17となっている


de00色差を計算してくれる

エクセルスプレッドシートでde00色差を確認出来て途中計算の結果も見れる


2017年10月30日月曜日

カラーチェッカーのリファレンス

colorCheckeの24色には幾つかリファレンスがある。
とりあえずどれだけ違うのか代表的なものだけだを確認したのでメモとして掲載。

公開されているリファレンスの値はD50の光源だが、映像系では白基準はD65が多いと思うので、ここではD65の値として比較した。

2014年11月以前と以後の製造で色が少し違うとのこと。
カラーチェッカーパスポートのクラシックターゲットも対象なのか?
BabelColorの30個の平均が今までは無難だと思っていた。
またBabelColorの値は分光反射率の数値なので光源を変えた時の値もより正確に求められるところも良かった。
でも最近になって、2014年11月以前と以後の製造で色が少し違うとのことになったのでリファレンスをどれにすればよいか迷うところ。
新色の平均をまたBabelColorが用意してくれたら嬉しい。

比較

X-Rite公表の2個の値とbabelColorの30個平均の値の3種類のリファレンスを比較
  • X-Riteで公表されている2014年11月以前に製造されたもの(古い色)
  • X-Riteで公表されている2014年11月以後に製造されたもの(新色)
  • babelcolor公表の30サンプル平均の分光反射率にD65光源を当てた結果(古い色)
u'v'色度図で三角形はsRGB領域
 
BabelColorの30個平均が彩度が少し低そう。(三角形の端に行くほど彩度が高い)
30個の平均だから彩度は少し落ちるのかな?

sRGBの色とそれぞれのチャンネル
 
RGBで見ると小さいとよくわからないが、拡大してみると少し違いが判る。dark skin,red,magentaの違いがわかる

2014年11月以前のカラーチェッカー クラシック用リファレンスデータ

beforeNov2014_D65:beforeNov2014をD65に変換した(白色点変更はBradford)
 

sRGB8bit
 [115  81  67] [199 147 129] [ 91 122 156] [ 90 108  64] [130 128 176] [ 92 190 172]
 [224 124  47] [ 68  91 170] [198  82  97] [ 94  58 106] [159 189  63] [230 162  39]
 [ 35  63 147] [ 67 149  74] [180  49  57] [238 198  20] [193  84 151] [  0 136 170]
 [245 245 243] [200 202 202] [161 163 163] [121 121 122] [ 82  84  86] [ 49  49  51]

XYZ
 [.111  .0996 .067 ] [.3785 .3459 .2534] [.1726 .186  .3401] [.1045 .1319 .069 ] [.247  .2329 .443 ] [.303  .4206 .4555]
 [.3851 .3045 .065 ] [.1341 .1165 .3966] [.2855 .1894 .1347] [.0867 .0642 .143 ] [.3333 .4409 .1143] [.46   .4275 .0777]
 [.0777 .0606 .284 ] [.1428 .2316 .1022] [.2062 .1216 .0513] [.5578 .5887 .0907] [.3072 .199  .3131] [.1451 .1976 .4092]
 [.8648 .9129 .976 ] [.5579 .5895 .6456] [.3434 .3634 .3997] [.1818 .1916 .21  ] [.0837 .0884 .1002] [.0295 .0311 .0354]

2014年11月以降のカラーチェッカー クラシック用リファレンスデータ

afterNov2014_D65:afterNov2014をD65に変換した(白色点変更はBradford)
 

sRGB8bit
 [116  79  65] [197 144 127] [ 91 120 155] [ 91 108  64] [131 127 175] [ 95 189 172]
 [224 124  48] [ 69  90 167] [197  80  95] [ 93  58 104] [156 187  58] [227 161  39]
 [ 40  62 145] [ 61 147  70] [178  54  57] [236 199  15] [191  79 146] [  0 133 165]
 [241 242 235] [201 202 201] [161 163 163] [121 121 121] [ 83  84  85] [ 50  50  50]

XYZ
 [.1093 .0971 .063 ] [.3681 .3327 .2443] [.1699 .181  .3371] [.1067 .134  .0683] [.2467 .231  .4349] [.3032 .4171 .4534]
 [.3853 .3053 .0669] [.1304 .1128 .3817] [.2804 .1847 .1292] [.085  .0632 .1384] [.3228 .4295 .1062] [.4497 .4214 .077 ]
 [.0769 .059  .2761] [.1345 .2231 .0941] [.2044 .1238 .0515] [.5534 .5901 .0891] [.2955 .1876 .2943] [.1335 .185  .3854]
 [.8298 .8802 .9152] [.5583 .59   .6373] [.3447 .3649 .3978] [.1809 .1906 .2068] [.0834 .0882 .0976] [.03   .0315 .0351]

ちなみにもっと前に公表されているものとしては下のリンクにある色彩データ。
X-Rite: MSCCC : ColorChecker Classic(カラーチェッカー・クラシック)
ここのL*a*b*は2014年11月以前のカラーチェッカー クラシック用リファレンスデータと同じであるがsRGBの値は正しくないみたい

babelcolorの30個のカラーチェッカーの平均(2014年11月以前

babelcolor : babelcolorの分光反射率にD65光源を当てた結果から
 

sRGB8bit
 [115  82  68] [195 149 128] [ 93 123 157] [ 91 108  65] [130 129 175] [ 98 191 170]
 [220 123  46] [ 72  92 168] [194  84  97] [ 91  59 104] [161 189  62] [229 161  41]
 [ 42  63 147] [ 72 149  72] [175  50  57] [238 200  21] [188  84 150] [  0 137 166]
 [245 245 240] [201 202 201] [161 162 161] [120 121 121] [ 83  85  85] [ 50  50  51]

XYZ
 [.1114 .1008 .0678] [.3719 .3458 .2524] [.1763 .1885 .3447] [.1061 .1335 .0696] [.2479 .2345 .4391] [.3095 .4267 .4486]
 [.3715 .2967 .0632] [.1355 .1181 .3867] [.2766 .187  .1353] [.0838 .0637 .1398] [.3365 .4421 .1132] [.4522 .4207 .078 ]
 [.0798 .0611 .2834] [.1464 .2343 .0984] [.1956 .1168 .0504] [.5604 .5942 .0925] [.2941 .1924 .3103] [.1462 .1995 .393 ]
 [.8621 .9125 .9534] [.5566 .5887 .6362] [.3403 .3597 .3909] [.1807 .1913 .2086] [.0845 .0894 .0988] [.0304 .032  .0354]

Babel Color

colorChekerの値について詳細に調べてある
The ColorChecker Pages (Page 1 of 3)
  • 30個のカラーチェッカーの平均を計測
  • X-Riteの値との比較分析
  • カラーチェッカーの画像ファイル(RGBやL*a*b*)
  • スペクトルデータ
  • カラーチェッカーRGB値(8bit 16bit)
  • 計測値からRGB座標に変換する方法
以下のページにリファレンスのカラーチェッカー画像が載っている
The ColorChecker Pages (Page 2 of 3)
  • 2014年11月以前 x-rite公表
  • 2014年11月以前 babelColor 30チャート平均
  • 2014年11月以降 x-rite公表

その他

L*a*b*(D50) darkSkin : 37.986, 13.555, 14.059
colorCheker1976 L*a*b*(D50) darkSkin : 38.14, 13.81 ,14.75
colorCheker1976,2005等が載っている。colorCheker2005として掲載されているものは一番上の文献と値は同じ
1976,2005で一番差が大きい色はno13 blueとのこと
L*a*b(D50) darkSkin : 39.42,13.80,14.58
D65のL*a*b*も掲載されている。colorChekerPassportの24色以外の色も掲載されている
L*a*b(D50) darkSkin : 37.257,12.752,14.852
ColorCheckerSpreadsheetsをダウンロードし中を見るとL*a*b*があり光源はD65,D50,C,Eが掲載されている

x-rite ColorCheckerデーター

L*a*b(C) darkSkin : 38.08,12.09,14.39

ColorChecker - Wikipedia

一つ上の文献と同じ(L*a*bは載っていないがxyYの値が同じ)

colorCheckerPassport付属のソフトウェアの中に入っているリファレンス値

この場所に保存されている
 C:\Program Files (x86)\X-Rite\ColorChecker Passport\win\Reference\ColorChecker24_spectral.txt
これは24色の分光反射だと思う。レンジは380-730nmだと思う
colorCheckerPassportのキャリブレーションのターゲットがこれだと思うのでリファレンスとしての信頼性は高そう。そのうち時間があればこのリファレンスの値を調べたい。
関連ページ
Creating CIE file for ColorChecker Passport - Tomas Sobek Photography
2017年10月29日日曜日

カラーチェッカーを6x4ピクセルに縮小する方法

6x4のピクセルサイズにしたいことが多々あるのでphotoShopでの方法をメモする

下のように各パッチの中心付近を平均化した値を調べて6x4の24ピクセルにしたい

今回使った画像
 eos6Dでカラーチェッカークラシックを撮影し、colorCheckerPassportでdcpを作成し、
 RawTherapeeというフリーの現像アプリでWBの補正と、そのdcpの適用をしてsRGBで現像したもの

手順

  1. カラーチェッカーをトリミング (台形補正タイプ)
  2. カラーパッチが正方形になるように解像度を補正
  3. 余白を追加
  4. 27x17ピクセルに縮小 (バイリニアによる平均化)
  5. 6x4ピクセルに縮小 (ニアレストネイバーによるポイントサンプル)

1. カラーチェッカーをトリミング (台形補正タイプ)


余白は後で作るので両端の余白は含めずに角の4点をクリックする 

台形補正されたトリミング結果

2. カラーパッチが正方形になるように解像度を補正

カラーパッチ1個を囲ったとこの情報は横21.5に対して縦が20.7となっている

なので今回は横解像度をその分小さくする。
この場合は1696x1073の画像に対して、横だけ 1696x20.7/21.5 ≒ 1633に変更(一応バイリニアで) 

3. 余白を追加

横解像度の4%に相当するピクセル数を上下に増やす。
この場合だと横1633ピクセルなので4%の65ピクセルを上下に増やすためにカンバスサイズの変更を行う。
中心を基準として1633x1073から1698x1138に変更して余白を作成

4. 25x17ピクセルに縮小 (バイリニアによる平均化)

(8倍拡大表示)

これによって枠の黒色が1ピクセルのラインに収まり、各カラーパッチの大きさの3x3ピクセルには黒枠の影響はほぼ受けずに色が平均化できる

sRGBガンマ空間のままで平均化しているが、本当はリニアスペースの値で平均化したほうが良いはず。
でも気にするほどの誤差ではないと思う。

5. 6x4ピクセルに縮小 (ニアレストネイバーによるポイントサンプル)

3x3のカラーパッチのうち中心のピクセルだけが取得される
(32倍拡大表示)
完成

スクリプトで画像のRGBの値を表示する例

上の画像の値を読み込んで表示

import cv2
imgPath='eos6D_classic_sRGB.tif'
img = cv2.imread(imgPath,-1) #exrでも読み込めるようにflagは-1
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #openCVはBGRの順なのでRGBの順に変える
print(img)
"""
[[[120  84  73]
  [200 148 134]
  [ 95 123 157]
  [ 95 109  68]
  [131 129 179]
  [100 190 175]]

 [[221 119  50]
  [ 67  88 169]
  [201  81  99]
  [ 91  57  99]
  [165 189  63]
  [232 158  41]]

 [[ 38  56 144]
  [ 78 150  81]
  [179  54  62]
  [241 197  35]
  [193  80 149]
  [  0 141 175]]

 [[252 240 242]
  [205 202 204]
  [164 163 164]
  [120 120 120]
  [ 84  84  85]
  [ 52  51  51]]]
"""

photoShopのポイントサンプルのテストしたときのメモ

ニアレストネイバーの縮小をテスト

4x4 to 2x2
  
 サンプルポイントが4ピクセルの中心だった時は右下が使われるみたい

6x6 to 2x2
  
 サンプルポイントがピクセルの中心の場合

25x17 to 6x4 (今回サンプルポイントする解像度)
  

カラーチェッカーの枠部分は下図のグレー部分に入っていればよい
 
 カラーパッチ3x3まではバイリニアで色の平均化をして、その中心の1ピクセルをポイントサンプルする