標準関数だけで画像にフィルタをかける

Tips

スポンサーリンク

この記事で扱っていること

  • 標準関数だけで画像にフィルタをかける方法

を紹介しています。

注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。

画像に対してフィルタ処理をかけるのは、画像をピクセル値の集まりとみなして各フィルタごとに決まっている「型」のピクセル値演算を行わせれば実現することができる処理です。

LabVIEWで行う場合、有償のアドオンソフトウェアであるVision Development Moduleを使用すれば既に用意されたフィルタの関数を使って手軽に実装することができますが、単に演算を行わせるだけであればアドオンを使用せずとも実現することは可能です。

本記事では、フィルタ処理を行うための基本となるプログラムの形を説明して、その基本形からどのように各種フィルタを表現していくかの例を紹介しています。

(各種フィルタの特徴や使用用途等の説明は本記事では行っていません。あくまで、LabVIEWで実装する場合の例を紹介しているだけなのでご注意ください。)

なお、ピクチャの扱い方について以下の記事の内容を知っていると本記事の内容をより理解できると思いますので、適宜参考にしてみてください。

スポンサーリンク

どんな結果になるか

フィルタの種類は数多くありますが、代表例として、ソーベルフィルタ、平均化フィルタと最大値フィルタを扱います。

まずはソーベルフィルタの実装例です。

次は、平均化フィルタの実装例です。

最後に最大値フィルタの実装例です。

プログラムの構造

ベースとなる考え方はどれも同じです。

画像全体から特定領域(カーネル)に注目して各種フィルタに応じた演算を行っていき、元画像のピクセル値を置換していきます。

置換のための関数、ピックスマップを非平坦化の関数では、8ビットピックスマップ以外に24ビットピックスマップとして値が得られる場合もあるので注意してください。

処理する対象領域であるカーネルは、奇数の長さを持った正方形(3×3、5×5など)としています。

もし元の画像に対してそのままカーネルを適用するとフィルタ後の画像サイズが変化(小さくなる)してしまうため、今回はどの場合でも0でパディング(必要分だけ0で回りを囲む)しておきます。

パディングの影響により、画像のサイズ自体はフィルタ前後で変わらないものの、画像の周りに黒い縁ができます。

例えば以下は、上下左右8ピクセル分を0で囲った画像としています。

カーネルとしては17(=8×2+1)を想定しているような感じですね(実際にここまで大きなカーネルサイズでのフィルタは私はみたことはないですが)。

どのような画像も2次元配列に落とし込めばフィルタ処理を行えますが、ユーザーがカーネルのサイズを変更することができるように組む場合、そのサイズ次第でパディングのサイズも変更されるように工夫が必要です。

基本的にはグレー画像を前提としていますが、ピクチャの関数では画像そのものがグレー画像に見えても実際は24ビットのピックスマップで表現されていることがあります。

そこで、24ビットピックスマップか8ビットピックスマップかどちらかで出力される場合に、どちらにも対応できるように工夫します。

全ての「工夫」を盛り込んだプログラムの実装例が以下の図です。

ベースとなるサブVIは既に紹介したものとほとんど同じですが、ピックスマップに対してU8にする必要があるため、最後の部分で範囲内と強制の関数を使って値を矯正しています。

これで、「ベース」ができました。

あとはそれぞれのフィルタの種類に応じて具体的なカーネル配列の中身やサブVIの中の演算を改造していきます。

以下で各フィルタの具体的な実装例を紹介します。

ソーベルフィルタの場合

ソーベルフィルタではカーネルの種類が決まっているので、指示通りにカーネルを指定するだけです。

平均化フィルタの場合

平均化フィルタでは、カーネルで取り出した対象領域のピクセル値の平均を使用するため、以下のように関数を組み合わせることで対応します。

サブVIに入れるカーネルは全ての要素が1の2次元配列とします。

最大値フィルタの場合

最大値フィルタでは、カーネルで取り出した対象領域のピクセル値の中で最大の値を使用することになります。

応用としては、最小値フィルタも同じ考え方で対応できますね。

こちらも、入力するカーネル配列は全ての要素が1となる2次元配列としています。

他の種類のフィルタも同様な考え方で実装できると思うので試してみてください。

本記事では、標準関数だけで画像にフィルタをかける方法を紹介しました。

カーネルの部分の係数としてどのような値を取ればいいかといった情報は検索すればいろいろと見つかると思います。それらの値を適用して、望みのフィルタ処理を実装する際の参考になればうれしいです。

ここまで読んでいただきありがとうございました。

コメント

タイトルとURLをコピーしました