[Remotte開発] ビデオ解析系のアプリ（演習３）

[前回](https://qiita.com/remotte_jp/items/ce77c0f5b796ccd818a8) の演習２では、「制御」系の構成要素について演習した。今回はビデオ解析系の構成要素について、「バーコード・ＱＲコードの読み取り」を題材に説明する。
### アプリの新規作成
これまでの演習と同様に、アプリを新規作成します。
![1 アプリの新規作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/6a3e2ff3-4a82-791a-97b9-ca98083658ef.png)
### ビデオのソースを追加
「構成」タブの画面の左下のメニューから、「メディア」を選択して、ビデオ入力として使用する要素を追加する。「カテゴリー」では、
　　標準 (USB)
　　URL (ネットワーク・ファイル)
　　ブラウザ
　　デスクトップ
　　カスタム
が選択でき、「タイプ」では、
　　ビデオ
　　音声
　　ビデオと音声
が選択できる。この演習ではノートパソコンに搭載されたカメラないしは USB 接続されたカメラの映像のみ（音声無し）を使用することとし、以下の画面のように設定する。
![2 メディアの追加ドロップダウン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/0de4791a-b281-c44f-1e18-df90d7c0b3b8.png)
![3 メディアの追加ダイアログ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/4b9ee27f-4098-c2eb-afb7-e12a9273aa70.png)
この要素の「設定」タブでは、以下のように色々なオプションが用意されている。本演習においては、「最大フレームレート」をデフォルトの２から５くらいに上げておくことにしよう。
![4 最大フレームレート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/dd142f71-d8fd-1c53-ae71-4ccd2ec14a3a.png)
### ビデオ解析を追加
ビデオのソースを追加できたら、今度はビデオ解析の構成要素を追加する。画面左下のメニューから「新規作成」を選択し、以下のように追加する。
![5 構成要素の新規作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/39f0d66f-3919-1d08-bd07-034cb411a061.png)
![6 ビデオ解析のダイアログ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/40755447-266e-cd50-f415-88c5bd28cf1c.png)
ビデオ解析の「設定」タブでは、以下のように設定しよう。つまり、
　　入力画像：前の手順で追加したビデオのソースを選択
　　解析周期を制限する：オフ
　　配信周期を制限する：オフ
　　解析結果を保存する：オン
にする。
![7 ビデオ解析の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/5a61c79e-ec97-3614-203c-a2196c40414d.png)
### ビデオ解析のコードを記述
「構成」タブ内の「コード」タブを選択する。この演習ではバーコードやＱＲコードを読み取るために、「pyzbar」というモジュールを利用するため、まず、インストールスクリプト「Install.ps1」にて、
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;python -m pip install pyzbar
と記述して、このモジュールをインストールする。
![8 Install.ps1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/17ae85b5-8aa6-2362-566e-a69b460e6d14.png)
早速インストールスクリプトが正しく動作するかを確認してみよう。画面上部の「保存」ボタンを押した後、画面左下のメニューから「インストールスクリプトの実行」を選択する。
以下のように、インストールスクリプトの実行ダイアログが表示され、ダイアログの左下に「実行完了」と表示されればオッケー。「閉じる」ボタンをクリックしよう。
![9 インストールスクリプトの実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/7a69f422-7494-b3e9-59fb-1fb873e87552.png)
ビデオ解析用の Python コードは、まず先頭に、

```Python:
from pyzbar.pyzbar import decode
import cv2
import numpy as np
```

と記述し、インストールスクリプトにてインストールしたモジュール、および検出したバーコードを線で囲って描画するために使うモジュールをインポートする。
さて、ビデオ解析では、関数
　　**[new_video_frame(self, video_frame, time_sec)](https://www.remotte.jp/ja/user_guide/program/functions)**
によって、解析すべき画像が Python 側に通知され、この関数内で解析処理を行い、その結果をプラットフォーム側に通知する。ここで引数 video_frame には入力画像が numpy.ndarray 型で格納され、time_sec にはアプリ開始からの経過時間（秒）が float 型で格納される。画像内に複数のバーコードが含まれる場合を考慮して、この関数を以下のように実装する。

```Python:
    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( ) は、演習１で出てきたように、プラットフォーム側に新しいデータを通知するためのもので、このアプリでは検出したバーコード毎に、そのバーコードの値とバーコードの種類を配列にしたものを通知する。関数 **[set_video_frame( )](https://www.remotte.jp/ja/user_guide/program/functions)** は、ビデオ解析を行った結果の画像をプラットフォーム側に通知するために使用する。
![10 ビデオ解析のソースコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/c7ad6df9-d680-576a-4c61-746dfd1cf71a.png)
### 利用ページの編集
「利用ページ」タブ内の「表示項目」タブにて以下の様に設定する。
![11 表示項目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/a80564fd-f311-ec93-0b23-eb457f639bc6.png)
「レイアウト」タブでは、２つの表示項目があり、例として以下の様に編集する。まず、ビデオ解析の構成要素の「分析後のコマ画像」は、デフォルトのまま「画像」という表現形式のままで良く、その矩形のサイズと配置位置を編集する。次に「履歴」は、その表現形式として「配列の履歴テーブル」を選択し、画面右側のオプション設定にてタイトルやヘッダーなどを編集してみよう。
![12 レイアウト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/64663495-058e-fe35-5f7f-972b59d780ec.png)
### 実行！
画面上部の「保存」ボタンを押してからアプリを「開始」してみよう。カメラにバーコードやＱＲコードを読ませると、「レイアウト」画面にその内容が表示される。もし、カメラのフォーカスが合わずに上手く読み込めない場合は、Windows10 に標準でインストールされているアプリ「カメラ」を利用して調整すると良い。

１）Windowsメニューから「カメラ」を選択する。
![13 カメラを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/2b56ac06-4efe-1f7c-a2c7-f8f8595edb38.png)
２）画面の右端で「ビデオの撮影」を選択した上で、左上の設定ボタンを押して「プロモード」をオンにする。
![14 プロモード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/44c63e41-59fa-9719-4e6d-98b7775e3041.png)
３）画面の左中央の「マニュアルフォーカス」ボタンを押して、ツマミを一番上の「無限遠」に設定する。
![15 無限遠.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/0fad04c3-08b6-b6ca-2936-77173395b283.png)
４）「カメラ」のアプリを閉じ、リモッテの管理ツール上で再度試してみる。
### ビデオ入力の属性
ところで解析するビデオの縦横のピクセル数やフレームレートはどうやって取得するのか？リモッテにおける構成要素のプログラミングでは、関数 \_\_init\_\_( ) の引数 opt にこれらの情報が渡される。例えば関数 new_video_frame( ) の先頭にて、
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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\_\_' というキーの値に、ソースに関する属性が入っていることが分かる。

<font color="Red">注意！
プラットフォームの仕様として、ビデオ解析及び音声解析の構成要素では、関数 \_\_init\_\_( ) の中で print( ) を行なってもコンソールに表示されません。</font>
### まとめ
本演習では、「ビデオ解析」系の構成要素について体験した。関数 [new_video_frame( )](https://www.remotte.jp/ja/user_guide/program/functions) によってプラットフォームから画像が与えられ、これを解析し、set_value( ) および [set_video_frame( )](https://www.remotte.jp/ja/user_guide/program/functions) 関数によって解析結果をプラットフォーム側に通知することを習得したい。次回の演習では音声解析系のアプリを扱い、マイクから取得した音声について「レベルメーター」を作ってみる。