ImageMagick の例 --
マスク

目次
ImageMagick の例の序文と目次
アルファ(マット)チャネル
画像でマスクを使用する
特殊画像マスク
領域と領域サブ画像
背景の削除
穴埋め (作成中)
これらの例では、透明度の特別な処理、透明度チャネル、マスクの使用、そして最終的には不要な背景や看板、テキスト、スパムなどの要素の削除について見ていきます。

アルファチャネル

画像の透明度(アルファ)チャネルは完全にオプションであり、多くの場合、通常の「カラー」チャネルとは別に特別な処理が必要です。上記の画像の色空間を参照してください。透明度チャネルが存在すると、さまざまな演算子が他のカラーチャネルを処理する方法にも影響を与える可能性があります。これは一般的に、完全に透明な色は演算子によって完全に無視されるべきであるためです。そうでない場合、IM v6 の初期に見られたような、画像の周りに「黒いハロー」が発生します。たとえば、リサイズハローバグ透明度のあるぼかしバグなどです。さらに悪いことに、このチャネルは、画像の「透明度」または「不透明度」チャネル、さらには画像の「マスク」と呼ばれることもあります。ただし、これらはすべて同じ特別な画像の4番目のチャネルを指します。[IM Output]違いを説明するために、作業例となる画像が必要です。ここでは、「三日月」画像のPNG画像(不透明度のコピー合成の例から)を使用します。ご覧のとおり、この画像には完全に透明な領域がたくさんあります。それだけでなく、透明色と半透明色を正しく理解し、処理できる少数の画像形式の1つである「PNG」画像形式を使用して画像を保存する必要がありました。
アルファ合成を使用して、画像をIM組み込みのチェッカーボードパターンに重ねることで、この透明度を示すことができます。

    magick composite -compose Dst_Over -tile pattern:checkerboard \
              moon.png  moon_background.jpg
[IM Output]

内部アルファチャネル

IM v7 は内部的に透明度情報を「アルファ」チャネルに格納します。これはカラーチャネルと同様に、完全に透明(またはクリア)な白から完全に不透明な黒までの値を持つプレーングレースケール画像です。元の画像のシルエットを見るとどうなるかのようなものです。 "-level" や "-threshold" などの低レベル演算子は、データをアルファとして処理します。不明な場合は、公式オプションリファレンスを確認してください。
作成日:2003年12月10日(元々は「チャネル」)
更新日:2018年10月2日
作成者:Anthony Thyssen、<Anthony.Thyssen@gmail.com>
生成された例:[バージョン画像]
URL:https://imagemagick.dokyumento.jp/Usage/masking/
これは、画像から「アルファ」透明度の値を抽出する非常に古い方法です。透明度チャネルを「アルファ」画像ファイル形式として保存し、正しい画像ファイル形式を定義するために2つの別々の手順とコマンドが必要でした。


magick moon.png alpha:moon.matte
magick MIFF:moon.alpha moon_matte2.png # You can join those two steps in a pipeline as well... magick moon.png alpha:- | magick - moon_matte3.png
[IM Output]
画像の「アルファ」を抽出するこの手法は、IM v5 が使用されていた頃は一般的でした。基本的には、画像の透明性にアクセスするために提供された唯一の方法でした。現在ではほとんど使用されていません。

画像の透明度の制御

メモリ内の画像の透明度チャネルを低レベルで制御できる演算子が2つあります。新しい演算子 "-alpha" メソッドが推奨される制御方法になりましたが、多くの IM の例では、古い "-alpha" 演算子が引き続き表示および使用されています。画像はアルファチャネルデータを持つだけでなく、チャネルデータが表示可能か有効かを定義する「スイッチ」も持っています。これは、画像はアルファチャネルに関して3つの状態を持つことができることを意味します。
スイッチ    チャネルデータ
 alpha off  アルファデータなし(メモリが割り当てられていません)
 alpha off  古いアルファデータが存在する(ただし使用されていない)
 alpha on  現在使用中のアルファデータ
これは、さまざまなメソッドの動作が上記の3つの状態のどれであったかによって異なるため、覚えておく必要があります。「スイッチ」がオフの場合、演算子はアルファデータに触れません。実際にはアルファデータがまったく存在しない可能性があるためです。そのような場合、古いアルファは変更されずに、したがって古くなったまま存在する可能性があります。ご覧のとおり、これは実際には状況によっては役立ちます。ただし、一部の演算子は、何らかの理由でアルファスイッチを自動的にオンまたはオフにする場合があることに注意してください。たとえば、 "-compose CopyOpacity -composite" は、結果の画像のアルファチャネルを常にオンにします。これは、データアルファチャネルにコピーするのが演算子のジョブだからです。そのため、最終結果に存在する必要があります。ただし、入力データに存在すると、他の結果が生じる可能性があります。詳細については、Copy_Opacity 合成メソッドを参照してください。同様に、「None」色を使用してキャンバスを作成すると、透明度チャネルが自動的に作成されて有効になり、空白の画像が本当に透明になるようにします。一方、他の色名を使用してキャンバスを作成すると、画像はデフォルトで不透明であるため、一般的に透明度チャネルは作成されません。
さまざまな "-alpha" メソッドと、それらが画像とその透明度にどのように影響するかを示す例を以下に示します。

アルファオフまたは"-alpha off"

これは画像の単純なスイッチであり、透明度が画像に与える影響をオフにします。画像に添付されているアルファチャネルを実際に削除または破棄するわけではなく、そのチャネルが画像に与える影響をオフにするだけです。同様に、透明チャネルがオフになっている間は、演算子は添付されているアルファチャネルに影響を与えません。たとえば、「三日月」画像(不透明度のコピー合成の例から)を使用し、画像のアルファチャネルをオフにします。

  magick moon.png  -alpha off     alpha_off.png
[IM Output] ==> [IM Output]
透明度がオフになったときに月の形が完全に消えたことに注意してください。ただし、これは実際にはまれなケースです。基本的には、「透明」領域にも色が付いていますが、通常は見えません。この場合、隠された色は、月の画像を作成するために使用されたフラクタルキャンバス画像でした。この隠された色は、上記のGIF形式がカラーテーブルで透明度を表すために使用する単純なGIF透明色から、画像の作成中に残されたゴミの色まで、何でもかまいません。より一般的には、透明色は、完全に透明だったピクセルでは単に純粋な黒です。エッジに近いピクセルは半透明である可能性があり、したがって部分的にしか見えない有効な色を持っている可能性があります。上記の "-alpha Off" 操作は、単にチャネルを「非アクティブ化」または「オフ」にするだけです。透明度データ自体は、メモリに保存されている画像データからクリアまたは削除されていません。まだ存在しますが、今のところ利用できません。ただし...透明度データがオフになっている間に画像が保存されると、透明度データは画像ファイル形式に保存されません。そのため、オフになったアルファデータは、メモリ内バージョンに存在(オフになっているだけ)していても、保存された画像のコピーには存在しません。また、多くのファイル形式(JPEGなど)は透明度を許可しないため、これらのファイル形式は画像の保存時に自動的に "-alpha Off" と同等の処理を行います(実際にはそうではありません)。一般に、これはJPEG画像として保存すると、すべての透明領域が通常は黒に変わることを意味します。JPEGファイル形式で保存する前に透明度を削除する正しい方法については、以下のアルファ削除-透明度の削除を参照してください。 "+alpha" 演算子は、 "-alpha Off" とまったく同じ古いコマンドです。つまり、透明度チャネルをオフにするだけです。アルファをオフにすることは、CopyOpacity アルファ合成メソッドでグレースケールマスク画像を使用する前に、多くの場合必要です。これを行わないと、合成演算子は、意図したグレースケール色を使用するのではなく、有効になっている透明度(不透明度チャネル)をコピーします。

アルファセットまたは"-alpha set"

'Set' アルファメソッドは、以前の "-alpha on" オプションと同じです。これは、画像に「透明度」またはアルファチャンネルがあることを保証しますが、存在しないかオフになっている場合は、完全に不透明になるように初期化されます(以下のアルファ不透明メソッドを参照)。ただし、画像に既にアルファチャンネルが存在し、有効になっている場合は、何も実行されません。つまり、この演算子は、メモリ内の画像の外観を変更せずに、アルファチャンネルが存在することを保証します。そのため、この演算子だけでは画像に変化は見られませんが、他の演算子と組み合わせると実際的な効果があります。アルファオフを使用してアルファチャンネルをオフにし、アルファセットを使用して再び有効にすると、画像はアルファチャンネルを持ちますが、'Set'操作が要求されたときと同じように完全に不透明になります。

  magick moon.png  -alpha off    -alpha set    alpha_set.png
[IM Output]
有効なアルファチャンネルを持つ画像に適用した場合、変更は行われません。

  magick moon.png  -alpha set    alpha_noset.png
[IM Output]
要約すると、この演算子は、演算子が適用された時点で画像の外観を変更するべきではありません。アルファチャンネルが、画像が*そのまま*になるように設定されていることを確認するだけです。これは通常、アルファチャンネルが存在する場合としない場合がある、不明な画像ファイル形式または入力ソースから画像を読み込んだ後に使用されます。この演算子は、画像にアルファチャンネルがあることを保証しますが(JPEGなどの画像形式の場合)、有効で既存のアルファチャンネルはそのままにします(GIFまたはPNG形式など)。これは、画像をメモリに読み込んだ後、またはより重要なことに、画像が処理された後にクリーンなアルファチャンネルを再び有効にしたい場合に、画像にアルファチャンネルがあることを保証するための推奨される方法です。

アルファオン

"-alpha On" は、前述のアルファオフメソッドの正反対です。通常、これは目的とする用途には*単純すぎる*ため、非常にまれにしか使用しないでください。ほとんどの場合、"-alpha Set" を使用する必要があります。基本的に、'On'メソッドは、画像の透明度データが再び見えるようにスイッチを切り替えるだけです。既存の透明度データは変更されないため、メモリ内の画像に古いアルファチャンネルデータがまだ存在する場合、そのデータが突然再び表示されます。たとえば、ここでは、透明度データを'Off'にしてからすぐに'On'に戻し、元の画像を再現します。

  magick moon.png  -alpha off  -alpha on    alpha_on.png
[IM Output]
ただし、画像に以前のアルファデータが(まだ)ない場合は、完全に不透明になるように初期化されます。これは論理的なことです。そのため、メモリに読み込まれたばかりの新しい画像の場合、アルファセットと同等ですが、この目的には使用しないでください。アルファオンを使用する必要があるのは、何らかの理由で*意図的にアルファをオフにした*場合のみで、そのデータを復元する場合です。たとえば、アルファチャンネルをオフにしてからオンにすると、"-shade"など、非常に特殊な演算子を適用する前にアルファチャンネルデータを保持するために使用できます。この特別な使用例については、シェード形状画像を参照してください。

アルファのアクティブ化/非アクティブ化

それぞれ、永続的にアルファチャンネルを有効および無効にします。これは、Imagemagick 6のオン/オフのようなものです。Imagemagick 7では、-alpha offはアルファチャンネルを完全に削除するため、-alpha onで再び有効にすることはできません。

アルファ個別

アルファチャンネルを独立して処理します(ブレンドしないでください)。

アルファ不透明

このメソッドは、アルファチャンネルが「アクティブ」であることを保証するだけでなく、画像に透明度が「アクティブ/オン」または「非アクティブ/オフ」のどちらであるかに関係なく、完全に不透明であることも保証します。例えば...


  magick moon.png  -alpha opaque    alpha_opaque.png
[IM Output]
古いバージョンのIMでは、これはアルファチャンネルをオフにするために"-alpha off"を使用し、次に不透明にリセットしながらオンにするために"-alpha on"を使用することと同等でした。

  magick moon.png  -alpha off -alpha on  alpha_opaque_matte.png
[IM Output]
元のアルファチャンネルデータが上書きされているため、この操作の後、画像の元の「形状」を復元することはできません。もちろん、それは "-alpha off -alpha set" を使用することと同等ですが、その場合は "-alpha opaque" を使用することもできます。

アルファ透明

同様に、これはアルファチャンネルが「アクティブ」であることを保証しますが、完全に透明でもあります。

  magick moon.png  -alpha transparent    alpha_transparent.png
[IM Output]
画像のカラーデータはまだ存在するため、後で透明度をオフにすると、画像の既存のカラーが再び表示されます。

  magick moon.png  -alpha transparent  -alpha off  alpha_transparent_off.png
[IM Output]
もちろん、画像の元の「形状」は実際に破棄されたため、この操作の後では復元できません。画像を完全に透明にする他の方法は、透明なキャンバスに示されています。

アルファ抽出

'Extract'メソッドは、画像の「アルファ」マスクをグレースケールチャンネルマスクとしてコピーするだけです。

  magick moon.png  -alpha extract    alpha_extract.png
[IM Output] ==> [IM Output]
完全に不透明は白で、完全に透明は純粋な黒であることに注意してください。画像には、エッジに沿って半透明のピクセルがいくつか含まれているため(アンチエイリアシングにより、画像の形状が滑らかに見えるようになっています)、この画像は純粋な白黒ではなく、エッジの周りに灰色のピクセルも含まれています。ImageMagickが古いIMv7バージョンである場合、これはチャンネル抽出を使用した(ほぼ)同等のテクニックです。

  magick moon.png  -channel a -separate +channel -negate alpha_extract.png
'Extract'メソッドは、アルファを'Off' にしますが、クリアされないため、アルファチャンネルを'On'に戻すと、元の画像の形状マスクが再作成されます。

  magick moon.png  -alpha extract -alpha on   alpha_extract_on.png
[IM Output]
元のすべての色が白に置き換えられ、エッジの周りにさまざまな濃淡の灰色が表示されることに注意してください。白い背景で透明度を削除すると、これがわかります(以下のアルファ削除メソッドを参照)。

  magick alpha_extract_on.png -background white -alpha remove alpha_edge.png
[IM Output]
これらの「灰色」のピクセルは、実際にはアンチエイリアス形状からのエッジアウトラインで、画像形状から滑らかなエッジまたはアウトラインを生成するために効果的に使用されます。アルファチャンネルを保存することのこの副作用は、画像のアルファチャンネルを理解または使用しないシェード演算子を使用する場合に特に利点があります。サブセクションマスクされたシェード形状を参照してください。

アルファコピー

'Copy'メソッドは'Extract'の逆であり、本質的にCopyOpacityをそれ自体に対して実行します。つまり、グレースケール画像(アルファチャンネルが有効かどうかに関係なく)を形状マスク画像に変換します。

  magick alpha_extract.png  -alpha copy   alpha_copy.png
[IM Output] ==> [IM Output]
画像に既存のアルファチャンネルがあるかどうかは関係ありません。画像のグレースケール値から画像の透明度を作成するだけです。形状マスクを作成したら、さまざまなカラートーンまたはDuff-Porterアルファ合成方法を使用して色を付けることができます。形状マスクの使用例については、マスクを色付きの形状としてを参照してください。

アルファ形状

グレースケール画像をより簡単に使用するために、「形状」メソッドは形状マスクを作成するだけでなく(アルファ抽出のように)、現在の背景色を使用して色付けも行います。

  magick alpha_extract.png -background Yellow -alpha shape   alpha_shape.png
[IM Output] ==> [IM Output]
これは、画像を整形してから異なる背景色に平坦化することで、グレースケールマスクを非常に迅速に色付けできることを意味します。

  magick alpha_extract.png -background Yellow -alpha shape \
                            -background Blue   -alpha remove alpha_colormask.png
[IM Output]
背景は、実際にはこの「形状」の色付け操作に使用する正しい色ではありません。形状の前景色を設定するには、「塗りつぶし」色を使用する必要があります。そのため、どの色を使用するかは変更される可能性があります。現在の塗りつぶし色にアクセスするのが内部的に困難なため、背景のみが使用されます。この変更は、IMv7の一部として行われる可能性があります。
もちろん、白黒画像を特定の色に直接マッピングする、より高速で優れた方法は、より特殊な色によるレベル調整を使用することです。これにより、既存の画像の透明度チャネルを有効にする、あるいは変更する必要がなくなります.

  magick alpha_extract.png  +level-colors Blue,Yellow   level_color.png
[IM Output]
上記は、線形色空間を使用して色をマッピングするため、視覚的に正しい色のグラデーションを得るためには、ある時点でsRGBに変換する必要がある場合があります。

アルファ削除

"-alpha Remove"メソッド(IMv7.7.5に追加)は、現在の "-background" を使用して、画像から透明度を削除するように設計されています。

  magick moon.png  -background tan  -alpha remove  alpha_remove.png
[IM Output]
透明度は「削除」されますが、アルファチャンネルはオンのままになり、完全に不透明になります。アルファチャンネルが不要になった場合は、アルファオフを使用して無効にすることができます。この操作はシンプルで高速であり、追加のメモリ使用量や、代替の透明度除去手法に関連する可能性のあるその他の副作用なしにジョブを実行します。したがって、画像の透明度を削除するための推奨される方法です。他の手法、またはImageMagickがv6.7.5より古い場合は、以下のより詳細な説明画像から透明度を削除する)を参照してください。

アルファ背景

IM v6.5.2-10以降、完全に透明なピクセルの非表示色を現在の背景色に設定する「背景」メソッドが利用可能になりました。通常、この色は、アルファチャンネルがオフになっている場合にのみ表示されるため、重要ではありません。ただし、完全に透明なピクセルの色はPNG画像ファイル形式で保存され、大きな画像の場合、ランダムな不明な完全に透明な色を使用すると、圧縮処理に大きな影響を与える可能性があります。詳細については、圧縮率の高いPNGおよびIMフォーラムのディスカッションアルファチャンネルのガベージの除去を参照してください。色の混合は適用されず、完全に透明な色に直接色が割り当てられるだけであることに注意してください。ただし、ピクセルは完全に透明なままであるため、画像に変更は表示されません。
たとえば、ここでは、完全に透明なすべてのピクセルを「ホットピンク」に設定するために使用します。

  magick moon.png -background HotPink -alpha Background moon_hotpink.png
[IM Output]
ご覧のとおり、これは画像の実際の外観には変更を加えませんでした。変更を確認するために、次にアルファチャンネルをオフにします

  magick moon_hotpink.png -alpha off moon_hotpink_off.png
[IM Output]
これは透明度の削除と同じではありません
形状のエッジは、すべての半透明ピクセルを不透明にし、その結果、強いエイリアシング(階段状)エッジ効果が生じます。通常は不透明なPNG24形式でも、すべての完全に透明な色が同じであれば、ブール値の透明度を保存できることに注意してください。詳細については、PNGサブフォーマットの例を参照してください。色の置換のこのプロセスは、実際には「-channel RGB -fill*色*-opaque None + channel」を実行することとほぼ同じです。直接の色置換を参照してください。他の多くの画像処理演算子も、完全に透明なピクセルを完全に透明な黒(色「なし」)に魔法のように変換することに注意してください。これは、数学的なゼロに相当する色であるためです。これは、この演算子を使用するのほど直接的または高速ではありませんが、これを行うことがわかっているいくつかの画像操作の概要を以下に示します。

  magick moon.png \( +clone -alpha off \) \
                        -compose SrcIn   -composite   moon_black.png
  magick moon.png -channel RGBA  -blur 1x.000000001  moon_black.png
  magick moon.png -channel RGBA   -gaussian 1x0      moon_black.png
  magick moon.png -fuzz 0% -transparent none         moon_black.png
最後の方法(ファズ係数と透明色を参照)は、すべての透明色を完全透明の黒('None')に設定できるだけでなく、ファズ係数を指定するだけで、ほぼ完全に透明な色(有効な色を持っているが、実際には見えない色)もすべて設定できるため、特に便利です。これは多少のデータ損失を招きますが、ほぼ完全に透明な色が多数含まれる画像の圧縮率を向上させる可能性があります。多くの場合、これらのほぼ完全に透明なピクセルは、非常に奇妙な色や間違った色を持つ可能性があり、この方法を使用すると、そのような奇妙なピクセルが他の問題を引き起こす前に削除できます。

画像から透明度を削除する

アルファオフは、単にスイッチを切り替えて透明チャネルをオフにするだけです。画像を透明度の使用を許可しないファイル形式に保存しようとすると、同じ効果を得ることができます。たとえば、JPEGに保存すると...

  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'"   a.png

  magick a.png  a.jpg
[IM Output] ==> [IM Output]
JPEGファイル形式は、アルファ(透明度)チャネルを保存しないため、単にオフにします。この場合、透明な部分は黒くなりました(典型的な結果です)。しかし、画像ソースによっては、透明な領域が他のランダムな色、または他の不適切な色になる可能性があります。また、多くの場合、半透明のピクセルは、ほぼ完全に透明であるため、通常は見えない非常に奇妙な色を持つことがあります。単に透明度をオフにすると、これらのピクセルが目立つようになり、結果が予想よりも悪化する可能性があります。上記の「A」の左上隅の例を参照してください。いずれの場合も、単に透明度をオフにすることは、通常は望ましいことではありません。*最良の解決策*は、アルファ削除メソッドを使用して、透明度を背景色のアンダーレイにすばやく簡単に置き換えることです...

  magick a.png   -background skyblue  -alpha remove -alpha off a_remove.jpg
[IM Output]
厳密に言えば、JPEGへの保存はこれを自動的に行うため、この場合はアルファオフは必要ありません。
透明度を削除する別の方法は、新しい「背景」または「キャンバス」画像を何らかの方法で生成し、オーバー合成して、透明度が置き換えられるようにすることです。できれば、プロファイル、ラベル、キャプション、コメントなど、元の画像のメタデータを保持しながら行います。このようなキャンバスを生成する方法は、同じサイズの画像キャンバスを作成するに例示されています。ここにそのような方法の1つがあります...

  magick a.png \( +clone -alpha opaque -fill SkyBlue -colorize 100% \) \
          +swap -geometry +0+0 -compose Over -composite  \
          -alpha off  a_compose.jpg
[IM Output]
これを行うための他のより簡単な方法は、演算子が実行しているより大きな画像処理操作の一部として生成される「*複製された背景キャンバス*」を内部的に作成する操作を使用することです。最も一般的な方法は、画像をフラット化することです。この演算子は、この目的で非常に頻繁に使用されるため、透明度を削除するプロセスは、しばしば誤って「フラット化」と呼ばれています。例えば...

  magick a.png   -background skyblue -flatten  -alpha off  a_flatten.jpg
[IM Output]
ただし、これは "mogrify" や複数の画像のシーケンスでは機能しません。これは基本的に、 "-flatten" 演算子が、実際には複数の画像を単一の画像にマージするように設計されているためです。複数の画像で機能するもう1つの一般的な方法は、画像に適切な "-bordercolor" を使用したサイズゼロのボーダーを与えることです。例えば...

  magick a.png   -bordercolor skyblue -border 0  -alpha off  a_border.jpg
[IM Output]
上記のメソッドと密接に関連する他の画像処理演算子も、画像から透明度を削除できます。これらには、モザイクマージフレームが含まれます。エクステント演算子も使用でき、透明度を削除すると同時に画像を拡大またはトリミングできますが、必要な最終画像のサイズがわかっている場合に限ります。透明度を単色で置き換える必要はありません。DIY合成(上記のとおり)を使用する場合、置換背景に任意の画像を使用できます。この簡単な例は、 "composite" コマンドを使用して、画像を元の画像の「下」にタイル状に配置することです(Dst_Overを使用)。この合成方法により、元の画像のメタデータとサイズが保持されます。

  magick composite -compose Dst_Over -tile pattern:checkerboard \
                                               a.png  a_undertile.jpg
[IM Output]
上記の多くのメソッドは、処理の一部として、画像が持つ可能性のある仮想キャンバス情報に影響を与えたり、破壊したりする可能性があります。仮想キャンバスが関係する場合、個々の演算子の詳細をより詳しく調べる必要がある場合があります。多くの場合、仮想キャンバス効果は、画像処理全体に役立ちます。

ブールアルファ透明度

一部の画像ファイル形式では、アルファチャネルを完全に削除する必要はなく、純粋なオン/オフまたはブール値の透明度のみを許可する必要があります。GIFPNG8などのインデックス(パレット)画像ファイル形式は、この典型です。例は現在GIFブール値の透明度で検討されていますが、最終的にはここに移動する必要があります。

アウトラインまたはハロー透明度

透明度を含む画像の周囲にアウトラインを追加したい場合があります。1つの方法は、エッジアウトモルフォロジーを使用して、元の画像に隣接するすべてのピクセルをすばやく取得し、色を付け、アンダー(DstOver)合成することです。元の画像を使用します。

  magick knight.png \( +clone \
             -channel A -morphology EdgeOut Diamond +channel \
             +level-colors red \
           \) -compose DstOver -composite    knight_outlined.png
[IM Output] ==> [IM Output]
これは、半透明のエッジピクセルを含むPNG画像からGIF形式の画像を作成する場合に特に便利です。最小限の背景色を提供しますが、画像の残りの部分は完全に透明のままにします。この問題の詳細については、背景パターン上のGIFを参照してください。別の方法は、形状の周囲に柔らかな半透明のハローを生成することです。これを行うには、画像をぼかして色を変更し、再びアンダー(DstOver)合成します。元の画像を使用します。

    magick knight.png \(  +clone \
              -channel A  -blur 0x2.5 -level 0,50% +channel \
              +level-colors red \
            \) -compose DstOver  -composite    knight_halo.png
[IM Output]
これは実際には、ソフトアウトライン複合フォント効果を使用するのと似ていますが、注釈付きテキストではなく形状の画像を使用します。

画像でマスクを使用する

画像のマスキング

前述のように、画像をマスクして画像の一部を透明にする方法はいくつかあります。どの方法を選択するかは、画像マスクがグレースケールマスクか形状マスクかによって異なります。

画像マスクの編集

画像のマスクは、非常に便利なものです。たとえば、元の画像のマスクを変更することで、画像の一部を非常に簡単に消去できます。"-draw" 演算子は何も描画できず、現在消去オプションがありません。ここでは、画像を作成し、マスクを抽出して変更してから、元の画像に復元します。

  magick -size 100x100 xc:none   -stroke black  -fill steelblue \
          -strokewidth 1   -draw "circle 60,60 35,35" \
          -strokewidth 2   -draw "line 10,55 85,10"      drawn.png

  magick drawn.png -alpha extract  mask.png

  magick mask.png -fill black -draw "circle 40,80 60,60" mask_bite.png

  magick drawn.png mask_bite.png \
          -alpha Off -compose CopyOpacity -composite \
          drawn_bite.png
[IM Output] ==> [IM Output] ==> [IM Output] ==> [IM Output]
マスクの「黒」は透明で、白は不透明であることを忘れないでください。そのため、必要なのは、表示したくないものの上に黒を描くことだけです。上記の "-alpha Off" 操作は、グレースケール画像に不要な透明チャネルが含まれていないことを確認するために不可欠であるため、忘れないでください。そして、プレストは元の画像から一口食べました。削除した画像の一部を再度追加することもできます。たとえば、ここでは、マスクに白い領域を描画することにより、元の画像から削除した「一口」の一部を再度追加します。マスクは、不透明度のコピーチャネル合成を使用して、再び元の画像に戻されます。

  magick mask_bite.png -fill white \
          -draw "circle 50,70 60,60" \
          -draw "roundRectangle  78,5 98,25 5,5" \
          -alpha off  mask_bite2.png
  magick composite -compose CopyOpacity mask_bite2.png drawn.png drawn_bite2.png
[IM Output] ==> [IM Output] ==> [IM Output]
パーツの再追加について一言警告します。通常、ImageMagickは、完全に透明な色を黒に置き換えます。これは通常、演算子の背後にある数学がそのように機能するためです。結局のところ、それは完全に透明であるため、その色は通常問題になりません。つまり、以前に描画していない画像の一部を不透明にすると、一般的に黒くなります。これは、画像の透明度の下にある色であるためです。ただし、上記の例では、PNG画像ファイル形式が画像の元の(透明になった)色を正しく保持していることに気付いたでしょう。そのため、再追加された部分の色は、元の画像の元の「SteelBlue」色のままでした。画像が他のファイル形式に保存されたり、さらに変更されたりした場合、これに頼るべきではありません。
ここでは、画像から一部を消去する別の方法を示しますが、グレースケールマスクを抽出して変更するのではなく、DstOut合成方法を使用して、形状マスクを一種の「消去」ツールとして使用します。 。

  magick -size 100x100 xc:none -draw "circle 40,80 60,60" mask_shape.png

  magick drawn.png mask_shape.png -compose DstOut -composite drawn_bite3.png
[IM Output] - [IM Output] ==> [IM Output]
ご覧のとおり、形状マスクはアルファチャネルを抽出および復元する必要がないため、処理が簡単な場合があります。ただし、私が使用しているDuff-Porterアルファ合成方法では、透明になった色を復元することはできません。これらの方法では、透明になった(したがって色が未定義の)ものは透明のままです。アルファ合成方法を使用して画像の一部を消去すると、実際には完全に透明なピクセルの下の色が破壊されます。それはそれを保存しません。結局のところ、透明な色は実際には実際の色ではありません!

マスクを色付きの図形として使用

マスクを使用して画像に透明度を追加または再追加する代わりに、マスクをさまざまな方法で画像と直接組み合わせることもできます。たとえば、マスクを記号または形状として使用して、さまざまな色で画像にオーバーレイしたいとします。このためにはマスクが必要です。これは特別な「記号」フォントから抽出します。

  magick -font WebDings -pointsize 24 label:Y \
          +trim +repage  -negate   heart_mask.gif
[IM Output]
黒い背景(透明)に白い前景(不透明)で構成される適切なマスク画像にするために、ラベル画像を反転したことに注意してください。IM v6.4.3-7以降、グレースケールマスクをカラー形状に変換する最も簡単な方法は、アルファ形状演算子を使用することです。これはアルファコピーとまったく同じですが、最終的な形状を着色するための追加の手順があります。

  magick heart_mask.gif  -background Red -alpha Shape  heart_red.png
[IM Output]
GIFブール値の透明度の問題を回避するために、生成された形状の画像にGIFではなく「PNG」画像形式を使用していることに注意してください。
これまでは、最も簡単な解決策は、アルファマスクをマットチャネル画像に反転してから、結合を使用して形状を作成することでした画像。

  magick heart_mask.gif -negate  \
          -background Gold  -channel A  -combine   heart_gold.png
[IM Output]
この場合の形状マスクの色は、結合が新しい画像の未定義チャネルを塗りつぶすために使用した "-background" 色によって定義されます。より古く、より複雑な方法は、 'CopyOpacity' 合成メソッドを使用して画像の透明度を指定されたマスクに設定し、均一なカラーステインティングを使用して結果の形状を着色することです。これは機能し、長い間使用するのに最適な手法でしたが、現在は推奨されていません。

  magick heart_mask.gif \( +clone \) -alpha off \
          -compose CopyOpacity  -composite \
          -fill HotPink  -colorize 100%    heart_hotpink.png
[IM Output]
「シェイプされた」画像ができたので、画像のレイヤー化技術アルファ合成方法のいずれかを使用して、組み込みのバラ画像など、任意の背景に画像を簡単に重ねることができます。

  magick rose: -page +2+2  heart_gold.png \
                 \( +clone -repage +7+29 \)  \
                 \( +clone -repage +52+14 \)  \
          -flatten       rose_with_love.gif
[IM Output]
すべてのシンボルを同じ色にしたい場合はこれで問題ありませんが、複数の色を使用したい場合は複数の中間画像が必要になり、多数のシンボルを多数の異なる色でオーバーレイするには実用的ではありません。多色のオーバーレイを作成する1つの方法は、画像を読み込んだ直後にシェイプされた画像の色を変更することです。

  magick rose: \(  heart_gold.png           -repage +2+2   \) \
          \( +clone -fill Red     -colorize 100% -repage +7+29 \) \
          \( +clone -fill HotPink -colorize 100% -repage +52+14 \) \
          -flatten      rose_colored_love.gif
[IM Output]
ここでは、シェイプされた画像を1つだけ読み込み、オーバーレイする新しい「レイヤー」ごとにその画像のクローンの色を変更しました。ベース画像の色の変更例については、色の変更のセクション全体を参照してください。画像内の特定の位置をマークする別の方法については、シンボルの描画も参照してください。また、より自動化されたレイヤー化技術については、ピン留めマップのレイヤー化例を参照してください。

数学的合成

マスクを何らかの背景にオーバーレイするのではなく、マスク自体の白または黒の部分だけで画像を着色することにのみ関心がある場合があります。これは比較的簡単で、数学的アルファ合成方法を使用してマスクの色を、色、タイル、または他の画像に一致するように変更するだけです。たとえば、「乗算」合成方法は、白い領域(乗算値1)をオーバーレイ画像に置き換え、黒い領域(乗算値0)は黒のままにします。「スクリーン」演算子は「乗算」とまったく同じですが、画像が反転されているため、事実上、画像の黒い領域が置き換えられます。たとえば、上記の大きなマスク画像を使用して、タイルパターンで生成された大きな画像をオーバーレイしてみましょう。

  magick mask_bite.png -size 100x100   tile:tile_disks.jpg \
                        -compose Multiply  -composite   compose_multiply.png
  magick mask_bite.png -size 100x100   tile:tile_water.jpg  \
                        -compose Screen    -composite   compose_screen.png
[IM Output] ==> [IM Output] [IM Output]
乗算」アルファ合成方法は、PostScriptドキュメントから生成された画像など、テキスト画像(つまり、白地に黒のテキスト)の背景を置き換えるのに特に役立ちます。

マスクされたアルファ合成

マスクされたアルファ合成の特別な3つの画像形式を使用すると、同じマスクを使用して2つの画像を直接マージできます。

  magick -size 100x100   tile:tile_water.jpg  tile:tile_disks.jpg \
           mask_bite.png    -composite   compose_masked.png
[IM Output]
最初の画像はマスクの黒い背景部分を置き換え、2番目の画像はマスクの白い前景部分を置き換えます。マスク自体は3番目の画像として指定されます。マスクは、2つの異なる画像を選択して混合し、最終結果を生成するために使用されます。実際には、2つの画像のマッピングされたブレンドのようなものです。結果の画像の最終的なサイズとメタデータは、上記の操作の最初の「背景」画像(黒い部分)から取得されるため、画像を入れ替えてマスクを反転すると、逆になります。最後に、「composite」コマンドではなく「convert」コマンドを使用すると、「オーバーレイ」画像(白い部分)が最初に指定され、「背景」画像(黒い部分)が2番目に指定されることに注意してください。つまり、このコマンドでは最初の2つの画像を入れ替える必要があります。

2つのマスクされた画像の位置合わせ

建設中
On aligning two masked images...

If your masks are pure boolean, you should have no problems however you
apply them.  However masks containing 'anti-aliased', 'gray', or
'semi-transparent' edging to make them 'smooth looking' can be serious
headache if you do not handle them properly and with care.

The rest of this discussion is on 'anti-aliased' masks.

Anti-Aliased Masks which join together come in two styles...

 * Ones which fit together like jigsaw puzzle pieces OR
   like a shaped peg into a shaped hole (shared boundary)

 * Masks that are ment to overlay a solid area (layered)

The latter is easy to handle and is the normal effect you get when you overlay
some colored shape over a fully-opaque image.  Essentially you would use
'over' composition to compose the shape.

The former 'jigsaw' masks however is harder.  Such masks are not meant to
either overlap, or underlap each other.  And yet if you try to join them
using the obvious and normal 'over' composition you will end up with a
semi-transparent join where 'anti-aliased edges' are merged.

Example of a bad 'jigsaw mask' join (over)

The correct way to join masks and shaped 'jigsaw' images is to use
Plus composition to 'add' the images together, with either a
black or fully-transparent background.

Example of a correct 'jigsaw mask' join (plus)


For another example of DIY image joining, using 'Dst-In', 'Dst-Out', and
'Plus' composition, see examples in...
  https://imagemagick.dokyumento.jp/Usage/compose/#dstin

I also go though this joining detail in the bug report of 3 image alpha
composition Composite Mask Bug
- Fixed.

For more on the difference between 'over' and 'plus' see 'Blend' (plus) vs 'Dissolve' (over)

Examples of correctly joining edge aligned pieces is shown in
3d Cubes - Affine and again in 3d Boxes - Perspective
and in Isometric Cube using Shears
  https://imagemagick.dokyumento.jp/Usage/warping/#sheared_cube

The Major problems in these examples is that the individual parts were NOT
generated using the same mask, but distorted to their final positions.
As such they do not quite fit together properly and joined together.

These examples need to be updated to use a 'Plus' composition method.  To
generate improved results, but even then they will still probably not be quite
'right' as the masks do not exactly 'fit' together.


エッジが正しく揃ったマスクの生成

The best idea is to use the same mask (negated) for BOTH pieces, rather than
attempting to draw the two masks separately. Otherwise you have the two masks
overlap, OR leave a gap, exactly as you have seen.

Correct methods of mask joining..

    * use mask to set transparency on one piece
      use negated mask to set transparency of other piece
      'Plus' the two pieces together.

    * Use mask to Add transparency to just one piece, then
      'Over' compose that piece over a complete image.

    * use a three image masked composition
      see https://imagemagick.dokyumento.jp/Usage/compose/#mask
      and https://imagemagick.dokyumento.jp/Usage/masking/#masked_compose
      Which uses the mask to select results from two different images.

Remember, 'Over' only needs the 'source' or 'overlay' image masked, the
background image should not have aligned semi-transparent edges.
But a 'plus' composition needs both images masked with and exact negative
mask of each other align the joined edge.

WARNING:  Draw does NOT currently allow you to generate two shapes that will
fit together properly without overlap!!!!

See Draw Fill Bounds for details.

I have not checked SVG to see if it has the same problem.


特別な画像マスク

書き込みマスク - ピクセルの変更を保護する

「書き込み」または「クリップマスク」は、同じサイズの既存の画像に追加される特別なグレースケール画像です。これは、ほとんどの画像処理演算子によって「不変」または「書き込み不可」として分類される画像の領域を定義します。演算子「-mask」は、メモリ内の画像にリンクされる外部画像を取得します。演算子の「プラス」形式「+mask」は、画像からマスクを削除します。たとえば、ここでは、「書き込みマスク」を使用して背景ピクセルが書き込まれないように保護しながら、色相を回転させて、前景の赤いバラを青いバラに塗り替えます。

  magick rose: -mask rose_bg_mask.png \
          -modulate 110,100,33.3  +mask rose_blue.png
[IM Output] [IM Output] ==> [IM Output]
マスクは少し粗いですが、うまく機能しました。「書き込みマスク」は、保護または保持する部分を指定するために使用されることを覚えておいてください。IMv7では...
-mask」演算子は「書き込み保護」マスクを定義します
より高度な例については、クロマキーマスキングを参照してください。これは、書き込みマスクとして適用するのではなく、マスクを生成することに関するものです。書き込みマスクまたはクリップマスクは、画像内のピクセルが直接変更される場合に機能するように設計されています。例:ネゲート、レベル、カラーティント、モジュレート、描画、合成、モルフォロジー、畳み込み。新しい画像(サイズ変更、歪み、範囲など)を生成する演算子の場合、マスクは新しい画像サイズに対応できないため、元のピクセルを保持できません。このような操作には、画像の「書き込みマスク」を削除または設定解除するという副作用もあります。別の例を次に示します...

  magick -size 70x70 xc:red  red_image.png
  magick -size 70x70 xc: -draw 'circle 35,35 30,5'  write_mask.png

  magick red_image.png  -mask write_mask.png \
          -fill blue -opaque red   +mask    masked_color_replace.png
[IM Output] [IM Output] ==> [IM Output]
マスクと結果の画像の両方のエッジが滑らか(アンチエイリアス)になっていることに注意してください。これは、マスクが単なるブールマスクではなく、ブレンドマスクであるためです。「書き込みマスク」は、マスク内の「グレー」ピクセルが存在するグレーの量によって、新しいピクセルと古い画像値のブレンドを生成するという点でブレンドマスクです。これにより、非常に滑らかなエッジが生成され、変更された領域と変更されていない領域の間に画像全体にグラデーションを生成することもできます。ただし、ブレンドマスクは単一の操作には適していますが、ブレンド効果が複数回適用されるため、複数の操作に使用すると適さない場合があります。この問題は、モルフォロジーなどのループ操作で特に顕著です。ただし、ブール値以外のブレンドマスクを使用する場合のみです。これが問題になる場合は、画像のコピーに対してすべての操作を実行してから、元の画像に対してマスクされたアルファ合成を使用する方がおそらく良いでしょう。注意が必要です。
このマスキングの使用方法は、実際には合成マスキングの仕組みとまったく同じです!ただし、適用されている合成演算子の期間中のみです。

  magick -size 70x70 xc:green  green_image.png

  magick red_image.png  green_image.png  write_mask.png \
          -composite    masked_composite.png
[IM Output] [IM Output] [IM Output] ==> [IM Output]
(反転したマスクで)同等です...

  magick write_mask.png  -negate -write MPR:mask +delete \
          red_image.png -mask MPR:mask \
          green_image.png  -composite  +mask  masked_composite_equiv.png
[IM Output]
つまり、マスクが反転され、最初の「宛先」画像に適用されます。次に、2番目が最初の画像の上に重ねられ、元のマスク画像の「白い」領域のみが変更されます。
3つの画像の「-composite」操作では、「書き込み」マスクを使用します

モルフォロジーでは、書き込みマスクは通常、操作の条件付きまたは制約付きモルフォロジー形式を生成するために使用されます。そのような例の1つは、IMディスカッションフォーラムのテキスト周辺のノイズのクリーンアップで、拡張の影響を制限するために説明されました。 *注:-cropは、マスクもトリミングして新しい画像に割り当てることにより、個々の画像の画像マスクを保持できるはずです。ただし、これは現在行われていません。*

クリップマスクとクリップパス

この演算子の「-clip-mask」形式は、上記とほぼ同じですが、ブール値(すべてか無か)スタイルのマスキングのみを提供します。結果として、「ブレンドされた」または滑らかな結果を得ることはできません。例えば...

  magick red_image.png  -clip-mask write_mask.png \
          -fill blue -opaque red   +clip-mask    clipped_modulate.png
[IM Output]
ご覧のとおり、結果は非常にエイリアス化されています(階段状のエッジがあります)。これは、「-clip-mask」が「-mask」のようにブレンドされた結果を生成しないためです。これについて唯一の良い点は、わずかに高速であることです(それほどではありませんが)。これはもともとTIFF画像ファイルのクリップパスの処理を可能にするために提供されたもので、非常に古い演算子(IMv5)です。代わりに、新しい「-mask」演算子を使用する必要があります。
IMv7では、「書き込みマスク」と「クリップマスク」は、技術的にはまったく同じ機能を実行しますが、並べて実装されています。そのため、両方のマスクを同時に適用できます。

ただし、両方を同時に使用することはお勧めしません。また、結果は定義されていません。また、この「ブールマスク」形式はIMv7から削除されました。

TIFF画像のクリップパス

「クリップパス」はTIFF画像ファイル形式の一部であり、TIFF画像内の「シェイプされた領域」を定義するために使用されるベクトルパスを定義します。IMでは、演算子「-clip」と「-clip-path」は、この「クリップパス」を読み取り、クリップマスク(上記)に変換します。そのため、シェイプが変更されないように保護する「書き込みマスク」を定義します。TIFF画像に格納されているクリップパスは、SVGパス描画として定義されます。これは、TIFF画像ファイル形式から次のように抽出できます。

  magick identify -format '%[8BIM:1999,2998:#1]' image_clip.tiff

人々がしばしば抱える最大の問題は、クリップされていないすべてを透明にすることです。これには、マスクが書き込み保護する領域に書き込む必要があります!これは1つの解決策であり、画像全体を透明に変換し、「クリップパス」をオンにして、書き込み可能になった部分を再び不透明(表示)にします。

  magick input.tiff -alpha transparent -clip -alpha opaque -strip out.tiff
+clip」演算子は、クリップマスクもオフにして削除します(「+clip_mask」と同様)。ただし、どのファイル形式も、どの画像ファイル形式の画像でも現在のクリップマスクを保存しません。(少なくともIMv7では)

読み取りマスク - ピクセル入力を無視する

書き込みマスクは、画像に書き込まれるピクセルを制限することに注意することが重要です。ただし、書き込まれる新しいピクセルデータを作成するために実行される操作の一部として「読み取られる」ピクセルは制限されません。これは基本的に、ぼかしモルフォロジー畳み込みなど、「領域効果」または「近傍」タイプの演算子を使用する場合、「書き込み可能ピクセル」エッジの近くには、マスクされた領域または書き込み不可の領域の色値が含まれる可能性があることを意味します。たとえば、ここでは、画像をぼかす前に、前景のバラを書き込み保護します。つまり、画像の背景部分のみをぼかしたいのですが、この場合はかなりぼかします。

  magick rose: -mask rose_fg_mask.png \
            -blur 0x8   +mask  rose_bg_blur_fail.png
[IM Output] [IM Output] ==> [IM Output]
結果は、**書き込み保護マスク**を使用しており、望ましいものではありません。
ご覧のとおり、前景の色はマスクによって保護されていましたが、色はバラの周りの背景をぼかすためにも使用されていました。このため、前景に近いぼやけた背景には、はっきりとした赤みがかった色合いまたはハローがあります。別の言い方をすれば、前景の色が周囲の背景に「漏れ」ました。これは一般に、レンズフォーカス効果の一部として画像の背景をぼかしたい場合に人々が意図することではありません。人々が本当に望んでいるのは、ぼかしが前景のピクセルを完全に「無視」し、背景の色のみをぼかし処理の一部にすることです。つまり、ぼかしが前景のピクセルを「読み取る」のを防ぎたかったのです。

IMv7の読み取りマスクソリューション

IMv7では、ピクセルカラーピクセルを読み取り不可にする唯一の方法は、ピクセルを透明にすることです。透明なピクセルは定義上色がなく、そのため「隠れた色」はぼかし操作によって行われる計算の一部ではありません。これは私たちに「チート」を与えてくれます。前景のピクセルを透明にし、ぼかし(またはその他)操作を適用し、透明度をオフにします(この場合は実際には必要ありません)。その後、画像の前景部分を復元できます。複雑に聞こえる場合は、そうです。これが関係する手順です。テクニックを明確にするために中間画像を示します...

  magick rose: rose_bg_mask.png -alpha off \
          -compose CopyOpacity -composite   +compose  rose_bg_only.png
  magick rose_bg_only.png  -channel RGBA -blur 0x8   rose_bg_blurred.png
  magick rose_bg_blurred.png      -alpha off         rose_bg_blur_opaque.png
  magick rose_bg_blur_opaque.png \
                rose: rose_fg_mask.png -composite    rose_bg_blur_good.png
[IM Output] ==> [IM Output] ==> [IM Output] ==> [IM Output]
[IM Output] ==> [IM Output] ==> [IM Output] [IM Output] ==> [IM Output]
結果は、以前はぼやけた背景に「漏れ」ていた赤いハロー効果の除去です。前景色の背景への「漏れ」をどのように除去したかを明確に確認できるように、書き込みマスクと読み取りマスクのバージョンの背景ぼかしを並べて比較します。
[IM Output]
書き込み
[IM Output]
読み取り
マスキング方法の違い
上記の例では、元の画像にアルファがないことを前提としています。画像にアルファチャネルも含まれている場合は、アルファを分離して個別に処理する必要があるため、作業量が2倍になります。この例として、「歪みサイズ変更」の議論があります。これは、歪みを使用してサイズ変更される画像を囲む仮想ピクセルを無視したいと考えていました。詳細については、正しいサイズ変更(歪みを使用)を参照してください。上記は、ぼやけた穴埋め手法にも非常に密接に関連していることに注意してください。唯一の違いは、変更から保護されているのが背景であり、前景ではないことです。そのため、少し簡単になります。真の「読み取りマスク」はIMv7で利用できるようになり、上記のように「読み取りマスク」とオプションで「書き込みマスク」を追加するだけで済みます。

領域と領域サブ画像

領域は、操作の効果を画像のより小さな領域に制限する別の方法です。たとえば、ここでは、長方形の領域全体を赤に着色しています...

  magick koala.gif  -region 40x33+15+5 -fill red -colorize 50% \
          koala_region_red.gif
[IM Output]
領域を透明にすることもできます...

  magick koala.gif -alpha set \
          -region 40x33+15+5 -alpha transparent   koala_region_trans.gif
[IM Output]
「領域画像」を透明にする前に、元の画像でアルファチャネルが有効になっていることを確認する必要がありました。それが行われなかった場合、IMは「領域画像」の透明度をシースルーにし、変更は表示されません。詳細については、以下の領域の仕組みを参照してください。
IM v6.6.9-5より前は、透明度の保持が壊れており、領域の透明度の結果は常に「元の画像が透けて見える」状態でした。そのため、上記の画像は、画像が透明度の使用を許可していたとしても、透明なピクセルを含みませんでした。
領域を使用する最大の理由は、その効果を小さな領域に制限するだけでなく、画像の長方形の領域を実際に抽出し、その小さな領域に続くすべての単純操作を適用することです。つまり、非常に大きな画像の非常に小さな領域のみを変更する場合、たとえば、赤目除去を行う場合、操作の範囲をその領域に制限するだけでなく、処理速度も*はるかに高速になり、抽出された領域の画像自体も小さくなります。要約すると... 書き込みマスクは画像全体にわたって操作を実行しますが、実際に変更されるピクセルを制限しますが、領域は抽出された小さなサブ画像を使用します。これらの方法を一緒に使用することを妨げるものは何もありません。ただし、クリッピングマスクを領域に適用する場合、クリッピングマスクは抽出された領域画像のサイズと一致する必要があります。

ローカル領域のワーピング

「画像領域」は実際には処理のために元の画像の「小さなサブ画像」を抽出するため、特別な「局所化された」円形歪みを使用して、元の画像の小さな領域を歪めることができます。たとえば、ここに縞模様の線があります。

  magick -size 600x70 xc:darkred \
          -fill white -draw 'roundrectangle 5,5  595,65 5,5' \
          -fill black -draw 'rectangle 5,25 595,31' \
          -fill red -draw 'rectangle 5,39 595,45' \
          lines.gif
[IM Output]
ここで、領域を定義することにより、異なる領域で線を異なる方法で歪めることができます。

  magick lines.gif \
          -region 90x70+10+0    -swirl  400  \
          -region 90x70+100+0   -swirl  400 \
          -region 90x70+190+0   -swirl -400 \
          -region 120x70+280+0  -implode 1.5 \
          -region 100x70+380+0  -implode -7  \
          -region 101x70+480+0  -wave 10x50 -crop 0x70+0+10\! \
          +region lines_regions.gif
[IM Output]
"-implode"と"-swirl"は、歪んだ画像の外側のエッジが定義された領域外の画像の残りの部分と一致するという特性を持っているため、領域の使用に非常によく適合します。つまり、それらは実際には「*局所的な画像の歪み*」を実行するように設計されています。波の歪みを使用したときは、結果の「波」画像のサイズを切りトリミングして、抽出元の元の領域に再び収まるようにする必要がありました。 領域は、単純な画像処理演算子と一緒に使用した場合にのみ機能することを忘れないでください。別の"-region"演算子を含む他の演算子は、その操作が適用される前に、領域処理をキャンセルします。

領域の仕組みとその問題点

実際には、領域の動作方法は次のとおりです...
  • 単純な切り抜きと領域引数を使用して、"-region"演算子に従って、画像から小さな画像を抽出します。
  • 続く単純な画像処理演算子を小さな画像に適用します。
  • 単純でない画像演算子が検出された場合、または別の"-region"演算子が検出された場合、または"+region"を使用して領域がオフになった場合、抽出された領域は抽出された場所で元の画像にオーバーレイされます。
領域は、画像スタック演算子を使用するのと似ていますが、これらの演算子よりもずっと前からImageMagickに存在していました。たとえば、IMバージョン5の不可欠な部分でした。たとえば、この領域操作がある場合...

  ... -region WxH+X+Y  ...simple-operators... +region ...
結果はこれと同じです(単一の画像の場合)...

  ... \( +clone -crop WxH+X+Y ...simple-operators... \
         \) -geometry +X+Y -composite   ...
またはこれ(複数の画像の場合)...

  ... \( -clone 0--1 -crop WxH+X+Y ...simple-operators... \
         null: +insert \) -geometry +X+Y -layer composite ...
「領域画像」が実際に「元の画像」にどのようにオーバーレイされるかは少し複雑です...元の画像に透明チャネルが有効になっていない場合、「領域画像」はオーバー合成を使用して合成されます。つまり、領域画像の透明な領域はシースルーになり、背後にある元の画像を見ることができます。たとえば、ここでは意図的に元の画像の透明度をオフにしましたが、次に領域を回転して、隅に透明な領域を作成しました。

  magick koala.gif -alpha off -region 30x30+10+10 \
          -alpha on -background None  -rotate 30  koala_region_rotate_1.gif
[IM Output]
ご覧のとおり、回転された領域の角(「領域画像」では透明だった)は「元の画像」を示しています。基本的には、元の画像が透明度を処理できないため、領域画像は単にオーバーレイされ、角が透けて見えます。元の画像にアクティブな透明度が含まれている場合、変更された領域画像の透明度も変更できるため、透明度はそのまま「コピー」されます。

  magick koala.gif -alpha set  -region 30x30+10+10 \
          -background None  -rotate 30    koala_region_rotate_2.gif
[IM Output]
ご覧のとおり、IMはコピー合成を使用しているため、領域画像に存在する透明度は元の画像にもコピーされます。何らかの理由で元の画像の元の透明度を保持したい場合は、最初にアルファをオフにし、領域画像が復元されたら、再びオンにして復元します。
拡大または縮小された領域画像は、元の画像に「収まらない」場合があります。たとえば、ここでは領域画像のサイズを変更(および色付け)して小さくしています...

  magick koala.gif  -region 30x30+10+10 \
          -resize 75% -fill red -colorize 30%  koala_region_shrink.gif
[IM Output]
ご覧のとおり、元の領域は復元された領域画像で覆われていませんでした。そのため、覆われていない部分は置き換えられませんでした。同様に、領域が大きくなると、元の画像のより多くの部分がオーバーレイされた領域画像で覆われる可能性があります。

  magick koala.gif  -region 30x30+10+10 \
          -resize 150% -fill red -colorize 30%  koala_region_enlarge.gif
[IM Output]
どちらの場合も、領域の左上オフセットは移動しません。領域画像を縮小して領域領域内の中央に配置したり、領域画像を別の位置に配置したりすることはできません。領域画像のサイズが変更されないように注意する必要があります。ただし、特別な状況では、サイズ変更された領域を処理できます。その例については、上記の「波の歪み」の例を参照してください。
"mogrify"のように、単純でない画像操作を使用する必要があるため、複数のサブ画像をマージすることはできません。ただし、代わりに"-draw"を代替の合成方法として使用できます。例については、Mogrifyでのアルファ合成を参照してください。

執筆時点では、「領域画像」には、元の画像から抽出された切り抜き仮想キャンバスオフセットがまだ含まれています。これは、この情報が役立つかどうかに応じて、バグと見なされる場合と見なされない場合があります。オフセットは現在、領域画像が復元されるときに使用されません。

オフセットが不要な場合(Distortなどの演算子の邪魔になるため)、"-region"オプションの後に"+repage"演算子を付けて、領域画像からオフセットを削除します。その削除または変更は、元の画像への復元には影響しません。


背景の削除

画像処理で最も一般的な問題の1つは、既存の完全に不透明な画像からマスクを生成することです。このような画像は、World Wide Webからダウンロードされたり、プログラムによって生成されたり、透明度を提供しない画像形式であることがよくあります。また、オブジェクトの写真があり、背景を削除したい場合もあります。写真は透明度を理解していないため、不要な部分を自分で削除する必要があります。残念ながら、この問題に対する一般的な解決策はありません。特に、画像に半透明のエッジを保持したい場合も同様です。結果として、このタスクを実行するには何百もの方法とバリエーションがあり、すべて正確な状況によって異なります。画像マスキングと密接に関連しているのは、画像がオーバーレイされる背景に一致するように透明度を調整することです。これは、ブール値の透明度のみを許可するGIF画像ファイル形式への保存の一部として詳細に説明されています。

単純な背景のマスキング(フラッドフィル)

画像の背景が単純な単色の場合、画像の色を置き換えるだけで、単純なマスク(および背景の削除)を生成できることがよくあります。たとえば、単色の背景を持つ画像の直接フラッドフィルマスキングを次に示します。

  magick cyclops.png -alpha set -channel RGBA \
          -fuzz 1% -fill none -floodfill +0+0 white \
          cyclops_flood_1.png
[IM Output]
右上隅のフラッドフィルの「シード」ポイントが画像のすべての部分に実際に到達しないため、これはうまくいきませんでした!!! この解決策は、画像をわずかに拡大して、フラッドフィルが画像のすべての外側のエッジに到達するためのパスを提供することです。ただし、これには背景の色を知る必要があります。

  magick cyclops.png -bordercolor white -border 1x1 \
          -alpha set -channel RGBA -fuzz 1% \
          -fill none -floodfill +0+0 white \
          -shave 1x1    cyclops_flood_2.png
[IM Output]
もちろん、私たちはあまり良いファズ係数を指定しませんでした。この問題は、画像内のオブジェクトの周りにハローが発生することです。これは、ほとんどの画像のエッジに、画像の外観を滑らかにする特別なピクセルが含まれているためです。ただし、この画像は背景に対して良好な黒い境界線を持っているため、適切な大きなファズ設定を使用すると、画像を背景からきれいに分離できます。

  magick cyclops.png -bordercolor white -border 1x1 \
          -alpha set -channel RGBA -fuzz 20% \
          -fill none -floodfill +0+0 white \
          -shave 1x1    cyclops_flood_3.png
[IM Output]
この手法にはいくつかの問題があります。まず、画像を全か無かでマスクするため、エイリアスが発生し、階段状の、しばしば見栄えの悪いエッジが生成されます。これは GIF 画像ファイル形式の制限には適していますが、その画像を別の背景に重ね合わせる場合はあまり適していません。また、アンチエイリアスされたすべてのエッジピクセルを取得することは非常に困難です。そのため、上記の画像を黒い背景に重ねると、通常よりもはるかに白いピクセルが表示される場合があります。

  magick cyclops_flood_3.png -background black -flatten \
          cyclops_flood_3_over.png
[IM Output]
また、高いファズ係数を使用できたとしても、エッジピクセルがほとんど残らなかったり、画像の中心に「漏れ」が生じたりする可能性があります。最後に、このような直接フラッドフィルは、単純な単色の背景では機能しません。

境界のあるオブジェクトの切り抜き

既存の単色の境界線を持つ画像は、これらの背景除去方法にとって明確な利点があります。境界線は、画像の「内側」と「外側」を明確に区別するため、背景画像の境界をより適切に指定する方法を使用できるようになります。つまり、背景と見なされる色を指定するのではなく、マスクされるオブジェクトの境界線を表す色を指定できます。さらに、境界線の色がわかっているため、画像の端の周りでは 2 つの特定の色のみが混合されます。つまり、両方の色がわかっているため、エッジの透明度も非常に明確になります。
建設中

既知の背景の削除

単純な背景を「ブール」マスクに削除するのは比較的簡単ですが、背景がそれほど単純でない場合は、事態はより複雑になります。ただし、背景自体がわかっている場合は、それを利用して他の画像から背景を削除できます。IM v6.3.4 以降、`ChangeMask` と呼ばれる特別な アルファ合成 メソッドが追加され、既知の背景を画像から直接削除できるようになりました。たとえば、ここでは、変更されていない背景画像と、単純なブール(オン/オフ)透明度を持つ GIF 画像が重ねられた画像があります。`ChangeMask` を使用すると、元の重ねられた画像(背景とは大きく異なる場合)を復元できます。

  magick overlay_figure.gif   overlay_bgnd.gif  \
            -compose ChangeMask  -composite  overlay_removed.png
[IM Output] [IM Output] ==> [IM Output]
基本的に、これはピクセルが一方の画像ともう一方の画像でどれだけ「異なる」かを判断し、その差が現在の ファズ係数 より小さい場合は、そのピクセルを透明にします。完全に透明なピクセルのみが画像に追加され、それ以外の場合は元の画像がそのまま(透明度も含めて)残されます。古い `Difference` 合成メソッドを使用して 比較差分画像 を生成することにより、演算子をシミュレートできます...

  magick composite overlay_figure.gif   overlay_bgnd.gif  \
            -compose Difference     overlay_difference.png
[IM Output] ==> [IM Output] ==> [IM Output]
ご覧のとおり、差分画像は変更されていない部分はすべて黒で、変更された部分は色の混合です。
個々のカラーチャネルを分離して加算し、しきい値処理を行うことで、2 つの画像間のチャネルの差分のマスクを取得します。

  magick overlay_difference.png -channel RGB -separate +channel \
          -evaluate-sequence add  -threshold 0   overlay_mask.png
[IM Output]
このマスクを使用して、変更されていない部分を透明に設定できます。

  magick overlay_figure.gif overlay_mask.png \
          -alpha off -compose CopyOpacity -composite \
          overlay_removed.png
[IM Output]
ご覧のとおり、`ChangeMask` 合成メソッドにより、このプロセスがはるかに簡単になります。ただし、これは「オン/オフ」スタイルの背景マスキングのみを提供します。ぼかしやアンチエイリアスされたエッジ、または結果の透明なフェザーは許可されません。

差分画像マスキングとフェザリング

上記は、エイリアスされたエッジを持つ画像や、単純でない背景を持つ画像にまで拡張できます。たとえば、ここでは白い背景に「サイクロプス」があり、それを抽出したいと考えています。次に、この画像と背景色(左上のピクセルで定義)の差分のグレースケール画像を生成します。

  magick cyclops.png \( +clone -fx 'p{0,0}' \) \
          -compose Difference  -composite  \
          -modulate 100,0  -alpha off  difference.png
[IM Output] [IM Output]
もちろん、この差分画像はマスクとして直接使用するには適していません。使用すると、周囲の背景だけでなく、画像のほとんどが半透明になってしまいます。ただし、この差分画像から、達成しようとしている内容に応じて、非常に多くの異なる透明マスクを作成できます。上記の差分画像を調整して、背景色と少しでも異なるすべてのピクセルのマスクを作成できます。

  magick difference.png  -threshold 0  boolean_mask.png
  magick cyclops.png  boolean_mask.png \
          -alpha off -compose CopyOpacity -composite \
          cyclops_boolean.png
[IM Output] [IM Output]
ご覧のとおり、ブールの「差分あり」の結果、元の背景のかなりの部分が含まれています。これは、元の画像がアンチエイリアスされているか、背景とわずかにぼやけているためです(この場合は、元の画像が JPEG 形式の画像からサイズ変更されたことが原因です)。元の画像自体がブールオーバーレイ(背景に重ねられた GIF 形式の画像など)である場合、これは問題になりません。その場合、結果は完璧になります(上記の「ChangeMask」の例を参照)。「-threshold」を変更することで、ブール(オン/オフのみ)マスクに「ファズ係数」を追加して、マスクを画像本体に近づけることができます。

  magick difference.png  -threshold 15%  threshold_mask.png
  magick cyclops.png  threshold_mask.png \
          -alpha Off -compose CopyOpacity -composite \
          cyclops_threshold.png
[IM Output] [IM Output]
サイクロプス画像の目が透明な**穴**と見なされていることに注目してください!この「穴」は、この手法全体の最大の欠点を浮き彫りにしています。背景色に近い、またはさらに悪いことに背景色と完全に一致する画像オブジェクトの部分は、背景と同じものと見なされます。もちろん、これはドーナツなどの「穴あき」オブジェクトの画像では望ましい場合がありますが、サイクロプスの場合は「穴あき目」は明らかに間違いです。元の「ハロー」効果は、他の「ノイズの多い」背景に重ねたい場合に読みやすくするために、テキストなどの場合にも望ましい場合があります。マスクを適用する前に少しぼかすことでハロー効果を強調し、結果の「ハロー」が距離によって減少するようにすることができます。

  magick difference.png -bordercolor black -border 5 \
          -threshold 10%  -blur 0x3  halo_mask.png
  magick cyclops.png -bordercolor white -border 5   halo_mask.png \
          -alpha Off -compose CopyOpacity -composite  cyclops_halo.png
[IM Output] [IM Output]
結果の「ハロー」効果は、マスク画像でさらに ヒストグラム調整 を使用することでさらに変更でき、特定の画像の結果を非常に正確に制御できます。適切なパラメータを使用すると、周囲のハローをほとんど存在しない程度に調整できますが、この方法で完全に排除するのは困難です。改良された手法については、次のセクションを参照してください。しきい値マスキングを生成する際には、マスクのエッジを滑らかにするために、少量のぼかし(たとえば「-blur 0x0.707」または 2 の平方根)を実際にお勧めします。もちろん、結果はブール値ではないため、GIF 形式の画像ファイルに保存しようとしないでください。これは ぼかしフェザー の例でもあります。ただし、これは真の 距離を使用した形状のフェザー とはまったく同じではないことに注意してください。ただし、上記で作成したような「ビットマップ」または「しきい値マスク」を扱う場合は、少量のぼかしフェザーに続いて大量の距離フェザーを行うと、おそらく全体的な結果が最良になります。

半透明のエッジの復元

上記で使用した 差分マスキング 手法は、以前の フラッドフィルマスキング 手法と組み合わせて使用​​することで、より単純なマスキング手法で見られたほとんどの問題を解決できます。ここでは、多層マスキング手法について説明しますが、これは画像の背景のほぼ理想的な除去を実現しながら、エッジに沿ったアンチエイリアスシェーディングピクセルを保持する手法です。ただし、これは既知の背景の画像に限定され、前景ピクセルとのコントラストが良好な「エッジ」が必要です。この例では、分離が非常に難しいが、アンチエイリアスの目的で通常よりもはるかに多くのシェーディングピクセルがエッジの周りに表示されるものを使用することにしました。影の効果を持つ形状です。

  magick -size 70x60 xc:none -font Candice -pointsize 50 -stroke black \
          -fill black          -annotate +12+42 'A' -channel RGBA  -blur 0x3 \
          -fill tile_disks.jpg -annotate +10+40 'A' \
          tile_water.jpg  -compose DstOver -composite letter.png
[IM Output]
まず、差分画像を生成する必要があります。幸いなことに、背景画像が何であるかはわかっています。もちろん、2 つのマスクを生成できるほどのコントラストがあれば、単色の背景でも同様に機能します。基本的に、差分画像を使用することで、背景画像の影響を取り除き、そこから使用するマスクを生成できます。

  magick letter.png  tile_water.jpg \
          -compose Difference -composite \
          -modulate 100,0 -channel B -evaluate set 0 \
          -alpha Off  diff_mask.png
[IM Output]
今回はグレースケール差分画像をわずかに処理し、赤と緑のチャネルに制限し、青のチャネルをクリアして、黒と黄色の差分画像を生成しました。これは、差分画像自体とは別に、クリーンなフラッドフィルマスクの生成を可能にするために「青」チャネルを解放するため、注意が必要です。技術的には、緑のチャネルもクリアして、2 番目のマスクに使用することもできます。しかし、先走りしないでおきましょう。ここで、2 つのマスクが必要です。完全に透明になるすべての領域を定義する外部マスクと、不要な「穴」を生成せずに画像内のオブジェクトの内部を定義するマスクです。そのため、さまざまなファズ係数を使用して、画像を外側から内側にフラッドフィルし、使用する 2 つの内側と外側のマスクを選択できるようにします。

  for fuzz in 01 03 06   28 32 34; do \
    magick diff_mask.png -fill blue -fuzz $fuzz% \
            -bordercolor black -border 1x1 -floodfill +0+0 black \
            -shave 1x1 diff_mask_$fuzz.png; \
  done
[IM Output]
-fuzz 1%
[IM Output]
-fuzz 3%
[IM Output]
-fuzz 6%
== [IM Output]
-fuzz 28%
[IM Output]
-fuzz 32%
[IM Output]
-fuzz 34%
上記の画像の青い領域は、マスクされている領域です。この目的のために青のチャネルをクリアしたことを忘れないでください。最初のマスクは、完全に透明にしたい画像の領域、つまり最終画像で完全に透明になると予想される部分をマスクする必要があります。マスクの内側の領域には、画像の黒いハローシャドウのほとんどが含まれている必要があります。この場合、画像本体と残りの背景との間に多くの相互作用があるため、画像の周囲に広い領域が含まれている「1%」の ファズ係数 を選択しました。より典型的な影のないケースでは、この領域はさらに小さく、パーセンタイル値ではない 5 や 10 などにすることができます。2 番目のマスクは、存在するすべての半透明ピクセルを食べ尽くすのに十分な大きさの「ファズ」を持っている必要があります。つまり、境界線を完全に削除したり、画像本体に「漏れ」たりすることなく、画像の境界線まで、できれば実際に境界線の中に入る必要があります(上記の最後の画像を参照)。このマスクの負の値は、実際には最終画像で完全に不透明になる(したがって内側を表す)すべてのピクセルを表します。この選択は難しく、使用する最適な値を見つけるために多くの試行錯誤が必要になる場合があります。この画像では、大きな問題なく非常に高いファズ「32%」を選択できました。基本的に、最終画像に元の「背景」ピクセルがまったく含まれないように、できるだけ高くしようとしますが、マスクが画像の内部を食べ尽くしたり(または漏れ込んだり)することなく行います。周囲の「エッジ」カラーにギャップがある場合は、マスクを適切に取得するために少し手動で編集する必要がある場合があります。これで、このマスクを使用して画像の「コア」または内側を抽出できます。つまり、削除しようとしている背景パターンと相互作用しないことがわかっている部分はそのまま残されます。

  magick diff_mask_32.png -channel blue -separate +channel -negate \
          letter.png +swap -alpha Off -compose CopyOpacity -composite \
          letter_inside.png
[IM Output]
フラッドフィルされたマスク画像から青いマスクをどのように抽出したかに注目してください。また、フラッドフィルの全か無かの性質により、マスクはエッジの周りに激しい階段状またはエイリアス効果を示します。これは、2 番目のマスクで修正できる問題です。この画像は、元の背景と相互作用しないことがわかっているピクセルのみの画像であり、最終画像ではそのまま残されることに注意してください。具体的に復元しようとしている影の効果やアンチエイリアスピクセルは含まれていません。これらのピクセルを復元することが、本当の作業です。マスクを反転して減算(乗算)することにより、半透明のエッジまたは影のピクセルを抽出したい領域を定義する新しいマスクを生成できます...

  magick diff_mask_01.png -negate diff_mask_32.png \
          -channel blue -separate +channel -compose multiply -composite \
          mask_aliasing_area.png
[IM Output]
次に、この領域を使用して、差分マスクからアンチエイリアスピクセルを抽出し、ピクセルの透明度を定義します。これらのピクセルを正規化して、不透明から透明へのスムーズな遷移を実現します。

  magick diff_mask.png -channel red -separate +channel \
          mask_aliasing_area.png -alpha Off -compose CopyOpacity -composite \
          -background gray30 -compose Over -flatten -normalize \
          mask_antialiased_pixels.png
[IM Output]
上記のマスクでは、色が明るいほどピクセルの不透明度が高くなります。同様に、色が暗いほど透明度が高くなります。ここでは、画像に存在する透明色が画像の正規化に干渉しないように、灰色の背景を使用しました。正規化を行わないと、この処理は失敗します。フラットなグレーの色自体はマスク領域外にあるため重要ではなく、後で無視されます。適切な透明度レベルが得られたので、これらの半透明ピクセルに使用する色を知る必要があります。この色は通常、画像のエッジの色と同じで、この場合は単純に黒です。しかし、元の背景との相互作用のため、影には濃いグレーを使用することにしました。
アンチエイリアスされたピクセルに正しい色を設定できるように、半透明のピクセルが何色であるべきかを何らかの方法で把握する必要があります。

これは以下のいずれかになります。
  1. 固定のエッジカラー(例:この例のようにほぼ黒)
  2. 最も近い完全不透明のエッジピクセルの色を使用する(モルフォロジーを使用。塗りつぶし演算子としてのスパースカラーを参照)
  3. 計算:アルファ値と背景色がわかれば、背景色を減算してピクセルの色を修正できます。以下の2つの背景を使用した背景の削除を参照してください。
基本的に、それはあなたの画像に依存します。
ついでに、画像を再マスクして、これらの特別なエッジピクセルだけを残しましょう。

  magick mask_antialiased_pixels.png mask_aliasing_area.png \
          -compose multiply -composite -negate \
          -background '#444' -channel A  -combine letter_edging.png
[IM Output]
あとは、画像の内部の「コア」を半透明のエッジピクセルで重ねるだけです。

  magick letter_inside.png letter_edging.png \
          -background none  -flatten    letter_recovered.png
[IM Output]
これで、背景が削除され、完璧なアンチエイリアスが適用された画像が作成され、半透明のエッジとシャドウが正しく復元されます。完全に異なる背景に重ねることもできます。

  magick letter_recovered.png tile_aqua.jpg \
          -background none -compose DstOver -flatten    letter_on_aqua.png
[IM Output]
この例で使用した画像は、大きな「エッジ」領域を持つ非常に難しい画像です。ほとんどの画像はそれほど悪くはありませんが、この方法は、おそらく最も優れており、最も普遍的な背景除去技術です。これは現在、"bg_removal"というシェルスクリプトに配置されています。これは、単一のコマンドを使用し、一時ファイルを使用せず、マスキングの実行方法に関する多くの追加オプションを備えています。

2つの背景を使用した背景の削除

以前の手法の主な問題は、前景オブジェクトに関するすべての情報を完全に復元するのに十分な情報が実際にはないことです。実際には、前景オブジェクトの各ピクセルの透明度と元の色の2つの情報を復元する必要があります。そして、1つの画像から両方の情報を完全に復元することはできません。背景画像がどのように見えるかを正確に知っていても、前景オブジェクトと背景オブジェクトが大きく異なり、色がわかっている場合を除き、前景オブジェクトから背景画像を差し引くことはできません。問題は、見える色が実際に与えられた色(不透明)なのか、それとも他の色と背景のブレンドなのか(半透明)なのかを確信できないことです。追加情報のソースがない限り、必要なアルファ値から元の色を分離することはできません。前景オブジェクトのすべての詳細を完全に復元できる唯一の状況は、2つの非常に異なるが完全に既知の背景色を含む2つの画像がある場合です。その状況では、前景オブジェクトの色とその透明度の両方を復元して、背景を完全に削除するのに十分な情報があります。2つの画像を選択する際の重要な要素は、画像全体で背景色ができるだけ異なることです。つまり、色は色の補色であるだけでなく、すべてのチャネルで強度が負になります。例えば...
[IM Input] [IM Input]
異なる背景色が使用されていますが、両方の画像にはまったく同じオブジェクトが含まれています。表示されているオブジェクトは単純ではなく、多くの半透明の色が含まれています。これは、画像の炎に濃い青色の背景が見えることからわかりますが、この透明度は明るい黄色の背景ではほとんど見えません。2色を使用することにより、重ねられたオブジェクトの半透明ピクセルは2つの非常に異なる色と混合されるため、2つの画像ではわずかに異なる色になります。各ピクセルがどれだけ異なるかを測定することで、どのピクセルが半透明であるか、そしてどの程度半透明であるかを正確に判断できます。基本的に、重ねられたオブジェクトの透明度を完全に復元できるだけの十分な情報があります。透明度または「マスク」の復元はもちろん最初のステップであり、実際には非常に簡単なステップです。差分画像を生成し、各チャネルで見つかった差分をマージして最大化します。

  magick match_navy.gif match_gold.gif \
          -compose difference -composite -separate \
          -evaluate-sequence max -auto-level -negate \
          match_alpha.png
[IM Output]
結果の画像は、各ピクセルの透明度を完璧に表したマップです。これは本質的に、ソース画像の元オブジェクトの「アルファマスク」です。ただし、オーバーレイ画像に完全な透明度と完全な不透明度の両方の領域が含まれている場合にのみ機能します。そうでない場合は、上記の正規化ステップ( "-evaluate-sequence max -auto-level")の代わりに、各チャネルを2つの背景色の差で除算する必要があります。つまり、0.0から1.0の間の値で除算します。差が大きいほど良いです。2つの背景色が純粋な黒と純粋な白の場合、正規化は必要ありません。2つの画像の差分だけです。差分は反転されるため、最大の差分はアルファゼロまたは完全な透明度を生成し、差分がない場合は最大のアルファまたは完全な不透明度を生成します。次のタスクはより困難です。各半透明ピクセルの色は背景によって変更されるため、アルファマスクを使用してソース画像の1つからオブジェクトを抽出するだけでは不十分です。例えば...

  magick match_navy.gif match_alpha.png \
          -alpha Off -compose Copy_Opacity -composite \
          match_bad_colors.png
[IM Output]
基本的に、私たちが得たのは、画像の半透明の「炎」にある背景色のひどいハローでした。決して良い結果ではありません。これは「カラースピル」と呼ばれ(クロマキーマスキングという用語、ブルーまたはグリーンスクリーン技術としても知られています)、大きな問題になる可能性があります。私たちがしなければならないことは、半透明ピクセルから背景色を削除することです。しかし、すでに元の画像のアルファチャネルを復元しているので、元の重ねられた色を復元するために、各ピクセルからどれだけの色を削除する必要があるかを正確に知っています。これを行うには、ソース画像の1つと、抽出したばかりのアルファチャネルだけでなく、そのソース画像の背景の正確な色を知る必要があります。これらの例のように、単色の背景を使用する場合、比較的簡単な問題です。たとえば、ここでは元の色を復元します...

  magick match_navy.gif match_alpha.png -alpha Off \
          -fx "v==0 ? 0 : u/v - u.p{0,0}/v + u.p{0,0}" \
          match_alpha.png -compose Copy_Opacity -composite \
          match_recovered.png
[IM Output]
ソース画像の左上隅のピクセル(FX式 'u.p{0,0}')を、半透明ピクセルから削除する背景色として使用しました。必要に応じて、これを調整するか、削除する色を直接置換してください。色の復元の鍵は、上記の複雑なFXブレンド減算演算です。これは、アルファマスク( 'v')に従ってソース画像の元のカラー( 'u')を強調し、最終結果から背景色(u.p{0,0}または左上隅のピクセル)を減算します。この式は簡単ではなく、IMフォーラムのディスカッション合成の取り消し-ディゾルブで必要な数学を決定してくれたHugoRuneに感謝します。ディスカッションでは、すべてのステップがどのように機能するか、どのように導き出されたか、さらには2つの既知の異なる背景パターンからオーバーレイを抽出する方法についても説明しています。1つのコマンドですべてのシーケンスを示します。

  magick match_gold.gif match_navy.gif -alpha off \
          \( -clone 0,1 -compose difference -composite \
             -separate -evaluate-sequence max -auto-level -negate \) \
          \( -clone 0,2 -fx "v==0?0:u/v-u.p{0,0}/v+u.p{0,0}" \) \
          -delete 0,1 +swap -compose Copy_Opacity -composite \
          match_recovered_2.png
[IM Output]
IM v6.6.8-3では、FXが 'p{}'を使用して透明ピクセルを参照する場合、実際の完全透明カラー値ではなくゼロ値が取得されます!これはバグであり、IM v6.6.8-5で報告され、修正されました。バグがいつ導入されたかは不明です。

これは、アルファ画像を最初にソース画像にマージしてから、既知の背景色を使用して半透明または「スピル」カラーを修正しようとするときにのみ問題でした。
今回は、色の抽出に「ゴールド」の背景画像が使用され、2番目の "-clone"操作の '0'によって選択されましたが、どちらのソース画像を使用することもできました。警告が1つあります。上記は、左上隅のピクセルが純粋な背景色であると想定しています。そうでない場合は、特定のピクセル色を指定するようにコマンドを変更するか、正しい背景色情報を含む3番目の画像を使用する必要がある場合があります。後者の方法は、背景色が画像全体で一定でない場合に不可欠ですが、その複雑さでも修正できます。純粋な黒と純粋な白の背景色に重ねられた画像のより簡単なシーケンスを次に示します。この場合、色は常に黒い背景画像から復元されます。これは単純な除算であるため、非常に遅いFX DIY演算子の代わりに、より高速な除算合成を使用できるためです。

  magick match_black.gif match_white.gif -alpha off \
          \( -clone 0,1 -compose difference -composite -negate \) \
          \( -clone 0,2 +swap -compose divide -composite \) \
          -delete 0,1 +swap -compose Copy_Opacity -composite \
          match_recovered_3.png
[IM Input] [IM Input] ==> [IM Output]

背景復元のためのスタジオ写真 理想的な背景は、マット(非反射)の黒と、シンプルな純粋な(非反射)の白です。背景は可能な限り滑らかで均一な色合いでなければなりません。背景除去専用の写真を撮影する場合、2つの補色を使用すると効果的です。たとえば、緑とマゼンタの背景で写真を撮ります。基本的に、2枚目の写真を撮る前に、背景色のスクリーンを何らかの方法で交換する必要があります。2枚の写真の順序は背景除去には関係ありませんが、可能な限りきれいで均一でなければならず、主要な被写体とカメラは完全に静止したままでなければなりません。より良い方法は、白いスクリーンを被写体のかなり後ろに置き、2つの異なる色のランプを使用してスクリーンを均一に照らし、被写体から影を生成しないようにすることです。この手法を使用すると、スタジオで物理的な変更を加えることなく、他の背景色に切り替えて、2つの異なる背景で2枚の写真を撮ることができます。これらの2色背景の手法は、透明なオブジェクトには有効ですが、撮影されるオブジェクトによる反射、背景の歪み、または「レンズ」効果は、この手法では記録されず、透明性のみが記録されます。一方、オブジェクト上の一定の光源の反射は保持されます! これを試してみる場合は、お知らせください。また、ソース写真と結果の例をここに含めてください。人々があなたの作品を見ることができるように、あなたのサイトへのポインタとともにあなたの名前が掲載されます。
ビデオ背景復元 多くの異なる複雑な背景(ビデオなど)を持つ一連の画像が十分にある場合は、すべての画像の最小値と最大値を取得して、ほぼ純粋な白黒の背景画像を生成することができます。画像が多いほど、これはうまく機能します。これらの2つの画像を使用すると、一定のロゴとその半透明性を抽出でき、同じ手法を使用してすべてのフレームからロゴを削除できます。ただし、これは一定の半透明オーバーレイに対してのみ機能し、色または色相の歪みを使用するロゴ、または単色のロゴには機能しない場合があります。しかし、少なくとも正確なロゴの形状を決定することができます。完全に不透明またはより困難なロゴの場合は、穴埋め(次を参照)を使用して、周囲の色から欠落している詳細を埋めることができます。詳細については、IMフォーラムディスカッションを参照してください。

穴埋め

マスキング、透明性の追加、背景の削除は、不要な要素に対処する1つの方法を提供しますが、多くの場合、「穴」は実際に結果として望ましいものではありません。もちろん、穴のある画像を他の画像に重ねて穴を埋めることができますが、それはシームレスな結果をもたらさない可能性があります。画像から要素を消去するには、要素を切り取るだけでなく、穴の周囲の部分の色、陰影、テクスチャで置き換える必要があります。以下は、その穴を埋めるために何を使用するかを決定するためのさまざまな手法です。

埋める穴の作成

醜いテキストのある画像があるとします...

  magick zelda_tn.gif -gravity Southwest -annotate +8+20 Zelda zelda_text.jpg
実際にやりたいことは、そのテキストを削除することです。最も簡単な方法は、テキストがあった場所に「穴」を残すようにマスクすることです。これにより、何が削除されたかは問題ではなくなるため、問題は単純化されます。埋めるべき穴があるだけです。
[IM Output]
ただし、この場合は、ユーザーが画像エディターをすばやく使用した場合と同様に、「醜いテキスト」を覆う描画線を使用してマスクを作成します。

  magick -size 120x90 xc:black  -stroke white  -strokewidth 7 \
          -draw 'stroke-linecap round line 9,62 36,63' \
          -threshold 10%  zelda_text_mask.gif
[IM Output]
「穴」自体を作成することさえ難しい場合があります。自動化されたソリューションは、削除しようとしているものによって異なったり、同じ「テキスト」または「ロゴ」を持つ数百の画像を比較して正確に特定することさえあります。穴が小さいほど、最終結果が良くなることに注意してください。元の画像から保存できる情報が多いほど、結果は良くなります。粗くて奇妙な形の穴は、非常に滑らかに輪郭が描かれた穴よりも優れています。そのため、すべての不要な効果を取り除く最小の穴を作るために時間をかけることで、大きな違いが生じる可能性があります。
次に、マスクを使用して画像から穴を切り取ります。これにより、不要な部分がすべて覆われていることも確認されます。

  magick zelda_text.jpg \( zelda_text_mask.gif -negate \) \
          -compose CopyOpacity -composite   zelda_text_hole.png
これで、埋める必要がある「穴」のある画像ができました。
[IM Output]

ぼかし塗りつぶし

そのため、何らかの色で埋める必要がある穴があります。画像から実際に何かを削除したように見えないもの。
最も簡単な方法の1つは、単に画像をぼかして、穴の周りの色が穴に「広がる」ようにしてから、透明度を削除することです。

  magick zelda_text_hole.png -blur 0x1 -alpha off zelda_text_fill.png
使用するぼかしの量は、使用した穴のサイズによって異なります。
[IM Output]
これで、このぼやけた画像を下敷きにして、以前に作成した「穴を埋める」ことができます...

  magick zelda_text_hole.png zelda_text_fill.png \
          -compose Dst_Over  -composite   zelda_text_removed.png
[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]
そして、テキストが削除されました。その領域の色のぼかしによって何かが削除されたことが明らかになるため、これは完璧ではありません。たとえば、ゼルダの頭の横にある窓枠をよく見ると、ぼかしの効果を確認できます。また、領域は画像の残りの部分よりも「滑らかに」見え、これは特に写真で顕著です。しかし、これは広く普及している高速な手法であり、著作権保護方法として一部のテレビ局が追加したロゴを削除しようとしたビデオでよく見られます。削除を隠そうとする代わりに、実際の削除を目立たせることもできます。たとえば、誰かの匿名性を保護する場合です。
建設中
他の方法へのリンク。サイズ変更ぼかし穴埋め方法... スパースカラー、シェパード法(高速)snibgo、穴埋め エッジピクセルのみをぼかす...も参照してください。塗りつぶし演算子としてのスパースカラーsnibgo、優先順位で穴を埋めるも参照してください。非表示の背景チャネルで距離を計算しながら、カラーチャネルに色を設定するモルフォロジー演算子を使用したいと思います。これは、「カラー拡散」と呼ばれる、非常に高速で漏れのないシェパードのような塗りつぶしを生成するはずです。この手法を多用する論文拡散曲線を参照してください。穴埋め(テキスト削除)に関する大規模で古い議論は、IMユーザーフォーラムのテキスト削除の議論にあります。新しい議論は境界から最も近い色で領域を塗りつぶすであり、これはぼかしなしで塗りつぶすことについてです。画像の一部を消去するための「穴埋め」のIM以外の方法がStack Overflow、jpegからテキストを削除するに示されています。たとえば、Python Skimageを使用します。または、Python OpenCVインペインティングを使用します。