そこにはたくさんのサンプル実装があります.. Googleはあなたの友達です :)
編集
以下は、プロセスの疑似コードです (2D で畳み込みを行うのと非常に似ています)。それを行うためのより賢い方法があると確信しています:
// grayscale image, binary mask
void morph(inImage, outImage, kernel, type) {
// half size of the kernel, kernel size is n*n (easier if n is odd)
sz = (kernel.n - 1 ) / 2;
for X in inImage.rows {
for Y in inImage.cols {
if ( isOnBoundary(X,Y, inImage, sz) ) {
// check if pixel (X,Y) for boundary cases and deal with it (copy pixel as is)
// must consider half size of the kernel
val = inImage(X,Y); // quick fix
}
else {
list = [];
// get the neighborhood of this pixel (X,Y)
for I in kernel.n {
for J in kernel.n {
if ( kernel(I,J) == 1 ) {
list.add( inImage(X+I-sz, Y+J-sz) );
}
}
}
if type == dilation {
// dilation: set to one if any 1 is present, zero otherwise
val = max(list);
} else if type == erosion {
// erosion: set to zero if any 0 is present, one otherwise
val = min(list);
}
}
// set output image pixel
outImage(X,Y) = val;
}
}
}
上記のコードは、このチュートリアルに基づいています (ページの最後にあるソース コードを確認してください)。
EDIT2:
list.add( inImage(X+I-sz, Y+J-sz) );
アイデアは、(X,Y) にある現在の画像ピクセルに sz (マスクの半分のサイズ) を中心とする (サイズ nxn の) カーネル マスクを重ね合わせ、マスクが存在するピクセルの強度を取得することです。値は 1 です (リストに追加しています)。そのピクセルのすべての近傍を抽出したら、出力イメージ ピクセルを、拡張用にそのリストの最大値 (最大強度) に設定し、浸食用に最小値に設定します (もちろん、これはグレースケール イメージとバイナリ マスクでのみ機能します)
。両方の X のインデックス上記のステートメントの /Y および I/J は、0 から始まると想定されています。必要に応じて、I/J のインデックスをマスクのサイズの半分 (-sz から +sz まで) でいつでも書き換えることができます。小さな変更(私がリンクしたチュートリアルが使用している方法)...
例:
この 3x3 カーネル マスクが配置され、ピクセル (X,Y) を中心として配置されていると考えて、その周囲をどのようにトラバースするかを確認します。
--------------------
| | | | sz = 1;
-------------------- for (I=0 ; I<3 ; ++I)
| | (X,Y) | | for (J=0 ; J<3 ; ++J)
-------------------- vect.push_back( inImage.getPixel(X+I-sz, Y+J-sz) );
| | | |
--------------------