ImageMagick の例 --
カラー量子化とディザリング

インデックス
ImageMagick の例:序文とインデックス
色の削減入門 (何が含まれるか)
画像内の色 (画像が使用している色)
カラー量子化 (画像内の色数を減らす)
誤差拡散ディザリング (または擬似ランダムディザリング)
閾値ディザリング手法
組織的なパターンディザリング (タイル状の閾値マップを使用)
DIYディザリングパターンと閾値マップ (独自のディザリング方法)
色数を減らしたり、特定の色を置き換えたりすることは、画像処理において非常に複雑で難しいステップであり、この例のページで取り上げられるトピックです。これには、使用する色の決定(カラー量子化)と、それらの色を画像上に配置する方法(ディザリングとパターニング)が含まれます。また、ビットマップまたは2色画像の生成、さらにはブール値(オン/オフ)の透明度の処理も含まれます。これは非常に重要であるため、色の削減または量子化は、ImageMagickが元の主要なタスクである、GIF、XPixmap、XBitmap形式などの色数の少ない形式に画像を変換できるように、しばしば自動的にバックグラウンドで実行されます。これがどのように機能するかを知ることで、プロセスをより詳細に制御し、特定の画像ファイル形式に保存された結果の画像を改善することができます。

色の削減入門

色の削減は、ImageMagickの非常に重要な側面です。たとえば、数百万色を含むJPEGまたはPNG画像を、最大256色を含むGIF画像に変換するには、効率的かつ効果的な方法で色を削減できる必要があります。画像形式の変換中に、これはしばしば自動的にバックグラウンドで実行されますが、これを手動で行いたい場合もあります。画像の色数を減らすのは、一般的に3つのステップのプロセスです。
  1. まず、通常、画像が使用する色を調査する必要があります。実際に使用されている色の数を確認するだけでなく、特定の色がどれくらいの頻度で使用されているかを確認する必要があります。特定のピクセルがその色を1つしか使用していない場合は、特定の色を保持しても意味がありませんが、それでも必要な場合もあります。
  2. 次に、画像を制限する最終的な色のセットを何らかの方法で決定する必要があります。IMに特定の画像に対して「最適」な色のセットを決定させたい場合があります。また、任意の画像で使用できる、より一般的でグローバルなものを必要とする場合もあります。使用する色のセットに色を明確に追加または削除したい場合もあります。
  3. そして最後に、選択した色のみを使用するように画像を修正する必要があります。できれば、結果が見栄えがよくなるようにするか、圧縮、比較、または最適化がうまくいくようにします。
さらに複雑なことに、これらの手順はしばしば相互に関連しています。色の置き換えの1つの方法は、特定の色のセットを使用してのみ適用できることがよくあります。また、特定の色のセットを使用している場合、何らかの種類の色の調査は必要ありません。または、特定の色に対して例外を作成する必要がある場合があります。基本的に、色の削減は多くの場合、バックグラウンドで自動的に処理されますが、何が起こっているのか、またその影響がどうなるのかを少なくとも認識しておくことをお勧めします。

色の調査

これはおそらく最も重要性が低く、IMは調査を実行する方法を提供していますが、色の削減を目的としてユーザーによって実行されることはめったにありません。詳細については、関連セクション「画像の色抽出」で説明します。

色の選択(量子化)

最初の概要については、「Wikipedia、カラー量子化」を参照してください。色の選択には、4つの基本的な方法があります。これらの4つのカラー制御方法:量子化定義済みカラーマップ均一な色閾値には、すべて制限があることがわかります。以下に、これら4つの各方法の例を示します...

  magick colorwheel.png +dither    -colors 32          color_quantize.gif
  magick colorwheel.png +dither -remap colortable.gif  color_predefined.gif
  magick colorwheel.png +dither   -posterize 3         color_uniform.gif
  magick colorwheel.png \
                  -separate -threshold 50% -combine     color_threshold.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]
各最終画像の色の数は、代表的なセットにすぎませんが、ほぼ32色です(ただし、閾値は8色のみです)。これから、それぞれから何が期待できるかのアイデアを得ることができます。他のすべてのメソッドには、カラーを削減する画像に関係なく、固定された色のセットがあります(演算子の引数に応じて)。最初のメソッド(「-colors」)のみが、現在の画像の内容に基づいて色を実際に選択します。テスト画像は主に白であるため、多くの明るい色が選択されます。オクトツリーを使用した「適応空間分割」として知られる手法を使用して、画像内の色を調査します。次に、指定された制限内で、特定の画像に最も適した特定の色セットを選択しようとします。下記の「カラー量子化演算子」を参照してください。「-remap」では、IMに独自の定義済み色のセットを指定できます(「ユーザー定義カラーマップ」を参照)。上記の「colortable.gif」で使用されているカラーマップは、昔のX Windowアイコンライブラリで使用するために特別に選択された32色のセットであり、漫画のようなアイコンを念頭に置いて設計されています。(詳細については、「AIconライブラリ、Xアイコンの色選択」を参照してください)。「-posterize」を使用すると、各カラーチャネルを色のレベルまたは強度のセットに数学的に分割して、「均一なカラーマップ」を作成することもできます。つまり、各チャネルが一定の色の値または強度に設定されたカラーマップです。そして最後に、「-threshold」は、画像のすべての色チャネルまたは特定の色チャネルを実質的にブール値またはオン/オフにすることができます。つまり、各カラーチャネルには、ゼロまたはMaxRGB(IMの「Q」レベルに依存)の値を与えることができます。ただし、これにより、約8色の最小限のセットのみが生成されます。非常に限られた色のセットです。閾値は、2色を選択する「-posterize」レベル「1」と同等でもあります。

色のセットの適用

色のセットができたら、次の問題は、選択した色のセットで既存の色が置き換えられるように、色を画像に適用することです。これは「ディザリング」と呼ばれ、その「これを選択するか、それともそれを選択するか?」という二者択一的な性質からそのように名付けられました。基本的に、ディザリングの考え方は、異なる色のピクセルを互いに近接して配置することにより、画像内で実際に使用されているよりも多くの色を目に錯覚させることです。つまり、画像のその領域の色は、人間の目が隣接する色を「マージ」する方法のために、画像の元の色により近いものになります。ディザリングの最適な入門の1つはWikipediaにありますが、最初に「オーディオディザリング」セクションをスキップする必要があります。これは、限られた色のセットがある場合にピクセルのディザリングパターンを使用することの利点の優れた例を示しています。基本的な色の置換スタイルは次のとおりです...
  • 直接カラーマッピング(閾値、ポスタリゼーション)
  • ランダムディザリング(ピクセルの純粋なランダム配置)
  • 誤差拡散ディザリング(ピクセルの擬似ランダム化パターン)
  • 拡散ピクセルディザリングの組織化(ピクセルの規則的なパターン)
  • デジタルハーフトーニング(さまざまなサイズのドット)
ダイレクトマッピングとは、指定されたセット内で最も近い色が、上記で示された色である場合を指します。基本的には、変化のない単色の領域が明確に区切られます。これを、空の実際の写真のように、色がゆっくりと変化する画像に適用すると、特に空の領域のように、滑らかなグラデーションになるはずの場所に色の帯が現れます。その結果は、一般的にあまり良くないと考えられています。ダイレクトカラーマッピングが許容されると通常考えられるのは、ロゴ、シンボル、アイコン、漫画のような画像の場合だけです。実際には、めったに選択肢になりません。そのため、画像内で色を直接マッピングしたくない場合は、通常、通常のディザリング方法をオフにする必要があります。ただし、ディザリングには独自の問題があります。画像がディザリングされると、色のパターンが画像の一部になります。そのようなパターンが存在すると、それを削除することは非常に困難です。また、ディザリングを複数回画像に再適用することは、画像を劣化させるだけなので、一般的に悪い考えです。このため、以下の量子化の例では、通常、各手法でディザリングされていないバージョンを作成する方法を示します。ディザリングがその情報を隠す前に、どのような色の選択が行われているかを確認できるようにするためです。ランダムディザリングは、作成された最も単純なディザリング方法です。また、最悪のディザリング方法とも考えられています。ただし、いくつかの特別な用途があります。IM内では2色でのみ機能するため、通常は特別なケースのビットマップディザリングに制限されます。詳細については、下記のしきい値を使用したランダムディザを参照してください。誤差拡散ディザリングは、画像内の領域の元の色に最も近い近似を生成するため、画像全体で色をディザリングする最良の一般的な方法であると一般的に考えられています。また、現在、任意の色のセットをディザリングできる唯一の方法であるため、4つの色削減手法すべてに使用できます。詳細については、下記のE-ディザリングの仕組みを参照してください。ただし、誤差拡散ディザリングには、特に画像の動画に関して、いくつかの重大な問題があります。最後の2つのディザリング手法である順序付き拡散ピクセルデジタルハーフトーニングも優れた手法と考えられており、アニメーションに適していますが、現在、固定された均一な色のセットのみを使用でき、任意の色のセットは使用できません。パターンを使用して画像を彩色する手段を提供し、そうでなければ簡単に生成できない興味深い効果を生み出すことができます。
色削減のこれらすべての側面は重要な技術であり、理解することで、IMが提供する一般的なデフォルトを超えて、画像操作の結果を改善できます。勉強する価値は十分にあります。

画像内の色

使用されている色の数や全体的な広がりなど、画像に関する情報は、使用する最適な手法について決定を下そうとするプログラムやスクリプトにとって非常に重要になる可能性があります。ここでは、色削減だけでなく、このタイプの情報を判断するために使用できるいくつかの方法について説明します。

画像の色抽出

カラーテーブルの抽出

画像からカラーパレットを抽出するには、冗長な「identify」を使用し、基本的にすべて同じことを行うこれらの方法のいずれかを使用します。

  magick identify -verbose  image.png
  magick image.png miff:- | identify -verbose -
  magick image.png  -verbose -identify null:
  magick image.png  -verbose info:
上記の冗長な識別からの出力は、色が1024色を超える場合はカラーテーブルまたはヒストグラムを返しません。そのため、色彩豊かな大きな画像の場合、これは当たり外れがあり、推奨されませんが、それでも役立つ可能性があります。
ただし、より良い方法は、画像の「histogram:」を生成し、結果に含まれるコメントを抽出することです。

  magick tree.gif  -format %c  -depth 8  histogram:info:-
[IM Output]
[IM Text]
info:」出力形式は、IM v6.2.4で追加されました。これより前のIMバージョンを使用する場合は..

  magick tree.gif histogram:- | identify -depth 8 -format %c -
これらの方法の問題点は、色のプレーンテキスト出力が与えられ、それを独自のニーズに合わせて解析する必要があることです。ただし、IM v6.2.8-8以降、「-unique-colors」演算子は、元の画像で見つかった一意の色ごとに1つのピクセルだけを含む、より小さな画像に画像を魔法のように変換します。つまり、画像を、存在する各色をリストした、より単純なカラーテーブル画像に魔法のように変換できます。画像の幅は色の数を返し、実際に色をリストする必要がある場合は、「txt:」画像形式に出力できます。たとえば、これはツリー画像のカラーテーブルです。

  magick tree.gif -unique-colors -scale 1000%  tree_colors.gif
  magick tree.gif -unique-colors -depth 16  txt:-
[IM Output]
[IM Text]
この削減されたカラーテーブルは、生成された色のカラーマップを非常に小さなファイルに保存する方法としても非常に重要です。このようなマップは、「-remap」色削減演算子にとって特に重要です(下記の事前定義済みカラーマップを参照)。画像内の色だけでなく、色の数を取得したい場合は、IMフォーラムディスカッションから開発された、以下のような色ヒストグラムのソリューションがあります。

  magick rose: -colors 256 -format %c histogram:info:- |
    sed 's/:.*#/ #/' |
      while read count color colorname; do
        magick -size 1x$count xc:$color miff:-
      done |
        magick - -alpha set -gravity south -background none +append \
                unique_color_histogram.png
[IM Output] ==> [IM Output]
内蔵の「rose:」画像には3020個の一意の色が含まれており、時間がかかり、非常に長い画像を生成するため、画像を色を削減する必要があったことに注意してください。上記に示されているバラのGIF画像には、同じ色削減のセットが含まれています。結果の画像は、透明なピクセルで埋められていますが、同じ数のピクセルが含まれており、緑がかった灰色、濃い赤、純粋な白の非常に強いピークが優勢であることがわかります。これは、一般的なカラーヒストグラムの最良の方法ではないかもしれませんが、この画像には適しています。
histogram:」と「-unique-colors」演算子の両方で、色の順序は未定義ですが、赤、次に緑、最後に青のチャネル値でソートされているようです。これは特定の画像に最適な方法ではない可能性がありますが、3次元の色を1次元の順序に一般的にソートすることは不可能です。

平均色の抽出

画像の平均色は、「-scale」を使用して画像を単一のピクセルに縮小することで非常に迅速に見つけることができます。たとえば、内蔵の「rose:」画像の平均色は次のとおりです。FXエスケープ形式を使用して色を出力します。これにより、変更せずにIMで直接使用できる色文字列が返されます。

  magick rose: -scale 1x1\! -format '%[pixel:s]' info:-
[IM Text]
%[pixel:...]FXエスケープを使用する場合の問題点は、RGB値ではなく、「white」や「silver」などの色名が返される可能性があることです。ただし、3つのFXエスケープを使用して、目的のビット深度で実際の色RGB値を返すことで、これをシミュレートできます。例えば...

  magick rose: -scale 1x1\! \
     -format '%[fx:int(255*r+.5)],%[fx:int(255*g+.5)],%[fx:int(255*b+.5)]' info:-
[IM Text]
IM v6.3.9以降、「-format」エスケープが多数追加され、冗長な「identify」や「info:」出力を解析する必要なく、画像に関するより具体的な情報を抽出するのに役立ちます。たとえば、画像の赤チャネル画像から「%[mean]」グレースケール値を取得することで、平均赤チャネル色を取得できます。

  magick rose: -channel R -separate -format '%[mean]' info:
[IM Text]

特定の色を抽出する

コマンドラインから、画像から特定のピクセルの色を抽出する基本的な方法が2つあります。特定のピクセル位置で「%[pixel:...]」や「%[fx:...]」などのFXエスケープを使用するか(上記を参照)...

  magick rose: -format '%[pixel:p{40,30}]' info:-
[IM Text]
または、「-crop」を使用して、目的の単一ピクセルを切り取ることで画像を簡略化し、以前の方法のいずれかを使用できます。例えば...

  magick rose: -crop 1x1+40+30 -depth 8 txt:-
[IM Text]

特定の色(またはその近くの色)のカウント

これは、特定の色に対するピクセル数またはパーセンテージを取得するために使用できます。行うことは、その色以外のものを黒にし、その色を白にします。たとえば、「ツリー」画像の「yellow」太陽の色数を取得してみましょう。

  magick tree.gif -fill black +opaque yellow \
                   -fill white -opaque yellow \
                   -print "yellow sun pixels = %[fx:w*h*mean]\n"   null:
[IM Text]
1つ注意点があります。テスト対象の色自体が黒の場合、これは機能しません。黒(または非常に暗い色)を処理するには、塗りつぶしを入れ替えて黒以外の色を白にマッピングし、反転してすべての黒ピクセルの白いマスクを生成します。「-print」オプションは「-format ... -write info:」を使用するのと同じであり、画像処理内のどこでも使用できることに注意してください。次に、特別な「null:」ファイル形式を使用して、不要な画像を破棄しました。画像を保存して、後で使用するためのマスクとして使用することもできます。これは小さな画像では問題なく機能しますが、非常に大きな画像(高解像度のデジタル写真など)では、「平均」が正確なピクセル数を取得するのに十分ではないことに注意してください。基本的には、上記の「平均」の使用は比率を生成するのに適していますが、正確なピクセル数には適していません。正確なピクセル数を取得するには、正確なピクセル数が記載されたヒストグラムの「コメント」出力を使用する方が適しています(上記を参照)。上記では、ファジーファクターオプション「-fuzz」を「-opaque」演算子の前に使用して、「近い」色も指定できます。

2色の比較

特定の2つの色があり、それらを比較したいとします。「magick compare」を使用してRMSE(標準誤差)を取得できます...

  magick compare -metric RMSE xc:Navy xc:blue null:
[IM Text]
これは、値の観点からも、黒から白までの距離の正規化されたパーセンテージとしても、2つの色の間の距離を取得できるため、優れています。ただし、この方法は透明度を適切に処理しません。たとえば、「完全に透明な黒」と「完全に透明な白」を比較します。

  magick compare -metric RMSE xc:'#0000' xc:'#FFF0' null:
[IM Text]
透明な色は、完全に透明であることは基礎となる色に関係なく同じであるため、実際には距離がゼロである必要があります。代わりに、4次元の超立方体の距離が得られました)。したがって、上記の色距離の方法は、完全に不透明な色のみを比較する場合にのみ適しています。
実際の距離を取得するのではなく、ファジーファクターを使用して、2つの色が近いかどうかを確認することもできます。

  magick compare -fuzz 20% -metric AE xc:Navy xc:Blue null:
  magick compare -fuzz 30% -metric AE xc:Navy xc:Blue null:
[IM Text]
ただし、ピクセルが一致しない場合(エラーピクセルの数)、結果は「1」になることに注意してください。値を分離する実際の「ファジー」ファクター距離を取得するには、「FUZZ」メトリックを使用できます。

  magick compare -metric FUZZ xc:Navy xc:Blue null:
[IM Text]
「正規化」された値は、実際の距離が28.7%であることを示しています。ファジーファクターを使用することは、透明度が関係する場合にRMSEを計算する場合とは異なります。つまり、ファジーファクターは、完全に透明な2つの色が等しいものとして扱われるように設計されているためです。したがって、「完全に透明な黒」と「完全に透明な白」はまったく同等です(0またはエラーピクセルなしの値が生成されます)...

  magick compare -metric FUZZ xc:'#0000' xc:'#FFF0' null:
[IM Text]
色を比較する別の方法は、適切なファジーファクターパーセンテージで色を置き換えることです。例えば...

  magick xc:Navy  -fuzz 20% -fill Blue -opaque Blue txt:
[IM Text]
Navy」が「Blue」に変化しなかったため、「Blue」とは20%以上の差があります。一方、

  magick xc:Navy  -fuzz 30% -fill Blue -opaque Blue txt:
[IM Text]
こちらは色が「Blue」に変化したので、「Navy」と「Blue」の距離が20%から30%の間にあることがわかりました。これをスクリプトで行うには、以下のように記述します...

  fuzz=%1
  color1="red"
  color2="#e00"

  color2=`magick xc:"$color2" -format '%[pixel:s]' info:`
  result=`magick xc:"$color1" -alpha set -channel RGBA -fuzz $fuzz \
            -fill $color2 -opaque $color2 -format '%[pixel:s]' info:`
  if [ "$result" = "$color2" ]; then
    echo "Colors match according to Fuzz Factor"
  else
    echo "Colors DO NOT match"
  fi
特別なオプション「-alpha set -channel RGBA」は、透明色や半透明色のファジーマッチングを可能にするために重要です。

色の量子化

色の量子化演算子

色の量子化の主要な作業の要であり、すべての自動色削減に内部的に使用されているのが、「-colors」演算子です。これは「適応空間分割」色削減アルゴリズムを実装しており、非常に優れた色削減アルゴリズムです。典型的な例を以下に示します。多くの色を含む「カラーホイール」画像があり、IMにさまざまなディザリング手法を使用して、色の数を64色に減らすように要求します。

  magick colorwheel.png  -dither None       -colors 64  colors_64_no.gif
  magick colorwheel.png  -dither Riemersma  -colors 64  colors_64_rm.gif
  magick colorwheel.png  -dither FloydSteinberg \
                                             -colors 64  colors_64_fs.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
IMはデフォルトで、画像全体に色をシェーディングする「ディザリング」を使用します。これにより、滑らかに変化するグラデーションにおける急激な色の変化を防ぎます。ディザリングをオフにする(「None」または「+dither」設定を使用)と、IMがこの特定の画像に最適な色のセットと見なしたものを生成するために、どの色がマージされたかを明確に確認できます。また、ディザリングが行われなかった場合に、色のグラデーションが生成する急激な色の変化も確認できます。もちろん、この画像はほとんどの画像よりもはるかに多くの色を使用しています。そのため、64色の制限は多くの画像で許容できることが多いですが、この画像ではまったく許容できません。言い換えれば、色の量子化は、特定の画像に最適な色のセットを見つけようとします。以下に、非常に少ない色数を使用したIMロゴの一部に対する色の量子化の例を示します。

  magick logo: -resize 40% -crop 100x100+105+50\! -normalize  logo.png
  magick logo.png  +dither             -colors 8  colors_8_no.gif
  magick logo.png  -dither Riemersma   -colors 8  colors_8_rm.gif
  magick logo.png  -dither FloydSteinberg \
                                        -colors 8  colors_8_fs.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
組み込みの「rose:」写真画像の結果と比較してください。

  magick rose: +dither             -colors 16 colors_16_no.gif
  magick rose: -dither Riemersma   -colors 16 colors_16_rm.gif
  magick rose: -dither FloydSteinberg \
                                     -colors 16 colors_16_fs.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
ご覧のとおり、漫画のような画像は、適切な結果を生成するために実際の写真よりもはるかに少ない色しか必要としません。
現在IMに実装されている色の量子化アルゴリズムは、「適応空間分割」のみであり、非常にうまく機能するため、他のものを追加する必要はほとんどありませんでした。ただし、フィードバックにより、このアルゴリズムは着実に改善されています。

余談:「Gifsicle」プログラムには、他の多くの色の量子化手法がリストされています(「--color-method」オプションを使用)。これらの色の量子化手法がIMと比較してどの程度優れているかは不明です。さまざまな色の量子化手法に関する良い参考資料を見つけた場合は、メールでご連絡ください。

色の量子化の内部構造

画像で使用する色の数を制限するプロセスは色の量子化と呼ばれ、多くの要因が関与する非常に複雑なプロセスです。その完全な技術的な説明は、ImageMagickのWebサイト色の削減アルゴリズムに記載されています。ただし、ここではより重要な側面の一部を例示してみます。おそらく最大の要因は、画像で使用される実際の色です。その色に近いピクセルが非常に少ない場合、画像に特定の色を選択しても意味がありません。そのため、色の選択は、画像で使用される色だけでなく、その色に近いピクセルの数にも依存します。2つの異なる2色画像を1つの共通の色に減らすことで、これを簡単に実証できます。

  magick -size 4x1 xc:blue -draw 'fill red   point 0,0' \
                                                -scale 20 colors_rb.gif
  magick -size 4x1 xc:red   -draw 'fill blue point 3,0' \
                                                -scale 20 colors_br.gif
  magick colors_rb.gif  -colors 1  colors_rb2.gif
  magick colors_br.gif  -colors 1  colors_br2.gif
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
ご覧のとおり、最終的な単一の色は、存在する色だけでなく、画像内の各色の量にも依存します。

  magick -size 20x640  gradient: -rotate 90  gradient.png
  magick gradient.png   +dither  -colors 5   colors_gradient.gif
[IM Output]
色の量子化は、現在のカラースペース内で均一であることに注意してください。
FUTURE: Just what are the effects of the "-treedepth"  setting?
Mail me if you know

色の量子化とカラースペース

選択される色に対するもう1つの大きな影響は、「近い」または「近傍」の色が正確に何を意味するかを定義することです。これは、量子化(色の選択)に使用されるカラースペースによって定義され、IM v6.2.8-6の時点では、「-quantize」カラースペース設定によって制御されます。「-quantize」設定は、非常に少ない色数を選択した場合に特に重要になります。例として、さまざまなカラースペースを使用して標準の「カラーホイール」画像を減らし、さまざまな「色の距離」を定義してみましょう。

  for S in    RGB CMY sRGB GRAY \
              XYZ LAB LUV  \
              HSL HSB HWB  \
              YIQ YUV OHTA ; do \
     magick colorwheel.png   -quantize $S   +dither -colors 16 \
             -fill black -gravity SouthWest -annotate +2+2 $S \
             colors_space_$S.gif; \
  done
[IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output]
ご覧のとおり、選択された色はカラースペースの構成方法に大きく依存します。sRGB(赤、緑、青)カラーキューブでは、一般に、少なくとも原色に近い色が選択されます。sRGBカラースペースは、漫画のような画像やアイコンの色を選択するのに特に優れていますが、実際には一般的な写真のような写真には適さないカラースペースです。CMYカラースペースは、sRGBとCMYのカラースペースの間で色チャネルが単純に否定されるため、sRGBカラースペースとまったく同じです。したがって、量子化色はほぼ同じ解になります。
CMYKカラースペース(表示されていません)も、異なる理由で同じ結果を生成します。内部的には、「K」チャネルと画像の「カラーマップ」が同じデータポインタを使用するため(パレットチャネルを参照)、IMは量子化の前にCMYに変換し直します。

予想どおり、sRGBカラースペースはRGBと同様の結果になりますが、カラースペース内のほぼ黒の色数を削除するように歪められています。したがって、カラーホイールの中心から選択する色は少なくなり、「完全には黒ではない」スポットが大きくなります。XYZカラースペースも線形RGBカラースペースと非常に似ています。ここでの大きな違いは、カラー軸が、表示できるすべての色(および通常は見ることができない色も)をより適切に含めるようにシフトされているため、カラーホイールの色データが少し圧縮され、その結果、量子化がより分散されるように見えることです。LABカラースペースとLUVカラースペースは、互いに異なるが類似したカラー軸に基づいています。これにより、色の量子化の配置が異なります。HSL(色相、彩度、明度)、HSL(色相、彩度、輝度)、HWB(色相、白、黒)など、「色相」チャネルを含む特別なカラースペースはすべて、カラースペースの一部として色の循環カラーホイール表現を持ちます。実際、このカラーホイールを生成するために使用されたのはHSLカラースペースでした。カラーホイールの生成を参照してください。
執筆時点では、IMで使用されている色の距離アルゴリズムは、カラースペースの「色相」の循環的な性質を考慮していません。このアルゴリズムは非常に異なります。このため、「色相」が折り返される「赤」のパスに沿って強い不連続が発生し、色の量子化プロセスで選択される赤色が非常に少なくなります。
YIQ、YUVは、写真や微妙な色の陰影、特に肌の色を含む現実世界の画像に適した、より自然な「パステル」および「中間色」の色の陰影を生成するように設計されています。Helmut Derschは、彼のWebサイトで、歪みにはLABカラースペースの使用を検討する必要があると述べています。
IMの古いバージョン(特にIMバージョン5)では、量子化に使用されるカラースペースは「-colorspace」オプションで設定されていました。ただし、IMバージョン6では、この演算子は画像がメモリに格納される方法を変更するために使用されるため、色の量子化の設定ではありません。

したがって、IM v6.2.8-6では、このジョブを実行するために「-quantize」設定が提供されました。ただし、これは「-colors」、色の量子化プロセスの設定としてのみ機能します。これは、「-remap」や「-posterize」、またはさまざまなディザリング手法を使用した色の置換とディザリングには影響しません。
利用可能なカラースペースの完全なリストについては、「-colorspace」演算子を参照してください。カラースペースが色の選択に与える影響の詳細については、ランダムな単色のスポットの例を参照してください。ここでは、さまざまなカラースペースを使用して、ランダム化された画像の色数を減らすために色の量子化が使用されています。

量子化は色を保持しません

上記のすべての画像では、純粋な黒色が色の量子化によって実際に選択されることはありません。いずれにせよ、純粋な黒ピクセルは1つだけであり、ほぼ黒の色は多くありません。その結果、最終的な画像に表示される唯一の黒は、画像のラベル付けの一部として後で追加されたものです。 「GRAY」カラースペースの画像でさえ、純粋な黒色を生成しませんでした。実際、どの画像にも、赤、青、緑、シアン、マゼンタなどの原色または二次色は含まれていません。この例外は白のみです。画像には純粋な白色がかなり含まれており、「優先色」になっているためです(以下を参照)。ただし、この状況はバグではありません。まず、「」色は、上記の例では通常、元の画像に黒色がほとんどないため、色の量子化は通常、暗い色をあまり気にしませんでした。実際、画像にはより一般的な明るい色をより多く生成しました。具体的な例については、前のセクションを参照してください。次に、量子化は画像内の既存のカラーピクセルの最大数に近い色を選択しようとしているため、これは、使用されているカラースペースの非常に極端な位置にある「純粋な」原色または二次色と一致させないことで最も効果的に実現できます。「オフカラー」は「原色」よりも多くの色に一致する傾向があるため、これらがより頻繁に選択されます。したがって、明確にさせてください...
色の量子化(「-colors」)は、
一般的に原色の選択を避けます!
IMバージョン6.3から、カラー量子化機能は、元の画像で非常に一般的な色を含めるように変更されました。そのため、画像に単一の色(上記の「white」など)の領域が含まれている場合、その色は通常、最終的なカラーマップに含まれます。これにより、特に「漫画」のような画像や、単色の背景を持つ画像の場合には、状況がいくらか改善されます。 「ソリッド」カラーは、後述するディザースペックリングを回避するために選択されることが一般的です。カラーマップ内の特定の色に関するソリューション現時点では、後でディザリングするために選択された色に「特定の色」が含まれることを保証する方法はわずかしかありません。1つの方法は、画像を通常どおり量子化しますが、生成されたカラーマップを(「-unique-colors」を使用して)出力することです。これで、特定の色が実際の色になるようにカラーマップを調整できます。最後に、カラーの再マップオペレーターを使用して、提供されたカラーマップを使用して画像をディザリングできます。カラーマップは画像の最適な色ではなくなる可能性があり、他のいくつかの色も調整する必要があるかもしれませんが、目的のカラーマップに近いものになります。または、「-colors」を使用する前に、画像内で保持したい特定の色の大規模なパッチを追加(画像を拡大)します。特定色の大きな「スウォッチ」を追加すると、その色が最終的なカラーマップで選択される可能性が高くなります。また、他のすべての色も、そのカラーマップにより適合するように自動的に調整されます)。これが機能する場合、追加した色のスウォッチは変更されないはずです(ディザリングされない)。その後、画像を切り抜いて、追加したスウォッチを削除できます。機能しない場合でも、IMは少なくとも目的の「特定の色」に近い色を追加しているはずなので、カラーの再マップを元の画像に使用する前に、生成されたカラーマップをわずかに調整するだけで済みます。これを試してみて、成功した場合でも失敗した場合でも、その結果を教えてください。理想的には、最終的なカラーマップの一部である必要がある特定の色を少数指定し、特定の画像に対してカラーマップ内の残りの色に最適な色をIMに選択させる方法が必要です。

カラー量子化と透明度

ImageMagickはデフォルトで完全に不透明な色を生成するだけでなく、半透明の色も生成しようとします。このように、透明な影やその他のオーバーレイ効果を含む画像は、それらの効果を失うことはありません。ただし、IM v6.2.6以降、透明度を含むカラー量子化は、完全に透明なすべての色を同じ色として扱うように変更されました。これは線形変更であるため、半透明なだけの色は、完全に不透明な場合よりも互いに近いと見なされます。この変更のため、IMカラー量子化は半透明の色を生成しますが、画像内の不透明な色に重点を置き、完全に透明な色にはあまり重点を置きません。たとえば、ここでは虹色グラデーションを生成します。画像は上部で完全に不透明で、上部で完全に透明です。画像の透明度を正確に確認できるように、背景パターンに画像を表示しました。

  magick xc:red xc:yellow xc:green1 xc:cyan xc:blue \
          +append -filter Cubic -resize 100x100\!  -size 100x100 \
          gradient: -alpha off -compose CopyOpacity -composite alpha_gradient.png
  magick alpha_gradient.png  +dither  -colors 256  alpha_colors_256.png
  magick alpha_gradient.png  +dither  -colors 64   alpha_colors_64.png
  magick alpha_gradient.png  +dither  -colors 15   alpha_colors_15.png
[IM Output] ==> [IM Output] [IM Output] [IM Output]
ご覧のとおり、この画像に必要な色の数を減らすようにIMに要求したところ、より多くの不透明な色が作成され、より半透明な部分には透明度の高い色がより少なく使用されました。その結果、特に色の数が非常に少ない場合、非常に優れた色の分布が得られます。ただし、上記で指摘したように、原色が選択されないだけでなく、完全に透明な色もまったく同じ理由で選択されません。実際、完全に不透明な色さえ選択されません!言い換えれば、前の例のカラー量子化された画像のすべての色は半透明です。それを明確にさせてください。
透明度が関係する場合、IMカラー量子化
完全に不透明な色、または完全に透明な色を選択しない可能性があります!
もちろん、IM v6.3以降、「一般的な色」のバグ修正(上記の量子化は色を保持しないを参照)により、画像に多くの不透明な色と完全に透明な色が含まれている場合(これはよくあることですが)、その可能性は低くなります。一部の画像には、煙や影の効果を含む画像のように、多くの半透明の色が含まれている可能性があるため、試行を実行して、完全に透明な色が結果の画像に含まれるように選択されていることを確認することをお勧めします。次に、最も透明な色を完全に透明にマップし、自分でカラーを再マップします。結果の画像に完全に不透明な色と完全に透明な色の両方を含めることを本当に確信したい場合は、アルファチャネルを正規化またはコントラストストレッチできます。たとえば、ここでは、「-contrast-stretch」を使用して、メインカラーの選択が不透明になるようにしています。ただし、これはより通常の状況では少しやりすぎかもしれません。

  magick alpha_gradient.png  +dither  -colors 15 \
          -channel A -contrast-stretch 10%  alpha_colors_15n.png
[IM Output] ==> [IM Output] ==> [IM Output]
これは、半透明の色を許可しないGIF画像、透明度を許可しないJPG、または適切に保存するために量子化を必要としないPNGには問題ありません。半透明の色が多数含まれている場合に、画像の色を強制的に減らす必要がある特別な場合にのみ問題になります。GIF形式では、半透明の色を保存することは無駄な努力であることを忘れないでください。したがって、そのような画像形式に対して自分でカラー量子化を行うことを計画している場合は、縮小された色セットを生成するときに、画像の透明度を無視するようにIMに指示する必要があります。これは、「-quantize」の色空間設定「transparent」を使用することで実現できます。

  magick alpha_gradient.png -quantize transparent \
                            +dither  -colors 15   alpha_colors_15qt.png
[IM Output] ==> [IM Output]
カラー量子化が色の透明度を完全に無視し、画像のアルファチャネルにまったく触れていないことに注目してください。つまり、画像のアルファチャネルを、他の色とは完全に別に、より適切な方法で処理できます。実際、問題なく「-colors」を使用する前または後にこれを行うことができます。結果には影響しません。したがって、この量子化色空間は、GIFやXPM画像形式などのブール値または透明度がない形式で保存する予定の画像の色数を減らす場合に推奨されます。生成された色の数を数えると、要求された数の色が正確に生成されていることもわかります。したがって、(可能性の高い)完全に透明な色も必要な場合は、「-colors」の引数を少なくとも1つ減らして、画像の最終的なカラースペースに余裕を持たせる必要があります。したがって、GIFファイル形式の256色のカラーテーブル制限を処理するには、色を256ではなく255に減らし、「-transparent-color」設定で定義されている、完全に透明なカラーインデックス用の追加スペースを残す必要があります。より小さなカラーテーブルサイズに合わせてこれを調整します。この量子化動作は、IMがGIFファイル形式で保存するときに自動的に行われますが、グローバルまたは共有カラーテーブルを生成しながら自分で量子化を行う必要がある場合には重要です。もちろん、半透明のピクセルも処理する必要があるため、画像の見え方に合わせて正しく調整されます。
FUTURE: This last part will probably move to a new section on 'Dithering
Alpha Channel' to be created in the near future. And a reference to this
section added here. 
以下に、画像の他のカラーチャネルに影響を与えることなく、アルファチャネルのみをブール値またはオン/オフ設定にディザリングするいくつかの例を示します。

  magick alpha_gradient.png \
          -channel A   -threshold 50%       alpha_dither_threshold.gif
  magick alpha_gradient.png \
          -channel A -ordered-dither checks alpha_dither_checks.gif
  magick alpha_gradient.png \
          -channel A -ordered-dither o8x8   alpha_dither_ordered.gif
  magick alpha_gradient.png \
          -channel A -ordered-dither h8x8a  alpha_dither_halftone.gif

  magick alpha_gradient.png -channel RGBA -separate \
          \( +clone -monochrome \) \
          +swap +delete -combine alpha_dither_monochrome.gif
  magick alpha_gradient.png -channel RGBA -separate \
          \( +clone -dither FloydSteinberg -monochrome \) \
          +swap +delete -combine alpha_dither_monochrome_fs.gif
  magick alpha_gradient.png -channel RGBA -separate \
          \( +clone -remap pattern:gray50 \) \
          +swap +delete -combine  alpha_dither_map.gif
  magick alpha_gradient.png -channel RGBA -separate \
          \( +clone -dither FloydSteinberg -remap pattern:gray50 \) \
          +swap +delete -combine  alpha_dither_map_fs.gif
[IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output]
アルファチャネルのコピーをディザリングして、「-monochrome」または「-remap」を使用してディザリングできるようにする場合は、画像が透明度を含む形状マスクではなく、純粋なグレースケール画像であることを確認してください。そうしないと、アルファチャネルがまだ存在していることから、非線形効果が発生する可能性があります。

グレースケールマスクとして画像を抽出してアルファチャネルを復元し、ディザリングできるようにする方法は多数あります。上記では、チャネル分離結合を使用してこれを行っています。他の方法は、アルファ抽出CopyOpacityコンポジションを使用します。

誤差拡散ディザリング

はじめにで説明したように、誤差拡散ディザーは一般に、縮小された色セットで元の画像の最も忠実な表現を生成するための最良の選択肢と見なされています。また、ユーザーが提供したか、IMカラー量子化ルーチンによって決定されたかどうかにかかわらず、事前定義されたカラーパレットに限定されます。このため、「-colors」、「-remap」、「-posterize」および「-monochrome」などのIMオペレーターによって提供される一般的な色の縮小の論理的なデフォルトの選択肢です。

E-ディザリング手法

バージョン6.4.2-9以降、IMは、「-dither」設定を使用して選択できる、複数のタイプのディザリングスタイルまたは方法を提供するようになりました。それ以前は、IMはRiemersmaディザーまたはヒルベルト曲線ディザーのバリエーションに限定されていました。これは「-dither Riemersma」を使用して設定できます。現在、「-dither FloydSteinberg」を使用してフロイド-スタインバーグディザーも選択できます。IMのバージョンに実装されているディザー方法のタイプは、以下を使用して確認できます。

  magick -list dither
[IM Text]
たとえば、以下はさまざまなディザリング方法を使用してディザリングされたカラーホイールです。

  magick colorwheel.png -dither Riemersma      -colors 16 dither_riemersma.gif
  magick colorwheel.png -dither FloydSteinberg -colors 16 dither_floyd.gif
[IM Output] [IM Output]
ご覧のとおり、フロイド-スタインバーグディザーは、デフォルトのリエマースマディザーよりもはるかに均一なディザーパターンを生成します。それらの最大の相違点は、それぞれが隣接するピクセル間で「色の誤差」をどのように分散させるかです。それでは、Eディザーがどのように機能するかを見てみましょう。

E-ディザリングの仕組み

再書き込み中
IMが一般的なディザリングに使用する特定の方法は、「ヒルベルト曲線誤差拡散ディザ」の変形版です。これは実際には非常に優れたディザリング技術であり、非常に明確に定義されており、比較的高速です。詳細な説明(および非常に類似した変形版)については、Riemersmaディザを参照してください。基本的に、画像の各ピクセルは「ヒルベルト曲線」として知られる非常に複雑なパスで調べられます。ピクセルには、そのピクセルの値に最も近い色が割り当てられ、ピクセルの元の色と選択された色との間の差は保存され、次のピクセルの色値(常に隣接するピクセル)に追加されてから、新しい色が再び選択されます。このようにして、選択された色と画像の元の色の間の色の変化は、同じ領域内の他のピクセルに分散されます。その結果、最終画像には特定の色のみが割り当てられますが、その領域の基本的な全体的な色は元の画像にほぼ一致します。たとえば、元の色を含まない色のセットを使用してIMにディザリングを依頼した小さなグレーの画像を次に示します。結果として得られる画像は、割り当てられた個々の色付きピクセルを確認できるように拡大されています。

  magick -size 10x10 xc:'#999999' -scale 80x80  dither_not.gif
  magick -size 10x10 xc:'#999999' \
          -remap colortable.gif   -scale 80x80  dither.gif
[IM Output] ==> [IM Output]
ご覧のとおり、元の画像の色は指定されたカラーマップに含まれていなかったため、元の色は、指定されたカラーテーブルにあった最も近い3色のパターンを使用して近似されています。 上記のディザパターンによって生成された色を平均すると、[IM Text]の色になります。これは、画像の元の平均色である[IM Text]に非常に近いものです。それが、生成されたディザパターンの要点です。ただし、色の割り当てに使用される「パス」は複雑であるため(ただし、一般的にローカル領域にとどまります)、色の割り当てによって、本質的にランダムなパターンが生成されます。厳密にはランダムではありませんが、同じ画像では同じパターンが生成されるため、結果はランダムであるか、少なくとも疑似ランダムである可能性があります。「F-S」ディザは、実際には、1970年代初頭の開始以来開発されたいくつかの「ラスタライズされたE-ディザ」の1つ(最初)にすぎません。また、最良のものとは見なされていませんが、おそらく最も広く実装されています。このようなアルゴリズムの詳細な概要については、ディザリングアルゴリズムの論文を参照してください。IM v6.4.3の時点で、IMでも直接利用可能になり、画像の最上部から最下部まで、行ごとに「蛇行」パスに従うように実装されています。

  magick -size 10x10 xc:'#999999'  -dither FloydSteinberg \
          -remap colortable.gif   -scale 80x80  dither_fs.gif
[IM Output] ==> [IM Output]
特に「フロイド-スタインバーグディザ」は、「ヒルベルト曲線ディザ」よりも「ハッシュ」のようなピクセルパターンを生成すると感じており、実際にはそのように設計されています。このような規則的なパターンは、小さなカラーアイコン画像の手動でのローレベルクリーンアップをはるかに簡単にすることができます。これは、アンソニーのアイコンライブラリで昔よくやっていたことですが、そのようなことは、おそらく小さなモノクロ画像の場合を除いて、もうあまり必要なくなりました。

E-ディザの問題 - 変化に敏感

誤差拡散ディザを使用する際に直面する最大の問題の1つは、本質的にランダムなピクセルパターンが得られることです。これは、変化にも非常に敏感です。たとえば、元のグレー画像を取り、ディザリングを再度行う前に、1つのピクセルを別の色に置き換えてみましょう。その結果、ヒルベルト曲線ディザによってたどられるパスに沿ってさらに先のすべてのピクセルで、ディザリングパターンが完全にシフトします。

  magick -size 10x10 xc:'#999999' -draw 'fill #C28 point 2,2' \
          -remap colortable.gif   -scale 80x80   dither_modified.gif
  magick compare dither.gif dither_modified.gif dither_difference.gif
[IM Output]
元のディザ
[IM Output]
1ピクセルの変更
==>
 
[IM Output]
変更の比較
ご覧のとおり、画像に1つのピクセルを追加しただけで、ディザパターンが劇的に変化しました。画像(拡大されていない場合)の全体的な外観は基本的に同じ(結局のところ、これは優れたディザアルゴリズムの目的です)ですが、結果として得られる画像が異なるには、わずか1ビットの変更で十分です。「magick compare」画像は、ディザパターンの変化の程度も示しています。この場合、ピクセルの約80%に完全に異なる色が割り当てられました。ヒルベルト曲線ディザでは、1つのピクセルの変更によって、後から来るすべてのピクセルが異なる可能性があり、ディザパターンの0〜100%が異なる可能性があることを意味します。変更が複雑なヒルベルト曲線内のどこで発生したかによって異なります。ただし、フロイド-スタインバーグディザは、画像内を1方向にのみ進むため、1つのピクセルの変更によって、その変更の片側のみのパターンが変更されます。

  magick -size 10x10 xc:'#999999' -draw 'fill #C28 point 2,2' \
          -dither FloydSteinberg -remap colortable.gif \
          -scale 80x80   dither_fs_modified.gif
  magick compare dither_fs.gif dither_fs_modified.gif dither_fs_difference.gif
[IM Output]
FSディザ
[IM Output]
1ピクセルの変更
==>
 
[IM Output]
変更の比較
ご覧のとおり、まったく同じ問題を抱えています。1つのピクセルの変更により、そのピクセルの後に処理された画像の領域のディザパターンがほぼ完全に変更されます。つまり、その行から下に向かってです。単一の画像の場合、ディザリングされた色の結果のパターンは重要ではありません。パターンの平均色は、画像のその領域に適切な色を与える必要があります。しかし、1つの画像に、非常に似た他の画像が続き、一定の色の広い領域があるアニメーションでは、変化するディザパターンは、ローレベルのバックグラウンド「ノイズ」として非常に目立ち、イライラさせられます。たとえば、同じディザリングされた色の3枚の画像のアニメーションを生成しますが、各フレームで1つのピクセルを変更します。また、この変化するパターンをより明確に確認できるように、中央の領域を拡大します。

  magick -size 80x80 xc:'#999999' \
          \( +clone -draw 'fill #C28 point 2,2' \) \
          \( +clone -draw 'fill #28C point 2,2' \) \
          -remap colortable.gif  -set delay 50 -loop 0   dither_anim.gif
  magick dither_anim.gif -crop 10x10+40+40 +repage \
                              -scale 80x80     dither_anim_magnify.gif
[IM Output] ==> [IM Output]
ご覧のとおり、E-ディザによって生成された疑似ランダム性によって、画像に一種の撹拌バックグラウンドが発生します。ほとんどの場合、使用される色は互いに十分に近いため、この「ディザノイズ」は目立ちません。しかし、ディザリングの色が明らかに異なるとき(この場合はカラーマップの使用によって強制される)、それは間違いなく問題になります。この「ディザノイズ」を示すアニメーションの実用的な例については、ビデオカラー最適化を参照してください。パターンの変化は、アニメーションの最適化にも問題を引き起こします。つまり、異なるパターンは、単純なフレーム最適化がフレームオーバーレイのサイズを縮小できないことを意味します。1つの解決策については、ファジーカラー最適化を参照してください。ただし、これは撹拌が非常に類似した色を使用している場合にのみ機能します。
他のディザリング方法(しきい値組織ディザなど)とは異なり、「-channel」設定は、色の量子化や誤差拡散ディザには影響しません。基本的に、これらの画像操作がどのように機能するかにおいて、その居場所はありません。
組織ディザにはこれらの問題はなく、変更は変更のすぐローカル領域に限定されます。残念ながら、数学的に導き出された色のセットを使用することに一般的に限定されています。(均一なカラーマップを使用した組織ディザを参照してください)。

E-ディザリングのピクセル斑点

E-ディザのもう1つの問題は、本来であれば比較的均一な色である領域に、時折、奇妙な色のピクセルを生成する可能性があることです。たとえば、グレースケール画像での時折の緑のピクセルなどです。または、以下の例のように、本来は単純なフラットな青色の領域に白いピクセルなどです。これは、多数の色を持つオブジェクトと、単純なソリッドな変化のない色の他の領域を含む大きな画像で特に当てはまります。これは、図や図面でよくあるように、フラットな色の背景に重ねられた色付きのオブジェクトで特に一般的です。上記のテスト例の拡大図で、そのような奇妙な色のピクセルを確認できます。そこでは、小さな1ピクセルの変更からかなり離れた場所に、余分な薄紫色のピクセルが追加されています。ただし、上記に追加された奇妙な色のピクセルはすぐに目に見えるわけではなく、カラーマップは画像をかなりうまくカバーしているため、奇妙なピクセルは画像のディザリングに使用される通常の3色に比較的近い色です。より極端な例として、ここではぼやけたグラデーションの背景があり、誤差拡散ディザを本当に強調するために64色に大幅に色を減らしました。

  magick -size 100x60 xc:SkyBlue \
          -fill DodgerBlue -draw 'circle 50,70 15,35' \
          -fill RoyalBlue  -draw 'circle 50,70 30,45' \
          -blur 0x5  -colors 64     speckle_gradient.gif
[IM Output]
この大幅に削減されたカラーマップでは、誤差拡散ディザが元のグラデーションをかなりうまく表現していることがわかります。しかし、上記の純粋な白いパッチを追加すると...

  magick -size 100x60 xc:SkyBlue \
          -fill DodgerBlue -draw 'circle 50,70 15,35' \
          -fill RoyalBlue  -draw 'circle 50,70 30,45' -blur 0x5 \
          -fill white -draw 'rectangle 40,40 60,55' \
          -colors 64   speckle_problem.gif
[IM Output]
E-ディザが、以前は何もなかった画像の上部領域に白いピクセルを散りばめ始めたことがわかります。
これらのピクセルをより明確に確認できるように、小さなセクションを拡大したものを次に示します...

  magick speckle_problem.gif -crop 15x15+75+0 +repage \
          -scale 90x90    speckle_prob_mag.gif
[IM Output]
奇妙な色のピクセルは、2つの要因によって引き起こされます。まず、色の量子化は、画像の最終的なカラーマップに単一の純粋な白色(ただし、他の白色-青色のアンチエイリアシング色はない)を含めるように強制されたため、ディザリングプロセスはこの余分な色を使用できるようになりました。しかし、E-ディザは特に極端な色の領域で、エラーをゆっくりと蓄積するため、上記画像の上部のように、エラーは最終的に、1つの追加の色を最も近い一致にするのに十分な大きさの値に追加されます。したがって、非常にコントラストの強い白いピクセルが、疑似ランダムな場所で「エラーを修正」するために、時々出力されます。その結果、非常に軽い白いピクセルの散布が発生します。エラーの蓄積が遅いほど、これらの白いピクセルはより広がり、より場違いに見えます。最良の解決策は、制限されたカラーテーブルを持たない他の画像形式に切り替えることです。たとえば、GIF形式の画像をPNGにmagickします。これにより、色の量子化(削減)の必要性が回避され、したがって、削減された色をディザリングする必要がなくなります。次の解決策は、E-ディザの使用を、組織ディザのようにエラーを「局所化」する他のディザリング方法に置き換えることです。ただし、現時点ではIMでこれを適用するのは簡単ではありません。より一般的な方法が見つかるまでは、このような方法の1つとして、より優れた組織ディザの結果を参照してください。別の画像形式に切り替えるか、別のディザリング方法を使用するのが現実的でない場合(そして多くの場合そうではありません)、その特定の画像の状況を修正しようとするしかありません。最良の修正は、E-ディザのエラー蓄積を引き起こしている大きな色のグループのすぐ外側に、他の色を何らかの方法で確実に存在させることです。ただし、通常のカラー量子化では、これは行われません。カラーグループを表す平均色のセットを選択する傾向があります。必要なのは、単純な平均色ではなく、大きなカラーグループのエッジを「ピケットフェンス」する追加の色です。たとえば、ここでは正方形ではなく円を使用しました。これにより、純粋な白色が追加されるだけでなく、多数の白色-青色も追加されます。これらは、円のエッジのアンチエイリアシングにより、その外観をスムーズにするために自動的に追加されました。

  magick -size 100x60 xc:SkyBlue \
          -fill DodgerBlue -draw 'circle 50,70 15,35' \
          -fill RoyalBlue  -draw 'circle 50,70 30,45' -blur 0x5 \
          -fill white -draw 'circle 50,45 40,40' \
          -colors 64  speckle_fixed.gif
[IM Output]
そして、前と同じ領域の拡大図です。

  magick speckle_fixed.gif -crop 15x15+85+0 +repage \
          -scale 90x90    speckle_fix_mag.gif
[IM Output]
ご覧のとおり、追加の色は青-シアンのグラデーションの外側にある、より多くの色を提供しています。これらの追加の色は、実際のグラデーションに使用できる色が少なくなることを意味しますが、E-ディザリングがより早く、より頻繁に自己修正できるようにする、他の青-白の色を提供します。つまり、E-ディザリングの斑点を防いだということではなく、ディザリングアルゴリズムが使用するためのより良い色を提供したということです。画像を拡大して調べると、まだ斑点パターンが見られますが、色は背景色に近く、より多くの色がより均一に分散した斑点を生成しています。別の方法は、IMが生成したものをベースにして独自のカラーテーブルを生成し、エラーの蓄積を防ぐために適切な色を追加することです。しかし、これは特に3次元の色空間では簡単なことではありません。この特定の画像例では、「斑点」を防ぐ1つの方法は、必要な色よりもわずかに少ない色で背景を個別に生成してディザリングし、次に白いボックスとその追加の色を重ねることです。

  magick -size 100x60 xc:SkyBlue \
          -fill DodgerBlue -draw 'circle 50,70 15,35' \
          -fill RoyalBlue  -draw 'circle 50,70 30,45' -blur 0x5 \
          -colors 63 \
          -fill white -draw 'rectangle 40,40 60,55'  speckle_perfect.gif
[IM Output]
これにより、画像に「白」の色が追加されますが、エラー補正ディザリングを使用するときに白が利用できなかったため、背景に斑点効果は発生しません。結果として、画像は正確に64色になり、斑点はまったくありません。ただし、これは画像と達成しようとしていることに非常に依存するため、斑点問題に対する一般的な解決策ではありません。
追加の色を追加するよりも一般的な代替手段は、最終的なディザリングされた画像から斑点を取り除くことを試みることです。つまり、何らかの方法で画像をクリーンアップします。ただし、これはそれ自体が難しい問題です。なぜなら、通常のディザリングパターンの一部であるピクセルを削除したくないからです。必要なのは、周囲のすべての色とは何らかの点で非常に異なり、なおかつある程度の距離で他の同様の色から十分に隔離されている色のピクセルを見つけることです。 より良い画像フィルターソリューションはありますか? まとめ私にとって、斑点は非常に厄介な問題です。特に、非常に限られたカラーテーブルを使用するデスクトップアイコン画像の場合です。私自身、小さな「アイコン」画像を編集して、斑点を取り除いたり、垂直バンディングのような他のディザリング効果を修正したりすることがよくあります。もしあなたが別のより良い解決策を知っているなら、教えてください。

モノクロディザリングされたビットマップ画像

-monochrome」オペレーターは、「-colors」オペレーターの特殊な形式であり、ビットマップ画像を生成します。そのため、「ヒルベルト曲線ディザリング」を実証するだけでなく、色の選択を詳しく調べるのに理想的なオペレーターです。以下に典型的な例を示します。

  magick logo.png  -monochrome     monochrome.gif
[IM Output]
オペレーターは、グレースケールの明るさ「強度」または「レベル」のみに基づいて画像をディザリングしましたが、グレースケール範囲全体を直接ディザリングするのではなく、極端な値を最大値に閾値処理します。IMにグラデーション画像をディザリングさせることで、これを確認できます。

  magick -size 15x640 gradient: -rotate 90 \
                   -monochrome     monochrome_gradient.gif
[IM Output]
ご覧のとおり、グラデーションは「-monochrome」オペレーターによってディザリングされた色の約50%の中央部分のみを持っています。IMの動作に関するこの興味深い事実を指摘してくれたイワノワさん<flamingivanova@punkass.com>に感謝します。グレースケール範囲全体を使用してディザリングする場合は、(組み込みパターン画像で提供される)純粋な白黒カラーマップを使用して「-remap」オペレーターを使用できます。

  magick logo.png  -remap pattern:gray50  mono_remap.gif
  magick -size 15x640 gradient: -rotate 90 \
                   -remap pattern:gray50     mono_remap_gradient.gif
[IM Output]
[IM Output]
-remap」を使用して色をより慎重に選択することにより、「-monochrome」オペレーターで使用されているのと同じ「閾値」範囲、またはその他の任意の閾値範囲を効果的に生成できます。

  magick xc:gray20  xc:white  +append   ctrl_colors.gif
  magick logo.png -colorspace Gray \
          -remap ctrl_colors.gif  -normalize  mono_remap_ctrl.gif
  magick -size 15x640 gradient: -rotate 90 \
          -remap ctrl_colors.gif  -normalize  mono_remap_grad_ctrl.gif
[IM Output]
[IM Output]
-monochrome」が実際に行うことは、まず指定された画像をグレースケール画像に変換し、その後、2色の「色量子化」を実行して、画像をディザリングする閾値を決定することです。これは、次の例のセクションで説明します。
+dither」設定は、現在「-monochrome」の結果に影響を与えません。ただし、これは将来変更される可能性があるため、このオペレーターを使用するときは、スクリプトでオフになっていないことを確認してください。

2色量子化

2つのコントロールカラーを自分で選択するのではなく、「-colors」オペレーターを使用することにより、画像内で最適な2つの色を選択するために色量子化を使用できます。

  magick logo.png   -colors 2 -colorspace gray  -normalize \
                                                 colors_monochrome.gif
[IM Output]
ただし、画像は最初にグレースケールに変換しなかったため、「-monochrome」を使用するのと同じ結果にはなりません。代わりに、画像は選択された2つの非グレー色値の間で直接ディザリングされました。つまり、2つのグレースケール輝度レベルではなく、画像をディザリングするための最適な2つの色が選択されます。したがって、同じグレースケール「レベル」の色のみを使用する画像に対して、より良い結果が得られます。たとえば、ここでは、「-colors」と、「-monochrome」ビットマップディザリングオペレーターを、赤-青グラデーションで使用します。ご覧のとおり、結果は同じではありません。

  magick -size 20x640 gradient:red-blue -rotate 90    gradient_rb.png
  magick gradient_rb.png   -colors 2 -colorspace gray \
                                -normalize        colors_threshold.gif
  magick gradient_rb.png       -monochrome       mono_threshold.gif
[IM Output] [IM Output] [IM Output]
上記の「-monochrome」オペレーターは、青と赤の両方がほぼ同じ強度であるため、ビットマップディザリングとの違いを見つけることができませんでした。ただし、「-colors」量子化方式では、ディザリングするのに適切な色を見つけるのに問題はありませんでした。色の真ん中の部分のみがディザリングされていることもわかります。これは、色量子化が選択した2つの色「クラスター」の中央の色を選択するためです。したがって、選択した色の「外側」の色は、ディザリングなしでその色に効果的に閾値処理されます。これは、量子化色空間の外側の色はディザリングされないことを示していますが、この事実を実用的に利用するのは困難です。
量子化する前に「-colorspace」をグレースケールに設定することにより、「-monochrome」オペレーターの内部操作を再現します。

  magick logo.png -colorspace gray   -colors 2  -normalize \
                                                 monochrome_equivelent.gif
[IM Output]
最後に、ディザリングをオフにすることにより、固定の「-threshold」設定を使用するよりも、画像内の色をより自動的に分離できます。

  magick logo.png  -colorspace gray  +dither  -colors 2  -normalize \
           threshold_two_grays.gif
[IM Output]
-monochrome」は現在、「+dither」設定を無視するため、そのオペレーターを使用して「スマート閾値」を行うことはできません。
画像処理の色量子化段階で「-colorspace」を削除すると、その画像に対して可能な最良の色分離(グレースケール色分離ではなく)に基づいて画像の閾値を設定できます。

  magick logo.png  +dither  -colors 2  -colorspace gray -normalize \
           threshold_two_color.gif
[IM Output]

定義済みのカラーマップを使用したディザリング

上記のように、「-colors」は画像を表現するために使用する最適な制限された色のセットを選択しようとします。「-remap」を使用すると、IMに、それらの色をディザリングするか、最も近い隣接色と置き換えるかにかかわらず、画像に使用する最終的な色のセットが提供されます。引数は、使用したいすべての色を含む画像として与えられます。色数の多い画像を単色のリストに減らしたい場合は、「-unique-colors」を使用してから、「-remap」で使用するために保存できます。
-remap」オペレーターは使用する任意の画像を受け入れますが、この画像にJPEG画像を使用しないでください。そうしないと、「可逆圧縮」によって追加の色が生成され、余分な色が多くなります。

一方、JPEGを使用して余分な色を生成すると、以前に見られた「斑点」の問題を解決するのに役立つ可能性があります!
たとえば、ここでは、IMロゴで使用する色を、名前付きXウィンドウカラーの定義済みマップに制限しています。デフォルトは「Riemersma」ディザリングですが、IM v6.4.4以降、「-dither」が拡張され、「FloydSteinberg」などの他のディザリング方法を選択できるようになりました。「+dither」オプションを使用すると、ディザリングをオフにすることもできます。

  magick logo.png  -dither None       -remap colortable.gif  remap_logo_no.gif
  magick logo.png  -dither Riemersma  -remap colortable.gif  remap_logo_rm.gif
  magick logo.png  -dither FloydSteinberg \
                                       -remap colortable.gif  remap_logo_fs.gif
[IM Output]  + [IM Output] [IM Output] [IM Output] [IM Output]
ご覧のとおり、IMは与えられた色のみを使用して画像を表現するために妥当な処理を試みましたが、結果は、IMに使用する色のセットを選択させた場合に得られる画像ほど良好ではありません。ちなみに、この「colortable.gif」画像は、画像をディザリングするために設計されたものではなく、古いより原始的なXウィンドウカラーディスプレイの漫画のようなカラーアイコンを設計するためのカラーセットとして設計されたものでした(詳細については、Anthony's X Window Icon LibraryAIcons Color Selectionを参照してください)。また、最終的な画像は、このマップで提供された32色すべてを使用したわけではありません。ただし、何らかの形のディザリングが有効になっている場合は( それぞれ)、オフにした場合( )よりも、マップ内のより多くの色が使用されます。この最後の例は、適切なカラーマップを選択することがいかに重要かを示しています。このため、より差し迫った理由がない限り、「-colors」オペレーターを使用して画像で使用される色選択をIMに最適化させ、それをニーズに合わせて変更することをお勧めします。最後に、色を選択するために「-colors」が最適な色のセットを見つける色空間を指定できますが、現在、カラーマッピングまたはディザリングフェーズの色空間を定義することはできません。私のすべての実験では、色のセットは(エラー補正ディザリングと最も近い色への置き換えの両方)RGB空間に基づいて適用されているようです。「-quantize」カラースペース設定は、色の選択にのみ使用され、マッピングには使用されません。したがって、カラーマップを使用することがそのような悪い考えである場合、なぜそれを使用したいのでしょうか?通常、画像の特定の色パレットをより詳細に制御する必要があるため、いくつかの一般的な理由があります。別のユーザーは、Risograph(デジタル印刷システム)で使用できるように、カラーマップを分離しました。下に示していない「-remap」オペレーターを使用する別の理由を知っている場合は、メールしてください。

共通または「最適」なカラーマップ

複数の画像を扱う際のもう一つの手法は、関連するすべての画像に対して共通のカラーテーブルを生成することです。基本的には、すべての画像を1つの大きな画像に結合し、"-colors" オペレーターを使用して、すべての画像に共通して使用できる適切なカラーマップを算出します。カラーマップ画像ができたら、この生成された定義済みカラーマップを使用して、元の各画像の色を再度設定できます。または、特別な "+remap" オペレーターを使用することもできます。これは、255色のカラーマップに対して同じ処理を行います。色の数を数え、適切な共通カラーマップを生成するためのカラー量子化を実行し、必要に応じて画像をディザリングしてそのマップを使用します。"-remap" と "+remap" の両方の形式には、GIFアニメーションにとって非常に重要な機能が1つあります。それは、すべての画像を同じカラーパレットを使用する 'Palette' という "-type" の画像に変換することです。その理由は、GIF画像を書き込む際、最初の画像のカラーパレットがファイル形式の「グローバルカラーマップ」として使用されるからです。そして、各画像が書き込まれる際、これらの画像が同じ色のセットを使用していることを記録するため、「ローカルカラーマップ」は作成されません。これにより、最終的なGIFファイルの画像ごとに最大256 × 3、つまり768バイトのカラーマップ領域を節約できます。この処理を実行できるのは "-remap" オペレーターのみです。したがって、GIF、特にGIFアニメーションを扱う場合、覚えておくべき重要なポイントとなります。詳細と例については、GIFアニメーション、グローバルカラーテーブルを参照してください。

Webセーフカラーリング

WWWが最初に作成されたとき、コンピューターディスプレイで利用できる色の範囲は限られており、Webブラウザーは通常、画像にシンプルな色のセットを使用していました。そのため、画像をこの色のセットに再着色して、サイズを小さくするとともに、ユーザーのブラウザーで適切に表示されるようにすることが一般的でした。詳細については、Webスタイルガイド、ディザリングを参照してください。これを支援するため、IMは、この216色の特別なテーブルの組み込みカラーマップ画像「netscape:」を提供しました。それでは、これらの色を使用して、古いWebブラウザーディスプレイでテスト画像がどのように表示されるかを見てみましょう。

  magick logo.png         -remap netscape:  remap_netscape.gif
  magick logo.png +dither -remap netscape:  remap_netscape_nd.gif
[IM Output]  + [IM Output] [IM Output] [IM Output]
この色のセットは、グラフィックアーティストではなく、ディスプレイとコンピューターのエンジニアによって設計された数学的に決定されたパレットでした。写真などの実際の画像には十分に機能しますが、ロゴ、背景、グラフなどのコンピューターで生成された画像、および漫画のような画像など、大きなフラットな色領域を含む画像には非常に不向きです。基本的に、これは色の変化が大きい領域では機能しますが、大きく一定の色領域には、(一般的に)3色のディザリングが適用されます。たとえば、上記のIMロゴのテスト画像のオフブルーのシャツなどです。つまり、Webで使用する画像やロゴをデザインする場合は、通常、大きなフラットな領域にはこのパレットの色を使用し、色の濃淡が異なる領域にのみディザリングされた色を使用しようとします。上記のコマンドを使用すると、より原始的なコンピューターディスプレイで画像がどのように表示されるかをテストし、これらの色を使用するように画像を編集して、適切に機能するようにすることができます。これは、シンボルやナビゲーション画像にとって特に重要です。もちろん、今日では、ゲームやWebユーザーの要求のおかげで、ほとんどのユーザーが古い色の制限のない最新のコンピューターディスプレイを持っていることはほぼ確実です。ただし、この「Webセーフパレット」の使用は、画像の圧縮などの他の利点もあるため、今でも使用されています。現代におけるWebセーフカラーの使用に関する議論については、Webセーフカラーパレットの終焉?、そしておそらく、このカラーマップを最初に特定したグラフィックデザイナーからのより重要な見解であるリンダ・ワインマンを参照してください。

カラーマップの生成

任意の画像、または特定の画像のセットに対して適切なカラーマップを決定することは、非常に重要になる可能性があります。これは、GIFアニメーションに使用される画像のシーケンスを扱う場合に特に重要になります。基本的には、各フレームに個別のカラーテーブルを使用するのではなく、アニメーションのすべてのフレームに使用するカラーテーブルを1つだけにする必要があります。つまり、すべての画像に対して1つのカラーマップが必要です。この場合、選択肢は2つしかありません。すべての画像にうまく機能するカラーマップを作成しようとするか、適用する特定の画像のセットに対してカラーマップを最適化しようとするかです。

Webセーフカラーマップ

[IM Output] 最初の方法は通常、IM組み込みの「netscape:」カラーマップなど、数学的に生成されたカラーマップです。これにより、GIF形式の256色の制限にうまく収まり、画像の透明度を処理したり、シャドウやテキストオーバーレイなどの特別な目的のためにいくつかの追加色を追加する余裕がある、216色のセットが提供されます。このカラーマップは、3つのカラーチャネルそれぞれに6つのレベルの色を作成し、6×6×6色、つまり216色を生成することで生成されました。野獣の数です。219色しか使用されないため、特定の目的のためにカラーマップにさらに色を追加する余裕(GIF画像の場合)があります。たとえば、透明な色や、グレースケールシェードなどです。Webセーフマップの古いMacintoshバージョンは、全体的な結果を改善するためにまさにこれを行いましたが、Macintosh Webクライアントでのみ使用されました。これは、そのシンプルさと、World Wide Webでの一般的な使用のおかげで、一般的に使用されている最も一般的な「均一」(または数学的に導出された)カラーマップです。

均一332カラーマップ

一般的に使用される別の均一カラーマッピングは、「332 RGBカラーマップ」です。この数値は、8ビットカラーインデックス内の各色を表すために使用されるビット数を指します。つまり、赤の3ビット(または8レベル)、緑の3ビット、そして青の2ビット(または4つのカラーレベル)です。これは、人間の目が青にうまく反応しないためです。これにより、3 + 3 + 2ビット、つまり8ビットのカラーインデックス、または256色が与えられます。制限されたGIFカラーテーブルに最適です。ただし、GIF透明色やその他の特別な用途の色に使用できる余地は残りません。IMにこのカラーマップを生成させる1つの方法は次のとおりです...

  magick -size 16x16 xc: -channel R -fx '(i%8)/7' \
                          -channel G -fx '(j%8)/7' \
                          -channel B -fx '((i>>3&1)|(j>>2&2))/3' \
          -scale 600% colormap_332.png
[IM Output]
ビットシフト演算子 '>>' および '<<' は、IMバージョン6.2.9-2まで "-fx" オペレーターに欠落していました。
同じことを行うより簡単な方法は、操作 "-ordered-dither threshold,8,8,4" を使用して均一カラーレベルを使用した順序付きディザを使用することです(例の領域を参照してください)。上記のDIY FXメソッドよりもはるかに簡単で高速な手法であり、より優れたグラデーション処理のために他の組み込みディザリングマップを使用することもできます。このマップの唯一の欠点は、実際には「グレイ」色がまったく提供されないことです。ただし、この欠点は、ディザリングを使用すると、わずかな色の違いがグレースケールグラデーションでの色の境界線の変化の影響を減らし、少し滑らかな外観になるため、プラスになる可能性があります。

TrueColor 16ビットカラーマップ

上記の「332カラーマップ」と同様の均一カラーマップは、めったに使用されない16ビットのビジュアルクラスでX windowsによって使用されます。この場合、16ビットがカラーインデックスに使用され、赤に5ビット、緑に5ビット、青に6ビットに分割されます。言い換えれば、このカラーマップは「556カラーマップ」に近く、'threshold' ディザマップを使用する均一カラーレベルを使用した順序付きディザを使用することで最もよく実現できます。具体的には、操作 "-ordered-dither threshold,32,32,64" です。ただし、16ビットカラーマップはめったに見られません。カラーマップを使用する画像は通常、8ビットカラーテーブルを必要とするためです。したがって、これ以上言及しません。

ガンマ補正された均一カラーマップ

現時点では、IMはガンマ補正されたカラーマップを直接実行していません。代わりに、すべきことは、画像を(IMのQ16以上のコンパイル時の品質バージョンがあることを前提として)sRGBまたは画像が持つガンマレベルから線形RGBモデルに変換してからディザリングを行うことです。これは、リサイズ、ぼかしなど、他の多くの画像処理操作にも当てはまります。例については、ガンマ補正を使用したリサイズを参照してください。

ポスタリゼーション、均一カラーマップを使用した再着色

このオペレーターの本来の目的(引数「2」を使用)は、画像が基本的な色のみを使用したシンプルで安価なポスター印刷方法を使用して生成されたかのように、わずか8つの基本色を使用して画像を再着色することです。したがって、オペレーターの名前が付けられています。"-posterize" オペレーターの実際の事実は、画像内の各カラーチャネルに指定された色の「レベル」の数に基づいてカラーマップを生成し、エラー補正ディザを使用して画像をディザリングする特別な色の削減オペレーターです。

  magick netscape: -scale 50%  +dither  -posterize 2   posterize_2_ns.gif
  magick netscape: -scale 50%  +dither  -posterize 3   posterize_3_ns.gif
  magick netscape: -scale 50%  +dither  -posterize 6   posterize_6_ns.gif
[IM Output] [IM Output] [IM Output] [IM Output]
ご覧のとおり、"-posterize" の引数 '2' は、カラーチャネルごとに2色のみを提供することを意味し、上記のような3チャネルRGB画像に対してわずか8色のマップを生成します。基本的に、8色のしきい値セットを使用して画像を再着色します。引数 '3' は、ミッドトーンカラーを含む27色のカラーマップに基づいて画像の色をマップします。引数 '4' は64色のカラーテーブルを生成し、 '5' は125色のカラーマップを生成します。もちろん、上記のように、引数 '6' は、組み込みの "netscape:" 画像で提供されるのと同じ216色のセットを再現します。"-posterize" の引数 '0' または '1' は意味がなく、最新のIMリリースでは画像を純粋な黒に変換するだけです(論理的ですが、まったく役に立ちません)。その結果、画像は数学的に導出された、または「均一」なカラーマップを使用して再着色されました。これは、グラデーション画像ではより明確に確認でき、ポスタリゼーションされたグレーレベルの均等な分布が生成されます。

  #magick -size 20x640  gradient: -rotate 90  gradient.png
  magick gradient.png  +dither  -posterize 5   posterize_gradient.gif
[IM Output]
たとえば、さまざまなレベルでIMロゴ画像をポスタリゼーションしてみましょう...

  magick logo.png  +dither -posterize 2  posterize_logo.gif
  magick logo.png          -posterize 2  posterize_logo_dither.gif
  magick logo.png          -posterize 6  posterize_6_logo.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
より良いテストとして、陰影付きの "カラーホイール" 画像をポスタリゼーションしてみましょう。

  magick colorwheel.png  +dither  -posterize 2   posterize_2_cw.gif
  magick colorwheel.png  +dither  -posterize 3   posterize_3_cw.gif
  magick colorwheel.png  +dither  -posterize 6   posterize_6_cw.gif
[IM Output] [IM Output] [IM Output] [IM Output]
そして、こちらがディザリングを有効にした場合の結果です...
[IM Output] [IM Output] [IM Output] [IM Output]
もちろん、次のセクションで取り上げる多くのビットマップディザリングは、さまざまなディザリングスタイルを使用して、レベル2の組織ディザリングを生成することもできます。ただし、より多くのグレーレベルを使用できるものはほとんどありません。組織ディザリングは、IM v6.2.9の時点では、均一なカラーマップを使用したディザリングにおける現在の制限により、ポスタリゼーション手法でもあります。ただし、ディザパターンは、"-posterize"によって生成される疑似ランダム化ディザよりも均一で、より多くのスタイルを選択できます。上記のディザリングされた"-posterize"バージョンと比較してみてください。

  magick colorwheel.png  -ordered-dither o8x8,2   posterize_2_od.gif
  magick colorwheel.png  -ordered-dither o8x8,3   posterize_3_od.gif
  magick colorwheel.png  -ordered-dither o8x8,6   posterize_6_od.gif
[IM Output] [IM Output] [IM Output] [IM Output]
(上で使用した 'o8x8'の代わりに)'threshold'ディザマップを使用すると、"-ordered-dither"は事実上、ディザリングされていないポスタリゼーション手法に変換されます。最後に、組織ディザリングでは、個々のカラーチャンネルごとに異なるカラーレベル数を指定できます。これは、"-posterize"演算子が現在許可していないものです。

閾値ディザリング手法

閾値画像

画像を白黒ビットマップ(カラーへ)画像に変換する最も簡単な方法は、"-threshold"を使用することです。これは実際には、単にカットオフ値を提供する単純な数学的演算子です。その値以下はすべて黒になり、それより大きい値はすべて白になります。

  magick logo.png     -threshold   -1   threshold_0.gif
  magick logo.png     -threshold  25%   threshold_25.gif
  magick logo.png     -threshold  50%   threshold_50.gif
  magick logo.png     -threshold  75%   threshold_75.gif
  magick logo.png     -threshold 100%   threshold_100.gif
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
ご覧のとおり、'-1'の値はすべての色を白に変え、'100%'はすべての色を黒に変えます。'50%'はもちろん最も一般的に使用される値です。
'0'の値は特殊なケースであり、純粋な黒以外のすべての色を白に変えます。もちろん、画像に純粋な黒の色がない場合は、単に真っ白な画像が得られるだけです!

  magick logo.png  -threshold   0    threshold_black.gif
[IM Output]
実際に純粋な白以外のすべての色を黒にしたい場合は、正しい閾値値を計算しようとする代わりに、反転した画像を閾値処理することをお勧めします(IMの現在の'MaxRGB'より1つ少ない値)。この値は、品質、つまり「Q」設定における特定のIMのコンパイル時に依存します。

  magick logo.png  -negate -threshold 0 -negate threshold_white.gif
[IM Output]
"-threshold"演算子は、閾値レベルで色の違いを最大化する究極の「コントラスト」演算子として分類できます。ただし、これはグレースケール演算子であるため、"-channel"設定を使用して、演算子が適用されるカラーチャンネルを調整できます。たとえば、画像の個々のチャンネルをそれぞれ閾値処理して、ディザリングされていないレベル2の"-posterize"演算と同じ効果を生み出すことができます。

  magick logo.png  -channel R -threshold 50% \
                     -channel G -threshold 50% \
                     -channel B -threshold 50%   threshold_posterize.gif
[IM Output]
"-threshold"は、画像の透明度をアルファチャンネルではなく、マットチャンネルとして扱います(IM内部に保存されているのと同様)。そのため、この演算子をアルファチャンネルに適用する場合は注意が必要です。詳細については、マットチャンネルを参照してください。
より自動化された閾値処理手法については、以前に示した2色量子化手法を使用できます。
たとえば、これにより、画像内で見つかった最適な2色に基づいて画像が閾値処理されます。これらの色は、必ずしもグレースケールである必要も、反対色である必要もなく、画像全体を最もよく表す2色です。次に、この2色が("-normalize"を使用して)純粋な黒と白にマッピングされます。

  magick logo.png  +dither  -colors 2  -colorspace gray -normalize \
             threshold_two_color.gif
[IM Output]

ランダムディザと閾値

"-random-threshold"演算子は、ビットマップ画像変換の特殊な形式です。この場合、特定のピクセルを白ピクセルにするか黒ピクセルにするかを決定するために、非常に単純な「ランダムディザ」を使用します。"-threshold"または"-monochrome"演算子、または前のセクションのバリエーションとは異なり、選択されたチャンネル("-channels"で設定)は、単一のグレースケールチャンネルにマージされて単一のユニットとしてディザリングされることはありません。代わりに、"-random-threshold"は、選択された各チャンネルで互いに完全に独立して動作します。
もちろん、演算子を直接使用すると、ランダムディザを使用した画像の2レベルポスタリゼーションになります。

  magick logo.png  -random-threshold  0x100%  random_posterize.gif
[IM Output]
グレースケールに変換すると、ディザリングされる前に画像内のすべてのチャンネルが均等化されます。ただし、各チャンネルは互いに独立してランダムにディザリングされるため、結果は期待されるようなビットマップ画像にはなりません。代わりに、特に中間色の場合は、色のピクセルの飛び散りが得られます。

  magick logo.png  -colorspace Gray -random-threshold  0x100% \
                                                   random_greyscale.gif
[IM Output]
以下に、適切なランダムディザリングされたビットマップ画像を生成する正しい方法を示します。

  magick logo.png  -colorspace Gray -channel B \
          -random-threshold 0x100%    -separate   random_monochome.gif
[IM Output]
基本的に、グレースケール化された画像の1つのチャンネルのみをディザリングし、"-separate"チャンネル演算子を使用して、そのチャンネルを最終的なビットマップ画像として抽出しました。トリッキーですが効果的です。
この演算子の特別な機能として、IMは、'All'の特別な"-channels"オプションが使用されている場合、ビットマップ画像が生成されるようにします。

  magick logo.png  -channel All -random-threshold 0x100% random_all.gif
[IM Output]
ただし、この方法を使用すると、アルファチャンネルは無視されて失われることに注意してください。そのため、通常はお勧めしません。私自身も、この古い機能を発見したのは、ソースコードから偶然発見したにすぎません。カラー画像からビットマップを正しく生成するために演算子を使用する方法がわかったので、ディザリングの範囲に引数がどのように影響するかを見てみましょう。これは、このディザリングによって生成されるピクセルの「クラスタリング」も明確に示しています。

  #magick -size 20x640  gradient: -rotate 90  gradient.png
  magick gradient.png  -channel All \
                        -random-threshold 0x100%  random_grad_0x100.gif
  magick gradient.png  -channel All \
                        -random-threshold 10x90%  random_grad_10x90.gif
  magick gradient.png  -channel All \
                        -random-threshold 25x75%  random_grad_25x75.gif
  magick gradient.png  -channel All \
                        -random-threshold 50x50%  random_grad_50x50.gif
[IM Output] [IM Output] [IM Output] [IM Output]
'0x100%'の"-random-threshold"設定は、画像の純粋な「ランダムディザ」を生成します。2つの境界が同じ値に設定されている(または互いを越えている)場合、純粋な"-threshold"画像が生成されるだけです。(通常はパーセントを使用して指定される)その他の境界セットを使用すると、指定された範囲外でビットマップが閾値処理され、指定された範囲内の値に対してランダムなディザパターンが生成されます。
"-monochrome"演算子を使用する場合と同様に、少し小さい範囲を使用すると、最良の結果が得られます。ほとんどの場合、約'30x80%'の値が最良の結果となるでしょう。

  magick logo.png  -channel All -random-threshold 30x80%  random_30x80.gif
[IM Output]
もちろん、結果はまだあまり良くありません。しかし、これは得られる最も単純で最悪の形式のディザリングです。実際に起こることは、ランダム化されたディザパターンが、滑らかなディザパターンではなく、ピクセルの「塊」を生成する傾向があるということです。これは、乱数ジェネレーターの高周波「ノイズ」が原因です。ただし、非常に高解像度では、ランダムディザは、十分にランダムであれば、非常に良い結果を生み出すことが示されています。IMは暗号化レベルのランダム性を使用しているため、非常にランダムである可能性が高いですが、画像は通常、この方法で役立つほど高い解像度で使用されることはめったにありません。提案されているこのディザリングの1つの「修正」は、ランダムな「ブルーノイズ」ジェネレーターを使用することです(サウンド制作で使用される低周波「ピンクノイズ」フィルターとは対照的に、高周波フィルター)。これにより、ピクセルのクラスタリングが削除されるはずですが、デジタル的に実装することは非常に困難です。「ブルーノイズランダム化ディザ」の既知の実装は見つかっておらず、作成される可能性は低いでしょう。

組織ディザリング

ランダムディザはピクセルのランダムな塊を生成し、さまざまな誤差補正ディザは本質的にランダムなドットパターンを生成しますが、組織ディザリングは基本的にその反対です。できる限り数学的に決定論的になるように設計されています。非常に決定論的であるため、画像をディザリングする際に使用するパターンを実際に指定する必要があります。"-ordered-dither"演算子は、画像内の選択された"-channels"を、事前定義されたパターンでディザリングします。引数は、使用するパターン(閾値マップとして知られている)を定義します。これらの閾値マップは、3つの基本スタイルに分類されます。拡散ピクセルディザ。ここでは、ピクセルが「塊」やタイルアーチファクトを回避するために、互いに可能な限り離れた場所に配置されます。または、デジタルハーフトーニングとして知られる手法で、機械的に印刷しやすくするために、タイトなドットにまとめてクラスタリングします。また、これから調べるいくつかの特殊な芸術的な閾値マップや、独自のディザリングパターンまたは閾値マップを設計することもできます。いずれの場合も、閾値マップでオンまたはオフになっているピクセルの数は、ビットマップにディザリングされている画像(または個々のカラーチャンネル)のグレーレベルの強度によって異なります。マップは、特定の「閾値」でピクセルがオンになると、より明るいグレーカラーではオンのままになるように、一貫した方法でピクセルの閾値レベルを追加します。この一貫性は非常に重要です。そうしないと、ディザパターンの変化の境界に沿ってアーチファクトが生成されます。これに関する重要な点は、画像内の各ピクセルの結果は、画像の他のピクセルとは完全に独立して数学的に決定されるということです。そのため、元の画像への小さな変更は、誤差補正ディザに見られたように、他の領域の画像にまったく影響を与えません。この点は、ビデオ画像のディザリングと最適化されたアニメーションの一貫性を保つために非常に重要です。

拡散ピクセルディザリング

組織ディザリングの本来の目的であり、ほとんどのグラフィックプログラマーが組織ディザリングを使用するときに期待しているものは、より正確には「拡散ピクセル組織ディザ」と呼ばれることもあります。これは、閾値強度が増加するにつれて、ピクセルがタイルマップに追加され、互いに可能な限り離れて均等に分散されることを意味します。これにより、ほとんどの最新のディスプレイで非常に滑らかでほとんど見えなくなる、非常に一貫したパターンが生成されます。このようなパターンは、2のべき乗、つまり2、4、および8のタイルサイズについて解決されています。ただし、IMは3 x 3の閾値マップタイルの合理的な閾値パターンも提供します。これは、IMが現在提供している組み込みの組織ディザの現在のセットです。引数は、組織ディザのタイルサイズを反映していることを忘れないでください。

  magick logo.png    -ordered-dither o2x2    logo_o2x2.gif
  magick logo.png    -ordered-dither o3x3    logo_o3x3.gif
  magick logo.png    -ordered-dither o4x4    logo_o4x4.gif
  magick logo.png    -ordered-dither o8x8    logo_o8x8.gif
[IM Output] [IM Output] [IM Output] [IM Output]
タイルサイズが大きくなると、より多くの「カラーレベル」をシミュレートできますが、特定のレベルでは、より目立つ欠陥またはピクセルの長方形配列も生成されることに注意してください。
'o8x8'組織ディザは、長い間IMコアコードの一部でしたが、使用されていませんでした。この演算子の使用の詳細をIM Examplesが開始したときに、IM v6.2.9の"-ordered-dither"演算子のオプションとしてのみ追加されました。

この時点で、"-ordered-dither"演算子のさらなる拡張を可能にするために、マップにはより決定的な名前が付けられましたが、古い下位互換性のある「タイルサイズ」の名前は新しい名前のエイリアスとして保持されました。

また、'o3x3'と'o4x4'を生成する「マップ」は、より優れた「拡散ピクセル」ディザパターンを生成するために完全に改訂されました。これ以前は、マップは明確なピクセルの「塊」を生成していました。

修正される前の古いパターンの例や、IM v6.3.0での公式リリースに向けての開発中に加えられたその他の変更については、組織ディザリングのアップグレードノートページを参照してください。
もちろん、画像のすべてのチャンネルの適切なビットマップを作成するには、まず画像をグレースケールに変換する必要があります。しかし、この処理はランダムではないため、-random-threshold" 演算子のように画像の後処理を行う必要がなく、大幅に簡略化されます。

  magick logo.png -colorspace Gray  -ordered-dither o2x2  logo_bw_o2x2.gif
  magick logo.png -colorspace Gray  -ordered-dither o3x3  logo_bw_o3x3.gif
  magick logo.png -colorspace Gray  -ordered-dither o4x4  logo_bw_o4x4.gif
  magick logo.png -colorspace Gray  -ordered-dither o8x8  logo_bw_o8x8.gif
[IM Output] [IM Output] [IM Output] [IM Output]
参考として、"-ordered-dither" の「拡散ピクセル」パターンをそれぞれグレースケールグラデーションに適用した結果を以下に示します。これにより、それらがどのように見えるかを明確に確認できます。

  # Threshold Non-Dither / Minimal Checkerboard Dither
  magick gradient.png   -ordered-dither threshold  od_threshold.gif
  magick gradient.png   -ordered-dither checks     od_checks.gif
  # Diffused Pixel Dither
  magick gradient.png   -ordered-dither o2x2       od_o2x2.gif
  magick gradient.png   -ordered-dither o3x3       od_o3x3.gif
  magick gradient.png   -ordered-dither o4x4       od_o4x4.gif
  magick gradient.png   -ordered-dither o8x8       od_o8x8.gif
[IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output]
特定の組織的ディザリングによって生成される実質的なまたは擬似的なレベルパターンの数は、通常(常にではありませんが)、パターン内のピクセル数に 1 を加えたものと等しくなります。したがって、'o3x3' の組織的ディザリングでは、結果の画像でチャンネルごとに 3×3+1 または 10 個の有効なグレーレベル(黒、白、および 8 個の人工グレーパターン)が生成されます。上記には、2 つの特別な最小ディザ閾値マップも示されています。
  1. 追加のグレーレベルを生成しないストレートな「50%閾値」非ディザと
  2. 結果のグラデーションに追加の「擬似レベル」を追加するために、単一のパターンのみを挿入する「チェック」または市松模様のディザパターン。

デジタルハーフトーンディザリング

"-ordered-dither" は、IM v6.2.8-6 で、デジタルハーフトーンディザパターンのセット(Glenn Randers-Pehrson氏に感謝)によって拡張されました。これらはすべて、単純な 45 度のドットパターンを生成するように設定されました。IM v6.3.0 では、同様の、より大きな角度のないハーフトーンのセットによってさらに拡張されました。
IM v6.3.0 のリリース前は、ハーフトーンスクリーンは '{number}x1' の形式の引数を使用して選択されていました。組織的ディザリングの再開発により、この制限は解除され、より適切な名前が選択され、追加のハーフトーンスクリーン(直交形式)が追加されました(以下の引数の例を参照)。
デジタルハーフトーニングは厳密には真のハーフトーンスクリーンではないことに注意してください。これは、紙、段ボール、または金属などの媒体に機械的に堆積される円形のインクドットを処理するように設計されています。このようなドットは、印刷プロセス中に重なり合ったり、にじんだりする可能性があるため、非線形レベル調整が必要になります。これは、純粋にデジタルハーフトーン効果を生成するためには必要ありません。プロセスの詳細については、ドキュメントディザリングとハーフトーニング(PDF)を参照してください。そうは言っても、組織的ディザリングのデジタルハーフトーンパターンは、新聞や安価な印刷雑誌で見られるものと同じ基本的な効果を提供します。

  # Halftone Screen (45 degree angle)
  magick logo.png   -ordered-dither h4x4a    logo_h4x4a.gif
  magick logo.png   -ordered-dither h6x6a    logo_h6x6a.gif
  magick logo.png   -ordered-dither h8x8a    logo_h8x8a.gif
  # Halftone Screen (orthogonal)
  magick logo.png   -ordered-dither h4x4o    logo_h4x4o.gif
  magick logo.png   -ordered-dither h6x6o    logo_h6x6o.gif
  magick logo.png   -ordered-dither h8x8o    logo_h8x8o.gif
[IM Output] [IM Output] [IM Output]       [IM Output] [IM Output] [IM Output]
画像の実ビットマップディザを生成するには、"-colorspace" 演算子を再び使用します。

  # Halftone Screen (45 degree angle)
  magick logo.png -colorspace Gray  -ordered-dither h4x4a logo_bw_h4x4a.gif
  magick logo.png -colorspace Gray  -ordered-dither h6x6a logo_bw_h6x6a.gif
  magick logo.png -colorspace Gray  -ordered-dither h8x8a logo_bw_h8x8a.gif
  # Halftone Screen (orthogonal)
  magick logo.png -colorspace Gray  -ordered-dither h4x4o logo_bw_h4x4o.gif
  magick logo.png -colorspace Gray  -ordered-dither h6x6o logo_bw_h6x6o.gif
  magick logo.png -colorspace Gray  -ordered-dither h8x8o logo_bw_h8x8o.gif
[IM Output] [IM Output] [IM Output]       [IM Output] [IM Output] [IM Output]
そして最後に、ハーフトーンディザパターンを明確に示す別のグラデーション参照画像と、グレーレベルが変化するにつれてディザパターン内のピクセルクラスターが互いに成長する方法を示します。

  # Halftone Screen (45 degree angle)
  magick gradient.png   -ordered-dither h4x4a      od_h4x4a.gif
  magick gradient.png   -ordered-dither h6x6a      od_h6x6a.gif
  magick gradient.png   -ordered-dither h8x8a      od_h8x8a.gif
  # Halftone Screen (orthogonal)
  magick gradient.png   -ordered-dither h4x4o      od_h4x4o.gif
  magick gradient.png   -ordered-dither h6x6o      od_h6x6o.gif
  magick gradient.png   -ordered-dither h8x8o      od_h8x8o.gif
  magick gradient.png   -ordered-dither h16x16o    od_h16x16o.gif
  # Circle Halftones (black and white)
  magick gradient.png   -ordered-dither c7x7b      od_c7x7b.gif
  magick gradient.png   -ordered-dither c7x7w      od_c7x7w.gif
[IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output]
ImageMagick バージョン 6.2.9 までは、上記の閾値組織的ディザリングマップはすべて IM で可能でした。これが現在変更され、ユーザーは独自のパターンを追加したり、IM コミュニティに投稿したりすることもできます。「円」ハーフトーン閾値は Glenn Randers-Pehrson 氏によって追加されました。IM v6.6.5-6。

オフセットハーフトーンディザリング

上記のハーフトーンディザリングに関する唯一の問題は、まったく同じ閾値マップ(タイル)が、同じ方法ですべてのカラーチャンネルに適用されるということです。つまり、同じセットの原色が同じ「中心」を持つドットで配置されるということです。「オフセット印刷」と呼ばれるものを得るには、色の小規模な「ロゼットパターン」を形成するように、特定の方法で閾値パターンを回転させます。これにより、発生する可能性のある、よりひどい干渉(モアレ)パターンが破壊されます。この図は、基本的にプロセスを説明しており、Wikipediaページ、ハーフトーンで詳細に説明されています。
[IM Output]
ただし、回転したスクリーンはあまり適切にタイル状にならないことに注意してください。そのため、最善のアイデアは、タイル閾値パターンを使用するのではなく、回転したパターンを直接生成することです。これは、小さい回転した 2x2 ピクセルの市松模様パターンを使用して、画像にオフセットハーフトーン印刷の外観を与える 1 つの方法です。これは、使用できる最小の「スクリーン」です。

  magick colorwheel.png  -set option:distort:viewport '%wx%h+0+0' \
          -colorspace CMYK -separate null: \
          \( -size 2x2 xc: \( +clone -negate \) \
                +append \( +clone -negate \) -append \) \
          -virtual-pixel tile -filter gaussian \
          \( +clone -distort SRT 60 \) +swap \
          \( +clone -distort SRT 30 \) +swap \
          \( +clone -distort SRT 45 \) +swap \
          \( +clone -distort SRT 0 \)  +swap +delete \
          -compose Overlay -layers composite \
          -set colorspace CMYK -combine -colorspace RGB \
          offset_colorwheel.png
[IM Output]
4 つの回転した「スクリーン」が画像全体に適用されることに注意してください。スクリーニングされた画像から 4 つの異なるカラーチャンネルを実際に抽出するのは、CMYK 色空間での "-combine" ステップのみです。また、最後の「黒」チャンネルの「no-op」歪みは、回転はされていないにもかかわらず、他のチャンネルが回転中に使用されたガウスフィルターに従って、入力市松模様パターンをぼかすため、重要です。ここでは、SRT 歪みの拡大縮小関数を使用して、回転したタイルを作成し、わずかに大きく、よりぼやけた「スクリーンパターン」を作成しています。

  magick parrots_med.png  -set option:distort:viewport '%wx%h+0+0' \
          -colorspace CMYK -separate null: \
          \( -size 2x2 xc: \( +clone -negate \) \
                +append \( +clone -negate \) -append \) \
          -virtual-pixel tile -filter gaussian \
          \( +clone -distort SRT 2,60 \) +swap \
          \( +clone -distort SRT 2,30 \) +swap \
          \( +clone -distort SRT 2,45 \) +swap \
          \( +clone -distort SRT 2,0  -blur 0x0.7 \) +swap +delete \
          -compose Overlay -layers composite \
          -set colorspace CMYK -combine -colorspace RGB \
          offset_parrots.png
[IM Output]
パターンは非常に「正方形」のまま、特に他のすべての派生元である黒いスクリーンは特にそうです。将来の可能性:上記の 2 ピクセル市松模様を「pattern:gray50」ピクセルレベルの市松模様パターンに置き換えます。ガウスフィルターオプションを使用して、拡大縮小されたパターンのぼかしを調整できます。または、パターンをぼやけさせて拡大縮小し、それを閾値処理して、より丸いドットを作成することもできます。次に、これを以前のように回転させて、4 つのカラースクリーンを作成できます。また、上記の市松模様パターンではなく、六角形のドットのパターンを使用した、より大きなスクリーンを使用する方が望ましいでしょう。
これは、実際のオフセット印刷のようなカラードットを実際に生成しているのではなく、カラースクリーンを元の画像に乗算するだけで偽装していることに注意することが重要です。緑の背景に対する赤いオウムの端に沿ったシャープな色の変化により、これが事実であることがわかります。純粋な色のドットのみを使用する実際のオフセット印刷では、ドットの色の中央に色の変化はありません。ソース画像のドットによって再表示される領域の色平均に応じて変化する必要があるのは、純粋なカラードットのサイズです。各カラーチャンネルの適切なサイズの円形ドットのみを含む、実際のオフセット印刷画像を実際に生成するには、さらに多くの作業が必要です。各カラーチャンネルの各ドットの平均色を決定し、そこから、適切なサイズのカラードット(アンチエイリアスされた円)を生成する必要があります。誰か試してみませんか?上記は、IM フォーラムの議論CMYK ハーフトーン効果での議論から来ており、photoshop がどのように「偽装」し、ImageMagick が同じ効果をどのように実現できるかを見ています。この議論は、適切なサイズの実際のドットを使用して真のハーフトーンスクリーンを生成することをより詳しく検討しているB/W ハーフトーンディザリングにも関連しています。ただし、その議論では、オフセット(回転)スクリーンを使用する次のステップには進みませんでした。このようなスクリーンでは、おそらく画像を回転させてドットを生成し、その特定のカラーチャンネルのドットパターンを再び回転させる必要があるでしょう。

XML閾値マップ

IM バージョン 6.3.0 以降では、以前に示された IM のソースコードに組み込まれた固定セットのマップを使用するのではなく、マップはプログラム自体とは別の XML データファイルのセットから読み込まれるようになりました。この変更の一部として、"-ordered-dither" 演算子が使用できる利用可能な「閾値マップ」を一覧表示できるようになりました。

  magick identify -list threshold
[IM Output]
上記の一覧には、使用可能な閾値マップだけでなく、下位互換性や代替命名のために提供されたエイリアス、および私の個人用の "thresholds.xml" XML データファイル(私のホームの ".magick" サブディレクトリに保存)で定義されたものも示されています。"-ordered-dither" がマップを探している場合、上記の一覧で最初に見つかったマップが使用されます。したがって、システム定義の閾値パターンをオーバーライドすることはできません。システムファイル "thresholds.xml"(そのパスは上記の "-list" オプションで指定)には、XML ファイルの形式の完全な概要が含まれています。これは、ユーザーが独自の組織的ディザリング閾値マップを定義および作成できるように、十分に単純な形式(IM によるエラーチェック付き)です。たとえば、以下に、個人用の "threshold.xml" ファイルで定義した 'diag5x5' 閾値マップのコピーを示します。
[IM Output]
これを見ると、閾値レベルが増加するにつれて太くなる単一の対角線の単純な 5x5 マップが作成されていることがわかります。マップ内のレベル番号は 0 から 5 までであり、カラーグラデーションを分割する必要のある「グレー」の数を示す除数より 1 つ少なくなっています。以下は、この個人用の閾値マップを使用してディザリングされたグラデーションです。

  magick gradient.png   -ordered-dither diag      od_diag.gif
[IM Output]
そして、これは単純な影付き画像のアルファチャネルをディザリングするために、その閾値を使用した例です。これは私がそれを設計した目的です。

  magick -size 70x60 xc:none -font Candice -pointsize 50 \
          -fill black -annotate +10+45 'A' -channel RGBA  -blur 0x5 \
          -fill white -stroke black -draw "text 5,40 'A'"   shadow.png

  magick shadow.png  -channel A  -ordered-dither diag   shadow_diag.gif
[IM Output] ==> [IM Output]
かなりクールでしょう!アルファチャネルのディザリングについては後ほど詳しく説明します。まず、拡張された "-ordered-dither" 演算子のカラーリング機能の使用方法も示す必要があります。

均一なカラーレベルを使用した組織的ディザリング

IM v6.3.0 のリリースにより、"-ordered-dither" で使用される閾値マップが外部ファイルから読み込まれるようになっただけでなく、数学的に定義された「ポスタライズ」カラーマップを使用できるように内部操作が強化されました。つまり、「誤差拡散ディザリング」で実現できるよりも、より決定的な画像のディザリングを生成できるということです。これは、フレーム間の色の違いによって問題が発生しないため、アニメーションを含む色の削減に特に重要です。ポスタライズレベルは、使用する閾値マップの名前に追加のコンマ区切りの数値リストを使用して、"-ordered-dither" 引数に渡されます。数値が指定されていない場合、演算子は通常の 2 色(またはポスタライズレベル 1)のカラーマップに戻ります。たとえば、「checks,6」という引数は、古典的なWeb セーフカラーマップ(ポスタライズレベル 6)カラーマップ(「netscape:」組み込みカラーマップ画像でも定義されています)を使用します。ただし、「checks」の最小限のディザマップが使用されているため、6 つのカラーレベルのそれぞれに追加のディザリングレベルが 1 つ追加され、画像の各チャネルで 11 の擬似レベルの色が作成されます。言い換えれば、チャネルあたり 6 つのレベルの色しか使用されていない(6^3 または 216 色を生成)にもかかわらず、レベル間の単一のディザパターンによって、ディザは実質的に 11 レベル(実質的に 11^3 または 1331 色を生成)に増加します。たとえば、以下は、6 つのグレーレベルとさまざまな閾値マップを使用してディザリングされたグレースケールグラデーションです。最初のマップ「threshold」は、使用される色のみを示す、特別な非ディザリングの順序付きディザ閾値マップです。

  magick gradient.png   -ordered-dither threshold,6  od_threshold_6.gif
  magick gradient.png   -ordered-dither checks,6     od_checks_6.gif
  magick gradient.png   -ordered-dither o2x2,6       od_o2x2_6.gif
  magick gradient.png   -ordered-dither o4x4,6       od_o4x4_6.gif
  magick gradient.png   -ordered-dither o8x8,6       od_o8x8_6.gif
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
ご覧のとおり、6 色しか使用されていませんが、順序付きディザリングを使用すると、グラデーションを定義するために使用される実効的な色数を増やすことができ、実際に使用された色がどれほど少ないか気づきにくいほどです。すべてのチャネルのポスタライズレベル数を定義できるだけでなく、"-posterize" 誤差拡散ディザリングオプションとは異なり、チャネルごとにレベルを指定できます。数値は、"-channels" 設定に従ってチャネルに割り当てられます。たとえば、ここでは、合計 256 色を定義する特別な 332 カラーマップ(赤と緑は 8 レベル、青は 4 レベル)を使用してグラデーションをディザリングしました。

  magick gradient.png   -ordered-dither o8x8,8,8,4   od_o8x8_884.gif
[IM Output]
チャネルごとのカラーレベル数が異なるため、上記の画像には純粋なグレー色だけでなく、追加のグレーレベルを生成するためにお互いを打ち消し合う、いくらか青みがかったピクセルと黄色がかったピクセルが含まれています。次に、ポスタライズレベルが 2 と 6 の場合、および「332 カラーマップ」(赤と緑は 8 レベル、青は 4 レベル)を使用して、O-ディザリングバージョンと誤差拡散ディザリングバージョンを比較します。

  magick logo.png  -ordered-dither o8x8        logo_o8x8_2.gif
  magick logo.png  -posterize 2                logo_posterize_2.gif
  magick logo.png  -ordered-dither o8x8,6      logo_o8x8_6.gif
  magick logo.png  -posterize 6                logo_posterize_6.gif
  magick logo.png  -ordered-dither o8x8,8,8,4  logo_o8x8_332.gif
  magick logo.png  -remap colormap_332.png     logo_remap_332.gif
[IM Output] [IM Output]     [IM Output] [IM Output]     [IM Output] [IM Output]
上記の各ペアの最初の画像は、数学的に順序付けられたディザリングが適用されており、2 番目の画像は擬似ランダムに「誤差拡散」ディザリングが適用されています。最後のペアは、特別な「332 カラーマップ」(カラーマップの生成を参照)を使用しており、これは 256 色の制限がある一般的な画像に最適なポスタライズカラーマップであると考えられています。チャネルレベルの奇妙な違いは、この漫画のような画像の色合いをわずかに向上させています。"-ordered-dither" 演算子に、各カラーチャネルに個別のレベルを指定する機能を含めたのは、この「332 カラーマップ」の生成を可能にするためでした。

より良い組織的ディザリング結果

先ほど生成したレベル 6 のO-ディザリングを詳しく見てみましょう。

  magick logo.png -ordered-dither o8x8,6 -format %k info:
[IM Text]
この画像では、GIF カラーテーブル(256 の制限)を埋めるところまでには至っていないことがわかります。基本的に、画像は主に青色で構成されているため、レベル 6 の均一なカラーマップの赤色または緑色の色合いはほとんど使用されていません。ただし、ポスタライズレベル数を増やすことで、GIF カラーテーブルをより適切に埋めることができるため、より優れたO-ディザリング画像を生成できます。

  magick logo.png -ordered-dither o8x8,13 -format %k info:
[IM Text]
これにより、GIF カラーテーブルの制限よりもわずかに小さい程度の十分な色が生成されます。色数の増加により、結果は単純な標準的な均一カラーマップの結果よりもはるかに見栄えがよくなります。

  magick logo.png -ordered-dither o8x8,13    logo_o8x8_13.gif
[IM Output]
ご覧のとおり、「レベル」値が高い場合、"-ordered-dither" は、カラー量子化によって生成された特定の色選択に対して、カラー量子化に匹敵する画像を生成できます。これらの画像に関する主な点は、それらが高品質であるということではありません。結局のところ、完全なカラー量子化の方が、画像に適したカラーマップをより簡単に生成できます。しかし、これらの画像内の低レベルディザパターンは、発生する可能性のある小さな変更に関係なく固定されているということです。順序付きディザリング画像で変更されるのは、領域の変更のみです。つまり、GIF アニメーションでのフレーム最適化で問題を引き起こす変化に対するE-ディザリング感度がありません。(最適化の問題を参照)もちろん、アニメーションの場合は、実際に使用されている色数を確認する前に、すべての画像を "-append" で結合する必要があります。また、色削減とディザリングを既に実行している場合でも、IM にすべて画像用の「共通グローバルカラーマップ」を強制的に生成させるには、"-ordered-dither" を使用した後に特別な "+remap" オプションを使用する必要があります。この色レベル数を決定する方法は単純ではありませんが、機能します。特に GIF アニメーションの場合に、IM が最適なレベルを自動的に決定する方法を開発したいと思っています。

DIY ディザパターンと閾値マップ

以前に、新しい "-ordered-dither" 演算子が、ユーザー定義のディザリングパターンを受け入れることができることを示しました。ここでは、水平線で構成される影を生成するのに役立つ、特別なパターンを作成する方法を紹介します。

マルチイメージディザパターン

まず最初に、作成したいパターンを定義する一連の画像を作成する必要があります。パターンは、最初の画像として適切なサイズの完全に黒い画像(すべてのピクセルがオフ)、反対端に完全に白い画像(すべてのピクセルがオン)で始める必要があります。次の画像は、達成しようとしているディザリングの基本スタイルを定義する、中間の 50% グレーのパターンである必要があります。たとえば、以下は私の最初の DIY ディザパターンです。これをマルチイメージ GIF ファイル(GIF アニメーションではない)に保存します...

  magick -size 2x2 xc:black \
          \( +clone -draw 'fill white line 0,0 1,0' \) \
          xc:white     dpat_hlines2x2.gif
  montage dpat_hlines2x2.gif    -tile x1 -background none -frame 2 \
          -filter box  -geometry 32x32+5+0    dpat_hlines2x2_imgs.gif
[IM Output]
これは、入手可能な最も単純なディザパターン画像のセットであり、「checks」または「チェッカーボードディザ」に非常に似ていますが、チェッカーパターンではなく、水平線を使用します。このディザパターンがどのように見えるかを確認できるように、以下に、閾値ディザリングイメージセットを直接使用する、かなり単純な DIY 順序付きディザを示します。

  magick gradient.png   dpat_hlines2x2.gif \
          -virtual-pixel tile  -fx 'u[(floor((n-1)*u)+1) % n]' dgrad_hlines2x2.gif
[IM Output]
ご覧のとおり、ディザパターンは特に凝ったものではありません。"-fx" 関数は、カラー参照テーブル関数の変形であり、具体的には、IM ディザ参照パターンのタイプの関数です。"-virtual-pixel" を 'tile' に設定すると、関数は使用しているディザパターン画像のサイズを知る必要さえありません。
計算されたインデックスを使用した "-fx" 演算子による "-virtual-pixel" の使用は、IM バージョン 6.2.9-2 より前は壊れていました。
このディザパターンセットをもう一度試してみましょう。ただし、単純な影付きの画像を使用します...

  magick shadow.png dpat_hlines2x2.gif  -channel A \
          -virtual-pixel tile  -fx 'u[floor((n-1)*u)+1].g' \
          shadow_dpat_hlines2x2.gif
[IM Output] ==> [IM Output]

DIY組織的ディザリング閾値マップ

上記の DIY ディザパターンは、入手できる最も単純なディザパターンであり、そのため、高速な組み込み "-ordered-dither" 演算子で使用できるように、XML 閾値マップに直接魔術的に変換することができます。以下は、最終的な XML 定義です。これは、自分の個人用閾値マップファイル「~/.magick/thresholds.xml」(「$HOME」ディレクトリ内)に保存しました。
[IM Output]
XML 形式は非常に単純で、2x2 ピクセルのマップを定義します。最初の黒い画像はゼロの値が与えられ、ピクセルがないため、ゼロの値は存在しません。中間の画像でオンになった(白くなった)ピクセルは「1」に設定され、残りのピクセル、つまり 2 番目の画像のピクセルには「2」の値が与えられます。「divisor=」は、このディザパターンが表す画像の数、つまり擬似カラーレベル(偽のカラーレベル)を定義するため、「3」の値を持っています。ピクセル値を分割して、そのピクセルがオンになるカラーレベルを定義します。このように、上の 2 つのピクセルは 1/3 より大きい色でオンになり、下の 2 つのピクセルは 2/3 より大きい色の値でオンになります。つまり、各ピクセル値は「閾値」レベルを表しており、ディザパターンが閾値マップとも呼ばれる理由です。定義の残りの部分では、順序付きディザ演算子の閾値マップを参照できる名前(およびオプションのエイリアス)を定義します。試してみましょう...

  magick gradient.png  -ordered-dither hlines2x2  od_hlines2x2.gif
  magick shadow.png  -channel A \
          -ordered-dither hlines2x2   shadow_hlines2x2.gif
[IM Output]
[IM Output] ==> [IM Output]
ご覧のとおり、結果はかなり良好ですが、結果を改善するために他のことを行うことができます。マップ内の閾値を調整することで、境界を変更して、カラースペースを 3 つの等しい領域に分割しないようにすることができます...
[IM Output]
除数を「10」に増やし、カラーレベルを 10 等分したことに注目してください。次に、閾値設定を変更して、パターンが透明側(黒)の 30% の閾値から開始し、完全に不透明(白)の場合は 90% になるようにしました。以下は、閾値マップを変更した結果です。

  magick gradient.png  -ordered-dither hlines2x2a  od_hlines2x2a.gif
  magick shadow.png -channel A \
          -ordered-dither hlines2x2a  shadow_hlines2x2a.gif
ご覧のとおり、これにより、純粋な水平線をディザパターンとして使用する半透明ピクセルの範囲が広がりました。これにより、影の効果が向上しますが、ここで使用した例よりもぼやけの少ない影でのみ使用する必要がある可能性があります。ただし、このような閾値の変更は非常にまれであることに注意してください。ただし、このケースで意図された使用には正当性があります。基本的に、グラデーションを適切に定義せず、パターンを明るくしたり暗くしたりすることができません。そのためには、より多くのピクセルとより多くのパターンを含む、はるかに複雑な閾値マップを作成する必要があります。

DIY水平線ディザリング

ここで、上で作成した単純な水平線ディザパターンをパターンセットに拡張して、「オフ」から「オン」へのスムーズなグラデーションを生成します。これが結果でした。

  montage dpat_hlines.gif   -filter box   -geometry 60x20+2+0 \
          -tile x1 -background none  -frame 2   dpat_hlines_images.gif
  magick gradient.png  dpat_hlines.gif  \
          -virtual-pixel tile  -fx 'u[(floor((n-1)*u)+1) % n]' \
          dgrad_dpat_hlines.gif
  magick shadow.png dpat_hlines.gif  -channel A \
          -virtual-pixel tile  -fx 'u[floor((n-1)*u)+1].g' \
          shadow_dpat_hlines.gif
[IM Output]
[IM Output]
[IM Output] ==> [IM Output]
ご覧のとおり、9 つの 12x4 ピクセルの画像で構成されています。使用可能なすべてのピクセルパターンを表しているわけではありませんが、これにより線の効果が強化されます。また、線のギャップを適切にジッタリングするために、高さを 2 倍にしました。このディザパターンを使用した別の例を次に示します...

  magick -size 120x55 xc:white  -draw 'fill #777 ellipse 50,43 30,5 0,360' \
          -motion-blur 0x15+180   -blur 0x2      sphere_shadow.png
  magick sphere_shadow.png dpat_hlines.gif \
          -virtual-pixel tile  -fx 'u[(floor((n-1)*u)+1) % n]' \
          sphere_shadow_dither.gif
  magick sphere_shadow_dither.gif   -fill red  -stroke firebrick \
          -draw 'circle 35,25 35,5'     sphere_shadow_hlines.gif
[IM Output] ==> [IM Output] ==> [IM Output]
次のステップでは、このディザパターンセットを、複数の画像ではなく、単一の閾値マップ画像に変換します。これは、すべての画像を結合するために、いくつかの高度な画像操作を使用することで実現されます。
[IM Output]
[IM Output]

  magick -size 1x10 gradient: -flip -crop 1x1 +repage -delete 0,-1 \
          -scale 12x4\! null: \( dpat_hlines.gif -delete 0 \) \
          -alpha off -compose CopyOpacity -layers Composite \
          -reverse -compose Over -flatten -alpha off dmap_hlines.png
[IM Output]
値「10」は、ディザパターン内の画像の数に1を加えたもので、「-scale 12x4\!」は、閾値マップに変換されるディザパターンのサイズです。結果は、純粋な黒または白の色を含まないグレースケールマップです。ピクセルに使用されるグレーレベルは、色のレベルがそのグレー値以上の場合、そのピクセルがオンになる必要があることを意味します。つまり、各グレーレベルは、色の値が黒から白に変わる「閾値」レベルです。別の見方をすると、暗いピクセルは一般的に、より多くの色レベルでそれらのピクセルがオンになります。一方、明るいピクセルは、画像の色が非常に明るくなった場合にのみオンになります。これは、画像が実際にどのように見えるかのほぼ否定ですが、考えてみれば意味があります。また、マップにはGIF画像ではなくPNG画像を使用しました。これは、保存する必要がある画像が1つだけであること、そして最も重要なこととして、閾値の16ビット品質レベルを維持しようとするためです。GIFは8ビットの色レベルしか処理できません。これで、単一の画像と、ディザリング閾値画像(またはマップ)に対する各ピクセルの直接比較という、より単純な閾値比較を使用して、画像をディザリングできます。

  magick gradient.png dmap_hlines.png \
          -virtual-pixel tile  -fx 'u>=v'   dgrad_dmap_hlines.gif
[IM Output] ==> [IM Output]
閾値マップがいかに単純であるかをご覧ください。ディザリングされるチャネルごとに、1つの画像と、ピクセルごとに1つの直接比較を行うだけで済みます。これにより、閾値マップを使用したディザリングは非常に高速になります。フルカラー量子化よりもはるかに高速です。この単純さが、ImageMagickとほとんどのグラフィックソフトウェアが、さまざまなディザパターンを保持するために閾値マップを使用する理由です。
より大きいか等しい('>=')テストは、IMバージョン6.2.9-2まで「-fx」演算子に追加されませんでした。これが問題になる場合は、上記の反転テスト「v<u」を使用してください。
ただし、ユーザーが複数のカラーレベルを使用してディザリングしたい場合、この単純さははるかに複雑になります。この概念実証は、IMコア機能に組み込まれる前に、ポスタライズドオーダードディザのページの例で最初に検討されました。統合された閾値画像が得られたので、次に上記の画像を、IMが直接読み取り、「-ordered-dither」演算子が使用できるXML閾値マップに変換する必要があります。これを行うには、画像が表す9つのグレーレベルを表す数値として画像を出力する必要があります。これは、「NetPbm」画像処理ソフトウェアを使用した深度調整とともに、NetPBMまたはPBMplus画像形式を使用するのが最適です。このパッケージは一般的に標準的なLinuxインストールであるため、ほとんどのユーザーはすでに持っているか、通常のソフトウェア配布からインストールできます。「pnmdepth」の数値は、閾値画像に含まれるグレーレベルの数です。

  magick dmap_hlines.png pgm:- | pnmdepth 9 | pnmnoraw > dmap_hlines.pgm
[IM Text]
上記の数値(「P2」画像マジック識別子以外)は、個人の「thresholds.xml」ファイルに追加できる適切な「閾値マップ」を生成するために必要な数値です。たとえば、上記から作成された結果の閾値マップエントリを次に示します。
[IM Output]
そして、この閾値マップの使用例を次に示します。

  magick shadow.png  -channel A  -ordered-dither hlines   shadow_hlines.gif
[IM Output] ==> [IM Output]
以上が、画像の進行状況から複雑な閾値マップを生成する方法です。

シンボルパターンを使用したディザリング

これで、ほとんどのディザリング操作で、マルチイメージパターンセットの代わりに、単一の閾値マップまたは閾値画像を使用できますが、マルチイメージマップに独自の用途がないという意味ではありません。一度に1つずつではなく、複数の領域を一度にタイル表示するために、ルックアップ画像のセットを使用できます。たとえば、単純な画像を拡大縮小し、画像の各ピクセルを特定のシンボルに置き換えることができます。たとえば、非常に小さい「目」の画像[IM Output]を取り、元の画像の各ピクセルに対してそのようなパターンを生成するために、個々のピクセルをさまざまなシンボルに置き換えます。

  montage dpat_symbols.gif   -geometry +5+0 \
          -tile x1 -background none -mattecolor blue  -frame 3 \
          dpat_syms_images.gif
  magick eyes.gif -alpha off -colorspace sRGB -grayscale Average \
          -alpha off -scale 1600% -negate  \
          dpat_symbols.gif -virtual-pixel tile -fx 'u[floor(15.9999*u)+1]' \
          eyes_syms.gif
[IM Output]
[IM Output]
モンタージュは、マルチイメージGIF画像を「アニメーション化」せずにコンテンツを見ることができるように展開するために使用されます。通常の「Rec709Luminance」から暗い「Rec709Luma」まで、または非線形の「sRGB」カラースペースまたは線形の「RGB」カラースペースの「average」を使用するなど、使用したい「-grayscale」強度メソッドを調整できます。値の「-gamma」スケーリングを調整して、最適な色の広がりを得ることもできます。可能性はたくさんあり、何が良いかは、選択した実際の方法よりもシンボルの配置に大きく依存します。上記で重要なのは、入力画像の各色が固有のシンボルを生成することを何らかの方法で保証することであり、これは達成するのが非常に難しい場合があります。この例は、趣味の人が従うことができるクロスステッチまたは編み物のガイドを作成したり、小さなコンピュータ画像から大規模なアートワークを生成したりするために使用できます。この手法を使用して、グレースケール画像をタイル状のカラー画像のセットでタイル表示できます。結果は、多くの古いコンピュータ戦争ゲームで見られる風景マップに少し似ています。

  montage dpat_map.gif   -geometry +5+0 -tile x1  -background none  \
          dpat_map_images.gif
  magick -seed 100 \
          -size 200x200 plasma:'gray(50%)-gray(50%)' -blur 0x15 \
          -channel G -auto-level +channel -set colorspace sRGB \
          dpat_map.gif -virtual-pixel tile  -fx 'u[floor(5.999*u.g)+1]' \
          map.gif
[IM Output]
[IM Output]
IMが、グレースケール画像を(タイル画像と同様に)すでに最終的なsRGBカラースペースにあるものとして認識するようにする必要があったことに注意してください(実際にはFXインデックルックアップに使用されている線形RGBデータであるにもかかわらず)。これがないと、結果の「マップ」は水域の可能性がほとんどなく、樹木が茂った風景に偏ってしまいます。ご覧のとおり、任意の画像のセットをタイルに使用できます。画像は互いに整列する必要も、同じサイズのタイルである必要もありません。もちろん、タイルが同じサイズで、3つの青い「海」タイルのように互いに密接に関連している場合、タイル状のパターンは、あるタイル状の領域から別のタイル状の領域に「流れる」ことができます。タイルを数字の画像に置き換えることで、ナンバーガイドによるペイントのようなものも生成できます。ただし、さまざまな領域を区切るには、追加の処理が必要になる場合があります。これは練習問題として残しておきます。解決策をメールで送信してください。この手法の作成者として、IMの例にあなたの名前が載るでしょう。

オーダードディザリングのランダムなメモと将来の可能性

建設中

色の数が少ない場合のオーダードディザリング。

小さな画像に少数の色を使用する場合、IMのヒルベルト曲線誤差補正ディザのような疑似ランダムディザリングや、より単純なフロイド-スタインバーグ誤差補正ディザリング(上記の誤差補正ディザリングを参照)でさえ、ひどい結果になります。理想的には、オーダードディザリングを、ローカラーで小さなアイコンのような画像で使用して、はるかに見栄えの良い結果を生成する必要があります。ただし、現時点では、IMのオーダードディザリングは、「最適な」色のコレクションではなく、「固定」された数学的に生成されたカラーテーブルでのみ使用できます。

任意の色のマップでのオーダードディザリング

オーダードディザリングに特定の色セットを使用できるようにするアルゴリズムがいくつかあります。基本的に、オーダードディザリングアルゴリズムが生成できる「疑似色」(3色ディザリングを含む可能性がある)を、指定されたカラーマップに追加して、「埋める」ことで実現できます。その後、画像の個々のピクセルをこの「拡張カラーマップ」に「マップ」できます。その特定の疑似色への初期マッピングから、その疑似色を生成する閾値マップから実際のカラーを選択できるため、その色の領域をオーダードディザリングし、したがって、画像全体を特定の色セットにオーダードディザリングできます。アイコン、そして現在はGIFアニメーションの私のバックグラウンドから、私は間違いなく任意の色オーダードディザリングの実装を見たいと思っていますが、固定された色のセットでオーダードディザリングを行う方法に関する実用的な参考文献をまだ見つけていません。