この記事で扱っていること
- LabVIEWの標準関数で画像操作
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWには、画像処理を行うための専用の関数群が揃ったアドオンソフトであるVision Development Moduleというものがあります。
これを使うとパターンマッチングや二値化、粒子解析などの処理を実装することができます。ただ、これは有償のアドオンとなるので、購入しないと使用できません。
じゃあLabVIEWだけでは画像を扱えないのかというと、やれることは限られますが簡単な処理なら行うことができます。
今回の記事では、画像を配列データに変換することで簡単に実装できる複数の操作を、画像表示用のviと、操作用のviとで分けて扱えるようにしてみました。
どんな結果になるか
メインとなるviは一つで、これを実行することにより操作用の別ウィンドウが表示されます。

実行時にまずどの画像を扱うかを選択します。そして選ばれた画像が表示されます。
また、画像に対する操作を指定するためのパネル(別ウィンドウ)も表示されます。

操作画面上にあるそれぞれのボタンを押すことで、回転や反転、一部のみの切り出しや加工した画像を保存したりクリップボードに貼ることができます。

プログラムの構造
別画面で画像操作の表示を出すためには、これを単体のサブviとして、このサブviからの指示をメインvi(画像を表示している側)の方で受け取り処理させるような仕組みとします。
これにはキューを使用しています。メインvi上での位置関係としては以下の図のような感じです(操作パネルにあたるサブviはimage_controller.vi)

画像操作の指示を出すサブviは、単にイベントストラクチャがあるだけの簡単な作りです。ただし一部の操作でメインviに値を渡す必要があるため、キューは「メインviでどのステートを実行するかの指示」用の列挙体と「特定のステートで必要になるデータ」用のバリアントを組み合わせたクラスタを扱うこととします。

サブviに対しては、VIプロパティを設定しておけばフロントパネルを表示させることができます。

あらためてサブviの中身について。ほとんどのイベントケースでは単にstateを指定しているだけです。

どれもこれも、ステートを指定していきメインviの方で受け取ったらそのステートに対応した処理を行います。

画像ファイル保存と切り取りのイベントでようやくdataバイナリの部分に値を渡します。

なお、このサブviを作るときには、メインviの中にWhileループやイベントストラクチャ、そしてキューの関数を一通り配置してから、Whileループをドラッグして囲み、メニューバーの「編集」から「選択範囲をサブVIに変換」とすると楽です。その後適宜フロントパネルの見栄えを整えます。
これでサブviのブロックダイアグラムの実装は終わりです。
メインvi側のプログラムはサブviからの指示によって実行されるステートマシンの構造を取っています。
以下それぞれのステートについて紹介します。
まずはInitializeステートです。文字通り初期化を行います。
下の図ではPNGファイルを読み取るようにしていますが、関数パレットの「グラフィック&サウンド」の中にある「グラフィック形式」では、他にBMPやJPEGといった選択肢もあります。

注意点としては、扱う画像によっては「8-bit pixmap」ではない、ということです。その場合には、何bitのピックスマップかをあらかじめ調べておいて、クラスタ部分もそれに合わせるようにします。

次にLeftTurnステートです。2次元配列を左回りに回転させるというイメージですね。
2D配列転置だけでは思った通りに動作しないので1D配列反転を加えています。

次のRightTurnステートは順番を逆にし先に2D配列転置をしています。

Reverseは左右の反転で、これには転置は使用せずに1D配列反転を使用します。
Forループを使用することで、行ごとに処理しています。

UpsideDownステートでは上下逆転させています。

BackToOriginalステートでは、最初に読み込んだデータを使用しています。

Saveステートは、配列を画像に戻してファイルに書き込んでいます。書き込み用の関数も、読み込み用の関数と同様に関数パレットの「グラフィック&サウンド」の中にある「グラフィック形式」のパレットにあります。

Clipboardステートでは、クリップボードに画像を貼り付けます。
ピクチャ表示器のインボークノードに画像をエクスポートする機能があるのでこれを使用しています。

ExtractImageステートでは画面の切り出しを行っています。
配列操作を行うために指定した値を使って範囲を指定して部分配列の関数に入れています。
(以下の図では浮動小数点で扱っていますが、座標は整数しかとりえないので、浮動小数である必要はありません)

最後にfinishステートです。特に何もしません。

その他の画像操作
上で紹介したのは回転や反転といった処理ですが、ベースになる考え方は配列操作なので、配列関数を使用すれば他の操作を実装することもできると思います。
例えば、グレースケール画像であれば白黒の反転を行うようなことができますね。

あるいは、指定した位置にマスク処理をする場合には以下のような処理が考えられます。

ピクチャ表示器の枠を消す
今回のプログラムでは画像を表示するのにピクチャ表示器を用いています。
そのままでもいいのですが、クリップボードに張り付けた場合には、ピクチャ表示器の枠やラベルまで含めてクリップボードに貼られてしまうので、枠を消したい場合が多いと思います。
そんなときにはフロントパネルで枠を透明(Trasnparent)にしておくといいと思います。

本記事では、Vision Development Moduleのアドオンソフトウェアを使用しないで画像に対して操作を行う方法を紹介しました。
本格的な画像解析はなかなか難しいですが、配列操作で行える範囲の処理であれば頑張れば実装できたりもするので、いろいろといじるきっかけになればうれしいです。
ここまで読んでいただきありがとうございました。
コメント