2017年7月11日火曜日

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

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


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


一番スタンダードな方法。
グレーへ変換
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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」強度の種類を指定出来る。
グレー化時「Intensity」を選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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」を使用して手動でグレー変換してみる。
1
2
//「FX」を使う
myMagick.Fx("0.2*r+0.7*g+0.1*b");
処理に時間が掛かります。
「Photoshop」に近い結果は得られない。


「ColorMatrix」で手動グレー変換


「ColorMatrix」は彩度の変更、色相の回転、アルファの輝度、様々なエフェクトが可能。
基本は以下の様な記述になります。
画像の変更無し
1
2
3
4
5
6
7
8
9
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となる。
1
2
3
4
5
6
7
8
9
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画像にオフセットを付けてコントラストを追加
1
2
3
4
5
6
7
8
9
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になるように調整すれば、
グレー出力となります。
1
2
3
4
5
6
7
8
9
10
11
12
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」の処理結果と同じ物を作るには以下のような記述となります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//「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へ