標準関数だけで粒子枠を抽出

Tips

スポンサーリンク

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

  • 標準関数だけで粒子枠を抽出する方法

を紹介しています。

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

LabVIEWで画像処理を行うためのアドオンソフトであるVision Development Moduleが無くても、簡単な画像処理であれば配列関数を用いて実装することができます。

今回の記事では、画像内の特定対象に対して輪郭を強調するような処理を実装します。

要は輪郭を抽出するという操作になるわけですが、グラフ表示に応用することもでき、これは記事後半で紹介しています。

スポンサーリンク

どんな結果になるか

フロントパネルには、画像を表示させるための2Dピクチャ表示器と、対象領域を選択する際の四角の色を指定するカラーボックス、対象領域を識別する際のピクセル値しきい値を設定する数値制御器があります。

プログラムを実行して画像を指定し、ドラッグ操作で四角を描くとその中の対象の輪郭を強調表示することができます。

複数の対象を囲めばまとめて強調させることもできます。

プログラムの構造

ピクチャに四角を描画する仕組みは、サンプルファインダのサンプルで既に機能があるので、これを丸々コピペするのが簡単です。

サンプルがそもそもイベントベースのプログラムになっており、ここから改造していく想定で作ると効率がいいです。

まずはピクチャのマウスダウンイベントです。

サンプルに元々あるイベントですが、ケースストラクチャはいらないので以下の図のようにしておきます。

次にピクチャのマウス移動イベントです。

こちらもサンプルプログラムの内の一部のケースを使用するのみです。

次のピクチャのマウスアップイベントにて、二つのサブVIを使用しています。

サブVIのうちの一つは、エッジ検出処理を行います。

後で使用するもう一つのサブVIで輪郭を描画する際の、その輪郭点がどこにあるかを調べて配列として出力します。

ブロックダイアグラムはかなり大きくなっているのですが、ほとんど似たような操作を行っているForループが4つあるだけなので、見た目ほど作るのは大変ではなく、コピペしてから違いがある部分のみ関数を置き換えれば作ることができます。

以下の図はこのサブVIのブロックダイアグラムの左上部を表しています。

入力されたピクチャの情報から画像データを抽出、2次元配列に変換してから「色をRGBに変換」関数によって色の一部を取り出しています。

この処理は、扱う画像がカラー画像であることを前提にしており、そのうちの一部の色の情報を抜き出して処理を行うためのもので、抜き出すのがRかGかBかは「これじゃなきゃだめ」というものはありません。

画像によって切り替えるような仕組みを設けることもできると思いますが今回は実装していません。

4つあるForループの左上にあるものは、二重Forループの内側で左から右へエッジを検出するための処理を進め、右端に到達したら次の行に進み再び左から右へエッジを検出するための処理を進める、ということを外側のForループで繰り返しています。

あとは、こういった操作を「左から右」だけじゃなく「右から左」に対しても行います。

それがサブVIの左下部分にあるForループです。

そして、左右方向だけでなく「上から下」および「下から上」に対してエッジ検出を行う処理も追加しておきます。

4つあるForループの中身はそれぞれ微妙に違いがある(内側のForループの「名前でバンドル」関数のX、Yの順序と、外側のForループの「名前でバンドル解除」の項目名)のでそれぞれ注意してみてください。

次に、もう一つのサブVIであるdraw_contour.viです。

こちらは、find_edge contour.viで抽出したエッジ部分に対して指定の色(今回は赤で固定)でピクチャ上に表示する処理を行っています。

find_edge contour.viで得られた、エッジの座標情報(クラスタ)の配列に対して赤色を置換していくだけです。

もちろん、このサブVIで固定している色を赤から別の色にすれば、別の色で輪郭を強調できるようになります。

メインVIのイベントの紹介に戻ります。

ピクチャのマウス境界内外、停止ボタンの値変更イベントは特別説明することもありません。

最後に、ファイルパスの値変更イベントです。

こちらについては、ピクチャが画像全体を表示できるようにプロパティノードに対して読み込んだ画像のサイズの情報を入力しておきます。

グラフとして取り出す場合

輪郭を囲った対象領域をグラフに表示させることもできます。

既に(x,y)のペアの配列としてデータを取得しているので、これをXYグラフにそのまま配線すること自体はできますが、反転して表示されてしまいます。

そのため、ピクチャに表示したとおりにXYグラフに移すには少し変換処理を加える必要がありますが、それさえ追加すれば以下のようにXYグラフ上で輪郭の情報を扱えるようになります。

この反転表示を直すための処理としてxy_graph_convert.viを挟むことで、ピクチャに表示した輪郭のままXYグラフに表示させることができ、この処理はfind_edge contour.viの後に置きます(以下の図ではdraw_contour.viの前に置いています)。

xy_graph_convert.viは以下のようなフロントパネルをもちます。

ブロックダイアグラムは以下のような形をしています。

ピクチャの縦の長さの情報(Rectangle.bottom)から、輪郭のYの値を引くだけです。

なお、XYグラフの表示位置がピクチャにかぶらないようにするためには、以下の図のような処理をファイルパスの値変更イベントに実装する必要があります。

本記事では、標準関数だけで粒子枠を抽出する方法を紹介しました。

配列操作が少しめんどくさいですが、そんなにタイムラグなく輪郭抽出できる方法として参考になればうれしいです。

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

コメント

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