画像のフィルタリング - mist-team/mist GitHub Wiki
はじめに
MISTが提供する画像・音声のフィルタは,各コンテナに対して適用することができるようになっています. 例えば,音声や2次元画像や3次元画像のどのMISTコンテナに対しても,メディアンフィルタやモルフォロジ演算等を適用することができます. ただし,各次元によって入力パラメータが異なる場合もあるので,ドキュメント を読んで確認してください.
ヘッダの準備
どういうフィルタをかけたいかによって,インクルードするヘッダファイルが異なります. 例えば,メディアン(中央値)フィルタでは,
#include <mist/filter/median.h>
とかく必要がありますし,モルフォロジ演算では,
#include <mist/filter/morphology.h>
とかく必要があります.
まずは,目的のフィルタがMISTに存在するかを ドキュメント を読んで確認してください.
メディアン(中央値)フィルタ
基本的なフィルタの適用方法はいたってシンプルです. 今回は,メディアンフィルタの使用例を説明してみます. メディアンフィルタでは,フィルタのマスクサイズ(中央値を計算する範囲)を設定する必要があります. MISTでは,各軸方向で異なるマスクサイズが利用できるようになっています. まず,読み込んだ2次元画像に対し3×5のメディアンフィルタを適用する場合はこんな感じで書きます.
mist::median( image_in, image_out, 3, 5 );
また,MISTでは複数スレッドを用いた高速化も行っているので,例えば2個スレッドを使って計算したい時は
mist::median( image_in, image_out, 3, 5, 2 );
と書きます. この最後の引数は省略することができ,省略した場合は自動的に最適なスレッド数を設定するようになっています. あたりまえですが,入力画像に画像が設定されていない場合は何も起きないので注意してください.
モルフォロジ演算
基本的なフィルタの適用方法はいたってシンプルです. 今回は,モルフォロジ演算の使用例を説明してみます. モルフォロジ演算では,構造要素を設定する必要があります. MISTでは,任意の凸形状の構造要素に対してモルフォロジ演算が適用できるようになっています. まず,読み込んだ2次元画像に対し半径3の円を構造要素とする opening 演算を適用する場合はこんな感じで書きます.
mist::opening( image, 3.0 );
ここで,MISTのモルフォロジ演算ではアスペクトを考慮した円・球がデフォルトの構造要素となっていることに注意してください. そのため,設定する半径の値は double 型となっています. また,MISTでは複数スレッドを用いた高速化も行っているので,例えば2個スレッドを使って計算したい時は
mist::opening( image, 3.0, 2 );
と書きます. この最後の引数は省略することができ,省略した場合は自動的に最適なスレッド数を設定するようになっています. あたりまえですが,入力画像に画像が設定されていない場合は何も起きないので注意してください. 同様の書き方で,erosion,dilation,closing にも適用することができます.
次に,任意の構造要素を用いてモルフォロジ演算を行う場合には,まず構造要素の作成を0と1の値を持つ画像として作成します. 作成した構造要素画像を element とすると,次のようにして opening 演算を適用することができます.
mist::opening( image, mist::morphology::create_morphology_structure( element, cx, cy ) );
ここで,create_morphology_structure の引数 (cx, cy) というのは,構造要素の中心座標を表しています. これを用いることで,任意の構造要素でモルフォロジ演算を行うことができます. ただし,構造要素は凸形状である必要があるということに注意してください.
サンプルコード
三角形の構造要素を用いて,opening 演算を実行する
// MISTの一番メインとなるヘッダファイル
// 1・2・3次元画像を扱うコンテナが用意されてます
#include <mist/mist.h>
// ファイルから画像を読み込んでMISTで提供するコンテナにデータを格納します
// サポートされている形式は
// JPEG, PNG, TIFF, BMP, PNM です
#include <mist/io/image.h>
// モルフォロジ演算のサポートを追加します
#include <mist/filter/morphology.h>
int main( int argc, char *argv[] )
{
// mist::???? という風にMISTは ''mist'' という名前空間で囲まれています
// (C++の知識が必要?なければおまじないだと思って・・・)
// MISTは全てC++のtemplateの機能を利用して作成されてます.
// なので,2次元画像といってもいろんなデータ型が作成できます
// (例えばグレースケールだったりカラーだったり・・・).
// まずは,画像のデータ形式がどんな物かを決めます(重要です!!)
typedef mist::rgb< unsigned char > value_type; // 画像の要素がRGBの3成分からなるようにします
typedef mist::array2< value_type > image_type; // RGBが要素となる2次元画像の設定
image_type img; // 画像の実体を作ります(プログラムミスを考えて,newで確保するのは控えめに・・・).
if( !mist::read_image( img, "読み込むファイル名を設定します" ) )
{
// ファイルが読めないみたい・・・
return( 1 );
}
// 構造要素を三角形に設定する
mist::array2< unsigned char > element( 9, 5 );
element( 4, 0 ) = 1;
element( 3, 1 ) = 1; element( 4, 1 ) = 1; element( 5, 1 ) = 1;
element( 2, 2 ) = 1; element( 3, 2 ) = 1; element( 4, 2 ) = 1;
element( 5, 2 ) = 1; element( 6, 2 ) = 1;
element( 1, 3 ) = 1; element( 2, 3 ) = 1; element( 3, 3 ) = 1;
element( 4, 3 ) = 1; element( 5, 3 ) = 1; element( 6, 3 ) = 1;
element( 7, 3 ) = 1;
element( 0, 4 ) = 1; element( 1, 4 ) = 1; element( 2, 4 ) = 1;
element( 3, 4 ) = 1; element( 4, 4 ) = 1; element( 5, 4 ) = 1;
element( 6, 4 ) = 1; element( 7, 4 ) = 1; element( 8, 4 ) = 1;
// 三角形を構造要素とする opening 演算を実行する
mist::opening( img, mist::morphology::create_morphology_structure( element, 4, 2 ) );
mist::write_image( img, "書き出すファイル名を設定します" );
return( 0 );
}