この記事で扱っていること
- 動画再生をコントロールする方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWのアドオンソフトであるVision Acquisition SoftwareあるいはVision Development Moduleがあると、aviファイルの動画再生を行うための関数を使用することできます。
使い方は特別難しいものではなく、動画再生の場合には、対象のファイルを開く、閉じるの関数を用いてそれらの間に動画ファイルの中身の各画像について番号を指定して取り出す関数を使用します。
番号の指定は例えばループの反復端子が便利ですが、任意の値を数値制御器で指定することもできます。
そこで、手動で任意の番号の画像を見ることやあるいは自動で再生、逆再生を行うようなプログラムを考えてみました。
どんな結果になるか
フロントパネルには、再生する動画を指定する制御器や、手動で動画操作を行うための数値制御器(水平ポインタスライド)と自動で再生、逆再生を行うためのボタン、手動と自動を切り替えるためのボタンをつけています。
動画ファイルを指定してプログラムを実行すると、再生位置のスライドを変えることで動画中の任意の位置の画像を表示させることができます。
また、手動と自動のモードを切り替えるスイッチ動作のブールをTRUEにすると再生と逆再生が選べ、ボタンを押せば再生位置が自動的に切り替わります。
なお、今回のプログラムでは、自動のモードにして、再生か逆再生どちらかの再生方法を選んだ後に止めたい場合にはモード切替のボタンを押して手動モードにすることで止めるようにしています。
プログラムの構造
全体の構成はイベント駆動のステートマシンと生産者消費者ループを組み合わせました。
ユーザーのボタン操作によってステートを「割り込ませる」ようにしています。
各イベントごとに、消費者ループに渡すデータを変えています。そのため、キューで扱っているデータタイプはステートを指示する列挙体以外にバリアントデータを設定し、あるイベントでは数値、あるイベントではブールのデータを渡せるようにしました。
次に各ステートを見ていきます。
まず、initステートでは初期化処理として指定されたaviファイルを開いてその中の情報を取り出したりしています。この情報の中にはaviファイルの中の「画像数」の情報があり、これを再生位置のスライダの最大値プロパティに指定することで、aviファイルごとの再生位置指定を適切に行えるようにしています。
次にselectステートです。このステートでは、モード切替のたびに、再生位置あるいは再生および逆再生ボタンの操作どちらかをグレーアウトさせて操作させないようにしています。これらの操作がごちゃ混ぜになっているとプログラムを作るのが面倒です。
使用しているのは各制御器の無効プロパティです。
次にmanualステートです。これは単純に生産者ループから受け取った再生位置の値をIMAQ AVI2 Read Frameの関数に渡しています。
次にautoステートです。manualステート同様にIMAQ AVI2 Read Frameを使用するのですが、aviファイル自体が持つフレーム数の上限を超えるまで、自分自身で同じステートをエンキューし続けるようにしています。
このステートで上限いっぱいになるとエラー-1074396010が起こることがあったため、ステートの外でエラークリアの関数でこのエラーを消すようにしています。(ここ以外のタイミングでも、読み取るフレーム番号の指定がおかしいと同じエラーが起こるようなので、強制的にエラークリアするようにしています)
次にreverseステートです。基本的にはautoステートとやっていることは一緒ですが、読み取るフレーム番号がループごとに小さい番号になるようにしています。
この番号が負の数にならないようにしていますが、フレーム番号を指定する数値(青色ワイヤ)は符号なし整数ではうまく動かないことがあったため、符号あり整数(I32)としました。
最後はstopステートで、ユーザーがフロントパネル上の停止ボタンを押したら実行されるステートになっています。開いていたaviファイルを閉じてIMAQのメモリも開放しプログラム全体を終了させています。
自動モード時にプログラムを止める場合
ここで紹介しているプログラムは、自動モードで再生あるいは逆再生をしている間に停止ボタンを押される前提で作っていません。手動モードのときに停止ボタンを押すと止まりますが、自動モードだとエラーが起きます。(LabVIEWの設定を自動エラー処理にしていると止まりますが、手動エラー処理にしていると停止ボタンに反応しません)
もし自動再生の途中でも止まるようにする場合には、キュー解放の関数が全ての中で一番最後に行われるようにする必要があり、例えば以下のようにすることで止められるようになります。
画像再生がうまくされない場合
厳密な原因はわからないのですが、上記のAVI2の関数ではフレームを指定しているのにうまく動かないことがあります(動画ファイルによって異なるようです)。
そんな場合には、「AVI2」の関数ではなく、「AVI」の関数を使用することで解消されることがあります。この「AVI」の関数は、比較的最近のLabVIEW(例えば2020など)では関数パレットに表れていないのですが、インストールはされていると思います。
32 bitのLabVIEWを使用している場合には
C:\Program Files (x86)\National Instruments\LabVIEW XXXX\vi.lib\vision
のパス(XXXXにはLabVIEWのバージョンが入ります)に関数が見つかります。
ややこしいのが、Avi.llbには「AVI2」の関数があり、Avi1.llbとAvi2.llbに「AVI」の関数がある点です。AVI2と関数の名前は似ている(「2」がついていないだけ)ので、上で紹介したすべての「AVI2」の関数を同名の「AVI」関数に置き換えるのは迷わないと思います。
aviファイルの操作についても、各関数の使い方はそこまで複雑ではなく、通常のファイルIOと同じような関数を置いて、今回のような再生時には読み取るフレームの番号を指定するだけで表示させることができます。
サンプルファインダにあるサンプルは全て自動で再生するような仕組みになっているようですが、他の「再生」の仕方もあるということを今回のプログラムのような形で実感できるかと思います。
ここまで読んでいただきありがとうございました。
コメント
初心者で申し訳ないですが、lab viewで動画を再生するための基礎的な方法を詳しくご教示いただけませんか?
コメントいただきありがとうございます!
LabVIEWで動画を再生するための基本的な方法、とのことですが、サンプルファインダにあるサンプルは参考にはならないでしょうか?
LabVIEWのメニューバーにある「ヘルプ」から「サンプルを検索」でNIサンプルファインダが開くので、左上のタブで「検索」を選んでから
キーワードで「avi」としていただくと見つかると思います。例えば、Read AVI File.viがシンプルな形かなと思います。
LabVIEWのVisionソフトウェア(アドオン)で扱える動画ファイルタイプは私が知る限りAVIファイルだけだと思います。(LabVIEWでWindows Media Playerを
扱うこともできると思いますが)
もしこちらのサンプルでもよくわからない、ということでしたら、またコメントください。組み方としてどういった点がわからないかもあわせて
書いていただければ、解説記事を書けるかもしれないです。