2017年7月11日火曜日

C# Magick.NETを使ってみる。グレースケール変換

C# Magick.NETを使ってみる
目次→http://1studying.blogspot.jp/2017/07/c-magicknetmokuzi.html#kuw08


カラースペースでグレー変換


一番スタンダードな方法。
            using (var myMagick = new ImageMagick.MagickImage("./色チャート/色600_RGB.psd"))
            {
                //「マッチング方法」→「Perceptual」知覚的(Photoshopデフォルト)
                myMagick.RenderingIntent = ImageMagick.RenderingIntent.Perceptual;
                //「黒点の補正を使用」
                myMagick.BlackPointCompensation = true;

                //「ICCプロファイル」が埋め込まれていなければ
                if (myMagick.GetColorProfile() == null)
                {
                    myMagick.AddProfile(ImageMagick.ColorProfile.SRGB);
                    //MessageBox.Show("埋め込みました");
                }
                //プロファイルの削除
                myMagick.RemoveProfile("icc");

                //カラースペースをグレーに変更
                myMagick.ColorSpace = ImageMagick.ColorSpace.Gray;

                ////「背景」にする(アルファを白くします)
                //myMagick.ColorAlpha(ImageMagick.MagickColors.White);

                myMagick.Write("./test_outfile.tif");
            }
            MessageBox.Show("処理終了。");
一応グレー変換前に「ICCプロファイル」を消去しましたが、
グレー変換時、「ICCプロファイル」の影響は受けないっぽい。
消去していなくても、グレー変換時に「ICCプロファイル」は自動で消去される。
(「Rec709Luma」でグレー化したのと同じ結果になります。)
「Photoshop」に近い結果は得られない。




「Intensity」強度を指定してグレー変換


グレーへ変換時、「Intensity」強度の種類を指定出来る。
            using (var myMagick = new ImageMagick.MagickImage("./色チャート/色600_RGB.psd"))
            {
                //「マッチング方法」→「Perceptual」知覚的(Photoshopデフォルト)
                myMagick.RenderingIntent = ImageMagick.RenderingIntent.Perceptual;
                //「黒点の補正を使用」
                myMagick.BlackPointCompensation = true;

                //「ICCプロファイル」が埋め込まれていなければ
                if (myMagick.GetColorProfile() == null)
                {
                    myMagick.AddProfile(ImageMagick.ColorProfile.SRGB);
                    //MessageBox.Show("埋め込みました");
                }
                //プロファイルの削除
                myMagick.RemoveProfile("icc");

                //グレー化する時の「Intensity」強度の種類を選択できる
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Average);
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Brightness);
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Lightness);
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.MS);
                //「Rec601Luma」(R=0.298839 + G=0.586811 + B=0.114350)
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Rec601Luma);
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Rec601Luminance);
                //「Rec709Luma」(R=0.212656 + G=0.715158 + B=0.072186)
                myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Rec709Luma);
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Rec709Luminance);
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.RMS);

                ////「背景」にする(アルファを白くします)
                //myMagick.ColorAlpha(ImageMagick.MagickColors.White);

                myMagick.Write("./test_out_Rec709Luma.tif");
            }
            MessageBox.Show("処理終了。");
様々な強度の種類があるけど、「Photoshop」に近い結果が無かった。



「FX」で手動グレー変換


「FX」を使用して手動でグレー変換してみる。
                //「FX」を使う
                myMagick.Fx("0.2*r+0.7*g+0.1*b");
処理に時間が掛かります。
「Photoshop」に近い結果は得られない。


「ColorMatrix」で手動グレー変換


「ColorMatrix」は彩度の変更、色相の回転、アルファの輝度、様々なエフェクトが可能。
基本は以下の様な記述になります。
                var matrixElement = new double[]{
                    1.0, 0.0, 0.0, 0.0, 0.0, 0.0, //レッド or シアン
                    0.0, 1.0, 0.0, 0.0, 0.0, 0.0, //グリーン or マゼンタ
                    0.0, 0.0, 1.0, 0.0, 0.0, 0.0, //ブルー or イエロー
                    0.0, 0.0, 0.0, 1.0, 0.0, 0.0, //無し or ブラック
                    0.0, 0.0, 0.0, 0.0, 1.0, 0.0, //アルファ
                    0.0, 0.0, 0.0, 0.0, 0.0, 1.0
                    };
                myMagick.ColorMatrix(new ImageMagick.MagickColorMatrix(6, matrixElement));
この変換用パラメータの場合画像に対して何の変更も行いません。


変換用パラメータの行列
RGBA画像は5行×5列(6行×6列でも問題なし)
RGBA画像にオフセット(+やー数値の追加)を付けたい場合6行×6列
(CMYKのサポートの為、オフセット量は6列目に記述します。
 255で割った数値を記述します。-1.0〜+1.0)
CMYKA画像は6行×6列(6列目がオフセット量)
のパラメータ行列を使用します。
カラー行列(変換用パラメータ)は必ず行と列が同じ数となります。


パラメータ行列の意味
・列は入力値を示します。
 1列目〜5列目に「1.0」を100%とした各色の入力数値を設定します。
 (255の場合、1.0は255が入力、0.5の場合128が入力値となる)
 左から「R、G、B、AかC、M、Y、K、A」の順で列に入力値を割り振ります。
 上から何行目に数値を設定するかで出力色が決まります。

・6列目はオフセット用の列です。
 6列目のみ特殊な列となります。
 行内の各列各色の入力数値を合計した、合計出力値に対するオフセット値となります。
 合計出力値に対して-1.0(常に濃度0%)〜+1.0(常に濃度100%)を割り振れます。

・行は各色の出力値を示します。
1行目左から「RGBAかCMYKA」の入力合計値が「RかC」へ出力(0.0〜1.0)
2行目左から「RGBAかCMYKA」の入力合計値が「GかM」へ出力(0.0〜1.0)
3行目左から「RGBAかCMYKA」の入力合計値が「BかY」へ出力(0.0〜1.0)
4行目左から「RGBAかCMYKA」の入力合計値が「AかK」へ出力(0.0〜1.0)
5行目左から「RGBAかCMYKA」の入力合計値が「  A」へ出力(0.0〜1.0)
6行目左から「RGBAかCMYKA」の入力合計値が「ダミー?」へ出力(0.0〜1.0)


レシピ1
RGBのGを全てRの色に割り振りGは常に0となる。
                var matrixElement = new double[]{
                    1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                    0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 0.0, 1.0
                    };
                myMagick.ColorMatrix(new ImageMagick.MagickColorMatrix(6, matrixElement));

レシピ2
RGB画像にオフセットを付けてコントラストを追加
                var matrixElement = new double[]{
                    1.5, 0.0, 0.0, 0.0, 0.0,-0.157,
                    0.0, 1.5, 0.0, 0.0, 0.0,-0.157,
                    0.0, 0.0, 1.5, 0.0, 0.0,-0.157,
                    0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 0.0, 1.0
                    };
                myMagick.ColorMatrix(new ImageMagick.MagickColorMatrix(6, matrixElement));

RGBをグレー変換するには
行のR+G+Bの合計出力値が丁度1.0になるように調整すれば、
グレー出力となります。
                double red = 0.3;
                double grn = 0.6;
                double blu = 0.1;
                var matrixElement = new double[]{
                    red, grn, blu, 0.0, 0.0, 0.0,
                    red, grn, blu, 0.0, 0.0, 0.0,
                    red, grn, blu, 0.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 0.0, 1.0
                    };
                myMagick.ColorMatrix(new ImageMagick.MagickColorMatrix(6, matrixElement));

グレー化時、「Intensity」強度の種類に合わせるには
「Rec601Luma」(R=0.298839 + G=0.586811 + B=0.114350)
「Rec601Luminance」(R=0.298839 + G=0.586811 + B=0.114350)
「Rec709Luma」(R=0.212656 + G=0.715158 + B=0.072186)
「Rec709Luminance」(R=0.212656 + G=0.715158 + B=0.072186)
(「Rec601Luminance」と「Rec709Luminance」は
「Gamma1.0」なので同じにならない)
「Rec709Luma」の処理結果と同じ物を作るには以下のような記述となります。
                //「Rec709Luma」と同じ処理結果になります。
                //myMagick.Grayscale(ImageMagick.PixelIntensityMethod.Rec709Luma);
                double red = 0.212656;
                double grn = 0.715158;
                double blu = 0.072186;
                var matrixElement = new double[]{
                    red, grn, blu, 0.0, 0.0, 0.0,
                    red, grn, blu, 0.0, 0.0, 0.0,
                    red, grn, blu, 0.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
                    0.0, 0.0, 0.0, 0.0, 0.0, 0.0
                    };
                myMagick.ColorMatrix(new ImageMagick.MagickColorMatrix(6, matrixElement));



「Photoshop」のカラーモード変換をエミュレート






自分用めも:
「C# Magick.NETで「Photoshop」のカラーモード変換をエミュレート」非公開
http://00studying.blogspot.jp/2017/07/c-magicknetcolorpshopemu.html




以下のサイトを参考にしました。
ImageMagick v6の例 - 色の変更
http://www.imagemagick.org/Usage/color_mods/

【.NET】カラー行列(ColorMatrix)で画像のRGBの値を調整する
http://www.r-nakai.com/archives/30
【.NET】カラー行列(ColorMatrix)で画像をグレースケール化する
http://www.r-nakai.com/archives/41

C# ColorMatrixクラスを使用する方法
http://dobon.net/vb/dotnet/graphics/colorbalance.html

0 件のコメント:

コメントを投稿

↑Topへ