孤立点の除去を行う収縮・膨張処理は以下のようにします。
対象は2値画像であるとします。また、以下の例では画像は1列の配列として扱っています。
また、収縮と膨張を行う回数は同じでなければなりません。
除去したい孤立点の広さに応じて繰り返しこの関数を呼び出します。
複数回の収縮・膨張処理を施す場合、直前の収縮・膨張処理結果に対して次の収縮・膨張処理を行うので、パラメータで処理回数を指定する関数にすると間違えやすくなります。
また、4隅の点、隅の4辺と、場合分けを行わないと、領域外を処理してしまいます。
//膨張処理 void Inflate( Byte *btData, int nRow, int nCol ) { LONG i, j; Byte *btOut = new BYTE[nRow*nCol]; for ( i = 0; i < nRow; i++ ) { for ( j = 0; j < nCol; j++ ) { btOut[i*nCol + j] = btData[i*nCol + j]; if ( i == 0 ) //上の列の場合 { if ( j == 0 ) //左上角の場合 { if ( btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 255; } else if ( j == nCol-1 ) //右上角の場合 { if ( btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 255; } else //それ以外の場合 { if ( btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 255; if ( btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 255; } } else if ( i == nRow - 1 ) //下の列の場合 { if ( j == 0 ) //左下角の場合 { if ( btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 255; } else if ( j == nCol-1 ) //右下角の場合 { if ( btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 255; } else //それ以外の場合 { if ( btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 255; } } else { if ( j == 0 ) //左の列の場合 { if ( btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 255; if ( btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 255; } else if ( j == nCol-1 ) //右の列の場合 { if ( btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 255; if ( btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 255; } else //中の場合 { if ( btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 255; if ( btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 255; if ( btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 255; } } } } for ( i = 0; i < nRow; i++ ) { for ( j = 0; j < nCol; j++ ) { btData[i*nCol+j] = btOut[i*nCol+j]; } } delete btOut; } //収縮処理 void Deflate( BYTE *btData, int nRow, int nCol ) { LONG i, j; BYTE *btOut = new BYTE[nRow*nCol]; for ( i = 0; i < nRow; i++ ) { for ( j = 0; j < nCol; j++ ) { btOut[i*nCol + j] = btData[i*nCol + j]; if ( i == 0 ) //上の列の場合 { if ( j == 0 ) //左上角の場合 { if ( !btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 0; } else if ( j == nCol-1 ) //右上角の場合 { if ( !btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 0; } else //それ以外の場合 { if ( !btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 0; if ( !btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 0; } } else if ( i == nRow - 1 ) //下の列の場合 { if ( j == 0 ) //左下角の場合 { if ( !btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 0; } else if ( j == nCol-1 ) //右下角の場合 { if ( !btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 0; } else //それ以外の場合 { if ( !btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 0; } } else { if ( j == 0 ) //左の列の場合 { if ( !btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 0; if ( !btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 0; } else if ( j == nCol-1 ) //右の列の場合 { if ( !btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 0; if ( !btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 0; } else //中の場合 { if ( !btData[(i-1)*nCol + (j )] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j-1)] ) btOut[i*nCol+j] = 0; if ( !btData[(i )*nCol + (j+1)] ) btOut[i*nCol+j] = 0; if ( !btData[(i+1)*nCol + (j )] ) btOut[i*nCol+j] = 0; } } } } for ( i = 0; i < nRow; i++ ) { for ( j = 0; j < nCol; j++ ) { btData[i*nCol+j] = btOut[i*nCol+j]; } } delete btOut; }