画像の色の分布を『xy色度図』にプロットしてみる(あと、CMYKプロファイルの事も少し)
MacOSX付属の『Grapher』を使った画像の色の分布図の作成その2。
今回は、カラーマネジメント関係の書籍等には必ず出てくる、馬蹄形の『xy色度図』上の座標に、画像の色の分布をプロットしてみます。
前のエントリではPhotoshopで画像を開き、JavaScriptを使ってサンプリングしたピクセルの『L*a*b*値』をファイルに書き出して、そのファイルをGrapherに読み込ませて表示させましたが、今回はピクセルの色を『xyY』の値で書き出すので、『L*a*b*』から『xyY』の値に変換する部分をJavaScriptに新たに書き加えました。
今回は色度を表す『xy』の二次元のグラフなので、明度を示す『Y』の値は使いません。
『L*a*b*』から『xyY』ヘの変換式は、
『Color Conversion Algorithms 』(http://www.cs.rit.edu/~ncs/color/t_convert.html)や、
『Color Conversion Library in ANSI C』 (http://www.tecgraf.puc-rio.br/~mgattass/color/ColorIndex.html)
あたりをを参考にしています。
PhotoshopのAdobeRGB環境で下のグラデーデョン画像を開き、JavaScriptを実行して書き出されたファイルをGrapherで読み込んで、色度図にプロットしてみます。
赤と緑の三角形の部分はそれぞれ『AdobeRGB』と『sRGB』の色域を表していますが、それらは色度図上の値をあらかじめ調べておいてグラフに数値を入力しました。また、グレーの馬蹄形の部分、360nm~830nmの各波長の単色光の色度を示す『スペクトル軌跡』も別途計算して求めた数値を読み込ませてプロットしてあります。
上のグラデーション画像を『JapanColor2001corted』のプロファイル、レンダリングインテントが『知覚的』の設定でCMYKに変換した場合の色の分布を見てみると、色域が以下の様に圧縮されているのが解ります。
次に、下の画像は始めからCMYKモードで作成した、CMYK各色100%と、その二次色のレッド、グリーン、ブルーをグラデーションにしたもので、
これを『JapanColor2001corted』で開いた状態でプロットしてみると、非常になめらかな色の分布を持つグラフがプロットされました。
同じ画像を、『某印刷所の本機(枚葉)の印刷物を測色して作成したプロファイル』を適用した状態でプロットすると、
ややいびつな輪郭でプロットされました。グリーン(上の頂点の部分)の色域がやや狭く、イエロー方向に転んでいるのが見て取れます。
ただ、これはいびつなプロファイルが悪いと言うのではなく、あくまで『プロファイル』として実際の印刷物の状態を表したものなので、特に、JapanColorをターゲットとした『印刷の標準化』が行われていない印刷会社では、おそらく色が合わない等の問題も出てくる筈なので、必ずしも『JapanColor2001corted』の方が良い結果になるとは言い切れないと思います。
今回プロットした画像を見て思ったんですが、『JapanColor2001corted』の不自然なほど整ったプロファイルは、『理想的なJapanColor』をターゲットにして最適化の処理がされた、『架空のプロファイル』に近いものの様な気がします。
カラーマネジメントの書籍等では『CMYKのカラー設定はJapanColor2001corted推奨』というのが殆どで、もちろん出鱈目なプロファイルで運用する事に比べればベストに近い選択という事で異論は無いんですが、画像をCMYK分解する時点ではトーンジャンプも無くキレイに分解されていても、後の工程でRIPにデバイスリンクプロファイルを噛ましたり、刷版や印刷で色を調整する必要が出るとすれば、『画像が劣化する要因が他の工程に移っただけ』とも考えられるので、その辺りもツッ込んで解説してあればなぁとか思った次第です。(画像の段階で劣化しないのが望ましいとは思いますが)
画像を『xyY』の数値で書き出すのに使ったJavaScriptは以下の通り。
■動作確認
MacOSX 10.5.7
Photoshop CS4
今回は、カラーマネジメント関係の書籍等には必ず出てくる、馬蹄形の『xy色度図』上の座標に、画像の色の分布をプロットしてみます。
前のエントリではPhotoshopで画像を開き、JavaScriptを使ってサンプリングしたピクセルの『L*a*b*値』をファイルに書き出して、そのファイルをGrapherに読み込ませて表示させましたが、今回はピクセルの色を『xyY』の値で書き出すので、『L*a*b*』から『xyY』の値に変換する部分をJavaScriptに新たに書き加えました。
今回は色度を表す『xy』の二次元のグラフなので、明度を示す『Y』の値は使いません。
『L*a*b*』から『xyY』ヘの変換式は、
『Color Conversion Algorithms 』(http://www.cs.rit.edu/~ncs/color/t_convert.html)や、
『Color Conversion Library in ANSI C』 (http://www.tecgraf.puc-rio.br/~mgattass/color/ColorIndex.html)
あたりをを参考にしています。
PhotoshopのAdobeRGB環境で下のグラデーデョン画像を開き、JavaScriptを実行して書き出されたファイルをGrapherで読み込んで、色度図にプロットしてみます。
赤と緑の三角形の部分はそれぞれ『AdobeRGB』と『sRGB』の色域を表していますが、それらは色度図上の値をあらかじめ調べておいてグラフに数値を入力しました。また、グレーの馬蹄形の部分、360nm~830nmの各波長の単色光の色度を示す『スペクトル軌跡』も別途計算して求めた数値を読み込ませてプロットしてあります。
上のグラデーション画像を『JapanColor2001corted』のプロファイル、レンダリングインテントが『知覚的』の設定でCMYKに変換した場合の色の分布を見てみると、色域が以下の様に圧縮されているのが解ります。
次に、下の画像は始めからCMYKモードで作成した、CMYK各色100%と、その二次色のレッド、グリーン、ブルーをグラデーションにしたもので、
これを『JapanColor2001corted』で開いた状態でプロットしてみると、非常になめらかな色の分布を持つグラフがプロットされました。
同じ画像を、『某印刷所の本機(枚葉)の印刷物を測色して作成したプロファイル』を適用した状態でプロットすると、
ややいびつな輪郭でプロットされました。グリーン(上の頂点の部分)の色域がやや狭く、イエロー方向に転んでいるのが見て取れます。
ただ、これはいびつなプロファイルが悪いと言うのではなく、あくまで『プロファイル』として実際の印刷物の状態を表したものなので、特に、JapanColorをターゲットとした『印刷の標準化』が行われていない印刷会社では、おそらく色が合わない等の問題も出てくる筈なので、必ずしも『JapanColor2001corted』の方が良い結果になるとは言い切れないと思います。
今回プロットした画像を見て思ったんですが、『JapanColor2001corted』の不自然なほど整ったプロファイルは、『理想的なJapanColor』をターゲットにして最適化の処理がされた、『架空のプロファイル』に近いものの様な気がします。
カラーマネジメントの書籍等では『CMYKのカラー設定はJapanColor2001corted推奨』というのが殆どで、もちろん出鱈目なプロファイルで運用する事に比べればベストに近い選択という事で異論は無いんですが、画像をCMYK分解する時点ではトーンジャンプも無くキレイに分解されていても、後の工程でRIPにデバイスリンクプロファイルを噛ましたり、刷版や印刷で色を調整する必要が出るとすれば、『画像が劣化する要因が他の工程に移っただけ』とも考えられるので、その辺りもツッ込んで解説してあればなぁとか思った次第です。(画像の段階で劣化しないのが望ましいとは思いますが)
画像を『xyY』の数値で書き出すのに使ったJavaScriptは以下の通り。
■動作確認
MacOSX 10.5.7
Photoshop CS4
#target Photoshop var samplingPixelsAsYxy = { 'tristimulus_values': { /* 2 degrees */ 'ccTA_2': [109.850, 100.000, 35.585], 'ccTC_2': [98.074, 100.000, 118.232], 'D50_2': [96.422, 100.000, 82.521], 'D55_2': [95.682, 100.000, 92.149], 'D65_2': [95.047, 100.000, 108.883], 'D75_2': [94.972, 100.000, 122.638], 'F2_2': [99.187, 100.000, 67.395], 'F7_2': [95.044, 100.000, 108.755], 'F11_2': [100.966, 100.000, 64.370], /* 10 degrees */ 'A_10': [111.144, 100.000, 35.200], 'C_10': [97.285, 100.000, 116.145], 'D50_10': [96.720, 100.000, 81.427], 'D55_10': [95.799, 100.000, 90.926], 'D65_10': [94.811, 100.000, 107.304], 'D75_10': [94.416, 100.000, 120.641], 'F2_10': [103.280, 100.000, 69.026], 'F7_10': [95.792, 100.000, 107.687], 'F11_10': [103.866, 100.000, 65.627], /* PCS illuminant of AdobeRGB & sRGB profiles */ 'PCS_illuminant': [96.420, 100.000, 82.491], /* reference white in xyY coordinates */ 'chromaD65': [0.3127, 0.3290, 100.0] }, 'convertCIELabToXYZ': function(L, a, b) { var ref = this.tristimulus_values['PCS_illuminant']; //tristimulus of reference white var X, Y, Z; /* via http://www.cs.rit.edu/~ncs/color/API_JAVA/XYZSet.java var frac = (L + 16) / 116; if ( L < 7.9996 ) { Y = L / 903.3; X = a / 3893.5 + Y; Z = Y - b / 1557.4; } else { var tmp = frac + a / 500; X = tmp * tmp * tmp * ref[0]; Y = frac * frac * frac * ref[1]; tmp = frac - b / 200; Z = tmp * tmp * tmp * ref[2]; } */ /* via http://www.tecgraf.puc-rio.br/~mgattass/color/CIELabtoXYZ.htm */ var var_Y = ( L + 16 ) / 116; var var_X = a / 500 + var_Y; var var_Z = var_Y - b / 200; var_Y = Math.pow(var_Y, 3) > 0.008856 ? Math.pow(var_Y, 3) : ( var_Y - 16 / 116 ) / 7.787; var_X = Math.pow(var_X, 3) > 0.008856 ? Math.pow(var_X, 3) : ( var_X - 16 / 116 ) / 7.787; var_Z = Math.pow(var_Z, 3) > 0.008856 ? Math.pow(var_Z, 3) : ( var_Z - 16 / 116 ) / 7.787; X = var_X * ref[0]; Y = var_Y * ref[1]; Z = var_Z * ref[2]; // return [X, Y, Z]; }, 'main': function() { var t = new Date(); var outputFile = '~/Desktop/xy_colors_64x64.txt'; var sampling_size = 64; //var threshold = 10; var sampling_data = ''; var ru = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; var doc = app.activeDocument; doc.flatten(); doc.resizeImage(sampling_size, sampling_size, 72, ResampleMethod.BICUBIC); //doc.resizeImage(sampling_size*2, sampling_size*2, 72, ResampleMethod.NEARESTNEIGHBOR); var smpl = doc.colorSamplers.add([0, 0]); var col = new SolidColor(); var Yxy_x, Yxy_y; var XYZ = []; var X, Y, Z; for (var i=0; i<sampling_size; i++) { for (var j=0; j<sampling_size; j++) { smpl.move([j+0.5, i+0.5]); col = smpl.color; XYZ = this.convertCIELabToXYZ(col.lab.l, col.lab.a, col.lab.b); X = XYZ[0]; Y = XYZ[1]; Z = XYZ[2]; Yxy_x = X / ( X + Y + Z ); Yxy_y = Y / ( X + Y + Z ); if (Y > 1) { sampling_data += Yxy_x + '\t' + Yxy_y + '\r'; } } } var f = new File(outputFile); if (f.open("w")) { f.encoding = 'BINARY'; f.write(sampling_data); f.close(); } app.preferences.rulerUnits = ru; var now = new Date(); alert('Finished! time: ' + (now - t)); } } if (app.documents.length > 0) { samplingPixelsAsYxy.main(); }
- 関連記事
-
- 3DCGソフト『Blender』のDTPer的な利用法
- Flashで画像の色の分布を3Dグラフにプロットしてみる
- 画像の色の分布を『xy色度図』にプロットしてみる(あと、CMYKプロファイルの事も少し)
- 画像の色の分布を3Dグラフにプロットしてみる
- AppleScriptのシンタックスをハイライトするJavaScriptを少し改良
スポンサーサイト
コメント
管理人のみ閲覧できます
このコメントは管理人のみ閲覧できます
Re: 色度図
色度図のご質問の件にお答えします。
『線が3本で結ばれず2本にとどまってしまう』部分ですが、これは『AdobeRGB』や『sRGB』の三角形の事を指しておられるのでしょうか?その場合は、数値を入力されたポイントの編集画面で、最初のポイントの座標を最後に打ち込んでやれば閉じた三角形になります。(もし、そう言う事ではない様でしたら、申し訳ありませんがご質問からは意図を読み取れていないと思います)
あと、スペクトル軌跡を表す馬蹄形部分ですが、これは
http://cvision.ucsd.edu/database/data/cmfs/
で、360mmから830nmの波長のスペクトルの『XYZ』値を書き出したカンマ区切りテキスト(.csv)が公開されています。
ファイル名が『ciexyz31』で始まっているものはCIE1931の2°視野XYZ表色系、『ciexyz64』が10°視野XYZ表色系のものだと思います。また、『_1』と付いているものは1nm刻み、それ以外は5nm刻みの数値です。
これをxy色度図にプロットする為には、『XYZ』→『Yxy』の形に変換してやる必要があります。この内、『YxyのY』は明度を示す値なので、2次元のxy色度図では使いません。
『XYZ』→『Yxy』の変換は
Yxy_x = X / ( X + Y + Z ); // XYZ から Yxyのx座標を求める
Yxy_y = Y / ( X + Y + Z ); // XYZ から Yxyのy座標を求める
みたいな感じで求まります。
上の変換を行ったテキストを
https://dl.dropbox.com/u/271700/spectrum.txt
に置いておきます。これをGrapherに読み込むと、きれいな馬蹄形が現れると思います。
『線が3本で結ばれず2本にとどまってしまう』部分ですが、これは『AdobeRGB』や『sRGB』の三角形の事を指しておられるのでしょうか?その場合は、数値を入力されたポイントの編集画面で、最初のポイントの座標を最後に打ち込んでやれば閉じた三角形になります。(もし、そう言う事ではない様でしたら、申し訳ありませんがご質問からは意図を読み取れていないと思います)
あと、スペクトル軌跡を表す馬蹄形部分ですが、これは
http://cvision.ucsd.edu/database/data/cmfs/
で、360mmから830nmの波長のスペクトルの『XYZ』値を書き出したカンマ区切りテキスト(.csv)が公開されています。
ファイル名が『ciexyz31』で始まっているものはCIE1931の2°視野XYZ表色系、『ciexyz64』が10°視野XYZ表色系のものだと思います。また、『_1』と付いているものは1nm刻み、それ以外は5nm刻みの数値です。
これをxy色度図にプロットする為には、『XYZ』→『Yxy』の形に変換してやる必要があります。この内、『YxyのY』は明度を示す値なので、2次元のxy色度図では使いません。
『XYZ』→『Yxy』の変換は
Yxy_x = X / ( X + Y + Z ); // XYZ から Yxyのx座標を求める
Yxy_y = Y / ( X + Y + Z ); // XYZ から Yxyのy座標を求める
みたいな感じで求まります。
上の変換を行ったテキストを
https://dl.dropbox.com/u/271700/spectrum.txt
に置いておきます。これをGrapherに読み込むと、きれいな馬蹄形が現れると思います。
管理人のみ閲覧できます
このコメントは管理人のみ閲覧できます