標準関数だけで画像の部分的ズーム

Tips

スポンサーリンク

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

  • 標準関数だけで画像の部分的ズームを行う方法

を紹介しています。

画像の解析を行う際に、部分的に画像を拡大したいと思う場合、LabVIEWの有償アドオンであるVision関係のソフトウェアを使用しているのであれば標準機能としてズームが使用可能です。

もし有償アドオンは使用せずに、LabVIEWで標準関数として使える機能のみで拡大操作を行う場合、画像を表示することができるピクチャ表示器のプロパティとして設定が必要になります。

このプロパティの設定と、「指定した部分を拡大」という機能を一つにして実装する例を紹介します。

なお、記事後半では複数の拡大画像をそれぞれ独立したウィンドウで表示させる方法も紹介しています。

スポンサーリンク

どんな結果になるか

フロントパネルには画像を指定するためのファイルパス制御器や画像を表示させるためのピクチャ表示器や拡大率、拡大範囲を指定する際の枠の色を決めるカラーボックス制御器があります。

プログラムを実行して拡大したい部分を指定するとその部分の拡大画像を表示できます。

拡大の倍率は変えることができ、それに合わせて右に表示した拡大画像のピクチャ表示器自体も大きさが変わります。

プログラムの構造

プログラムは、このブログでは比較的よく参照している「ペン属性と画像サブセット」のサンプルをベースにしています。

このサンプルのブロックダイアグラムを新規viにコピペし、そこに修正を加えるようにプログラムを書くと楽です。

ブロックダイアグラムの全体像は以下のようにしています。

Whileループに入る前の段階で、最初に読み込む画像を処理します。

ピクチャではbmp以外にjpeg、jpg、pngファイルが指定できます。

フロントパネル上のメインのピクチャ表示器(画像全体を表示する)と、右隣のサブのピクチャ表示器(拡大画像を表す。下図では「サブセット」となっている)との位置関係が常に「メインより少し右にサブ」となるように、サブのピクチャ表示器のプロパティ「左」を指定しておきます。

get_image_size.viは以下のようなフロントパネルおよびコネクタペーンを持ちます。

やっていることは、画像をピックスマップに変換するだけです。

対象となる画像が24ビットピックスマップなのか8ビットピックスマップなのかは場合によりけりなので、どちらにも対応できるようにしています。

メインVIに戻り、Whileループの中身について紹介していきます。

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

オリジナルのサンプルプログラムの同イベントの中身から少し変更しています。

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

こちらも、オリジナルのサンプルと比べると少し修正しています。

次にピクチャのマウスアップイベントです。

Whileループに入る前に使用していたget_imze_size.viをここでも使用しています。

また、サブセットピクチャ表示器のズーム係数と描画領域サイズのプロパティを指定しています。

次はピクチャのマウス境界外イベントです。

サンプルプログラムそのままの実装にしています。

次はピクチャのマウス境界内イベントです。

こちらも、オリジナルのサンプルに少し修正を加えています。

次は画像変更のボタンの値変更イベントです。

次は停止ボタンの値変更イベントです。

Whileループを止めるだけですね。

拡大画像を別ウィンドウに表示させる場合

上で紹介したプログラムでは、一度に一つの拡大画像しか表示できません。

そうではなく、拡大倍率を変えた画像、あるいは異なる部分を指定した拡大画像を複数表示して比較するような場合に、各画像を独立したウィンドウに表示させることができると便利です。

別ウィンドウの実体はサブVI(subwindow.viという名前にしています)で、これを非同期呼び出しすることで複数表示させるようにします。

なのでサブVIを用意するのですが、用意するサブVIのフロントパネルは、ピクチャ表示器しか表示されないように、ウィンドウの枠を調整してください。

ただし、フロントパネルの表示されていない部分には、メインVIから値を受け取るための数値表示器やクラスタを置いておきます。

なお、上の図ではフロントパネルに3つの制御器や表示器しかないように見えますが、実際にはピクチャ制御器(メインVIから画像を受け取るために必要。「サブセット2」のこと)もあります。

ただ、ブロックダイアグラムで該当のピクチャ制御器(下の図で「サブセット2」となっているもの)を右クリックし「制御器を隠す」とすることでフロントパネルには表示されないようにしておきます。

こうしないと、メインVIから受け取る画像の大きさによっては、フロントパネルに無意味に表示されてしまうことになります。

また、subwindow.viの中で別のサブVIを使用しており、これはユーザーイベントを管理するためのサブVIになっています。

この仕組みは、メインVIを「停止」のボタンで閉じる際、もし複数の拡大画像がサブVIとして表示されていたらそれらも一度に全て閉じるための仕組みを設けるために必要となります。

このuser_event_preparation.viのブロックダイアグラムは以下のようになっていて、機能的グローバル変数的な構造をしています。

このuser_event_preparation.viをメインVIの最初に呼び出してユーザーイベントを作り出しておき、メインVIが閉じる際にユーザーイベントによってサブVIを閉じるようにしています。

そこで、メインVIの一部を以下のように修正していきます。

まず、全体像は下に示した通りで、Whileループに入る前にuser_event_preparation.viで「create user event」を指定しておきます。

また、Whileループ終了時には「close user event」が実行されるようにしておきます。

Whileループの中身も一部修正します。

ピクチャのマウスアップイベントにて、サブVI(拡大画像を表示させるsubwindow.vi)を非同期で呼び出すようにしています。

VIの呼び出しについてわからないよという方は以下の記事を参考にしてみてください。

次に画像変更の値変更イベントです。

前のプログラムに比べて、メインVIに拡大画像を表示させなくなった分、すっきりしています。

あとは、停止の値変更イベントです。

ここでuser_event_preparation.viを使用して「refer user event」を使用してユーザーイベントを駆動させることで、この時点で開いているサブVIであるsubwindow.vi全ての中でユーザーイベントが実行され、ウィンドウが閉じることになります。

本記事では、標準関数だけで画像の部分的ズームを行う方法を紹介しました。

大きな画像の細かい領域を確認したい場合にこういった機能を実装する方法の一案として参考になればうれしいです。

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

コメント

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