カーネル(画像処理)

画像処理においてカーネル畳み込み行列、またはマスクは、ぼかし、シャープ化、エンボス加工エッジ検出などに用いられる小さな行列です。これは、カーネルと画像の間で畳み込みを行うことで実現されます。より簡単に言えば、出力画像の各ピクセルが入力画像内の近傍ピクセル(自身を含む)の関数である場合、カーネルはその関数です。

詳細

畳み込みの一般的な表現は

ここで、 はフィルタリングされた画像、は元の画像、はフィルタカーネルです。フィルタカーネルの各要素は、 およびによって考慮されます

要素の値に応じて、カーネルはさまざまな効果を引き起こす可能性があります。

手術カーネルω画像結果 g(x,y)
身元
リッジまたはエッジ検出
シャープ
ボックスぼかし
正規化
ガウスぼかし3 × 3
(近似)
ガウスぼかし5 × 5
(近似)
アンシャープマスク5 × 5 ガウスぼかし(量1、しきい値0)
に基づく(画像マスクなし


上記は、カーネルと画像を畳み込むことによって実現できる効果のほんの一例です。

起源

原点は、(概念的に)現在の出力ピクセルの上にあるカーネルの位置です。これは実際のカーネルの外側に位置する場合もありますが、通常はカーネル要素の1つに対応します。対称カーネルの場合、原点は通常、中心の要素となります。

畳み込み

2D畳み込みアニメーション

畳み込みとは、画像の各要素をカーネルによって重み付けされた近傍要素に加算する処理です。これは数学的な畳み込みの一種に関連しています。ここで実行される行列演算(畳み込み)は、*で同じように表記されますが、従来の行列乗算とは異なります。

例えば、3行3列の行列が2つあり、1つ目がカーネル、2つ目が画像要素である場合、畳み込みとはカーネルの行と列を反転し、局所的に類似する要素同士を乗算して合計する処理です。結果の画像の座標[2, 2]の要素(つまり中心要素)は、画像行列のすべての要素の重み付き結合となり、重みはカーネルによって与えられます。

他のエントリも同様に重み付けされ、カーネルの中心を画像の各境界点に配置して、重み付けされた合計を計算します。

出力画像内の特定のピクセルの値は、各カーネル値と対応する入力画像のピクセル値を乗算することで計算されます。これは、次の擬似コードでアルゴリズム的に記述できます。

 入力画像画像行 について: 画像行ピクセルについて:      累計器をゼロに設定する  カーネル内のカーネル行 について: カーネル行内要素について:      要素の位置がピクセル位置  に対応する*場合 要素の値 に対応する*をピクセル値に掛け、 結果を累算器加算します     出力画像ピクセルをアキュムレータ設定する
*対応する入力画像ピクセルはカーネルの原点を基準にして検索されます。

カーネルが対称の場合、カーネルの中心(原点)を現在のピクセルに置きます。カーネルは原点を中心とする隣接するピクセルと重なり合います。カーネルの各要素に、重なり合うピクセルの値を掛け合わせ、得られた値をすべて合計します。この合計値が、カーネルの中心と重なり合っている現在のピクセルの新しい値になります。

カーネルが対称でない場合は、上記のように畳み込みを計算する前に、水平軸と垂直軸の両方を中心に反転する必要があります。[1]

行列畳み込みの一般的な形式は

エッジハンドリング

エッジ処理の拡張

カーネル畳み込みでは通常、画像境界外のピクセルの値が必要になります。画像のエッジを処理する方法は様々あります。

伸ばす
最も近い境界ピクセルは、畳み込みに必要な値を提供するために概念的に拡張されます。コーナーピクセルは90°のくさび形に拡張され、その他のエッジピクセルは線状に拡張されます。
包む
画像は概念的にラップ(またはタイル化)され、値は反対側の端または角から取得されます。
画像は概念的に端で反転されます。例えば、端から3単位外側のピクセルを読み取ろうとすると、端から3単位内側のピクセルが読み取られます。
切り取り/重なりを避ける
出力画像において、エッジを超えた値を必要とするピクセルはスキップされます。この方法では、エッジが切り取られ、出力画像が若干小さくなる可能性があります。カーネルを移動することで、画像外の値が必要なくなるようにします。機械学習では主にこの手法が用いられます。例:カーネルサイズ10x10、画像サイズ32x32、結果画像は23x23。
カーネル作物
入力画像を超えて拡張されたカーネル内のピクセルは使用されず、補正するために正規化が調整されます。
絶え間ない
画像外のピクセルには定数値を使用します。通常は黒ですが、場合によってはグレーが使用されます。一般的に、これはアプリケーションによって異なります。

正規化

正規化とは、カーネル内の各要素をすべてのカーネル要素の合計で割ることと定義され、正規化されたカーネルの要素の合計が1になるようにします。これにより、修正された画像の平均ピクセルの明るさが、元の画像の平均ピクセルと同じになります。

最適化

高速畳み込みアルゴリズムには次のものがあります。

  • 分離可能な畳み込み

分離可能な畳み込み

M × Nカーネルを用いた2D畳み込みでは、各サンプル(ピクセル)に対してM × N回の乗算が必要です。カーネルが分離可能であれば、計算はM + N回の乗算に削減できます。分離可能な畳み込みを使用すると、1D畳み込みを1回の2D畳み込みではなく2回行うことで、計算量を大幅に削減できます。[2]

実装

以下はGLSL シェーディング言語で行われた具体的な畳み込みの実装です 。

// 作者: csblo // 参考に作成した作品: // https://en.wikipedia.org/wiki/Kernel_(image_processing)// カーネルを定義します#define identity mat3(0, 0, 0, 0, 1, 0, 0, 0, 0) #define edge0 mat3(1, 0, -1, 0, 0, 0, -1, 0, 1) #define edge1 mat3(0, 1, 0, 1, -4, 1, 0, 1, 0) #define edge2 mat3(-1, -1, -1, -1, -1, 8, -1, -1, -1, -1) #define sharpen mat3(0, -1, 0, -1, 5, -1, 0, -1, 0) #define box_blur mat3(1, 1, 1, 1, 1, 1, 1, 1, 1) * 0.1111 #define gaussian_blur mat3(1, 2, 1, 2, 4, 2, 1, 2, 1) * 0.0625 #define emboss mat3(-2, -1, 0, -1, 1, 1, 0, 1, 2)// インデックスから行列要素の座標を見つけるvec2 kpos ( int index ) { return vec2 [ 9 ] ( vec2 ( - 1 , - 1 ), vec2 ( 0 , - 1 ), vec2 ( 1 , - 1 ), vec2 ( - 1 , 0 ), vec2 ( 0 , 0 ), vec2 ( 1 , 0 ), vec2 ( - 1 , 1 ), vec2 ( 0 , 1 ), vec2 ( 1 , 1 ) )[ index ] / iResolution . xy ; }                           // サンプラーから uv を中心とした 3x3 次元の領域を抽出します// sampler : テクスチャ サンプラー// uv : サンプラーの現在の座標// 戻り値 : 各インデックスがカラー チャネルに対応する mat3 の配列 mat3 [ 3 ] region3x3 ( sampler2D sampler , vec2 uv ) { //領域の各ピクセルを作成しますvec4 [ 9 ] region ; for ( int i = 0 ; i < 9 ; i ++ ) region [ i ] = texture ( sampler , uv + kpos ( i ));                        // 3 つのカラー チャネル (赤、緑、青) を持つ 3x3 領域を作成します。mat3 [ 3 ] mRegion ; for ( int i = 0 ; i < 3 ; i ++ ) mRegion [ i ] = mat3 ( region [ 0 ][ i ], region [ 1 ][ i ], region [ 2 ][ i ], region [ 3 ][ i ], region [ 4 ][ i ], region [ 5 ][ i ], region [ 6 ][ i ], region [ 7 ][ i ], region [ 8 ][ i ] ); return mRegion ; }                            // テクスチャをカーネルで畳み込む// kernel: 畳み込みに使用するカーネル// sampler: テクスチャ サンプラー// uv: サンプラーの現在の座標vec3 convolution ( mat3 kernel , sampler2D sampler , vec2 uv ) { vec3 fragment ; // uv を中心とした 3x3 領域を抽出mat3 [ 3 ] region = region3x3 ( sampler , uv ); // 領域の各カラー チャネルfor ( int i = 0 ; i < 3 ; i ++ ) { // 領域チャネルを取得mat3 rc = region [ i ]; // カーネルと領域チャネルのコンポーネントごとの乗算mat3 c = matrixCompMult ( kernel , rc ); // 行列の各要素を加算しますfloat r = c [ 0 ][ 0 ] + c [ 1 ][ 0 ] + c [ 2 ][ 0 ] + c [ 0 ] [ 1 ] + c [ 1 ][ 1 ] + c [ 2 ][ 1 ] + c [ 0 ][ 2 ] + c [ 1 ][ 2 ] + c [ 2 ][ 2 ]; // チャネル i のフラグメントの結果を設定しますfragment [ i ] = r ; } return fragment ; }                                                                     void mainImage ( out vec4 fragColor , in vec2 fragCoord ) { // 正規化されたピクセル座標 (0 から 1) vec2 uv = fragCoord / iResolution . xy ; // テクスチャとカーネルを畳み込むvec3 col = convolution ( emboss , iChannel0 , uv ); // 画面に出力fragColor = vec4 ( col , 1.0 ); }                          

参照

参考文献

  1. ^ 「2D畳み込みの例」。
  2. ^ 「畳み込み」www.songho.ca . 2022年11月19日閲覧

出典

  • Ludwig, Jamie (nd). 画像畳み込み(PDF) . ポートランド州立大学.
  • ルカルム、オリヴィエ、デルヴァール、カリーヌ(2013年1月)『GIMPの書:ほぼすべてのことへの完全ガイド』 No Starch Press、429ページ。ISBN 978-1593273835
  • ガムスター、ジェイソン・ヴァン; シモンスキー、ロバート(2012年3月). GIMPバイブル. ジョン・ワイリー・アンド・サンズ. pp.  438– 442. ISBN 978-0470523971
  • シャピロ, リンダ・G. ; ストックマン, ジョージ・C. (2001年2月).コンピュータビジョン. プレンティス・ホール. pp.  53– 54. ISBN 978-0130307965
  • FPGA上で2次元畳み込みを実装する
  • vImage プログラミングガイド: 畳み込み演算の実行
  • 2D畳み込みを用いた画像処理
  • GNU 画像操作プログラム - ユーザーマニュアル - 8.2. 畳み込み行列
  • 3x3畳み込みカーネルのGLSLデモ
  • 完全なC++オープンソースプロジェクト
Retrieved from "https://en.wikipedia.org/w/index.php?title=Kernel_(image_processing)&oldid=1315294573"