2015年9月15日火曜日

Maya色管理4 colorCheckerの数値


前回の調査でカラー値はレンダリング空間に合わせた数値入力が必要ということがわかたった。
今回はカラーチェッカーの値が正しく表示されるように各レンダ空間に適した色を入力してみる。

重要 : テクスチャの場合は入力空間の指定ができるので各レンダ空間毎にテクスチャを用意する必要は基本的にはない

Color Cheker の素材

本当は各レンダリング空間に合わせた白色光を当てたカラーチェーカーを用意したほうが良いが、白色点変更を施した値を使うのでも誤差は少ない。

今回はカラーチェッカーの分光反射から作成し、色はXYZ(E)として求めたものをベースとして使用した。
分光反射のリファレンスはNoboru Ohtaタイプを使用した。
これを各レンダ空間用に値を変更してどの様に見えるかをテストする。

単体の色を見るだけなのでレンダ空間に対応した数値になっていればプレビュー結果は全く同じになるはず。
ライトに色がついていたりすると同じにはならないので注意。

各レンダ空間に適用するための変換マトリクス

ある標準光源に照らされたカラーチェッカーのXYZ値があったとする。
カラーチェッカーに照らされた光源色の色を相殺し、レンダ空間の白に合わせることをする。
これがディフューズ色。

XYZ値がE光源(D65環境下では少し赤い色)で照らされたものなら。(今回はこれ)
使用するレンダ空間レンダ空間に変更するためのmatrix(白色変更はbradfordを使用した)
scene-linear CIE XYZ
XYZ(E) → XYZ(D65)   Mayaではレンダ空間XYZの白色点はD65
ACEScg
XYZ(E) → ACESap1(D60)
Sharp RGB
XYZ(E) → Sharp RGB(E)
scene-linear Rec 709/sRGB
XYZ(E) → sRGB(D65)

カラーチャートのXYZ値がD65光源(D65環境下では白色)で照らされたものなら
使用するレンダ空間レンダ空間に変更するためのmatrix(白色変更はbradfordを使用した)
scene-linear CIE XYZ
XYZ(D65) → XYZ(D65)   Mayaではレンダ空間XYZの白色点はD65
ACEScg
XYZ(D65) → ACESap1(D60)
Sharp RGB
XYZ(D65) → Sharp RGB(E)
scene-linear Rec 709/sRGB
XYZ(D65) → sRGB(D65)

カラーチャートのXYZ値がA光源(D65環境下ではかなり赤い色)で照らされたものなら
使用するレンダ空間レンダ空間に変更するためのmatrix(白色変更はbradfordを使用した)
scene-linear CIE XYZ
XYZ(A) → XYZ(D65)  Mayaではレンダ空間XYZの白色点はD655
ACEScg
XYZ(A) → ACESap1(D60)
Sharp RGB
XYZ(A) → Sharp RGB(E)
scene-linear Rec 709/sRGB
XYZ(A) → sRGB(D65)

ということ
結果はぴったりと一致した
各レンダリング空間に値を合わせたので左のプレビュー画像は全く違いがない。
右側がプレビューのRaw(レンダ空間の色)なので、もし後からでレンダ空間を変えた場合これだけ数値を変えなければ色が合わないということがわかる


各色空間で入力した値
no-|-----------------XYZ to RGB value------------------|Linear 8bit Value
----
01 |0.119341058      0.0999           0.0559           |   30   25   14
02 |0.412222651      0.363180818      0.236403888      |  105   93   60
03 |0.182681943      0.187540862      0.317664563      |   47   48   81
04 |0.106503072      0.128926832      0.0611           |   27   33   16
05 |0.269627348      0.242756637      0.417069611      |   69   62  106
06 |0.320807381      0.417457527      0.406387316      |   82  106  104
----
07 |0.400687638      0.308497094      0.054292495      |  102   79   14
08 |0.134942682      0.114781053      0.340796394      |   34   29   87
09 |0.315580939      0.204426014      0.126666899      |   80   52   32
10 |0.0925           0.0663           0.137877016      |   24   17   35
11 |0.352064935      0.435275631      0.101625589      |   90  111   26
12 |0.502433902      0.44538134       0.0771           |  128  114   20
----
13 |0.0821           0.06             0.271971018      |   21   15   69
14 |0.149383905      0.230356768      0.0865           |   38   59   22
15 |0.229218256      0.129139309      0.0478           |   58   33   12
16 |0.607374032      0.607579034      0.08706536       |  155  155   22
17 |0.322739172      0.202413208      0.281472653      |   82   52   72
18 |0.143264706      0.18994647       0.357691497      |   37   48   91
----
19 |0.885095979      0.887271216      0.873774268      |  226  226  223
20 |0.584241934      0.583949023      0.581522196      |  149  149  148
21 |0.358099806      0.358176938      0.358332475      |   91   91   91
22 |0.203062932      0.203056127      0.20335156       |   52   52   52
23 |0.0922           0.092532056      0.094            |   24   24   24
24 |0.0335           0.0335           0.0351           |    9    9    9
レンダ空間変換マトリクス: 
[[ 0.95318743 -0.02659057  0.02387315]
 [-0.03824666  1.02884062  0.00940604]
 [ 0.00260677 -0.00303325  1.08925647]] 

レンダリング空間へ変換後のカラーチェッカーの値を表示
no-|-----------------XYZ to RGB value------------------|Linear 8bit Value
----
01 |0.112432506547   0.0987425789306  0.0608975105697  |   29   25   16
02 |0.388911966306   0.360112663437   0.257477419236   |   99   92   66
03 |0.176726964917   0.188950647697   0.345925534397   |   45   48   88
04 |0.099547799967   0.129146484173   0.0664401329774  |   25   33   17
05 |0.260507123966   0.24336851637    0.45426229032    |   66   62  116
06 |0.304390871004   0.421049945085   0.44223003515    |   78  107  113
----
07 |0.375023436398   0.302580056209   0.0592472055066  |   96   77   15
08 |0.133709456272   0.116135846678   0.371218284112   |   34   30   95
09 |0.29839591557    0.19944330473    0.138175313043   |   76   51   35
10 |0.089698440226   0.0659711936423  0.150223454509   |   23   17   38
11 |0.326435763181   0.435319837368   0.110293785651   |   83  111   28
12 |0.468911352206   0.439735202522   0.0839404536851  |  120  112   21
----
13 |0.0831540574969  0.0611485560525  0.296278213317   |   21   16   76
14 |0.138330568568   0.23210058722    0.0939113659824  |   35   59   24
15 |0.216195207607   0.124546543416   0.0522722679866  |   55   32   13
16 |0.564863939401   0.602690903976   0.0945768560331  |  144  154   24
17 |0.308968275525   0.198554778269   0.30682324801    |   79   51   78
18 |0.140046552638   0.193309707235   0.389415082802   |   36   49   99
----
19 |0.840929049484   0.887227458755   0.951380209782   |  214  226  243
20 |0.555247290974   0.58391499331    0.633178541245   |  142  149  161
21 |0.340366626166   0.358181351028   0.390163014021   |   87   91   99
22 |0.193012296386   0.203058645585   0.221415422808   |   49   52   56
23 |0.087667476106   0.0925585635666  0.102349780445   |   22   24   26
24 |0.031878942036   0.0335150496585  0.0382186153583  |    8    9   10
レンダ空間変換マトリクス: 
[[  1.01338130e+00  -2.16585679e-02   8.27726497e-03]
 [ -5.21145827e-01   1.42051414e+00   1.00631690e-01]
 [ -4.65451231e-04   2.06045382e-03   9.98404997e-01]] 

レンダリング空間へ変換後のカラーチェッカーの値を表示
no-|-----------------XYZ to RGB value------------------|Linear 8bit Value
----
01 |0.119237005144   0.085340579405   0.0559611312186  |   30   22   14
02 |0.411829528784   0.324865094702   0.236583270819   |  105   83   60
03 |0.183693992863   0.203167635234   0.317459276775   |   47   52   81
04 |0.105641592316   0.133787352243   0.0612186211054  |   27   34   16
05 |0.271429748061   0.246294487165   0.416779074121   |   69   63  106
06 |0.319422445356   0.466712333214   0.406449958721   |   81  119  104
----
07 |0.399817149166   0.234871338398   0.0546550417605  |  102   60   14
08 |0.137083259863   0.127018209804   0.340426514504   |   35   32   87
09 |0.316424704236   0.138673057551   0.126739187723   |   81   35   32
10 |0.0934430521552  0.0598488953814  0.137750655576   |   24   15   35
11 |0.348189758002   0.44506477052    0.102196492145   |   89  113   26
12 |0.500148977869   0.378587861896   0.0776608544617  |  128   97   20
----
13 |0.0841502671583  0.0698136788968  0.271622637056   |   21   18   69
14 |0.147109642146   0.258078888028   0.086767140788   |   38   66   22
15 |0.22988417592    0.0687982712984  0.0478831545127  |   59   18   12
16 |0.603062859793   0.555305699459   0.0878956760262  |  154  142   22
17 |0.325003686468   0.147661719492   0.281290546958   |   83   38   72
18 |0.144028513348   0.231154941979   0.357445671136   |   37   59   91
----
19 |0.884955154539   0.887046610962   0.873796807652   |  226  226  223
20 |0.584225766608   0.583552157926   0.581525930139   |  149  149  148
21 |0.358100061642   0.358232786954   0.358332262622   |   91   91   91
22 |0.203065468634   0.203082310515   0.203351085504   |   52   52   52
23 |0.092207707309   0.0928528272792  0.0939978131296  |   24   24   24
24 |0.0335132436565  0.0336610107017  0.0350974479765  |    9    9    9
レンダ空間変換マトリクス: 
[[ 1.2703 -0.0989 -0.1714]
 [-0.836   1.8     0.0361]
 [ 0.0297 -0.0315  1.0017]] 

レンダリング空間へ変換後のカラーチェッカーの値を表示
no-|-----------------XYZ to RGB value------------------|Linear 8bit Value
----
01 |0.132137575977   0.082068865512   0.0563926094226  |   34   21   14
02 |0.447208224262   0.317641516521   0.237608591577   |  114   81   61
03 |0.159065374843   0.196319137976   0.317722709311   |   41   50   81
04 |0.112067448677   0.145237439408   0.0603058160304  |   29   37   15
05 |0.24701325744    0.226609696629   0.418139727509   |   63   58  107
06 |0.296580280702   0.497899160192   0.403456241552   |   76  127  103
----
07 |0.469177410312   0.222279862902   0.0565675566291  |  120   57   14
08 |0.101653340871   0.106096563071   0.341767942356   |   26   27   87
09 |0.358954027538   0.10871383525    0.129815567176   |   92   28   33
10 |0.0873135594576  0.0469873602776  0.138770206927   |   22   12   35
11 |0.38676070107    0.492838533903   0.0985434986943  |   99  126   25
12 |0.580978631185   0.384434979928   0.0781238446794  |  148   98   20
----
13 |0.0517417975148  0.0491825537498  0.272981738731   |   13   13   70
14 |0.152153990166   0.29287988782    0.0838275137865  |   39   75   21
15 |0.270211152937   0.042549874184   0.0506211539697  |   69   11   13
16 |0.696534663683   0.589020629944   0.0861136402914  |  178  150   22
17 |0.341712491196   0.104694989381   0.285160493867   |   87   27   73
18 |0.101895127563   0.235047014826   0.356571220508   |   26   60   91
----
19 |0.886821389326   0.888691201431   0.873597991528   |  226  227  223
20 |0.584737065991   0.583674935852   0.581468374949   |  149  149  148
21 |0.358052298179   0.358282852931   0.358294630899   |   91   91   91
22 |0.203014134175   0.203081408764   0.203331958732   |   52   52   52
23 |0.0918586396616  0.0928719008     0.093983380236   |   23   24   24
24 |0.03322576       0.03356111       0.03509937       |    8    9    9
レンダ空間変換マトリクス: 
[[ 1.59421809 -0.36784581 -0.22637229]
 [-0.69051897  1.67230359  0.01821538]
 [ 0.01110683 -0.00669355  0.99558672]] 

レンダリング空間へ変換後のカラーチェッカーの値を表示
no-|-----------------XYZ to RGB value------------------|Linear 8bit Value
----
01 |0.140853667147   0.0856741038219  0.0563101127311  |   36   22   14
02 |0.470062979485   0.327007211708   0.237508089068   |  120   83   61
03 |0.150338286085   0.193266290868   0.317036323562   |   38   49   81
04 |0.108532583255   0.143175371883   0.0611502819076  |   28   37   16
05 |0.246134784699   0.227377079049   0.416598767454   |   63   58  106
06 |0.265882105058   0.483994638022   0.405362695423   |   68  123  103
----
07 |0.513013803894   0.240207340437   0.0564383152247  |  131   61   14
08 |0.095759477598   0.104976021859   0.340022856883   |   24   27   87
09 |0.399233715566   0.126255017773   0.128244650146   |  102   32   33
10 |0.0918654614507  0.0495122058275  0.137852125489   |   23   13   35
11 |0.37814875709    0.486656631552   0.102173872938   |   96  124   26
12 |0.619704256008   0.399277077953   0.0793590012333  |  158  102   20
----
13 |0.0472478561342  0.0486006641809  0.271280991564   |   12   12   69
14 |0.133833550409   0.283649659662   0.0862355284825  |   34   72   22
15 |0.307099942616   0.0585512710621  0.0492705325873  |   78   15   13
16 |0.725082087103   0.598239235659   0.0893602551585  |  185  153   23
17 |0.37634217002    0.120765945589   0.28246018119    |   96   31   72
18 |0.077552732294   0.225236653535   0.35643270505    |   20   57   91
----
19 |0.886858750119   0.888527406419   0.873809673648   |  226  227  223
20 |0.58496535427    0.583702556875   0.581536159464   |  149  149  148
21 |0.358018764043   0.358233032313   0.358330931811   |   91   91   91
22 |0.203000098116   0.203056809465   0.203350331714   |   52   52   52
23 |0.0916703846174  0.0927880861391  0.0939898334468  |   23   24   24
24 |0.0331378043934  0.0335291446171  0.0350929387467  |    8    9    9
レンダ空間変換マトリクス: 
[[ 3.14625105 -1.66612389 -0.48012709]
 [-0.99553498  1.9557634   0.03977154]
 [ 0.06359784 -0.21459655  1.1509987 ]] 

レンダリング空間へ変換後のカラーチェッカーの値を表示
no-|-----------------XYZ to RGB value------------------|Linear 8bit Value
----
01 |0.182192047191   0.0787957955525  0.0504924661917  |   46   20   13
02 |0.57834779706    0.309315831524   0.220379689894   |  147   79   56
03 |0.109777579585   0.197553298877   0.337004055536   |   28   50   86
04 |0.0909415610322  0.148552887374   0.0494321332625  |   23   38   13
05 |0.243606272226   0.222938590808   0.445099562254   |   62   57  114
06 |0.118687036829   0.513235833685   0.398568986358   |   30  131  102
----
07 |0.720602223536   0.206608064081   0.0217710494819  |  184   53    6
08 |0.069698517114   0.103698419806   0.376206652782   |   18   26   96
09 |0.591481583347   0.0906747914694  0.121994586508   |  151   23   31
10 |0.114365716636   0.0430637092733  0.15035131577    |   29   11   38
11 |0.333668342625   0.504844998478   0.045952843732   |   85  129   12
12 |0.80170489919    0.373936387857   0.0251184144145  |  204   95    6
----
13 |0.0277591226605  0.0464290882977  0.305383878631   |    7   12   78
14 |0.0446653586574  0.305246672161   0.0596281146441  |   11   78   15
15 |0.483066014644   0.0262722228225  0.0418826747792  |  123    7   11
16 |0.856846800313   0.587081469663   0.00845543155505 |  218  150    2
17 |0.54303032867    0.0857688107746  0.301062997749   |  138   22   77
18 |-0.0374650001358 0.243091269811   0.380051918148   |  -10   62   97
----
19 |0.886907677278   0.888899914601   0.871597903257   |  226  227  222
20 |0.586035814515   0.583560880458   0.58117437498    |  149  149  148
21 |0.357859605045   0.35825989882    0.358351054351   |   91   91   91
22 |0.202935703874   0.203061094993   0.203396602156   |   52   52   52
23 |0.090782530253   0.0929210084643  0.0942005393068  |   23   24   24
24 |0.0327317986319  0.0335636332703  0.035341597819   |    8    9    9

カラーチェッカー作成のPyMel
import pymel.core as pm
from numpy import *
    
#光源色(白色点)のXnYnZnの配列 (3*1mat)
arrMatLightXYZ = [
matrix('1.09850;1.00000;0.35585'),   #0.A
matrix('0.99072;1.00000;0.85223'),   #1.B
matrix('0.98074;1.00000;1.18232'),   #2.C
matrix('0.96422;1.00000;0.82521'),   #3.D50
matrix('0.95682;1.00000;0.92149'),   #4.D55
matrix('0.95047;1.00000;1.08883'),   #5.D65
matrix('0.94972;1.00000;1.22638'),   #6.D75
matrix('1.00000;1.00000;1.00000'),   #7.E
matrix('0.99186;1.00000;0.67393'),   #8.F2
matrix('0.95041;1.00000;1.08747'),   #9.F7
matrix('1.00962;1.00000;0.64350'),   #10.11
matrix('0.952646075;1.00000;1.008825184')] #11.D60
arrKeyLightXYZ = ["A","B","C","D50","D55","D65","D75","E","F2","F7","F11","D60"]
arrMatLightXYZ = dict(zip(arrKeyLightXYZ,arrMatLightXYZ))
    
#XYZtoRGBの配列  (3*3mat)
arrMatXYZ2RGB = [
matrix('1 0 0; 0 1 0; 0 0 1'), #ZYZ(E)
matrix('3.2404542 -1.5371385 -0.4985314;-0.969266 1.8760108 0.041556;0.0556434 -0.2040259 1.0572252'), #sRGB(D65)
matrix('1.64102338 -0.324803294 -0.236424695; -0.663662859 1.615331592 0.016756348; 0.011721894 -0.008284442 0.988394859'), #ACESap1(D60)
matrix('1.049811018 0 -9.74845E-05; -0.495903023 1.373313046 0.098240036; 0 0 0.991252018'), #ACESap0(D60)
matrix('1.2703 -0.0989 -0.1714; -0.836 1.8 0.0361; 0.0297 -0.0315 1.0017')] #SharpRGB(E)
arrKeyXYZ2RGB = ["XYZ","sRGB","ACESap1","ACESap0","SharpRGB"]
arrMatXYZ2RGB = dict(zip(arrKeyXYZ2RGB,arrMatXYZ2RGB))
    
#カラーチャートのディフューズの値XYZ(E) (3*1mat)
arrMatColorChecker = [
matrix('0.119341058; 9.99E-02; 5.59E-02'),       #no1
matrix('0.412222651; 0.363180818; 0.236403888'), #no2
matrix('0.182681943; 0.187540862; 0.317664563'), #no3
matrix('0.106503072; 0.128926832; 6.11E-02'),    #no4
matrix('0.269627348; 0.242756637; 0.417069611'), #no5
matrix('0.320807381; 0.417457527; 0.406387316'), #no6
matrix('0.400687638; 0.308497094; 0.054292495'), #no7
matrix('0.134942682; 0.114781053; 0.340796394'), #no8
matrix('0.315580939; 0.204426014; 0.126666899'), #no9
matrix('9.25E-02; 6.63E-02; 0.137877016'),       #no10
matrix('0.352064935; 0.435275631; 0.101625589'), #no11
matrix('0.502433902; 0.44538134; 7.71E-02'),     #no12
matrix('8.21E-02; 6.00E-02; 0.271971018'),       #no13
matrix('0.149383905; 0.230356768; 8.65E-02'),    #no14
matrix('0.229218256; 0.129139309; 4.78E-02'),    #no15
matrix('0.607374032; 0.607579034; 0.08706536'),  #no16
matrix('0.322739172; 0.202413208; 0.281472653'), #no17
matrix('0.143264706; 0.18994647; 0.357691497'),  #no18
matrix('0.885095979;0.887271216;0.873774268'),   #no19
matrix('0.584241934;0.583949023;0.581522196'),   #no20
matrix('0.358099806;0.358176938;0.358332475'),   #no21
matrix('0.203062932;0.203056127;0.20335156'),    #no22
matrix('9.22E-02;0.092532056;9.40E-02'),         #no23
matrix('3.35E-02;3.35E-02;3.51E-02')]           #no24

#bradford変換マトリクス(XYZtoLMS)
mBrad = matrix('0.8951 0.2664 -0.1614; -0.7502 1.7135 0.0367; 0.0389 -0.0685 1.0296')
    
#カラーチェッカーのsahpeを削除
def deleteColorCheckerMesh():
    oShapeList = pm.ls(type = 'shape')    #sahpeの一覧取得
    #sahpe親のtransformノードにアトリビュート'colorCheckerRoot'があったらそれ以下の使用マテリアルとノード削除
    for oShape in oShapeList:
        oParent = oShape.getParent()
        if oParent is not None:
            if oParent.hasAttr("colorCheckerRoot"):
                colPatchList = oParent.getChildren()
                for colPatch in colPatchList:
                    if len(colPatch.shadingGroups()) > 0:
                        sg = colPatch.shadingGroups()[0]
                        oShader = sg.surfaceShader.connections()[0]
                        pm.delete(oShader,sg)
                pm.delete(oParent)
                    
#カラーチェッカーのsahpeを作成しsahpeを返す
def createColorCheckerMesh():
    #黒の下地のshape作成
    baseTranse,baseShape = pm.polyPlane(name ='pPlane_base', height = 20.3, width = 28.8, sh = 1, sw = 1)
    baseTranse.addAttr('colorCheckerRoot', dt='string')
    shader , shadingEngine = pm.createSurfaceShader('lambert')
    shader.diffuse.set(1.0)
    pm.sets(shadingEngine,forceElement=baseTranse)
    shader.color.set(0.0,0.0,0.0)
        
    #24個のパッチ作成と新規マテリアル割り当て
    colPatchList = []
    for i in range(1, 25):
        patchTranse, patcShape= pm.polyPlane(name = 'pPlane_No' + str(i), height = 4, width = 4, sh = 1, sw = 1)
        patchTranse.translate.set(((i-1)%6)*4.5 - 11.25 ,0.1,floor((i-1)/6)*4.5 - 6.75)
        shader , shadingEngine = pm.createSurfaceShader('lambert')
        shader.diffuse.set(1.0)
        pm.sets(shadingEngine,forceElement=patchTranse)
        colPatchList.append(patchTranse)
    
    #下地の子供に24個のパッチ
    for colPatch in colPatchList:
        baseTranse.addChild(colPatch)
            
    return colPatchList
    
#マテリアルの色を設定する
def setColor(colPatchList,xyz2rgbColor):
    for i,colPatch in enumerate(colPatchList):
        sg = colPatch.shadingGroups()[0]
        oShader = sg.surfaceShader.connections()[0]
        oShader.color.set(xyz2rgbColor[i])
    
#カラーチェッカーの値XYZ(E)を意を任意のカラースペースに変換する関数(変換先の色空間、変換元の白色点、変換先の白色点を指定する)
def ColorChange(XYZtoRGBname,sorceWname,distWname):
    print '使用するXYZtoRGBMatrix :',XYZtoRGBname,'\n',arrMatXYZ2RGB[XYZtoRGBname],'\n'
    print '変換元白色点 :',sorceWname,"\n ",arrMatLightXYZ[sorceWname],'\n'
    print '変換先白色点 :',distWname,"\n ",arrMatLightXYZ[distWname],'\n'
    
    #LMSスケールを求める
    lmsS = mBrad * arrMatLightXYZ[sorceWname]
    lmsD = mBrad * arrMatLightXYZ[distWname]
    mScale = matrix(zeros((3, 3)))     #対角行列の入れ物
    fill_diagonal(mScale,(lmsD/lmsS))  #対角行列を作成
    print "LMSスケール: \n",mScale,'\n'
                        
    #白色点変換マトリクス
    mChangeW = mBrad.I* mScale * mBrad
    print "白色点変換マトリクス: \n",mChangeW,'\n'
        
    #レンダ空間変換マトリクス(from XYZ)
    mRenderSpace = arrMatXYZ2RGB[XYZtoRGBname] * mChangeW
    print "レンダ空間変換マトリクス: \n",mRenderSpace,'\n'
        
    #変換後のカラーを格納する配列
    distCol = empty((24,3),dtype = float64)
    for i,elem in enumerate(arrMatColorChecker):
        arrCol = mRenderSpace * elem
        distCol[i] = (arrCol.T)
            
    return distCol
    
#shape削除
deleteColorCheckerMesh()
    
#shape作成
colPatchList = createColorCheckerMesh()
    
# 色変換
#白色点はここから選ぶ : A B C D50 D55 D65 D75 E F2 F7 F11 D60
#XYZtoRGB変換はここから選ぶ : XYZ sRGB ACESap1 ACESap0 SharpRGB"
XYZtoRGBname,sorceWname,distWname = 'ACESap1',"E","D60"
xyz2rgbColor = ColorChange (XYZtoRGBname,sorceWname,distWname)  #カラースペースに変換する関数を実行
    
#変換値のログ表示
print 'レンダリング空間へ変換後のカラーチェッカーの値を表示'
print '{:^3}|{:-^51}|{:^17}'.format('no','XYZ to RGB value','Linear 8bit Value')
for i,colPatch in enumerate(xyz2rgbColor):
    if (i)%6 == 0:
        print "----"
    val8 = around(xyz2rgbColor[i] * array([255, 255, 255])).astype(int)
    print str(i+1).zfill(2),'|{:< 17}{:< 17}{:< 17}|{:>5}{:>5}{:>5}'.format(xyz2rgbColor[i][0],xyz2rgbColor[i][1],xyz2rgbColor[i][2],val8[0],val8[1],val8[2])
    
#色をセット
xyz2rgbColor = xyz2rgbColor.tolist() #配列からリストへ変換
setColor(colPatchList,xyz2rgbColor)  #setColor関数でlambertのカラーを設定
    
#プレファレンスのレンダリング設定も連動して変更する場合
strRenderSpaceList = ["scene-linear CIE XYZ","scene-linear Rec 709/sRGB","ACEScg","ACES2065-1","Sharp RGB"]
index = arrKeyXYZ2RGB.index(XYZtoRGBname)
pm.colorManagementPrefs(e=True,rsn = strRenderSpaceList[index])

149行目の3個の変数のうち1つ目と3つ目を指定して実行(maya2016にnumpyを入れた環境で確認)
XYZtoRGBname,sorceWname,distWname = 'ACESap1',"E","D60"
#XYZtoRGBname:変換するレンダ空間 XYZ sRGB ACESap1 ACESap0 SharpRGB
#sorceWname:変換前のXYZホワイトバランス(今回のリファレンスカラーはEで作成しているのでE)
#distWname:変換先のな白色点(基本はレンダ空間のネイティブな白色点)でここから選ぶ : A B C D50 D55 D65 D75 E F2 F7 F11 D60
from numpy import *
   
#光源の色XnYnZnの配列 (3*1mat)
arrMatLightXYZ = [
matrix('1.09850;1.00000;0.35585'),   #0.A
matrix('0.99072;1.00000;0.85223'),   #1.B
matrix('0.98074;1.00000;1.18232'),   #2.C
matrix('0.96422;1.00000;0.82521'),   #3.D50
matrix('0.95682;1.00000;0.92149'),   #4.D55
matrix('0.95047;1.00000;1.08883'),   #5.D65
#matrix('0.950455927;1.00000;1.089057751'),#5.D65 mayaではこちらが使われていると思われる
matrix('0.94972;1.00000;1.22638'),   #6.D75
matrix('1.00000;1.00000;1.00000'),   #7.E
matrix('0.99186;1.00000;0.67393'),   #8.F2
matrix('0.95041;1.00000;1.08747'),   #9.F7
matrix('1.00962;1.00000;0.64350'),   #10.11
matrix('0.952646075;1.00000;1.008825184')] #11.D60
arrKeyLightXYZ = ["A","B","C","D50","D55","D65","D75","E","F2","F7","F11","D60"]
arrMatLightXYZ = dict(zip(arrKeyLightXYZ,arrMatLightXYZ))
    
#XYZtoRGBの配列  (3*3mat)
arrMatXYZ2RGB = [
matrix('1 0 0; 0 1 0; 0 0 1'), #ZYZ(E)
matrix('3.2404542 -1.5371385 -0.4985314;-0.969266 1.8760108 0.041556;0.0556434 -0.2040259 1.0572252'), #sRGB(D65)
matrix('1.64102338 -0.324803294 -0.236424695; -0.663662859 1.615331592 0.016756348; 0.011721894 -0.008284442 0.988394859'), #ACESap1(D60)
matrix('1.049811018 0 -9.74845E-05; -0.495903023 1.373313046 0.098240036; 0 0 0.991252018'), #ACESap0(D60)
matrix('1.2703 -0.0989 -0.1714; -0.836 1.8 0.0361; 0.0297 -0.0315 1.0017')] #SharpRGB(E)
arrKeyXYZ2RGB = ["XYZ","sRGB","ACESap1","ACESap0","SharpRGB"]
arrMatXYZ2RGB = dict(zip(arrKeyXYZ2RGB,arrMatXYZ2RGB))
    
#カラーチャートのディフューズの値XYZ(E) (3*1mat)
arrMatColorChecker = [
matrix('0.119341058; 9.99E-02; 5.59E-02'),       #no1
matrix('0.412222651; 0.363180818; 0.236403888'), #no2
matrix('0.182681943; 0.187540862; 0.317664563'), #no3
matrix('0.106503072; 0.128926832; 6.11E-02'),    #no4
matrix('0.269627348; 0.242756637; 0.417069611'), #no5
matrix('0.320807381; 0.417457527; 0.406387316'), #no6
matrix('0.400687638; 0.308497094; 0.054292495'), #no7
matrix('0.134942682; 0.114781053; 0.340796394'), #no8
matrix('0.315580939; 0.204426014; 0.126666899'), #no9
matrix('9.25E-02; 6.63E-02; 0.137877016'),       #no10
matrix('0.352064935; 0.435275631; 0.101625589'), #no11
matrix('0.502433902; 0.44538134; 7.71E-02'),     #no12
matrix('8.21E-02; 6.00E-02; 0.271971018'),       #no13
matrix('0.149383905; 0.230356768; 8.65E-02'),    #no14
matrix('0.229218256; 0.129139309; 4.78E-02'),    #no15
matrix('0.607374032; 0.607579034; 0.08706536'),  #no16
matrix('0.322739172; 0.202413208; 0.281472653'), #no17
matrix('0.143264706; 0.18994647; 0.357691497'),  #no18
matrix('0.885095979;0.887271216;0.873774268'),   #no19
matrix('0.584241934;0.583949023;0.581522196'),   #no20
matrix('0.358099806;0.358176938;0.358332475'),   #no21
matrix('0.203062932;0.203056127;0.20335156'),    #no22
matrix('9.22E-02;0.092532056;9.40E-02'),         #no23
matrix('3.35E-02;3.35E-02;3.51E-02')]           #no24
    
#bradford変換マトリクス(XYZtoLMS)
mBrad = matrix('0.8951 0.2664 -0.1614; -0.7502 1.7135 0.0367; 0.0389 -0.0685 1.0296')
#cat02
#mBrad = matrix('0.7328 0.4296 -0.1624; -0.7036 1.6975 0.0061; 0.003 0.0136 0.9834') #mayaではこちらが使われていると思われる
    
#カラーチェッカーの値XYZ(E)を意を任意のカラースペースに変換する関数(変換先の色空間、変換元の白色点、変換先の白色点を指定する)
def ColorChange(XYZtoRGBname,sorceWname,distWname):
    print '使用するXYZtoRGBMatrix :',XYZtoRGBname,'\n',arrMatXYZ2RGB[XYZtoRGBname],'\n'
    print '変換元白色点 :',sorceWname,"\n ",arrMatLightXYZ[sorceWname],'\n'
    print '変換先白色点 :',distWname,"\n ",arrMatLightXYZ[distWname],'\n'
    
    #LMSスケールを求める
    lmsS = mBrad * arrMatLightXYZ[sorceWname]
    lmsD = mBrad * arrMatLightXYZ[distWname]
    mScale = matrix(zeros((3, 3)))     #対角行列の入れ物
    fill_diagonal(mScale,(lmsD/lmsS))  #対角行列を作成
    print "LMSスケール: \n",mScale,'\n'
                        
    #白色点変換マトリクス
    mChangeW = mBrad.I* mScale * mBrad
    print "白色点変換マトリクス: \n",mChangeW,'\n'
        
    #レンダ空間変換マトリクス(from XYZ)
    mRenderSpace = arrMatXYZ2RGB[XYZtoRGBname] * mChangeW
    print "レンダ空間変換マトリクス: \n",mRenderSpace,'\n'
        
    #変換後のカラーを格納する配列
    distCol = empty((24,3),dtype = float64)
    for i,elem in enumerate(arrMatColorChecker):
        arrCol = mRenderSpace * elem
        distCol[i] = (arrCol.T)
            
    return distCol
    
# 色変換
#白色点はここから選ぶ : A B C D50 D55 D65 D75 E F2 F7 F11 D60
#XYZtoRGB変換はここから選ぶ : XYZ sRGB ACESap1 ACESap0 SharpRGB"
xyz2rgbColor = ColorChange (XYZtoRGBname="ACESap1",sorceWname="E",distWname="D60")
    
print 'レンダリング空間へ変換後のカラーチェッカーの値を表示'
print '{:-^3}|{:-^51}|{:-^17}'.format('no','XYZ to RGB value','Linear 8bit Value')
for i,colPatch in enumerate(xyz2rgbColor):
    if (i)%6 == 0:
        print "----"
    val8 = around(xyz2rgbColor[i] * array([255, 255, 255])).astype(int)
    print str(i+1).zfill(2),'|{:< 17}{:< 17}{:< 17}|{:>5}{:>5}{:>5}'.format(xyz2rgbColor[i][0],xyz2rgbColor[i][1],xyz2rgbColor[i][2],val8[0],val8[1],val8[2])


Mayaで使われているものと少し誤差があった (9/19追記)

Mayaで使われている色管理のデータはここにあるみたい
C:\Program Files\Autodesk\Maya2016\synColor

例えば
C:\Program Files\Autodesk\Maya2016\synColor\transforms\primaries
CIE-XYZ_to_ACES.ctf

これはXYZ(D65)からACESプライマリに変換するマトリクスが記述されている
[ 1.062366127968  0.008406953886 -0.016655789688]
[-0.493941366673  1.371109485626  0.090316586196]
[-0.000334668584 -0.001037458307  0.919469654560]

スクリプトで今回求めた変換マトリクスがMayaで使われているものと少しだけ誤差があった
xyz2rgbColor = ColorChange (XYZtoRGBname="ACESap0",sorceWname="D65",distWname="D60")
として実行すると下のようになり少し値が違った

[ 1.06344949  0.00638714 -0.01576369]
[-0.49208912  1.36824527  0.09135557]
[-0.00280919  0.00463247  0.91661469]

白色点変更はbradfordではなくてcat02みたい
bradfordではなくcat02を使った白色点変更にすると近づいた
さらにD65の値をx:0.3127 y:0.329から求めたXnYnZnにしたらもっと近づいた。

[  1.06236611e+00   8.40695406e-03  -1.66557898e-02]
[ -4.93941371e-01   1.37110952e+00   9.03165869e-02]
[ -3.34668584e-04  -1.03745828e-03   9.19469647e-01]

15/9/24追記
やはりcat02みたい
↓Mayaのインストール場所のファイルに書いてあった
C:\Program Files\Autodesk\Maya2016\synColor\transforms\whitepoint


カラーチェッカー作成のPyMel(修正)
白色変更をbradfordからcat02タイプに変更
import pymel.core as pm
from numpy import *
    
#光源色(白色点)のXnYnZnの配列 (3*1mat)
arrMatLightXYZ = [
matrix('1.09850;1.00000;0.35585'),   #0.A
matrix('0.99072;1.00000;0.85223'),   #1.B
matrix('0.98074;1.00000;1.18232'),   #2.C
matrix('0.96422;1.00000;0.82521'),   #3.D50
matrix('0.95682;1.00000;0.92149'),   #4.D55
#matrix('0.95047;1.00000;1.08883'),  #5.D65
matrix('0.950455927;1.00000;1.089057751'),#5.D65 mayaではこちらが使われていると思われる
matrix('0.94972;1.00000;1.22638'),   #6.D75
matrix('1.00000;1.00000;1.00000'),   #7.E
matrix('0.99186;1.00000;0.67393'),   #8.F2
matrix('0.95041;1.00000;1.08747'),   #9.F7
matrix('1.00962;1.00000;0.64350'),   #10.11
matrix('0.952646075;1.00000;1.008825184')] #11.D60
arrKeyLightXYZ = ["A","B","C","D50","D55","D65","D75","E","F2","F7","F11","D60"]
arrMatLightXYZ = dict(zip(arrKeyLightXYZ,arrMatLightXYZ))
    
#XYZtoRGBの配列  (3*3mat)
arrMatXYZ2RGB = [
matrix('1 0 0; 0 1 0; 0 0 1'), #ZYZ(E)
matrix('3.2404542 -1.5371385 -0.4985314;-0.969266 1.8760108 0.041556;0.0556434 -0.2040259 1.0572252'), #sRGB(D65)
matrix('1.64102338 -0.324803294 -0.236424695; -0.663662859 1.615331592 0.016756348; 0.011721894 -0.008284442 0.988394859'), #ACESap1(D60)
matrix('1.049811018 0 -9.74845E-05; -0.495903023 1.373313046 0.098240036; 0 0 0.991252018'), #ACESap0(D60)
matrix('1.2703 -0.0989 -0.1714; -0.836 1.8 0.0361; 0.0297 -0.0315 1.0017')] #SharpRGB(E)
arrKeyXYZ2RGB = ["XYZ","sRGB","ACESap1","ACESap0","SharpRGB"]
arrMatXYZ2RGB = dict(zip(arrKeyXYZ2RGB,arrMatXYZ2RGB))
    
#カラーチャートのディフューズの値XYZ(E) (3*1mat)
arrMatColorChecker = [
matrix('0.119341058; 9.99E-02; 5.59E-02'),       #no1
matrix('0.412222651; 0.363180818; 0.236403888'), #no2
matrix('0.182681943; 0.187540862; 0.317664563'), #no3
matrix('0.106503072; 0.128926832; 6.11E-02'),    #no4
matrix('0.269627348; 0.242756637; 0.417069611'), #no5
matrix('0.320807381; 0.417457527; 0.406387316'), #no6
matrix('0.400687638; 0.308497094; 0.054292495'), #no7
matrix('0.134942682; 0.114781053; 0.340796394'), #no8
matrix('0.315580939; 0.204426014; 0.126666899'), #no9
matrix('9.25E-02; 6.63E-02; 0.137877016'),       #no10
matrix('0.352064935; 0.435275631; 0.101625589'), #no11
matrix('0.502433902; 0.44538134; 7.71E-02'),     #no12
matrix('8.21E-02; 6.00E-02; 0.271971018'),       #no13
matrix('0.149383905; 0.230356768; 8.65E-02'),    #no14
matrix('0.229218256; 0.129139309; 4.78E-02'),    #no15
matrix('0.607374032; 0.607579034; 0.08706536'),  #no16
matrix('0.322739172; 0.202413208; 0.281472653'), #no17
matrix('0.143264706; 0.18994647; 0.357691497'),  #no18
matrix('0.885095979;0.887271216;0.873774268'),   #no19
matrix('0.584241934;0.583949023;0.581522196'),   #no20
matrix('0.358099806;0.358176938;0.358332475'),   #no21
matrix('0.203062932;0.203056127;0.20335156'),    #no22
matrix('9.22E-02;0.092532056;9.40E-02'),         #no23
matrix('3.35E-02;3.35E-02;3.51E-02'),            #no24
matrix('0.037;0.037;0.037')]                     #mount 台紙の色(適当)
    
#bradford変換マトリクス(XYZtoLMS)
#mBrad = matrix('0.8951 0.2664 -0.1614; -0.7502 1.7135 0.0367; 0.0389 -0.0685 1.0296')
#cat02
mBrad = matrix('0.7328 0.4296 -0.1624; -0.7036 1.6975 0.0061; 0.003 0.0136 0.9834') #mayaではこちらが使われていると思われる
 
#カラーチェッカーのsahpeを削除
def deleteColorCheckerMesh():
    oShapeList = pm.ls(type = 'shape')    #sahpeの一覧取得
    #sahpe親のtransformノードにアトリビュート'colorCheckerRoot'があったらそれ以下の使用マテリアルとノード削除
    for oShape in oShapeList:
        oParent = oShape.getParent()
        if oParent is not None:
            if oParent.hasAttr("colorCheckerRoot"):
                colPatchList = oParent.getChildren()
                for colPatch in colPatchList:
                    if len(colPatch.shadingGroups()) > 0:
                        sg = colPatch.shadingGroups()[0]
                        oShader = sg.surfaceShader.connections()[0]
                        pm.delete(oShader,sg)
                pm.delete(oParent)
                    
#カラーチェッカーのsahpeを作成しsahpeを返す
def createColorCheckerMesh():
    #黒の下地のshape作成
    baseTranse,baseShape = pm.polyPlane(name ='pPlane_base', height = 20.3, width = 28.8, sh = 1, sw = 1)
    baseTranse.addAttr('colorCheckerRoot', dt='string')
    shader , shadingEngine = pm.createSurfaceShader('lambert')
    shader.diffuse.set(1.0)
    pm.sets(shadingEngine,forceElement=baseTranse)
    shader.color.set(0.0,0.0,0.0)
        
    #24個のパッチ作成と新規マテリアル割り当て
    colPatchList = []
    for i in range(1, 25):
        patchTranse, patcShape= pm.polyPlane(name = 'pPlane_No' + str(i), height = 4, width = 4, sh = 1, sw = 1)
        patchTranse.translate.set(((i-1)%6)*4.5 - 11.25 ,0.1,floor((i-1)/6)*4.5 - 6.75)
        shader , shadingEngine = pm.createSurfaceShader('lambert')
        shader.diffuse.set(1.0)
        pm.sets(shadingEngine,forceElement=patchTranse)
        colPatchList.append(patchTranse)
    
    #下地の子供に24個のパッチ
    for colPatch in colPatchList:
        baseTranse.addChild(colPatch)
        
    colPatchList.append(baseTranse)   #台紙も配列の最後に加える
    return colPatchList
    
#マテリアルの色を設定する
def setColor(colPatchList,xyz2rgbColor):
    for i,colPatch in enumerate(colPatchList):
        sg = colPatch.shadingGroups()[0]
        oShader = sg.surfaceShader.connections()[0]
        oShader.color.set(xyz2rgbColor[i])
    
#カラーチェッカーの値XYZ(E)を意を任意のカラースペースに変換する関数(変換先の色空間、変換元の白色点、変換先の白色点を指定する)
def ColorChange(XYZtoRGBname,sorceWname,distWname):
    print '使用するXYZtoRGBMatrix :',XYZtoRGBname,'\n',arrMatXYZ2RGB[XYZtoRGBname],'\n'
    print '変換元白色点 :',sorceWname,"\n ",arrMatLightXYZ[sorceWname],'\n'
    print '変換先白色点 :',distWname,"\n ",arrMatLightXYZ[distWname],'\n'
    
    #LMSスケールを求める
    lmsS = mBrad * arrMatLightXYZ[sorceWname]
    lmsD = mBrad * arrMatLightXYZ[distWname]
    mScale = matrix(zeros((3, 3)))     #対角行列の入れ物
    fill_diagonal(mScale,(lmsD/lmsS))  #対角行列を作成
    print "LMSスケール: \n",mScale,'\n'
                        
    #白色点変換マトリクス
    mChangeW = mBrad.I* mScale * mBrad
    print "白色点変換マトリクス: \n",mChangeW,'\n'
        
    #レンダ空間変換マトリクス(from XYZ)
    mRenderSpace = arrMatXYZ2RGB[XYZtoRGBname] * mChangeW
    print "レンダ空間変換マトリクス: \n",mRenderSpace,'\n'
        
    #変換後のカラーを格納する配列
    distCol = empty((25,3),dtype = float64)
    for i,elem in enumerate(arrMatColorChecker):
        arrCol = mRenderSpace * elem
        distCol[i] = (arrCol.T)
            
    return distCol
    
#shape削除
deleteColorCheckerMesh()
    
#shape作成
colPatchList = createColorCheckerMesh()
    
# 色変換
#白色点はここから選ぶ : A B C D50 D55 D65 D75 E F2 F7 F11 D60
#XYZtoRGB変換はここから選ぶ : XYZ sRGB ACESap1 ACESap0 SharpRGB"
XYZtoRGBname,sorceWname,distWname = 'ACESap0',"E","D60"
xyz2rgbColor = ColorChange (XYZtoRGBname,sorceWname,distWname)  #カラースペースに変換する関数を実行
    
#変換値のログ表示
print 'レンダリング空間へ変換後のカラーチェッカーの値を表示'
print '{:^3}|{:-^51}|{:^17}'.format('no','XYZ to RGB value','Linear 8bit Value')
for i,colPatch in enumerate(xyz2rgbColor):
    if i<=23:
        if (i)%6 == 0:
            print "----"
        val8 = around(xyz2rgbColor[i] * array([255, 255, 255])).astype(int)
        print str(i+1).zfill(2),'|{:< 17}{:< 17}{:< 17}|{:>5}{:>5}{:>5}'.format(xyz2rgbColor[i][0],xyz2rgbColor[i][1],xyz2rgbColor[i][2],val8[0],val8[1],val8[2])
    
#色をセット
xyz2rgbColor = xyz2rgbColor.tolist() #配列からリストへ変換
setColor(colPatchList,xyz2rgbColor)  #setColor関数でlambertのカラーを設定
    
#プレファレンスのレンダリング設定も連動して変更する場合
strRenderSpaceList = ["scene-linear CIE XYZ","scene-linear Rec 709/sRGB","ACEScg","ACES2065-1","Sharp RGB"]
index = arrKeyXYZ2RGB.index(XYZtoRGBname)
pm.colorManagementPrefs(e=True,rsn = strRenderSpaceList[index])


0 件のコメント:

コメントを投稿