ImageMagick のグレースケール変換

ImageMagick で RGB 画像をグレースケール変換する方法について公式マニュアルを元に、少しばかり追加して解説します。

グレースケールそのものについては、以下のエントリをご参照下さい。

-  グレースケール画像のうんちく
   - https://qiita.com/yoya/items/96c36b069e74398796f3

# 公式マニュアルの方法

- http://www.imagemagick.org/Usage/color_mods/#grayscale

公式マニュアルで紹介されている、-colorspace, -grayscale, -modulate, -fx, -compose, -evaluate, -evaluate-sequence, -color-mat(旧 -recolor ) について、一通り並べます。

## サンプル画像

公式マニュアルのサンプル画像をそのまま使います。

| test.png |
|---|
| ![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/1bf547c4-352b-6bf1-0aca-b82a0ce602f6.png) |

## -colorspace Gray

公式のお勧め (The best method) は  -colorspace Gray です。(gray でも同じ。大文字小文字を区別せず)
色空間をグレースケールに変更する命令です。

- https://www.imagemagick.org/Usage/color_basics/#colorspace

```shell:
%  magick test.png -colorspace Gray gray_colorspace.png
```

|test.png | gray_colorspace.png |
|---|---|
|![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/1bf547c4-352b-6bf1-0aca-b82a0ce602f6.png) | ![gray_colorspace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/c7f7beaf-93de-5390-dd6a-60f2ba3a7a5f.png) | 

## -grayscale

RGB を1つの輝度値にまとめる方法は色々とあって、-grayscale オプションはそれを指示します。
-list Intensity で一覧が出せます。

```shell:
% magick -list Intensity
Average
Brightness
Lightness
Mean
MS
Rec601Luma
Rec601Luminance
Rec709Luma
Rec709Luminance
RMS
```

なお、冒頭で紹介した -colorspace Gray は -grayscale Rec709Luma 相当です。

```shell:
% magick test.png  -grayscale rec709luma gray_grayscale.png
```

|gray_grayscale.png|
|---|
|![gray_grayscale.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/7a2fd207-1d81-df93-4d94-02e27a12ed03.png)|

全ての Intensity で処理して montage で並べてみます。

```shell:
% for i in `magick -list intensity` ;  \
    do magick ../test.png -grayscale $i  $i.png ; \
    done
 % magick montage  -background lightgray \
        -label %f *.png gray-intensity.png
```

| gray-intensity.png |
|---|
| ![gray-intensity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/c05cff76-2eb1-4ed9-d671-1ab7e9caf3c4.png) |


## -modulate

-modulate は HSL 色空間の明るさ、彩度、色相に手を加えるオプションです。

- https://www.imagemagick.org/Usage/color_mods/#modulate

2番目のパラメータが彩度で、0 にするとグレースケール化します。

```shell:
% magick test.png -modulate 100,0 gray_modulate.png
```
|gray_modulate.png|
|---|
| ![gray_modulate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/ae0caed6-9f61-ba0e-a51c-915422f04a2c.png) |

-define modulate:colorspace を使うと HSL 以外でも modulete 操作が可能です。

```shell:
% for cs in HCL HCLp HSB HSI HSL HSV ;  \
    do magick ../test.png -define modulate:colorspace=$cs  \
            -modulate 100,0  $cs.png ; done
 % magick montage  -background lightgray \
        -label %f *.png gray-colorspace.png
```

| gray-colorspace.png |
|---|
| ![gray-colorspace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/72dcc242-8013-5e38-381c-bc812c54ca93.png) |

## -fx

任意の計算ができる -fx は、既存の機能で満足できるものがない時に便利です。

```shell:
% magick test.png -fx '(r+g+b)/3' gray_fx_average.png
% magick gray_fx_average.png -alpha off alpha-off.png
```

透明度データも作られる為、分かりやすいよう alpha off した画像もつけます。

|gray_fx_average.png| alpha-off |
|---|---|
| ![gray_fx_average.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/cea9a091-ef14-bfd4-f694-0fe024034f53.png) | ![alpha-off.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/0acc7d60-58bf-d374-ade0-846492570e0a.png) |


intensity (色の強さ)のキーワードを直接指定できます。

```shell:
% magick test.png  -fx intensity  gray_intensity.png
% magick gray_intensity.png -alpha off alpha-off.png

```
|gray_intensity.png|alpha-off.png|
|---|---|
| ![gray_intensity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/e1a88965-edc3-0e98-9d95-a6084c9bf979.png) | ![alpha-off.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/d333da88-075a-8f79-8d78-cb4aa00404ea.png) |

## -separate & -compose

R,G,B チャネルを３つのグレースケールとして分解したあと、それらを合成します。

```shell:
% magick test.png -separate \
          -background black -compose plus -flatten   gray_added.png
```

この例だと plus で合成するので、真っ白になります。


### -evaluate multiply 

-evaluate を使って各チャネルに乗算するする方法です。

```shell:
% magick test.png -channel R -evaluate multiply .2 \
                   -channel G -evaluate multiply .5 \
                   -channel B -evaluate multiply .3 \
                   +channel -separate -compose add -flatten gray_253.png
```

|gray_253.png|
|---|
| ![gray_253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/2000813d-9969-9872-e1ee-182bad449c76.png) |

6系ではこれで良かったのですが、7系では alpha が合成でまざってしまい画像が崩れます。
これは実装の不具合ではなく、6 は RGB と A を区別してたのを 7 でやめたので、その一貫した挙動の一つだと思われます。
とはいえマニュアル的にまずいので公式の issue で指摘しておきました。

- Grayscale by FX DIY Evaluate Operator no longer works as documented with ImageMagick 7. #5389
   - https://github.com/ImageMagick/ImageMagick/issues/5389

ImageMagick 7 では、以下の方法が提案されました。(マニュアルも書き変わってます)

```shell:
% magick test.png -channel R -evaluate multiply .2 +channel \
                   -channel G -evaluate multiply .5 +channel \
                   -channel B -evaluate multiply .3 +channel \
                   -channel RGB -separate -compose add -flatten gray_253.png
```


+channel は念の為です。処理が終わったら戻すお行儀の良さ。
アルファデータが全部 0xff に変化しますが、元からそうです。(マニュアルの注意書きに追加されました)

### -evaluate-sequence mean

```shell:
% magick test.png -separate -evaluate-sequence mean  gray_average.png
```

| gray_average.png |
|---|
| ![gray_average.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/4d6d2016-8d70-413c-9601-1e7f3feea78b.png) |

こっちはうまく変換できます。

## -color-matrix (旧 -recolor)

公式マニュアルは古い記述のままで -recolor は今は -color-matrix に改名されてます。

```shell:
% magick test.png -recolor '.2 .5 .3
                            .2 .5 .3
                            .2 .5 .3'   gray_recolor.png
magick: option has been replaced '-recolor', use "-color-matrix" at CLI arg 2 @ warning/operation.c/CLISimpleOperatorImage/3187.
magick: unrecognized option `-recolor' at CLI arg 2 @ error/operation.c/CLISimpleOperatorImage/3285.
````
エラーが出ました。
気を取り直して、-color-matrix で実行。

```shell:
% magick test.png -color-matrix '.2 .5 .3
                                 .2 .5 .3
                                 .2 .5 .3'   gray_colmat.png
```
|gray_colmat.png|
|---|
| ![gray_colmat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/8391e0cc-59f4-42ff-24a9-00cee8e24b4f.png) |

# マニュアル以外の方法

## -type

type はファイルを入力する時、または出力する時に画像をどう扱うかを指定するフラグです。

- https://www.imagemagick.org/Usage/basics/#type

この -type でグレースケール形式を指定する事により、グレースケールでない画像をグレースケール化して最終出力します。

### -type Grayscale

```shell:
 magick test.png  -type GrayScaleAlpha  gray_type.png
```
| gray_type.png |
|---|
|![gray_type.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/3a4829a9-ff29-3f1c-e427-4796c80457b7.png) |

### -type GrayScaleAlpha

透明度を残したい場合は、こちらをどうぞ。

```shell:
 magick test.png  -type GrayScaleAlpha  gray_typealpha.png
```

|gray_typealpha.png|
|---|
| ![gray_typealpha.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/c56d03da-5564-0df8-897c-a7ae47c48965.png) |

## -colorspace

冒頭で -colorspace gray を紹介しました。その gray 以外での方法です。
ちなみに、-modulate 100, 0 とやってる事はほぼ同じです。
ただし、こっちは ImageMagick が対応する任意の色空間を使えます。-modulate の対応空間はそのうち半分程度なので。

### -colorspace OHTA

```shell:
% magick test.png -colorspace OHTA -channel Red -separate +channel gray_OHTA.png
```

|gray_OHTA.png|
|---|
| ![gray_OHTA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/abd8253d-d4a1-271e-9652-8a75a5bbecdc.png) |

### -colorspace HSI

```shell:
% magick test.png -colorspace HSI -channel Blue -separate +channel gray_HSI.png
```

| gray_HSI.png | 
|---|
| ![gray_HSI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/56c24bac-d7da-e67d-924a-241a101e1284.png) |

## -channel G

RGB のうち RB に比べて G の輝度が圧倒的に高いので、G だけ取り出してグレースケールとしても、そこそこ良い結果になります。

```shell:
% magick test.png -separate -delete 0,2,3  gray_G.png
```

|gray_G.png |
|---|
| ![gray_G.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/70991470-ccea-76ac-c788-cf9ff49a706e.png) |

あと、特殊用途でうが、輝度の極端に小さい B だけ残すと、見えなかったノイズが強調できる事もあるので、これはこれで有用です。モニタテスト等で。

```shell:
% magick test.png -separate -delete 0,1,3  gray_B.png
```

|gray_B.png |
|---|
| ![gray_B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/58d46202-1e29-d819-adf6-59092a2ace78.png) |

## -hald-clut

CLUT (Color LookUp Table) と -hald-clut オプションを使って変換する方法があります。
なお、擬似カラーを作るのに便利な -clut オプションの方は R,G,B を各々独立して変換する方式なので、グレースケール化には使えません。

```shell:
% magick HALD:8 -colorspace Gray hald8gray.png
% magick test.png hald8gray.png -hald-clut gray_hald-clut.png
```

慣れてないと分かりにくいのですが。-hald-clut の後でなく前に CLUT画像ファイルを置きます。

| hald8gray.png | gray_hald-clut.png |
|---|---|
|![hald8gray.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/f2a181aa-bc43-60e0-71fc-956e27353503.png) | ![gray_hald-clut.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/efca45d6-07da-a077-c291-fadc60bb76fa.png)|

これの利点は、単純なグレースケール変換であれば、任意の処理に対応する CLUT を指定するだけで、その処理を再現できる事です。

例えば、以下のサイトのように、処理系毎の CLUT ファイルを用意すれば、

```shell:
% wget https://raw.githubusercontent.com/SzieberthAdam/cvd-palette/master/haldclut/gray/gray.skimage.png
% magick test.png gray.skimage.png -hald-clut gray_ski.png
```

| gray_ski.png |
|---|
|![gray_ski.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/4bcbf57d-8849-1cd4-b120-7c1d9cc8e514.png)|


このようにして、SKImage のグレースケールを再現する事ができます。(なお、これらの CLUT ファイルが正しいかの検証はしてません。ご利用は自己責任で)

# 参考

- http://www.imagemagick.org/Usage/color_mods/#grayscale
- https://stackoverflow.com/questions/13317753/convert-rgb-to-grayscale-in-imagemagick-command-line