前回 の演習2では、「制御」系の構成要素について演習した。今回はビデオ解析系の構成要素について、「バーコード・QRコードの読み取り」を題材に説明する。
アプリの新規作成
ビデオのソースを追加
「構成」タブの画面の左下のメニューから、「メディア」を選択して、ビデオ入力として使用する要素を追加する。「カテゴリー」では、
標準 (USB)
URL (ネットワーク・ファイル)
ブラウザ
デスクトップ
カスタム
が選択でき、「タイプ」では、
ビデオ
音声
ビデオと音声
が選択できる。この演習ではノートパソコンに搭載されたカメラないしは USB 接続されたカメラの映像のみ(音声無し)を使用することとし、以下の画面のように設定する。
この要素の「設定」タブでは、以下のように色々なオプションが用意されている。本演習においては、「最大フレームレート」をデフォルトの2から5くらいに上げておくことにしよう。
ビデオ解析を追加
ビデオのソースを追加できたら、今度はビデオ解析の構成要素を追加する。画面左下のメニューから「新規作成」を選択し、以下のように追加する。
ビデオ解析の「設定」タブでは、以下のように設定しよう。つまり、
入力画像:前の手順で追加したビデオのソースを選択
解析周期を制限する:オフ
配信周期を制限する:オフ
解析結果を保存する:オン
にする。
ビデオ解析のコードを記述
「構成」タブ内の「コード」タブを選択する。この演習ではバーコードやQRコードを読み取るために、「pyzbar」というモジュールを利用するため、まず、インストールスクリプト「Install.ps1」にて、
python -m pip install pyzbar
と記述して、このモジュールをインストールする。
早速インストールスクリプトが正しく動作するかを確認してみよう。画面上部の「保存」ボタンを押した後、画面左下のメニューから「インストールスクリプトの実行」を選択する。
以下のように、インストールスクリプトの実行ダイアログが表示され、ダイアログの左下に「実行完了」と表示されればオッケー。「閉じる」ボタンをクリックしよう。
ビデオ解析用の Python コードは、まず先頭に、
from pyzbar.pyzbar import decode
import cv2
import numpy as np
と記述し、インストールスクリプトにてインストールしたモジュール、および検出したバーコードを線で囲って描画するために使うモジュールをインポートする。
さて、ビデオ解析では、関数
new_video_frame(self, video_frame, time_sec)
によって、解析すべき画像が Python 側に通知され、この関数内で解析処理を行い、その結果をプラットフォーム側に通知する。ここで引数 video_frame には入力画像が numpy.ndarray 型で格納され、time_sec にはアプリ開始からの経過時間(秒)が float 型で格納される。画像内に複数のバーコードが含まれる場合を考慮して、この関数を以下のように実装する。
def new_video_frame(self, video_frame, time_sec):
data = decode(video_frame)
for c in data:
self._sys.set_value({'value': [c.data.decode('utf-8'), c.type]})
points = c.polygon
pts = np.array(points, np.int32)
pts = pts.reshape((-1, 1, 2))
cv2.polylines(video_frame, [pts], True, (0, 255, 0), 2)
self._sys.set_video_frame(video_frame, time_sec)
関数 set_value( ) は、演習1で出てきたように、プラットフォーム側に新しいデータを通知するためのもので、このアプリでは検出したバーコード毎に、そのバーコードの値とバーコードの種類を配列にしたものを通知する。関数 set_video_frame( ) は、ビデオ解析を行った結果の画像をプラットフォーム側に通知するために使用する。
利用ページの編集
「利用ページ」タブ内の「表示項目」タブにて以下の様に設定する。
「レイアウト」タブでは、2つの表示項目があり、例として以下の様に編集する。まず、ビデオ解析の構成要素の「分析後のコマ画像」は、デフォルトのまま「画像」という表現形式のままで良く、その矩形のサイズと配置位置を編集する。次に「履歴」は、その表現形式として「配列の履歴テーブル」を選択し、画面右側のオプション設定にてタイトルやヘッダーなどを編集してみよう。
実行!
画面上部の「保存」ボタンを押してからアプリを「開始」してみよう。カメラにバーコードやQRコードを読ませると、「レイアウト」画面にその内容が表示される。もし、カメラのフォーカスが合わずに上手く読み込めない場合は、Windows10 に標準でインストールされているアプリ「カメラ」を利用して調整すると良い。
1)Windowsメニューから「カメラ」を選択する。
2)画面の右端で「ビデオの撮影」を選択した上で、左上の設定ボタンを押して「プロモード」をオンにする。
3)画面の左中央の「マニュアルフォーカス」ボタンを押して、ツマミを一番上の「無限遠」に設定する。
4)「カメラ」のアプリを閉じ、リモッテの管理ツール上で再度試してみる。
ビデオ入力の属性
ところで解析するビデオの縦横のピクセル数やフレームレートはどうやって取得するのか?リモッテにおける構成要素のプログラミングでは、関数 __init__( ) の引数 opt にこれらの情報が渡される。例えば関数 new_video_frame( ) の先頭にて、
print(self._opt)
と記述して実行してみると、「構成」タブ内の「コード」タブの「コンソール」ウィンドウに、以下の様に表示される。
{'__video__': {'width': 640, 'height': 480, 'frame_rate': 5.0, 'scale': 100.0, 'auto_scale': False, 'scaled_width': 640, 'scaled_height': 480, 'rotation': 0}, '__audio__': None, '__guid__': None, '__remotte__': None}
'__video__' というキーの値に、ソースに関する属性が入っていることが分かる。
注意!
プラットフォームの仕様として、ビデオ解析及び音声解析の構成要素では、関数 __init__( ) の中で print( ) を行なってもコンソールに表示されません。
まとめ
本演習では、「ビデオ解析」系の構成要素について体験した。関数 new_video_frame( ) によってプラットフォームから画像が与えられ、これを解析し、set_value( ) および set_video_frame( ) 関数によって解析結果をプラットフォーム側に通知することを習得したい。次回の演習では音声解析系のアプリを扱い、マイクから取得した音声について「レベルメーター」を作ってみる。