標準関数だけでキャリパ処理

Tips

スポンサーリンク

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

  • 標準関数だけでキャリパ処理を実装する方法

を紹介しています。

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

画像処理によって得られるデータには、何かしらの目安となる距離や角度といった情報が挙げられます。

画像に映った対象物がどのような形状をしているかを検査する中でこれらの情報が必要となることがありますが、LabVIEWでこういった情報を得るには有償ソフトであるVision Development Moduleを使用してキャリパ処理を行うのが有効です。

ただ、有償ソフトウェアを使用するというのが障害となることもあるため、もう少し気軽に実装できないかと思い、2Dピクチャを使用してキャリパ処理を実現する方法を考えました。

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

スポンサーリンク

どんな結果になるか

フロントパネルには、対象となる画像ファイルやペンの色、何を測りたいかの選択肢を示した列挙体と、リセットボタンや終了ボタン、結果の表示器があります。

画像を選択して例えば「距離」を選択したら、画像上に距離を調べたい2点をクリックします。すると、結果の表示器に距離の情報が表示されるようになります。

他には、角度の情報として例えば水平軸(X軸)や垂直軸(Y軸)からの角度の情報を出すことができます。

あるいは3点、4点打った時に定義される角度を表示したりします。

ただし、ここでの長さや角度の計算はサブピクセル単位で行うものではありません。

そのため、有償ソフトウェアであるVision Development Moduleで行った結果とは多少異なることがありえます。

場合によっては精度として十分、ということもあるかもしれないですが、あくまで目安として使用する程度の気持ちで考えてください。

プログラムの構造

ベースのプログラムは、サンプルファインダのサンプルを使用しています。

このサンプルをベースにすることで、以下でそれぞれ紹介する機能を追加するだけでキャリパ処理を実現していきます。

実際のプログラムを以下で紹介します。

サンプルプログラムをベースとしているのでサンプルのままでいいイベントもありますが、いくつか追加しています。

各イベントの中で処理に使ういくつかの値をループに入る前に初期化しておきます。

「いくつかの値」としては以下があります。

  • Mouse Position・・・マウスクリックした際の位置情報を記録する配列。記録するべき位置情報の数は処理の内容により、その数の分だけ配列要素を用意しておくために配列初期化を使用。デフォルトだと最初は「距離」の処理でありこれは記録するべき位置情報の数は2つとしている。
  • pict size・・・処理の一部で画像全体の大きさの情報を使用するためその情報を保持する役割がある。
  • # of points・・・何回クリックしたかをカウントする。処理によってこのクリック数がどの値になったら演算を始めるかが決まっている。

では、各イベントの中身を紹介します。

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

サンプルプログラムで既に実装されている処理に加えて、実際に距離や角度の演算処理を行うのをこのイベント内で行っています。

ただし演算は毎回行うのではなく、処理内容によって「何回このイベントが発生したら演算するか」が決まっています。

例えば「距離」を計算するのであれば、2点があればいいですが、「3つの点でできる角度」についてはその名の通り3点が必要となる、といった具合です。

また、処理内容はそれぞれケースストラクチャで以下のように分けています。

各ケースストラクチャ内のサブVIの中身については後述する「処理用のサブVI例」を参考にしてみてください。

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

拡張子の種類に応じて、どの関数を使用するかをケースストラクチャで分けています。

画像ファイルから画像を読み取るこれらの関数は、関数パレットの「グラフィック&サウンド」の「グラフィック形式」パレットにあります。

また、この時点で画像のサイズは確定するのでその情報をシフトレジスタに入れるようにしています。

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

サンプルをベースにしているので何か大きく追加する処理は特にありません。

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

ここは正直何も入れなくていいです。

ピクチャのマウス境界外イベントでは、マウスカーソルの形を変更します。

これもサンプルのままで大丈夫です。

ピクチャのマウス境界内イベントも同様です。

項目選択やリセットボタンの値変更イベントでは、クリックした点の仕切り直しや何回クリックしたかの回数カウントを仕切り直します。

以下の図にあるケースストラクチャはピクチャのマウスダウンイベントにあるものと同じです。

そして停止ボタンの値変更イベントです。

このイベントが発生することでWhileループが終了します。

処理用のサブVI例

それでは次に距離や角度の算出に関連するサブVIを紹介していきます。

実装や計算の仕方はいくつかあると思うので、これが唯一の方法だ、ということではないのであしからず。

まずは距離を測る処理です。

pointのクラスタ配列には、クリックされた2点の情報(配列要素として2つある)が入力されてくるので、それらから距離を求めます。

計算としては、三平方の定理を使えば求められますね。

次に中点を計算するサブVIです。

こちらもpointには2つの要素をもった配列が入ってきます。

単純に「足して2で割る」ことで中点を求めています。

次にライン交点のサブVIです。

この場合、pointの配列は4つの要素を持っていて、1番目と2番目にクリックされた点を通る直線と、3番目と4番目にクリックされた点を通る直線の交点座標を演算で求めます。

和や差、積や商の関数を用いると煩雑になるのでフォーミュラノードで実装してみました。

なお、「境界」(ブロックダイアグラム上ではpict sizeとなっている)は、座標系を扱いやすくする(2Dピクチャの場合Yの値は下に行けば行くほど大きくなるという直感とは逆方向となっているためこれを補正する)ために用いています。

水平線からの角度を計算する場合、pointには2つの要素をもった配列が入力され、その2要素を通る直線の傾きを求めるといった手法を取っています。

垂直線からの角度計算も、水平線からの角度計算と同じ考え方で実装しています。

3点からできる角度の計算は、1番目と2番目、2番目と3番目にクリックされた点を結んで作られる2つの直線(当然2番目にクリックされた点がそれらの交点)に対して定義できる角度をしています。

もちろんフォーミュラノードでの実装の方が見た目がすっきりすると思いますが、ここでは四則演算の関数をそのまま使ってみました。

注意点としては、途中の計算でU32やI32が交わることで演算結果が正しくなくなる場合があることです。

下の図では、ところどころI32に変換する処理を置いています。

4点からできる角度の計算では、ベクトルの内積を求める処理を使用しています。

高校数学を思い出しながら実装してみてください。

結果も表示したい場合

上で紹介したプログラムでは、それぞれの処理に対して結果を文字で表示してくれるのですが、ものによっては結果を画像上に表したいと思うものもあると思います。

簡単に実装できるものとしては、「中点」と「ライン交点」になります。

これらについては以下のようにプログラムの一部を書き換えるだけで実装できます。

やろうと思えば、線分や角度の表示もできるとは思います(本記事では割愛します)。

本記事では標準関数だけでキャリパ処理を実装する方法を紹介しました。

やっていることの本質は座標に対する単純な四則演算や高校で習ったベクトルの内積の計算であり、本記事で紹介した以外の「距離」や「角度」等の情報も計算次第で出せると思いますが、基本的な組み方については本記事で紹介している方法が参考になればうれしいです。

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

コメント

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