2015年8月23日日曜日

RGB to RGB

別の色空間へのRGBに変換する場合のメモ。
2015/9/24修正(Mayaの白色点変更がcat02みたいなのでMayaと合わせた)

例えばACES色空間のRGB値をsRGB空間の値に変換したい等の場合、変換先の色空間への変換行列を求めれば直接変換できる。

異なる色空間へのRGB変換方法

変換元と変換先それぞれのXYZtoRGBマトリクスと白色点Xn,Yn,Znの計4個のパラメータから求めることができる。白色点変更はcat02を使用。(白色点変更に関しては最近はbradfordよりもcat02が使われるケースが多いのかも)

下記はsRGBからACES2065-1に変換する場合。


下記は左から[ACES→ACEScg] 、 [ACES→XYZ(D65)]、 [adobeRGB→sRGB]

 

pythonのコード 15/10/02追記

from numpy import *

#白色点のXnYnZnの配列 (3*1mat)
arrMatLightXYZ = [
matrix('1.0;1.0;1.0'),                       #E   from(x,y = 1/3,1/3)
matrix('1.09849061235,1,0.355798257455'),    #A   from(x,y = 0.44758,0.40745)
matrix('0.98070597166;1;1.18224949393'),     #C   from(x,y = 0.31006,0.31616)
matrix('0.96429567643;1;0.82510460251'),     #D50 from(x,y = 0.3457,0.3585)
matrix('0.95264607457;1.0;1.00882518435'),   #D60 from(x,y = 0.32168,0.33767)
matrix('0.950455927052;1.0;1.08905775076'),  #D65 from(x,y = 0.3127,0.3290)
matrix('0.894586894587;1.0;0.954415954416')] #dci from(x,y = 0.3140,0.3510)
arrKeyLightXYZ = ["E","A","C","D50","D60","D65","dci"]
arrMatLightXYZ = dict(zip(arrKeyLightXYZ,arrMatLightXYZ))

#XYZtoRGBの配列  (3*3mat)
arrMatXYZ2RGB = [
matrix('1 0 0; 0 1 0; 0 0 1'), #ZYZ(E)
matrix('3.2409699419 -1.5373831776 -0.4986107603; -0.9692436363 1.8759675015 0.0415550574;0.0556300797 -0.2039769589 1.0569715142'), #sRGB(D65)
matrix('2.7253940305 -1.0180030062 -0.4401631952; -0.7951680258 1.6897320548 0.0226471906;0.0412418914 -0.0876390192 1.1009293786'), #DCI-P3
matrix('1.716651188 -0.3556707838 -0.2533662814; -0.6666843518 1.6164812366 0.0157685458;0.0176398574 -0.0427706133 0.9421031212'), #Rec.2020
matrix('1.6410233797 -0.3248032942 -0.236424695; -0.6636628587 1.6153315917 0.0167563477; 0.0117218943 -0.0082844420 0.9883948585'), #ACESap1(D60)
matrix('1.0498110175 0 -0.0000974845; -0.4959030231 1.3733130458 0.0982400361; 0 0 0.9912520182'),                                   #ACESap0(D60)
matrix('1.2694188828 -0.0988302413 -0.1705886415; -0.8363858117 1.8007170555 0.0356687562; 0.0297300599 -0.0314712627 1.0017412028')] #SharpRGB(E)
arrKeyXYZ2RGB = ["XYZ","sRGB","P3","2020","ACESap1","ACESap0","SharpRGB"]
arrMatXYZ2RGB = dict(zip(arrKeyXYZ2RGB,arrMatXYZ2RGB))

#白色点変更メソッドはcat02
mAdaptation = matrix('0.7328 0.4296 -0.1624; -0.7036 1.6975 0.0061; 0.003 0.0136 0.9834')

#変換先の色空間へ変換するマトリクスを求める関数(変換元の色空間名,変換先の色空間名,変換元の白色点,変換先の白色点 を指定する)
def getMatrixRGBtoRGB(sourceXYZtoRGBname,destXYZtoRGBname,sourceWname,destWname):
    print '変換元:',sourceXYZtoRGBname,'  変換先:',destXYZtoRGBname,'  変換元白色点:',sourceWname,'  変換先白色点:',destWname,'\n'
    
    #---LMSスケールを求める---
    lmsS = mAdaptation * arrMatLightXYZ[sourceWname]
    lmsD = mAdaptation * arrMatLightXYZ[destWname]
    mScale = matrix(zeros((3, 3)))     #対角行列を入れる準備
    fill_diagonal(mScale,(lmsD/lmsS))  #対角行列を作成
    
    #---白色点変換マトリクス---
    mChangeW = mAdaptation.I* mScale * mAdaptation
    
    #---レンダ空間変換マトリクス(from XYZ)---
    mRGBtoRGB = arrMatXYZ2RGB[destXYZtoRGBname] * mChangeW * arrMatXYZ2RGB[sourceXYZtoRGBname].I
    
    set_printoptions(suppress=True,precision=10) #少数10桁表示
    print "sourceRGB to destRGB matrix: \n",mRGBtoRGB,'\n'
    return mRGBtoRGB

#**** 変換前色空間と変換先色空間、さらに変換前白色と変換先白色の4個の名前を指定する   ****
#**** 色空間 XYZ sRGB P3 2020 ACESap1 ACESap0 SharpRGB| 白色点 E A C D50 D60 D65 dci (白色点変更しない場合は双方同じものを入れておけば何でもよい)****
mRGBtoRGB = getMatrixRGBtoRGB('sRGB','ACESap0',"D65","D60")

'''変換元: sRGB   変換先: ACESap0   変換元白色点: D65   変換先白色点: D60 

sourceRGB to destRGB matrix: 
[[ 0.4395756842  0.3839125894  0.1765117265]
 [ 0.0896003829  0.8147141542  0.0956854629]
 [ 0.0174154827  0.1087343522  0.8738501651]] '''

色空間の原色であるRGBWのxyからrgb/xyz変換を求める場合はこれ > rgb/xyz 変換行列

0 件のコメント:

コメントを投稿