この記事で扱っていること
- PC間で画像データを転送する方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWのプログラムを使ってPC間でデータをやり取りする際の方法の一つに、TCP/IP通信があります。
LabVIEWに付属するサンプルでは、適当な数値データをサーバーとクライアントで送受信する方法を確認できますが、画像データをピクセル値の2次元配列化してしまえば、画像データの送受信への応用が可能です。
LabVIEWで画像データを扱うにはVision 関連のアドオンソフトウェアがありますが、そういった有料のアドオンソフトウェアを使用せずともLabVIEWの標準関数で画像を扱える関数があるので、これを用いてPC間で画像データをやりとりするプログラムを作成してみました。
どんな結果になるか
サーバー、クライアントそれぞれのプログラムを用意する必要があります。Visionのアドオンソフトウェアを使用しない場合、LabVIEW上で画像を表示するにはピクチャ表示器を使用するため、サーバーもクライアントもピクチャ表示器を用意して、ここに対象の画像を表示するようにしています。
サーバー側を実行してからクライアントを実行し、サーバー側では送りたい画像をリストボックスから選択します。画像を選択した状態で送信ボタンを押すとクライアント側に送ることができます。
通信にはいくらか時間がかかるので、全体の受信にどれくらいの時間がかかるのかを表示するためのプログレスバーをクライアント側のフロントパネルに用意しています。
プログラムの構造
二つのプログラムを使用する必要があるのでそれぞれ紹介しますが、ベースの考え方はLabVIEWのヘルプで「サンプルを検索」を選択して表示されるNIサンプルファインダにあるSimple TCPのサンプルプログラムと同じです。
まずはサーバー側のプログラムから。
プログラムの全体像は以下のようです。ユーザーが画像を指定し、送信ボタンを押すまでをイベントストラクチャを使用して待機させています。
なお、このサンプルではTCPリスンの関数でlocalhostを指定しています(そのためこのままだとサーバプログラムとクライアントプログラムが同じPC内で使用する前提となっています)が、別PCと通信する際にはそのPCのIPアドレスを指定できるようにサーバ名入力を定数ではなく制御器にしたほうがいいかもしれません。
二つのイベントを定義していますが、片方は単に停止ボタンを押されたことでプログラム自体を終了する、停止ボタンの値変更イベントなので特に説明することはありません。
送信ボタンの値変更イベントの中では、指定された画像を、グラフィック&サウンドの関数パレットの中のグラフィック形式パレットの中にあるピックスマップを非平坦化関数により2次元配列データに変換しています。これをキューでサーバループに渡しています。
そのためキューの要素データタイプは数値の配列になりますが、数値の表記法はピックスマップを非平坦化の関数の出力に合わせる必要があります(出力が24ビットピックスマップの場合には数値配列の表記法はU32にする、など)。
サーバループの方では、TCP書き込みの関数で複数回に分けてデータをクライアントに渡しています。
まず送るのは画像の2次元配列のサイズのデータです。これはクライアント側で何回Forループを回すかに関わってきます。次に画像データの中身を一行ごとに送信しています。
なお、Whileループの中にある大きなケースストラクチャの「エラー」ケースでは特にプログラムは用意しておらず、デキュー関数のエラーワイヤをWhileループの条件端子に配線しているだけです。
プログラムが終了する、つまり終了ボタンが押されたらサーバループは抜けますが、その後はサンプルと同様、エラーの有無に応じて接続を閉じた状態をポップアップするようにしています。
続いてクライアント側のプログラム。こちらは、サーバ側でデータを送る順番に合わせて受け取るだけです。
最初にForループのサイズを受信できるはずです。ここでデータを受け取れない場合にはケースストラクチャの「..0」を実行し、Whileループが回るようにしています。
画像サイズを受信して何行あるか(Forループを何回回すか)の情報を取得する際には、これは配列になっていて要素番号0が配列の行の数になっているので、指標配列で要素0の数字を取り出してForループのカウント端子に指定、後はForループの中でそれぞれの行を順々に受信していきます。
Forループの出力トンネルを自動指標付け有効にして、後は送信時とは逆にピックスマップに平坦化して平坦化ピックスマップ描画の関数で画像を表わします。ここら辺のピクチャに関する関数はどれも グラフィック&サウンドの関数パレットの中にあります。
プログラム終了、つまりWhileループを抜けた後の動作はサーバプログラム同様、ポップアップを出しているようにしますが、必須ではありません。
画像がうまく送受信できない場合
このプログラムで正しく画像の受け渡しを行うコツは、データタイプを一致させることです。
サーバ側、クライアント側それぞれで数値のタイプを合わせないとうまく数値配列を扱えなかったりします。
また、画像が表示されない場合には、そもそも平坦化、非平坦化の関数で24ビットピックスマップに変換されていない可能性もあるかもしれません。これらの関数には8ビット、4ビットなど他の入出力もあるのでどこから値が出力されているかを確認する必要があります。
JPEG以外の画像ファイル形式として、BMPやPNGも関数として扱えるものはあるのですが、変換がうまくいかないのか、期待した結果が得られないことがあるようです。
そのため今回のプログラムを期待通りに動作させるためにはJPEGがいいと思います。(おそらくBMPなどでもちゃんと画像を正しく表示させるには、画像ファイル形式に依らず画像配列データを画像に変換できる、Visionアドオンソフトウェアの関数を使用する必要があると思います)
今回の記事ではTCP通信によって画像データをPC間で受け渡す方法を紹介しました。もちろんVisionのアドオンソフトウェアを使用しても同様な機能を実現することができると思うのでそれでもいいのですが、LabVIEW標準の関数で対応できるようにすることを目的にしたサンプルとしているのでアドオンがない方にも参考にしてもらえるとうれしいです。
ここまで読んでいただきありがとうございました。
コメント