ImageMagick の例 —
画像の畳み込み
- 索引
-
ImageMagick の例 序文と索引
-
畳み込みの紹介
-
画像のぼかし (ローパスフィルタリング)
- ぼかしカーネル
- ガウスカーネルと Blur カーネルの比較
- ソフトぼかし (元の画像とのブレンド)
- ぼかしを使った「アンシャープ」処理 (元の画像からの減算)
-
エッジ検出畳み込み (ハイパスフィルタリング)
- エッジ検出カーネル
- エッジ検出による画像のシャープ化 (元の画像のエッジの強調)
-
方向畳み込み (勾配、コンパスフィルタリング)
-
相関 (Correlate)
- 畳み込みと相関の比較 (非対称カーネルの影響)
- 相関と形状検索
- 相関と HitAndMiss の比較
-
近傍カウント
畳み込みの紹介
「Convolve
」メソッドと密接に関連する「Correlate
」メソッドは、多くの点で形態学と非常に似ています。実際、それらはほぼ同じ方法で動作し、各位置で近傍の「カーネル」を照合するため、形態学の別の特別な「メソッド」にすぎません。実際、それらは基本カーネルとユーザー定義カーネルで定義されたものと同じコード、さらには同じカーネル定義の多くを使用します。この演算子で使用するために設計されたより具体的なカーネルについては(そして、たくさんあります)、ぼかしカーネルとエッジ検出カーネルを参照してください。「Gaussian
」カーネルが最も重要なカーネルです。ただし、畳み込みは形態学よりもはるかに古く、形態学が通常生成するバイナリ形状の研究効果ではなく、より多くのグレースケール勾配効果を生成します。そのため、形態学とは非常に異なる、または別個の演算であり、画像処理の中心となる演算であると見なされることがよくあります。基本的に、畳み込みまたは相関は、指定された近傍内のすべてのピクセルの「加重平均」を実行します。つまり、近くの各ピクセルの値にカーネルに与えられた値を掛け、それらの値をすべて加算して最終結果を生成します。そのため、最終画像の各ピクセルには、一般的に、ソース画像の周囲にある他のすべてのピクセルの少なくとも小さな部分が含まれます。別の見方をすると、画像内の各ピクセルの色は、使用されるカーネルによって定義されるように、その近くのすべての隣接ピクセルの色に追加(ぼかし)または減算(シャープ化/エッジ検出)されます。「畳み込み」と「相関」は、非常に小さく重要な点以外は同じ演算であり、これから見ていく例とコントロールについては、基本的に同じものとして扱うことができます。後ほど(畳み込みと相関の比較を参照)では、2 つの演算子が実際にどのように異なり、なぜそれほどわずかな点で異なるのかを調べます。しかし、ほとんどの場合、それらは同じメソッドです。畳み込み (Convolve)(
)
上記のように、「Convolve
」メソッドは、カーネル内の浮動小数点値に従って、局所近傍内の各ピクセルに重み付けします。次に、重み付けされた値を単純に合計して、結果の画像に新しい置換ピクセルを作成します。たとえば、非常に小さいユーザー定義畳み込みカーネルを使用して、単一のピクセルを畳み込んでみましょう。カーネル表示設定も設定しているので、定義および使用されているカーネルの詳細を確認できます(表示された画像は拡大されています)。
|
![]() |
![[IM Output]](pixel_mag.gif)

![[IM Output]](kernel_spread.gif)

![[IM Output]](pixel_spread_mag.gif)
0.5
」値が重み付けされ、結果の「半分明るさ」のピクセルが結果の画像に追加されます。同様に、カーネルの原点が元のピクセルに正確に配置されると、「1.0
」の値を取得し、近傍の他の値(黒)が結果にコンポーネントを追加することなく、元のピクセルを再現します。「0.0
」のカーネル値は、最終計算にまったく関与しません。ゼロ値は効果的に「近傍」の一部ではなく、「Nan
」値は形態学カーネルでまったく役割を果たさないのと同じです。そのため、このカーネルは 5 要素の近傍で構成されています。多くの点で、「Convolve
」メソッドは形態学の「Dilate
」メソッドと非常に似ていますが、「Dilate
」はカーネルを一種のビットマップマスクとして扱い、近傍内で最大の値を見つけます。一方、「Convolve
」は近傍内のすべての値の加重和であるため、各カーネル要素の値が全体的な結果に役割を果たします。畳み込み演算の構文は…-morphology Convolve {convolution_kernel}
-convolve {convolution_kernel}
![]() ![]() |
IM v6.5.9 より前、古い「-convolve 」は、形態学カーネル定義を理解しませんでした。コンマ区切りの値だけで構成される、ある奇妙なサイズの正方形カーネルを生成するための「古いスタイル」のユーザー定義カーネルのみを受け付けます。現在は、「新しいスタイル」の畳み込みカーネル定義を受け入れます。ただし、それでも「奇数サイズ」の正方形カーネルに制限されています。新しい「形態学」畳み込みメソッドを使用するようになるまで、そのままでしょう。 |
![]() ![]() |
古い「-convolve 」演算子は、新しい形態学「Convolve 」メソッドとまったく同じではありません。次の2つの操作の違いをリストに示します。
最終的には、新しい形態学「 Convolve 」メソッドと統合されるにつれて、上記のほとんどの違いは変わります。 |
Convolve
」が実際にどのように機能するかの優れた例をいくつか見たい場合は、EECE \ CS 253 画像処理、講義 7、空間畳み込みもご覧ください。Wikipedia、畳み込みの記事には、畳み込みプロセスの優れた1Dアニメーションがいくつかあります。畳み込みカーネルのスケーリング
上記の例は、単一のピクセルのようなほとんど黒の画像にはうまく機能しますが、これを実際の画像に適用すると、問題が発生します。
|
![[IM Output]](../images/face.png)

![[IM Output]](kernel_spread.gif)

![[IM Output]](face_spread.png)
0.5
」と、元のピクセルの完全なコピーを加算すると、カーネル内のすべての値の合計は3になり、結果の画像は3倍明るくなります!上記で「showKernel」の出力をもう一度確認すると、このカーネルは「0~3の畳み込み出力範囲」としてリストされていることがわかります。これは、このカーネルが一般的に画像を3倍明るくする可能性を示しています。これを修正するには、カーネル内のすべての値を3で割る必要があります。つまり、「0.5
」の値は実際には約「0.1667
」である必要があり、「1.0
」の中央値は「0.3333
」である必要があります。これは「カーネル正規化」として知られるプロセスです。たとえば、手動で正規化された結果とカーネル定義を次に示します。
|
![]() |
![[IM Output]](../images/face.png)

![[IM Output]](kernel_spread_norm.gif)

![[IM Output]](face_spread_norm.png)
![]() ![]() |
上記の「カーネルイメージ」(特別なカーネル2イメージスクリプトを使用して生成)には、正規化されたカーネルの結果も表示されます。ご覧のように、カーネル自体は非常に暗く、すべての値も暗くなっていますが、合計すると「1.0 」になります。この時点以降、表示されるすべての畳み込みカーネルイメージは、最大値が白になるように調整されます。そうでなければ、一般的に見えるのは暗く、基本的に役に立たない「カーネルイメージ」です。 |
-define convolve:scale={kernel_scale}
」を使用すると、カーネルのグローバルなスケーリング係数を指定し、全体的な結果の明るさを調整できます。
|
![]() |
カーネル正規化(自動スケーリング)
上記のようにスケーリング係数を計算するのではなく、特別な「!
」正規化フラグを指定することで、IMにこの「正規化スケーリング係数」を内部的に計算させることができます。
|
![]() |
![]() ![]() |
「! 」文字は、さまざまなUNIXコマンドラインシェルでも特別な目的で使用される場合があります。そのため、引用符内であっても、バックスラッシュを使用して文字をエスケープする必要がある場合があります。注意が必要です。 |
-convolve
」バリアントは、この正規化を自動的に行います。IMにカーネルを正規化させ、その後、出力範囲を調整するために、さらに所定の量だけスケーリングさせることができます。さらに簡単に、スケーリング係数をパーセンテージで指定できます。たとえば、ここではカーネルを正規化し、その後、計算されたサイズの50%に値を再スケーリングして、より暗い結果を生成します。
|
![]() |
!
」の値を使用することは、「1!
」や「100%!
」を使用することと実際には同等です。カーネル内の正の値と負の値を入れ替えたい場合は、負のスケーリング係数を使用することもできます。これの例については、ぼかしを使用した「アンシャープニング」画像を参照してください。このようにカーネルが正規化されている場合、カーネルの表示出力には、正規化されていることが示されます。正規化の仕組み
実際の「カーネル正規化」の仕組みは、すべてのカーネル値(負の値も含む、これも可能です)が合計されます。結果がゼロ以外の場合、すべての値をスケーリングして、その合計値が1(「1.0
」)になるようにします。負の値がある場合、これは実際には1より大きい値を持つカーネル(通常は原点で)を作成する可能性があります。アンシャープカーネルで特に発生します。ただし、重要な点は、カーネル全体が「1.0
」になるように合計されるため、最終的な画像は畳み込み演算によって暗くも明るくもならないことです。合計の結果がゼロ(「0.0
」)の場合、カーネルは特別なゼロ合計カーネルであると見なされます。その場合、カーネルは、すべての正の値が「1.0
」になるようにスケーリングされ、同様に、すべての負の値は「-1.0
」になります。これらのカーネルは、エッジ検出手法で特に一般的です。カーネルがこの形式の場合、カーネルの表示出力にもゼロ合計であることが指定されます。ただし、実際には正規化されたゼロ合計カーネルではない場合でも、表示される他の数値によって簡単にわかります。数学的に決定されたカーネルの大部分は、事前に正規化されています。これには、数学的に導き出されたカーネル「ユニティ
」、「ガウス
」、「LoG
」、「DoG
」、「ぼかし
」、「コメット
」が含まれます。ただし、離散定数カーネルは事前に正規化されていないため、上記カーネル正規化設定を使用して正規化を行う必要があります。これには、「ラプラシアン
」、「ソベル
」、「ロバーツ
」、「プリウィット
」、「コンパス
」、「キルシュ
」、「フライチェン
」カーネルが含まれます。「フライチェン
」カーネルには、より具体的な目的のために特別に重み付けされたサブタイプがあります。フライチェンカーネルは正規化せずにそのまま使用してください。ゼロ和正規化
すべての畳み込みカーネルが正の値だけを使用するわけではありません。正の値と負の値の組み合わせを使用するカーネルも取得でき、多くの場合、これらのカーネルの値は、ゼロ合計カーネルを生成するためにゼロになるように意図されています。このようなカーネルは、より高度な画像畳み込みにおいて非常に重要であり、エッジ検出と画像のシャープ化の手法を提供します。前のセクションで述べたように、通常の正規化フラグ「!
」は、このようなカーネルでも機能します。しかし、特別な状況のために、カーネルが「ゼロ合計」のままになるようにしたい場合があります。特別な「^
」正規化方法は、次のような状況でカーネルが「ゼロ合計」であることを保証する方法を提供するだけです。- ユーザーのカーネル定義がゼロ合計を保証するのに十分な精度がない場合。たとえば、「
1/3
」または3のその他の分数係数を正確な浮動小数点10進数として指定することはできません。 - 数学曲線はカーネルサイズ(半径)によって「クリップ」されるため、ゼロ合計ではなくなる可能性があります。たとえば、これは、無限応答曲線を基にした「
LoG
」または「DoG
」カーネルで発生します。IMは、まさにこの理由から、これらのカーネルでこの特別な正規化を内部的に使用しています。 - 相関「シェイプマスク」がゼロ合計になるようにします。これにより、検索でIMは正と負の両方のマッチを同じように検索できます。相関シェイプ検索を以下で参照してください。
-1.0
」になるようにスケーリングされ、すべての正の値は「+1.0
」になるようにスケーリングされます。その結果、カーネル全体はゼロになることが保証されます。この正規化方法を「ガウス」などのすべて正のカーネルに使用した場合でも、適切に正規化されたカーネルが得られます。そのため、この形式の正規化は、ぼかしカーネルでも使用できます。ただし、これは、負の値を含めることができるが、1の値に合計する必要がある(通常の正規化方法を使用)シャープニングまたはアンシャープニングカーネルを直接正規化するために使用しないでください。恒等カーネルとのカーネルのブレンド
カーネルスケーリング設定の完全な構文は次のいずれかです。-define convolve:scale='{kernel_scale}[!^] [,{origin_addition}] [%]'
-set option:convolve:scale '{kernel_scale}[!^] [,{origin_addition}] [%%]'
-set
」を使用する場合、パーセント文字が2倍になることに注意してください。オプションの正規化フラグ「!
」または「^
」は、最初に(要求された場合)ユーザー定義または組み込みのカーネルに適用されます。その後、カーネルは「kernel_scale」係数によってスケーリングされ、結果に対する畳み込みの有効な「パワー」が増減します。デフォルトのスケーリング係数は「1.0
」です。最後に、カーネルの「原点」値に、コンマの後の数値が追加されます。デフォルトの「origin_addition」は「0.0
」です。この最後のステップは、以前に生成された正規化およびスケーリングされたカーネルに、指定された「スケーリング」のユニティカーネルを効果的に「追加」します。これにより、次のことができるカーネルが生成されます。- ぼかしカーネルの影響を柔らげる。
- ぼかしカーネルを、画像をアンシャープにするために直接使用できるカーネルに変換する。
- エッジ検出カーネルを画像シャープ化カーネルに変換することもできます。
%
」)フラグを指定した場合、「kernel_scale」係数と「origin_addition」の両方にそのパーセンテージが適用されることに注意してください。これにより、分数を使用する場合、スケールを読みやすく理解しやすくなります。カーネルスケーリング定義の使用例...
-define convolve:scale='!50%,100%' -morphology Convolve Laplacian:2 |
ラプラシアン:2
」カーネルを生成します...0 | -1 | 0 |
---|---|---|
-1 | 4 | -1 |
0 | -1 | 0 |
0 | -0.25 | 0 |
---|---|---|
-0.25 | 1 | -0.25 |
0 | -0.25 | 0 |
0 | -0.125 | 0 |
---|---|---|
-0.125 | 0.5 | -0.125 |
0 | -0.125 | 0 |
0 | -0.125 | 0 |
---|---|---|
-0.125 | 1.5 | -0.125 |
0 | -0.125 | 0 |
ラプラシアン:2
」をシャープニングカーネルとして使用できますが、「50%
」のシャープニングパワーだけです。スケール設定のどこかに指定された「%
」フラグは、両方の値をパーセンテージにします。存在しない場合は、両方の値は単純な直接乗数です。たとえば、これらのすべてのスケーリングオプションは同等です。2つの正規化フラグについても同様です。畳み込みスケーリング設定のどこにでも表示できますが、常に他のスケーリングの前に適用されます。
50,100% 50%,100 %50,100 .5,1 0.5,1.0
出力結果のバイアス制御
負の値を含むカーネルを処理する場合、結果の画像のピクセルによっては負の値を割り当てる必要があります。これは、ゼロ合計カーネル(以下を参照)で特に当てはまります。残念ながら、生成された負の値を保持するために特別に構築されたImageMagickのHDRIバージョンがない限り、生成された負の結果はゼロ(黒)にクリップされます。畳み込みからの正の結果のみが得られます。通常の画像形式では保存できないため、結果の半分しか得られません。生成された負の値を保持するためにImageMagickのHDRIバージョンを構築し、必要な情報を抽出することができます。あるいは、負のスケーリング係数を使用してカーネルを反転させることができます。たとえば、次を使用します。-define convolve:scale='-1'
-bias
」を使用すると、正の結果と負の結果の両方を保持できます。IMの非HDRIバージョンで使用する設定は次のとおりです。
-define convolve:scale=50%\! -bias 50% |
-1.0
」を表し、白は「+1.0
」を表します。これを行う例は、以下の相関シェイプ検索の例に示されています。画像のぼかし(ローパスフィルタリング)
IMの別の例セクション、特に画像のぼかしとシャープ化では、このトピックの実用的な側面について詳しく説明しています。ここでは、より具体的な詳細を見ていきます。まず、基本的なカーネルと、変更せずに直接使用する方法について説明します。その後、ぼかしを変更して他の効果を生み出す方法を見ていきます。ぼかしカーネル
![[IM Output]](kernel_unity.gif)
ユニティ
これは、実際には何も行わない特別なカーネルです。カーネル要素は1つだけ指定され、その結果、各ピクセルは変更せずに自分自身に置き換えられます。たとえば、ここに無効な畳み込みがあります。IM v 6.6.9-4以降、カーネルはカーネル固有のスケール引数として単一の引数を取ることができます。これにより、画像の値を乗算するために使用できます(画像を明るくしたり暗くしたりなど)。
|
![]() |
Disk:0.5
」を使用して生成することもでき、カーネル生成の一部として追加のスケーリング引数を指定することもできます。(例:「Disk:0.5,0.5
」を最後の例として)。同様のカーネル(畳み込み用)は、「Gaussian
」カーネルジェネレーターで「*sigma*」を「0.0
」に設定することでも生成できます。ただし、これは中央の「1.0
」の値とそれを囲む8つの「0.0
」の値からなる小さな3x3カーネルしか生成できません。
![[IM Output]](kernel_shape.gif)
シェイプカーネルを使用した平均フィルタリング
以下で定義されている畳み込みカーネルのほとんどは、何らかの方法でガウスカーブを使用していますが、以前のMorphology Shape Kernelsを使用して、所定の(大きい)領域のピクセルの平均値を求めることもできます。もちろん、近傍の合計ではなく平均値を生成するために、カーネルを正規化する必要があります。たとえば、ここでは、より小さい「Octagon
」形状のカーネルを使用して、各ピクセルを取り囲む円形領域内にあるすべてのピクセル値の平均を求めます。その結果、各ピクセルの値は、定義された近傍のすべての25ピクセルに均等に分散されます。つまり、これは、指定された形状に対する「平均」または「平均化」フィルターと同等です。その平均から元のピクセルを除外し、周囲のピクセルのみを使用する場合は、「Ring
」カーネルを使用できます(半径を1つだけ指定します)。他のShape Kernelsも同様に使用して、たとえば「Diamond
」、「Square
」、または大きな「Disk
」形状のピクセル値を任意のサイズで平均化できます。ただし、形状領域の一定の平均化は画像をぼかしますが、結果の画像に異常な効果(特にエイリアシングアーティファクト)を生み出す傾向があります。「フラット」平均化カーネルを使用すると、シャープなエッジが、エッジで急激な変化のある、より厚い線形勾配に変換される傾向があります。結果の厚さはカーネル「`radius*2-1`」です。異なるエッジ角度が勾配の厚さと線形性にどのように影響するかは、「フラット」または平均化カーネルの形状によって異なります。
magick -size 80x80 xc: -draw 'polygon 15,15 15,65 60,15' shape.png magick shape.png \ -define convolve:scale=! -morphology Convolve Square:5 \ shape_mean_square.png magick shape.png \ -define convolve:scale=! -morphology Convolve Disk:5 \ shape_mean_disk.png |
![[IM Output]](shape.png)

![[IM Output]](shape_mean_square.png)
![[IM Output]](shape_mean_disk.png)
![[IM Output]](kernel_gaussian.gif)
ガウスカーネル(2次元ガウスぼかし)
お気づきかもしれませんが、「Gaussian
」カーネルは、画像を畳み込むために最も一般的に使用されるカーネルです。これは、ぼかし効果のための数学的な理想的なカーネルです。たとえば、小さな「Gaussian
」カーネルのShow Kernelを以下に示します(非常に迅速に非常に大きくなる可能性があります)...実際には、使用するカーネルだけを表示したかったので、上記の畳み込みを適用したくありませんでした。そのため、「:0
」Iteration Countを使用したので、何も行いません。同様に、特別な「null:
」ファイル形式を使用して、結果の画像出力を破棄します。畳み込み出力範囲からわかるように、「Gaussian
」カーネルはすでに正規化(スケーリング)されています。ただし、依然として非常に大きなカーネルであり、小さな分数値で満たされていることにも気付くでしょう。よく見ると、最大の値(2.48678、これは最初の行にも記載されています)は中央にあり、エッジとコーナーに向かって最小値(約0.000000194の値)があります。これは、畳み込みを使用した典型的なガウスぼかしです...カーネルの構文は簡単です...
Gaussian:[{radius}]x{sigma} |
-gaussian-blur
」演算子(これはこのカーネルを使用して畳み込みを実行します)で使用されるものとまったく同じです。ほとんどのMorphology Kernelsと同様に、最初の数値はカーネルの「*radius*」またはサイズです。これは単なる整数であり、最小値は1で、可能な最小カーネルのサイズは3x3要素です。常にゼロを指定するのが最適な方法です。これにより、ImageMagickは指定された「*sigma*」値に適切な半径を計算できます。2番目のより重要な引数は「*sigma*」であり、各ピクセルがどれだけぼやけるか、「広がる」かを定義します。値が大きいほど、画像のぼやけが大きくなります。これは浮動小数点値です。「*sigma*」値は必ず指定する必要があります。「0.0
」のシグマ値が与えられると、かなり役に立たない「Unity
」カーネル(指定された半径、または半径1、したがって「1.0
」の値とそれを囲む「0.0
」の値からなる3x3カーネルを生成します。)が生成されます。上記のように、あらゆる種類の「Unity
」カーネルとの畳み込みは、画像に何も行いません!「*radius*」を指定する場合は、一般的に「*sigma*」の少なくとも2倍にするのが良いでしょう。IMは通常、約3倍の半径(実際には意味のある結果を提供する最大の半径)を計算しますが、特定のIMインストールのコンパイル時の品質によって異なります。「Gaussian
」カーネルの引数の影響、および一般的な画像ぼかしの詳細については、...画像のぼかしを参照してください。
![[IM Output]](kernel_blur.gif)
ブラーカーネル(1次元ガウスぼかし)
「Blur
」カーネルはガウスカーネルと非常によく似ており、同じ引数も使用します(下記参照)。しかし、ガウスが2次元曲線であるのに対し、「Blur
」カーネルは1次元曲線を生成します。つまり、長く薄い単一の値の行を生成します。これは、小さな「Blur
」カーネルのShow Kernel出力です。
|
![]() |
||
|
Blur
」カーネルの実際のプロファイルです。Kernel Imageスクリプト「kernel2image
」を使用して作成され、その画像を「im_profile
」スクリプトを使用してグラフ化しました。このカーネルが表す「ガウスベル曲線」がはっきりと示されています。このカーネルを使用して画像を水平方向にぼかす例を次に示します。
|
![]() |
Gaussian
」とまったく同じですが、オプションの回転角度が追加されています。
Blur:[{radius}]x{sigma}[,{angle}] |
Unity
」カーネルの線形等価物が得られます。「*angle*」を使用すると、カーネルを90度回転させて、画像を垂直方向にぼかすことができます。
|
![]() |
Gaussian
」カーネルが生成する2次元画像ぼかしよりも高速な形式を作成することです。これについては、以下のガウスカーネルとブラーカーネルの比較を参照してください。
![[IM Output]](kernel_comet.gif)
コメットカーネル(半分1次元ガウスぼかし)
「Comet
」カーネルは「Blur
」カーネルとほぼ同じですが、実際にはブラーカーネルの半分だけです。原点の定義済みの位置がカーネルの中央ではなく左端にあることに注意してください。これは畳み込みカーネルとしては非常に珍しいことであり、そのため非常に珍しい結果が生成されます。濡れた絵の表面を指でこすったように、一方向に画像がぼやけ、色の跡が残ります。彗星の尾、または流星、または流れ星が残した跡のようなものです。
|
![]() |
|
![]() |
![[IM出力]](kernel_blur_profile.gif)
ガウスカーネルと Blur カーネルの比較
前述のように、「Gaussian
」と「Blur
」カーネルは非常に密接に関連しており、実際には同じ作業を行うことができます。どちらもガウス曲線を表しており、前者は2次元表現、後者は1次元表現です。たとえば、ここでは「-gaussian-blur 0x2
」の繰り返しを示します。これは「-morphology Convolve Gaussian:0x2
」演算と同等です。
|
![]() |
|
![]() |
|
Rotated Kernel List
」に1つのカーネルを展開するようにIMに要求することで、上記をさらに簡素化することもできます(この場合は2つのカーネル)。たとえば...
magick face.png -morphology Convolve 'Blur:0x2>' face_blur_x2.png |
上記のすべての例は互いに同等であり、「-blur 」演算子の動作方法です。
|
![]() |
-blur
」と「-gaussian-blur
」演算子の真の違いを表しています。後者では、1つの大きな2次元カーネルが使用されるのに対し、前者では2つの小さな1次元カーネルが使用されます。ただし、速度の点では、「-blur
」演算子は通常、1桁高速です。これは、非常に大きなカーネル1つではなく、はるかに小さなカーネル2つを使用するためです。ぼかし引数(*sigma*引数のサイズ)が大きいほど、カーネルが大きくなり、2つの操作間の速度の違いが大きくなります。そのため、「-blur
」演算子が一般的に推奨されます。2つの演算子の結果の違いは、小さな量子丸め効果(HDRIを使用していない場合)とエッジ効果(仮想ピクセル設定による)だけです。これらは両方とも、2つの別々の「blur」畳み込みのパスの間に中間画像を保存することによって生成される情報の損失によって引き起こされます。この違いは通常、目に見えず、実際的な用途には関係ありません。ソフトなぼかし(元の画像とのブレンド)
あらゆる種類のぼかしの効果を弱めるには、元の画像の一部とブレンドします。特に強いぼかしを適用する場合に有効です。例えば…
magick face.png -morphology Convolve Gaussian:0x3 face_strong_blur.png magick face.png face_strong_blur.png \ -compose Blend -define compose:args=60,40% -composite \ face_soft_blur.png |
![[IM Output]](../images/face.png)

![[IM Output]](face_strong_blur.png)

![[IM Output]](face_soft_blur.png)
ブレンド
」合成方法を使用して、ぼかし画像(合成ソース画像)の「60%
」と元の画像(合成宛先画像)の「40%
」を混ぜ合わせ、最終画像に「ソフトぼかし」効果を与えています。しかし、同じことをアイデンティティカーネルとのカーネルブレンドによって直接行うこともでき、比率は同じです。
|
![]() |
60%
」)は、与えられたカーネルをスケーリングして出力への影響を軽減し、2番目の数値(「40%
」)は「ユニティ
」(または「アイデンティティ」)カーネルを十分に追加して、結果が暗くなるのを防ぎます。重要なのは、ぼかしカーネルの場合、2つの数値の合計が「100%
」になることであり、合成ブレンドの場合と同じです。より高速な2パスぼかしを使用することもできますが、この場合、2つの個別の畳み込みが綺麗に「分離」されないため、カーネルに「ブレンド」を直接組み込むことはできません。ブレンド合成を後で改めて行う必要があります。
|
![]() |
100
」はぼかし画像を、「0
」は元の画像を与えます。![]() ![]() |
「-blur 」演算子は、より高速な2パスぼかしカーネルを使用することと完全に同等であることを覚えておいてください。 |
ぼかしを使った画像の「アンシャープ」化(元の画像から減算)
カーネルのブレンドをさらに進めて負のスケーリングを使用すると、元の画像からぼかし効果を減算できます。その結果、「アンシャープ」と呼ばれる手法になります。なぜこのような不幸な名前になったのかについては、Unsharp、Wikipediaを参照してください。
|
![]() |
100%
」になります。合成ブレンドでもこれを行うことができます。上記の例は、実際には誤って名付けられた「-sharpen
」演算子の動作方法とまったく同じですが、「シグマ」ぼかし制御のみです。ただし、演算の他の制御は提供されません。ブレンドは上記の通りです。より高速な2パス、1次元ぼかしカーネルを使用できますが、やはりブレンド操作を別手順として実行する必要があります。
|
![]() |
|
![]() |
-unsharp
」演算子は、別のタイプの制御を提供します。具体的には、差の閾値です。これにより、指定された差が大きい場合(画像内の実際のエッジ付近など)にのみシャープニングが適用されます。この閾値を使用して、しわやカメラノイズなど、小さな欠陥の「シャープニング」を防ぐことができます。画像のアンシャープ化は、通常、画像のサイズ変更や歪み後の非常に小さなぼかし(シグマ=0.75程度)で使用して、最終結果を改善します。これの例については、サイズ変更された画像のシャープ化を参照してください。画像のシャープ化にアンシャープ手法を使用する代わりに、実際に画像のエッジを特定してそれらを使用して画像をシャープ化する方法があります。詳細は、下記のエッジ検出による画像のシャープ化を参照してください。ただし、一般的にそれほどではないにしても、遅い方法と考えられています。エッジ検出畳み込み(ハイパスフィルタリング)
エッジ検出は、畳み込みが広く使用されるもう1つの分野です。ここでは、さまざまな方法で画像のエッジを強調または強化することが目的です。これは、エッジをできるだけ正確に位置特定するため、または各エッジの傾斜の角度や方向を決定するために行うことができます。ただし、スキャナー、デジタルカメラ、またはJPEG画像ファイル形式の損失のある圧縮によって生じるノイズなど、画像内のノイズの存在によって、作業がはるかに困難になる可能性があります。しかし一般的に、大きなカーネルの方がノイズの処理は優れていますが、エッジの局所化が不正確になります。一方、小さなカーネルはエッジの位置特定の結果がシャープになりますが、画像のノイズによって偽の結果が増える可能性があります。エッジ検出のために開発され、研究されてきた多くの小さな、よく知られたカーネルがあります。これらのほとんどは、特定のカーネルの種類の数学を研究した、または開発した数学者の名前にちなんで名付けられています。そのため、「ラプラシアン
」、「ソベル
」、「プリウィット
」などのカーネルがあります。これらの「名前付き」カーネルは一般的に非常に小さく、整数を使用して定義されているため、速度のために特別に設計された最適化されたソフトウェアとハードウェアに組み込むことができます。つまり、「離散」カーネルと呼ばれています。そのため、使用の一部としてカーネルをスケーリングまたは正規化する必要があります。エッジ検出には、画像のエッジをシャープ化する効果もあります。ゼロサムカーネル
すべてのエッジ検出カーネルには、共通の特徴があります。すべてゼロサムです。つまり、負の値が含まれていますが、カーネル内のすべての値の合計はゼロになります。滑らかなフラットカラー画像の場合、このようなカーネルを使用した畳み込みは、「ゼロ」または黒の画像を生成します。ただし、他の画像では、負の値と正の値の両方が含まれる結果が得られます。例として、基本的な形状を含む画像に離散「ソベル
」エッジ検出器を適用します…
magick -size 80x80 xc:black \ -fill white -draw 'rectangle 15,15 65,65' \ -fill black -draw 'circle 40,40 40,20' shapes.gif magick shapes.gif -define convolve:scale='!' \ -morphology Convolve Sobel shapes_sobel.gif |
![[IM Output]](shapes.gif)

![[IM Output]](shapes_sobel.gif)
ソベル
」カーネルによって定義されています)。ただし、1セットのエッジ、「正」の左から右への黒から白への傾斜のみが見つかりました。「負」の傾斜を取得するには、カーネルスケーリング設定を使用してカーネルを反転する必要があります。例として…
|
![]() |
ソベル
」カーネルでは、180度回転させて「スケール反転」と同じ結果を得ることもできますが、すべてのカーネルがこのように対称的であるわけではありません。もう1つの解決策は、結果に出力バイアスを追加することです。つまり、結果の画像に50%のグレーを追加して、負の値はこれよりも明るく、正の値は明るくします。ただし、「黒」と「白」の画像制限によって結果が「クリップ」されないようにするには、カーネルをスケーリングする必要もあります。
|
![]() |
|
![]() |
ソベル
」カーネルを参照してください。出力バイアスを使用するもう1つの代替手段は、ImageMagickの特別なHDRIバージョンを作成することです。これは、浮動小数点値を使用してメモリに画像を格納することを意味し、画像値は整数を使用することによって「クリップ」または「丸め」されません。ただし、この特別なバージョンのIMを使用する場合でも、通常の画像ファイル形式に保存する前に結果を後処理する必要があります。または、浮動小数点対応の特別な画像ファイル形式を使用する必要があります。ただし、中間画像結果のクリッピングや丸めの影響を心配する必要がなくなるため、処理が容易になります。エッジ検出カーネル
![[IM Output]](kernel_log.gif)
LoG:ガウシアンのラプラシアン
LoG:{radius},{sigma} |
LoG
」または「ガウシアンのラプラシアン」は、最高のエッジ検出カーネルの1つです。「メキシカンハット」カーネルとしても知られています。基本的に、「ラプラシアン
」微分(勾配)演算子であり、ガウシアンぼかしの追加によって平滑化されています。これにより、画像のノイズの影響の大部分が除去されます。これは、「シグマ」設定で調整できます。カーネルには、強い中心ピークの周囲にリング状に配置された負の値が含まれています。上記の「カーネルイメージ」では、負の値は暗い(ほぼ黒)の色で表示され、エッジに向かってゼロ(濃いグレー)に減衰します。そして、これがその効果です…画像のエッジがどのように強調表示されるかを示しています。ラプラシアンカーネルは方向を持たないが、エッジのどちら側にも正と負の値の尾根を生成します。エッジの位置を特定するには、正の尾根と負の尾根の間のゼロクロス点を探す必要があります。これはMarrとHildrethのエッジ検出として知られる手法です。このカーネルは画像のシャープ化にも最適です。![[IM Output]](kernel_dog.gif)
DoG:ガウシアンの差
DoG:{radius},{sigma1}[,{sigma2}] |
DoG
」または「ガウシアンの差」カーネルが生成されます。ここで、「シグマ1」によって生成されたガウシアンから「シグマ2」によって生成されたガウシアンが減算されます。通常、「シグマ2」の方が大きいため、カーネルの「中心ピーク」は正になります。2つの数値を反転すると、結果のカーネルが効果的に反転します。ガウシアンのラプラシアンの主な批判の1つは、非常に珍しい数学曲線であるため、実装が難しいことです。また、あまり文書化されていない曲線でもあります。もう1つの側面は、ガウシアンのように高速な2パスソリューションに「分離」できないことです(ガウシアン対ぼかしカーネルを参照)。ただし、わずかに異なるシグマ値(約1.6の比率)の2つの「ガウシアン
」カーネルを生成し、それらを互いから減算することで、ガウシアンのラプラシアンの近似を実際に生成できます。その結果、「DoG
」は「LoG
」カーネルよりもハードウェアで生成する方がはるかに容易になります。例として、比較のために「LoG
」と「DoG
」カーネルのカーネルイメージを並べて配置しました。ガウシアンの差、Wikipediaのウェブページを見ると、「LoG
」(または「メキシカンハット」)のプロファイルと「DoG
」を比較したグラフがいくつか表示され、一致する曲線間の非常にわずかな違いを示しています。 LoGのシグマをマッピングしてほぼ同等の「DoG」を生成する方法に関する詳細情報が必要です。ご存知の方は、フッターのアドレスまでメールでお知らせください。適用された結果も非常に似ています。
|
![]() |
両方の'sigma'値を定義し、少なくとも一方はゼロ以外にする必要があることに注意してください。いずれかのsigma成分がゼロ値の場合、「Unity 」カーネルと同等になり、イメージは変更されません。両方の値がゼロの場合、2つのガウシアンは「Unity 」カーネルとなり、差し引くと完全にゼロまたは黒の結果(バイアス値プラス)が生成されます。引数が'Dog:0,0,非ゼロ 'の場合、DoGは単純なハイパスフィルタになり、「Unity」カーネル(元のイメージを生成)からローパスフィルタカーネル(ぼかしイメージ)を引いたものとして定義されます。この場合、sigma1=0は「Unity」カーネルだけであり、sigma2=非ゼロはガウシアンローパス(ぼかし)フィルタカーネルです。したがって、以下はsigma2=2のフィルタ値を持つハイパスフィルタリングされたイメージを生成します。
|
![]() |
DoG:0,2,0
'を使用すると、前のイメージの反転バージョン(出力バイアス周辺)が基本的に返されることに注意してください。この手法は、3x3の「等方性ラプラシアン」カーネル、つまり不等な対角バイアスを持つのではなく、すべての向きで等しい結果を生成する「ラプラシアン
」カーネルを生成するためにも使用できます。たとえば、radius=1(3x3カーネルの場合)およびsigma=1は…を生成します。
|
![]() |
||
|
-blur
」演算子(内部的に「Blur
」カーネルを使用)を使用して、同じ結果を生成できることです。ただし、これを行うには、2つの「ぼかし」イメージをそれぞれ生成してから、適切なスケーリングとバイアスを追加して結果を減算する必要があります。例えば…
|
![]() |
4
')です。これは、2つの正規化されたぼかしを減算しても、「DoG
」カーネルで2つの減算されたガウシアン曲線を一緒に正規化することから得られる結果と同じ(増加した)大きさの結果が生成されないためです。ただし、大きさ以外では、上記の例画像は最初の「DoG
」カーネルの結果と同等であり、特にsigma値が大きい場合、生成が高速です。そして、それがポイントです。より多くの作業であるにもかかわらず、その複雑な方法は、「DoG
」または「LoG
」カーネルを直接使用する場合よりも高速です。離散ラプラシアンカーネル
Laplacian:{type} |
LoG
」カーネルを使用して計算されますが、小さなカーネル配列で離散整数値を使用するようにスケーリングされています。これにより、イメージデータを処理するために整数演算のみを使用する、生成された専用の高速イメージフィルタを使用できます。ただし、ImageMagickはより汎用的なイメージプロセッサであるため、そのような超高速専用フィルタは提供されません。しかし、人々はこれらを使用するのが簡単なので、それらの多くがIMに組み込まれています。ここで提供されているカーネルは回転可能ではなく、ほとんどが「異方性」です。つまり、特に対角方向では完全に円形ではありません。ただし、真の「等方性3x3ラプラシアンカーネル」を生成する方法については、前のセクション(「DoG
」カーネル)を参照してください。「Laplacian:0
」と「Laplacian:1
」の最初の2つのカーネルは、最も一般的に使用されている「離散ラプラシアンカーネル」の形式です。非常に小さいため、エッジを非常に正確に特定できますが、イメージノイズを強調する傾向もあります。すべての'type'番号が定義されているわけではないことに注意してください。将来、より多くの離散カーネルを定義するためのスペースを残しています。使用されている番号は、その番号で定義されているカーネルに最適に一致するように選択されました。Laplacian:0
(デフォルト)
8近傍ラプラシアン。おそらく最も一般的な離散ラプラシアンエッジ検出カーネルです。ここでは、Show Kernelを使用して「離散」で「正規化されていない」カーネルを抽出し、出力バイアスを使用して正規化されたカーネルの結果を表示する前に示します。LoG
」または「DoG
」であるかにかかわらず、目的よりも複雑な結果を生成することがあります。そのような場合、(出力バイアスなしで)バイアスのないイメージを生成すると、より効果的です。したがって、より明るい「正」のエッジのみを維持するために、バイアスなしで上記を繰り返してみましょう。
|
![]() |
|
![]() |
Laplacian:1
4近傍ラプラシアン。これも非常に一般的に使用されます。
|
![]() |
||
|
Laplacian:2
3x3ラプラシアン、中心:4、エッジ:1、コーナー:-2
|
![]() |
||
|
Laplacian:3
3x3ラプラシアン、中心:4、エッジ:-2、コーナー:1
|
![]() |
||
|
Laplacian:5
5x5ラプラシアン
|
![]() |
||
|
Laplacian:7
7x7ラプラシアン
|
![]() |
||
|
Laplacian:15
離散5x5 LoG(Sigmaは約1.4)
|
![]() |
||
|
Laplacian:19
離散9x9 LoG(Sigmaは約1.4)
|
![]() |
||
|
エッジ検出によるイメージのシャープ化(元のイメージのエッジを強調する)
「LoG
」および「DoG
」カーネルは、ぼかしを使用したイメージのアンシャープ化とは対照的に、イメージをシャープ化するためにも使用できます。基本的に必要なのは、カーネルの結果(負の結果を含む)を元のイメージに追加することだけです。これを行うのは簡単です。スケーリング係数に100%の重み付けされた「Unity
」または「Identity」カーネルを追加するだけです。これが提供された理由です。例えば…
|
![]() |
これは、アンシャープテクニックが生成したもの(右側に示されている結果)よりもはるかに幅広く滑らかなイメージのシャープ化です。つまり、ぼかしの減算によって偽造されたものではなく、イメージの実際の真のシャープ化であるためです。 |
![]() |
例えば、シャープさが低い…
|
![]() |
またはシャープさが高い…
|
![]() |
方向畳み込み(傾斜とコンパス)
上記のように、これらのカーネルはイメージの色強度の傾斜を探しますが、任意の傾斜ではなく、特定の方向の傾斜を探します。数学的には、これは「導関数」として知られており、これは「傾斜」という気の利いた言い方です。しかし、異なる方向の傾斜情報を知ることは、ある特定の点におけるイメージ内の傾斜またはイメージエッジの角度または「コンパス」方向を決定するための手段としても役立ちます。つまり、イメージ内の特定の点における傾斜の2次元方向です。傾斜は、「エンボス」や「シェーディング」などのイメージ処理技術にも使用されます。現時点では、「生成された」カーネルは使用できません。 SobelやRobertsなどの「名前付き」の事前に定義されたカーネルのみです。ただし、エンボスとシェーディングのカーネル生成関数は、将来のある時点で形態/畳み込みカーネルセットに移動されることは間違いありません。そこで、いくつかの「名前付き」の方向カーネルを見てみましょう。方向カーネル
Sobel
上記のゼロ合計カーネルの議論で既に「Sobel」カーネルを確認しました。このカーネルは、特定の直交方向にあるエッジの傾斜を返すように設計された、生の方向(1次導関数)カーネルです。「
Sobel:{angle}![]()
convolve
」操作を使用して、デフォルトでは左右の傾斜検出用に設計されています。結果は本質的にイメージのX導関数(傾斜)です。
|
![[IM Output]](slope_positive.gif)

![[IM Output]](kernel_sobel.gif)

![[IM Output]](slope_sobel.gif)
![]() ![]() |
カーネルを見ると、逆順に宣言されているように思えるかもしれません。ある意味では、実際には正しいです。ただし、これは「Convolve」の実際の動作方法によるものです。 この「反転」の詳細については、下記のConvolve vs Correlateで詳しく説明されています。 |
50%
」のバイアスも使用しない限り、これは見ることができません。前の例には負の傾斜はありませんが、次の例には負の傾斜があるため、バイアス設定も追加して確認できるようにしました。
|
![[IM Output]](slope_both.gif)

![[IM Output]](kernel_sobel.gif)

![[IM Output]](slope_sobel_bias.gif)
![]() ![]() |
このカーネルを「Correlate 」で使用すると、カーネルの定義方法に「一致」する傾斜が見つかります。その場合、左側が高く(白の値)、右側が低く(黒の値)傾斜した場合に正の結果が得られます。上記の例では、2本の線が入れ替わります。しかし、上記は「畳み込み」であり、「相関」(カーネルとの一致を意味する)ではありません。畳み込みと相関の違いで、その違いの詳細をさらにご覧ください。 |
Sobel
' カーネルを使用した結果です。Sobel、およびその他のほとんどのエッジ検出カーネルは、非常に強いエッジに沿って2ピクセルの厚さの応答を、1ピクセル幅の線に沿って3ピクセルの応答を生み出す傾向があります。これは、ラプラシアンエッジ検出器よりもはるかに強力です。このカーネルは、一般的に90度の倍数で 'angle' 引数を使用して回転させることができます。ただし、そのように設計されていませんが、45度の倍数で回転させることもできます。これは、45度量子化された方向微分、またはすべての45度回転微分結果の最大値からの勾配の大きさを取得するのに役立ちます。もう一度、90度回転させたもの(上から下)です。
|
![]() |
'
Sobel
' カーネルを使用して画像のすべてのエッジを収集する1つの方法は、カーネルをすべての向きに4回適用し、見られた最大値を収集することです(Lighten数理合成を使用)。これは、勾配の大きさの近似値です。
|
![]() |
Sobel
' カーネルのすべての90度回転の回転済みリストを作成できます。
|
![]() |
|
![]() |
|
![]() |
![]() ![]() |
上記で使用されている "-gamma " 関数は、'Sobel ' の結果によって返された値の数理的な「2乗」と「平方根」を実行するために使用されています。詳細については、べき乗数学関数を参照してください。余分な " +level " は、加算合成が画像の量子範囲を超えないようにします。詳細は量子効果、非HDRI対HDRIを参照してください。 |
magick -size 30x600 xc:'#0F0' -colorspace HSB \ gradient: -compose CopyRed -composite \ -colorspace RGB -rotate 90 rainbow.jpg magick shapes.gif -define convolve:scale='50%!' -bias 50% \ \( -clone 0 -morphology Convolve Sobel:0 \) \ \( -clone 0 -morphology Convolve Sobel:90 \) \ -delete 0 \ \( -clone 0,1 -fx '0.5+atan2(v-0.5,0.5-u)/pi/2' rainbow.jpg -clut \) \ \( -clone 0,1 -fx 'u>0.48&&u<0.52&&v>0.48&&v<0.52 ? 0.0 : 1.0' \) \ -delete 0,1 -alpha off -compose CopyOpacity -composite \ face_sobel_direction.png |
![[IM Output]](shapes.gif)

![[IM Output]](face_sobel_direction.png)
-fx
" 式は、'atan()' 関数を使用してX,Yベクトルを角度に変換する式です。これは、外部の虹色勾配画像で、カラー・ルックアップ・テーブルとして着色されます。2番目の "-fx
" 式は、傾斜のない領域を透明にするしきい値付きの透明度マスクを作成します。ただし、上記の手法は、傾斜の大きさを考慮していないため、実際の画像では大量の情報のかたまりを生み出す傾向があります。より複雑なバージョンを次に示します。これは、必要な画像処理量を3分の1に削減するために、緑の 'G' チャネルですべての計算を実行します。次に、HSBカラー空間を使用して、方向(色相)と大きさ(明るさ)を作成します。
|
![]() |
Roberts
'
Roberts:{angle}![]()
Roberts
' カーネルは、以前の 'Sobel
' カーネルよりもはるかに単純であり、さらにタイトなエッジ位置(最大2ピクセル)を生成します。もちろん、それはノイズの影響を受けやすくなります。通常、このカーネルは、はるかに小さい2x1または2x2カーネルで表されますが、3x3カーネルとして実装することにより、カーネルを45度刻みで「循環的に」回転させることができます。たとえば、これが45度の結果であり、より一般的には 'Roberts-Cross' カーネルとして知られています。
|
![]() |
Sobel
' と同様に、複数カーネル処理を使用して、すべての向きから最大傾斜を生成することもできます。しかし、今回は、4つではなく、8 x 45度の方向が得られます。
|
![]() |
Sobel
' のように、畳み込みの数の半分を単純にマージすることはできません。基本的に、単一の 'Roberts
' 畳み込みによって生成された傾斜は、実際の画像と整列することから半ピクセルオフセットされています。つまり、計算された傾斜は、ピクセルの間の '+1
' と '-1
' の値の間の点に位置しますが、中央の '-1
' ピクセルに格納されます。しかし、これはまた、ピクセル周囲のすべての傾斜を保存してそれらを合計することにより、シャープなエッジ境界を強調するわずか2ピクセル(4ピクセルではなく)の、はるかに小さくシャープなエッジ検出が得られることも意味します。Prewitt
Prewitt:{angle}![]()
'Prewitt ' カーネルは 'Sobel ' と非常に似ていますが、特定のエッジ検出の正確な方向にはるかに緩やかです。したがって、結果は少しぼやけています。
|
![]() |
Compass
Compass:{angle}![]()
これは 'Prewitt Compass' カーネルであり、'Sobel ' よりも方向感覚が強いとされています。
|
![]() |
Kirsch
Kirsch:{angle}![]()
これは、もう1つの強力な方向感知エッジ検出器です。
|
![]() |
Frei-Chen
この組み込み関数では、3つのカーネルセットが提供されています。最初は 'Sobel
' の '等方的'(均一な方向)な変種であり、'2
' の値が2の平方根に置き換えられています。
Frei-Chen:[{type},][{angle}]![]()
上記のカーネルは、'Frei-Chen ' カーネルの中核となるデフォルトの重み付けされていないカーネルです。
|
![]() |
Sobel
' と同様に、このカーネルは90度の倍数の角度を使用して適用する必要があります。簡単にするために、(同じ重み付けを持つ)2つのカーネルが提供されています。1つは直交用途用、もう1つは対角用途用です。
3番目のタイプのセットは、特定の方向のエッジ検出だけでなく、シャープなエッジの実際の角度も決定するために使用される、9つの特別に設計された重み付けカーネルで構成されています。この 'type' は '
Frei-Chen:1 ![]()
Frei-Chen:2 ![]()
11
' から '19
' の数値であり、セット内の9つのカーネルのいずれか1つを抽出できます。ただし、'type' の値を '10
' にすると、すべての9つの事前重み付けカーネルの複数カーネルリストが取得されます。The kernels are each applied to the original image, then the results are added together to generate the edge detection result. This is best done using a HDRI version of ImageMagick.
magick image.png \ \( -clone 0 -morphology Convolve FreiChen:11 \) \ \( -clone 0 -morphology Convolve FreiChen:12 \) \ \( -clone 0 -morphology Convolve FreiChen:13 \) \ \( -clone 0 -morphology Convolve FreiChen:14 \) \ \( -clone 0 -morphology Convolve FreiChen:15 \) \ \( -clone 0 -morphology Convolve FreiChen:16 \) \ \( -clone 0 -morphology Convolve FreiChen:17 \) \ \( -clone 0 -morphology Convolve FreiChen:18 \) \ \( -clone 0 -morphology Convolve FreiChen:19 \) \ -delete 0 -background Black -compose Plus -flatten \ result.pfm
If a type of 10 is given then a multi-kernel list of all the 9 weighted kernels shown above is generated. This lets you use multi-kernel composition to do the above, much more simply...
magick image.png -define morphology:compose=Plus \ -morphology Convolve FreiChen:10 \ result.pfm
I have not however found out what the supposed meaning of the results are. If anyone has any experience or knowledge about how this is actually used, please let me know, so I can include it here for others to use.
相関(
)
'畳み込み
' メソッドは基本的に画像処理に使用されるのに対し、'Correlate
' メソッドはパターンマッチングにもっと適しています。つまり、画像とそのカーネルの「相互相関」を実行し、画像内の特定の形状の一致を探します。実際には、'畳み込み
' と 'Correlate
' は同じ演算です。それらの間の唯一の違いは実際には非常に些細なものであり、つまり、カーネルのxとyの反射(180度の回転に相当)です。相関と畳み込みがどのように機能し、互いにどのように異なるかについての最高のガイドは、David JacobsによるCMSC 426、2005年秋学期、講義ノートです。畳み込みと相関(非対称カーネルの影響)
前述のように、2つの演算子 '畳み込み
' と '相関
' は本質的に同じです。実際、ユーザーは、実際は相関を意味している場合でも、畳み込みという言葉を使用することがよくあります。また、相関は実際に理解しやすい方法です。中心の「原点」を中心に左右対称であるカーネルの場合、これは非常に典型的な場合ですが、2つのメソッドは実際には同じです。違いは、非対称または不均一なカーネルを使用する場合にのみ明らかになります。たとえば、ここでは「単一ピクセル」画像に対して「L」字型の「フラット」カーネルを使用します。
ご覧のように、'畳み込み
' は、中心の単一ピクセルを拡張して、その周囲に「L」字型を形成しました。原点自体が「近傍」の一部ではない場合でも。今度は、代わりに '相関
' を使用してこの例を繰り返してみましょう。ご覧のとおり、'相関
' も単一ピクセルを拡張して「L」字型を形成しましたが、「回転」した「L」字型でした。これは、これらの2つのメソッド間の唯一の違いです。'相関
' メソッドはカーネルを「そのまま」適用するため、単一ピクセルが「回転」した形に拡張されます。一方、'畳み込み
' は実際にはカーネルの180度「回転」した形を使用するため、各ピクセルは同じ非回転形状に拡張されます。'畳み込み
' が実際にどのように機能するかについての素晴らしい例をいくつか見たい場合は、EECE \ CS 253 画像処理、講義7、空間畳み込みもご覧ください。22ページの図では、上記のように、実際に「反転」カーネルを単一ピクセルに適用しています。この回転の差はさほど大きくないように思えるかもしれませんが、数学的には、畳み込み演算(アスタリスク( '
*
' )記号で表される)が可換であることを意味します。つまり、カーネルと画像の両方を値の配列(または2つの画像)として扱うと、F * G == G * F
となります。また、畳み込みは結合的であるため、( F * G ) * H == F * ( G * H )
となります。これに関する詳細については、畳み込みの性質(Wikipedia)を参照してください。'相関
'演算は可換でも結合的でもありません。カーネルの回転によって密接に関連しているにもかかわらずです。基本的に '畳み込み
' は数学的な '掛け算' のように動作しますが、'相関
' はそうではありません。この議論の例外は、使用されるカーネルが180度回転しても同一である場合です。つまり、カーネルが「原点」に関して対称である場合です。その特別なケースでは、両方の演算は同等の結果を生成します。人々を混乱させるのは、ガウスぼかし、ラプラシアンなど、畳み込みに使用されるカーネルのほとんどが対称であるため、実際畳み込みを行っているのか、相関を行っているのかはあまり重要ではないということです。そのため、人々は意味を曖昧に理解しがちです。 形状検索(次を参照)の場合や、Sobelなどの方向性カーネルを使用する場合など、対称でない場合にのみ、その違いが本当に重要になります。相関と形状検索
'相関
'メソッド(回転なしでカーネル近傍をそのまま適用する)の実際の用途は、古くからある単純な方法で、提供されたカーネルにある形状とほぼ一致する形状のオブジェクトの位置を特定します。たとえば、'L'字型のカーネルで '相関
' を使用し、上記の畳み込みメソッドの例で作成した画像を検索しようとすると、次のようになります...
|
![[IM Output]](convolve_shape_mag.gif)

![[IM Output]](kernel_lshape.gif)

![[IM Output]](correlate_mag.gif)
補足:上記のカーネル画像の「黒」の領域は、値がゼロであることを表します。このカーネルには負の値はなく、一致する形状には正の値のみが含まれます。 |
相関
'メソッドは、カーネルの「原点」が画像内の同じ形状と完全に一致する点で最大輝度を生成しました。しかし、形状の一部のみが一致する場合にも、それほど明るくはない結果を生成します。形状の一致する部分が多いほど、ピクセルは明るくなります。ただし、'相関
'は今回のケースでは成功しましたが、これは実際には優れた方法ではありません。たとえば、非常に高い輝度の領域では、非常に多くの誤検出を生成する可能性があります。この問題は、画像の暗い背景と一致するべき領域に負の値を使用することで軽減できます。つまり、背景と一致しない領域は、結果のピクセルを暗くする必要があります。
|
![[IM Output]](convolve_shape_mag.gif)

![[IM Output]](kernel_lpattern.gif)

![[IM Output]](correlate_pattern_mag.gif)
補足:カーネル画像をより明確にするために、正(前景)の値を白、負(背景)の値を黒、ゼロ(無視)の値を透明にしてカーネル画像を生成しました。ただし、実際に使用されるカーネルは、数値で完全に定義されており、その「近傍」は完全な長方形です。 |
^
' に注意してください。これは重要です。カーネル内の正の値と負の値を別々に正規化するためです。つまり、前景ピクセルと背景ピクセルの両方を同等に検索する必要があります。つまり、IMのHDRIバージョンを使用するか、出力バイアスを適切に使用することで(上記参照)、与えられた形状の正と負の両方のマッチを検索できます。たとえば、ここでは、正と負の 'L' 字型の形状の両方が含まれるテスト画像に 'L' 字型検索を適用します(表示されている画像は拡大されています)。
|
![[IM Output]](test_mag.gif)

![[IM Output]](kernel_lpattern.gif)

![[IM Output]](correlate_bias_mag.gif)
50%
' のスケーリング係数を削除して、不一致のピクセルを黒、完全一致を白にすることができます。'相関
' 一致画像が作成されたら、一致する「ピーク」を見つける必要があります。これは別の相関を使用して行うことができますが、必ずしもうまく機能するとは限りません。より良い方法は、この目的のために作成された特別な 'ピーク
' を使用した、より正確なパターンマッチングメソッド 'ヒットアンドミス
' モルフォロジーを使用することです。これにより、より暗い色のピクセルにのみ囲まれた単一のピクセルが検出されます。他の 'ピーク
' カーネルを使用して、より緩い一致を見つけることができます。
そしてここでは、形状の最適な一致が見つかった場所を簡単に検出できますが、一致の程度は失われています。比較と部分画像検索の「ピーク検出」セクションを参照することをお勧めします。また、Fred Weinhausのスクリプト「maxima
」も参照してください。将来:非常に大きな画像(ソース画像と部分画像の両方)で非常に高速な画像相関を生成するための、高速フーリエ変換による正規化相互相関。 相関とヒットアンドミス・モルフォロジー
ヒットアンドミス・モルフォロジー法で使用されるカーネルと、私が表現したカーネル画像を比較すると、実際には同じものを表していることがわかります。'ヒットアンドミス ' |
'相関 ' |
|
---|---|---|
前景 | '1.0 ' の値 |
'1.0 ' の値(正規化前) |
無視 | 'Nan ' または '0.5 ' の値 |
'Nan ' または '0.0 ' の値 |
背景 | '0.0 ' の値 |
'-1.0 ' の値(正規化前) |
結果 | 前景の最小値から背景の最大値を減算します。したがって、完全一致のみが正の結果を生成し、閾値処理によりバイナリの一致画像が生成されます。 | 画像が形状にどの程度一致しているかの範囲を生成します。全体的なパターンが存在する限り、一部の背景ピクセルの値が前景ピクセルよりも大きくなる可能性があります。特定の「一致」ピークを見つけるのが困難な場合があります。負の一致も見つけることができます。 |
ヒットアンドミス
' は、明確な前景と背景の差を持つ完全な完全一致のみを見つけます。そのため、ノイズやニアミスに対して '相関
' よりもはるかに寛容ではありません。一方、'相関
' は線形画像処理、より具体的には高速フーリエ変換を使用して実行できます。これにより、特に複数のパターンが関与する場合、より大きなパターンとカーネルを使用したパターンマッチングを大幅に高速化し、画像とパターンを周波数領域に変換するコストを節約できます。実際の画像でも機能しますが、いくつかの前処理とHDRIの使用が必要になる場合もあります。どちらを使用するかは、実際にはユーザー次第であり、求める結果によって異なります。完全一致のみ、またはエラーの多いニアミス、および高速アルゴリズムの使用可能性です。より大きな画像内の小さなカラー画像の完全一致を見つけるには、「magick compare
」プログラムの部分画像検索機能が、'ヒットアンドミス
' または '相関
' メソッドよりもはるかに優れた方法を提供します。これは、「色のベクトル差の最小二乗」を使用して部分画像の一致を行うため、一致結果のより良いメトリックを生成できるためです。ただし、特に大きな画像の場合、速度は同じです。近傍カウント
畳み込みのより珍しい用途の1つは、近傍カウントと呼ばれています。つまり、画像内の各ピクセル点の周囲の特定の領域に存在するピクセルの数を計算することです。近傍のカウント
基本的に、非常に単純な畳み込みカーネルを使用することで、バイナリ画像内の特定の点を取り囲む近傍の数をカウントする画像を作成できます。サイズ '1.5
' のリングカーネルで畳み込むと、近傍カウントが得られます。ここでは、小さな領域内の各ピクセルの近傍をカウントし、前後の個々のピクセルの拡大表示を示します(画像拡大スクリプトを使用して生成)...ご覧のとおり、すべてのピクセルのグレースケールは、エッジに沿った仮想ピクセルの近傍を含め、近傍の数を示しています。カウントに現在のピクセルを含める場合は、代わりに正方形カーネルを使用できます。適切な変換(レベル調整を含む)とPbmPlusファイル形式を使用することで、上記のグレースケールを必要に応じて実際の数値に変換できます。実際の形状の内側に存在するピクセルを除外する場合は、中心ピクセルが強く負のカーネルを使用し、負の結果をクランプします(IMのHDRIバージョンを使用している場合)。大きな負の中心を囲む正の1のこのようなカーネルを生成する1つの簡単な方法は、標準の離散ラプラシアンカーネルを負のスケールすることです。
magick area.gif -define convolve:scale=-1\! \ -morphology Convolve Laplacian:0 -clamp neigh_edge.gif |
![[IM Output]](area_enlarged.png)

![[IM Output]](neigh_edge_enlarged.png)
ライフゲーム
1970年、イギリスの数学者ジョン・ホートン・コンウェイがScientific Americanに発表した、非常に人気のある特別なシミュレーションがあります。現在、これはライフゲーム(Conway's Game of Life)として知られています。これは、各点が「生きている」か「死んでいる」かのいずれかである点のグリッドに基づいていました。「細胞」が次の「世代」で「生きている」か「死んでいる」かは、周囲の生きている隣接細胞の数にのみ基づいた非常に単純なルールセットに依存していました。- 近傍とは、各「細胞」を取り囲む8つのピクセルです。
- 「生きている」細胞は、2つまたは3つの隣接細胞があれば生き続けます。
- 「死んでいる」細胞は、正確に3つの隣接細胞があれば「生きている」(誕生)状態になります。
- それ以外の場合は、細胞は「死んでいる」状態になります、または「死んでいる」状態のままです。
この結果、各ピクセル(「白」)の周囲の8つの隣接ピクセルの数と、中央のピクセルが「生きている」または「白」の場合は値10が加算されます。したがって、このカーネルの値は、死んでいるピクセルでは「
'3: 1, 1, 1 1, 10, 1 1, 1, 1'
0
」から「8
」、生きているピクセルでは「10
」から「18
」になります。このカーネルを20倍の値でスケーリングする(実際には「0.05
」でスケーリングしてグラデーションを生成します。後述)と、21個の可能なグレースケールレベルを持つ画像が生成されます。つまり、「0
」グレースケールレベルには「黒」の値、「21
」グレースケールレベルには白の値が得られます(カーネルがそのような値を実際に生成できるわけではありません)。これで、「ライフゲーム」のルールをカラー参照テーブルイメージにエンコードして、上記のカーネルによって生成された近傍数の「グレースケールレベル」を、「ライフゲーム」のルールに従って適切な「生死」の結果に変換することができます。
magick -size 21x1 xc:black -fill white \ -draw 'point 3,0 point 12,0 point 13,0' \ life_clut.gif enlarge_image -25.3 -ml 'Life Rules' life_clut.gif life_clut_enlarged.png |
![[IM Output]](life_clut_enlarged.png)
magick -size 15x15 xc:black -fill white \ -draw 'line 3,2 3,4 line 10,10 12,10 point 10,11 point 11,12' \ life_gen_000.gif magick life_gen_000.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_001.gif magick life_gen_001.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_002.gif magick life_gen_002.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_003.gif magick life_gen_003.gif -define convolve:scale=0.05 \ -morphology Convolve '3:1,1,1 1,10,1 1,1,1' \ life_clut.gif -interpolate integer -clut \ life_gen_004.gif |
![[IM Output]](life_gen_000_mag.gif)

![[IM Output]](life_gen_001_mag.gif)

![[IM Output]](life_gen_002_mag.gif)

![[IM Output]](life_gen_003_mag.gif)

![[IM Output]](life_gen_004_mag.gif)
![[IM Output]](../images/glider_gun.gif)
|
![[IM Output]](life_pattern.gif)

![[IM Output]](glider_gun_anim.gif)
これは、IMで処理できるさまざまな「セルオートマトン」のほんの一例です。「ライフゲーム」や「セルオートマトン」には、一般的にまったく同じことを行う、より高速な専用のプログラムが多く存在しますが、IMでも十分に柔軟性があることを示したかったのです。結果は単純なバイナリ画像であるため、IMのモルフォロジーメソッド(ヒットアンドミスパターン検索や相互相関など)を使用して特定のライフゲームパターンを検索することもでき、ライフゲームの研究にIMを使用する際の実際性(ただし速度は遅い)を高めることができます。