はじめに
一般に画像変換を行うと、元の画像にないノイズのようなものが大なり小なり乗り、その変化を Artifact(アーティファクト、アーチファクト) と呼びます。
リサイズ処理では Blur、Blocking、 Ringing、Aliasing、Halo といった形で Artifact が現れ、これらは、どれかを抑えると別のものが目立つトレードオフの関係にあります。
そこで画像に応じて Artifact を目立たなくする為の調整が必要で、補間フィルタや前処理/後処理等、綺麗な画像を作るのにコツがあります。
あまり知られていませんが、ImageMagick は以下のページにその tips をまとめています。
このエントリはほぼ、Nicolas Robidoux 特設ページの紹介です。
だいぶ意訳して省略もしているので、正確な詳細を知りたければ上記のページを直接読んで下さい。
あと、リサイズ補完フィルタを知っている前提で記事を書いています。知らない場合は以下のエントリを参考にどうぞ。
- ImageMagick リサイズ補間アルゴリズム
簡易コマンド例
なるべく簡潔なオプションで実行したい場合の例です。
-resize
バランスの良い以下のコマンドが使えます。-filter Mitchell は省略可です。
magick {input} -filter Mitchell -resize 200% {output}
Mitchell は BiCubic の一種で、主観テストによりバランスの良いパラメータを探った結果のフィルタです。
- 転載元) http://www.imagemagick.org/Usage/filter/#mitchell
- 論文) https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf
ぼやけてしまう場合、Lanczos に変更する事で画像をよりシャープに出来ます。ただしハロー効果(Halo effect)が出やすくなります。
magick {input} -filter Lanczos -resize 200% {output}
これらは HDRI 版 ImageMagick では問題ないですが、Q8, Q16 版だと各々、0〜255, 0〜65535 に clamp されて、画質が微妙に劣化します。また、sinc フィルタの限界もあります。
それでも処理がそこそこ速いので、多くのサービスでのリサイズで -resize が使われています。
-distort Resize
-resize より処理が重たいですが、画質を求めるならば -distort Resize がお勧めです。
-resize の sinc が -distort Resize では jinc 相当に置き換わり、EWA(Elliptical Weighted Average) として動作します。いわゆる Cylindrical Filter です。
要するに縦横と同等に斜めも綺麗にリサイズします。
-distort Resize はデフォルトで -filter Robidoux が適用されます。
magick {input} -distort Resize 200% {output}
これでだいたいバランスの良い結果になります。
ボケる場合、以下のコマンドでよりシャープな画像にする手もあります。
magick {input} -filter LanczosRadius -distort Resize 200% {output}
シャープにすると副作用でハロー効果(halo effect)を生じます。これを抑えるのに良いのが、 EWA Quadratic-windowed Jinc 3-lobe です。
magick {input} -define filter:window=Quadratic -distort Resize 200% {output}
また、Quadratic B-spline でもハローを消せます。ただし画像がぼやけがちです。
magick {input} -filter Quadratic -distort Resize 200% {output}
このように、さまざまな Artifacts (今回は主にブラーとハローのせめぎ合い)のトレードオフに応じてオプションを使い分けると良い結果を得られます。
推奨コマンド
ノウハウを詰め込んだ推奨コマンドです。オプションがそこそこ複雑です。
拡大
magick {input} -colorspace RGB +sigmoidal-contrast 7.5 \
-filter Lanczos -define filter:blur=.9891028367558475 \
-distort Resize 500% \
-sigmoidal-contrast 7.5 -colorspace sRGB {output}
まず、素の RGB は sRGB 規格に従いガンマ補正されているので、それを元に計算すると値が歪みます。傾向として暗くなります。それで、 -colorspace RGB でリニアRGB に変換して、リサイズ処理した後、-colorspace sRGB で元に戻します。
- Resizing with Colorspace Correction
sRGB のままリサイズ | gamma:1 にしてリサイズ |
---|---|
あと、リサイズをすると画像がボケがちなので、見た目の印象を変えない為には、Lanczos かつ filter:blur に 1未満の値を渡す事で画像をシャープ化します。
更に、シャープ化するとハロが出やすいので、シグモイド変換でハローを抑えます。
縮小
magick {input} -colorspace RGB \
-filter Lanczos -define filter:blur=.9891028367558475 \
-distort Resize 20% -colorspace sRGB {output}
縮小はハロー対策のシグモイド変換を外した事以外は、同じです。