この記事で扱っていること
- 画像をトリミングする方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWで画像のトリミングを行ってみましたという記事です。
LabVIEWで画像を扱うには、標準関数(特にアドオンなどなくてもLabVIEW単体で使用できるもの)としてのピクチャ関数、あるいはVisionのアドオン(Vision Acquisition SoftwareやVision Development Moduleなどの有償追加ソフトウェア)の関数を使用します。
この記事では、どちらの方法でもトリミングはできるのでそれらのやり方を紹介するのですが、せっかくなのでプログラム自体の構造も異なるデザインで作ってみました。
片方はステートマシン、もう片方は単純にWhileループによるポーリングです。
ステートマシンなんて知らないよ、という方はポーリングの方であればそこまで難しくないと思います(ただしプログラムの効率の面では多かれ少なかれ劣ります)。
画像はトリミングするだけでなくいろいろな処理を施す場合が多く、それらの処理についてはやはり有償のVisionのアドオンが優れているのでまずはこちらの方法を紹介し、その後にピクチャ関数による方法を紹介していきます。
なお、画像サイズを変換する関数自体はVisionの関数で既にあるのですが、今回のプログラムのような上下の調整や左右の調整ができないので、愚直に画像の配列データを編集する方が思い通りにトリミングできます。
どんな結果になるか
フロントパネル上には画像を選択するパスと、上下左右の幅を決めるボタンおよび一度にトリミングをキャンセルするボタンがあります。
画像の保存先を選んで保存画像ファイル名を指定し、保存ボタンを押せば保存もできます。今回の例ではBMPファイル形式としていますが、JPEGやPNG形式にも対応できます。
プログラムの構造
効率がいいプログラムといえばイベントストラクチャを使用した方法です。今回のプログラムはステートマシンと組み合わせたデザインパターンで作ってみました。
ステートの数は6個、イベントの数は4個としています。
まず最初に実行されるのが初期化のステートであるinitステートです。
今回のプログラムでは、この初期化のステートで、対象とする画像をファイルから呼び出し、その画像データをIMAQ ColorImageToArray.viによって二次元配列に変換しています。
また後の都合上画像の全体の大きさを知る必要があるため、画像のサイズをIMAQ GetImageSizeの関数で取得しこれを名前付きでバンドルしてクラスタにしています。
次はイベントを決めるeventステートです。4つのイベントのうち3つは単にボタン操作を受けてステートを変えるだけですが、上下左右の数値の制御器の値変更があった場合にはもうイベントストラクチャの中でそれらの値を読み取り、トリミングパラメタとしてtrimmingステートに渡すようにしています。
そのtrimmingステートでは、画像サイズの値と組み合わせて、画像の二次元配列から特定の部分だけを抜き出すために部分配列の関数を使用しています。抜き出し方については以下の画像を参考にしてみてください。
また、今回のプログラムでは画像のサイズを変更した後にこれを実際の表示画像に反映させるにはtrimmingステートを使用するしかありません。これは次のcancelステートの使い方に影響します。
キャンセルボタンが押された場合には、フロントパネル上の上下左右の数値をデフォルト(0)に戻し、かつその状態を画像表示器に反映させる必要があります。
そのため、cancelステートの後はeventステートではなく、trimmingステートに移る必要があります。
デフォルト値に戻すのは、上下左右それぞれの制御器へのインボークノードで設定が行えます。
画像を保存するためのsaveステートでは、画像ファイルに保存するためにIMAQ Write File 2の関数を使用しています。下の画像の例ではこの関数でBMPを選択していますが、この関数はJPEGやPNGなども対応しているため、特定の画像ファイルにする必要がある場合には関数の多態性ラベルを変更します。
またこれに伴い、画像ファイル名の文字列制御器と連結している「.bmp」の定数も適切な拡張子に変更します。
最後は停止ボタンが押された場合のfinishステートです。初期化のステートで用意したIMAQの画像リファレンスを閉じるため、IMAQ Disposeの関数を使用しています。
上記で各ステートの例は終わりです。
もちろんこれらはステートマシンの構造を知らないと組めないのですが、拡張性が高いのが特徴です。もしステートマシンではないやり方、あるいはピクチャの関数を使用した方法が知りたいということであれば以下のトピックを確認してみてください。
ピクチャ関数を使用する場合
さて、上の説明ではVisionの関数を使用したプログラムの例を紹介しました。次に、LabVIEWの標準関数であるピクチャ関数で同様なことを実現するためのプログラムを紹介します。
フロントパネルは下のような感じです。機能も全く一緒です。
プログラムは、今度はステートマシンではなく、すべてをWhileループにおさめる形で作ってみました。
画像をピクチャで扱うためには、グラフィック形式パレットにある、JPEGファイルを読み取るなどの関数を使用します。もちろん、BMPやPNGファイルを扱う場合にはそれぞれの関数を使用します。
これらの関数を使用して画像データ(ピンクのワイヤ)を取得し、これをピックスマップを非平坦化して二次元配列とできればあとはもうやることはVisionの関数を使用する場合と変わりません。
画像に戻す場合には、ピックスマップを平坦化してからピクチャパレットの平坦化ピックスマップ描画の関数を使用してピクチャデータとしてピクチャ表示器に渡しています。
下の例では、プログラムを一番最初に実行したとき、あるいは画像ファイルパスの中身が変わったらそれを読み込むようにしています。
各ボタンがFALSEの場合には以下の画像のプログラムを実行するようにします。
各ボタンの機械的動作は全てラッチとしているため、一度押したらずっとその動作が続くといったようなことにはなりません。
Visionの関数を使用してステートマシンではない組み方をしたり、あるいはピクチャ関数を使用してステートマシンで実装することもできると思います。
使用する関数は似てくるので、挑戦されたい方は試してみてください。
ここまで読んでいただきありがとうございました。
コメント