やりたいこと
前回の記事pythonでdarknet(yolov2)の検出結果を画像に埋め込むではdarknet yoloを利用したAPIを作ってみましたが、
あれではyoloのアピール点の1つである速さについてはあまり体感できない...
ということで、今回はWebSocket通信を利用して、リアルタイム感を出すようにしてみました。
いつのまにかyolov2からyolov3になっていたので。yolov3で試してみました。
ソース
サーバ側:https://github.com/komorin0521/yolo_ws_server
クライアント側:https://github.com/komorin0521/yolo_ws_client
各ページにReadMeがあるので、そちらに従って試してみてください
(不備があればコメント等頂ければ幸いです)
サーバ側で苦労したところ
yoloとの連携
darknet.py
の_convert_to_yolo_img
関数の部分
pythonからyolo(C)に対して、画像を受け渡す際の
画像のフォーマットの調整が少し大変でした。
PILのフォーマットをtranspose(2, 0, 1)した上で、
1次元配列にして、c_arrayに変換して、さらにrbggr_imgという
yoloの関数を利用しなきゃだめだった。
yoloの関数とにらめっこして、がんばりました。
WebSocket通信について
こちらは、PythonでWebSocketのお勉強を参考に作成
けっこう簡単に実装できた。
クライアント側で苦労したところ
カメラ画像キャプチャ
javascriptにはめっぽう弱いため、いろいろな記事を探しつつ実装
動画を静止画(png)にして、画像を送信する記事を発見したので、それを応用
また、WebSocket通信のモジュールについても、サンプルを見よう見まねで実装
n[sec]間隔で静止画を切り出して、送信するようにしました。
ただ、最初は画像を送信してもpythonでの形式がどの形式で表示可能かがわからずで。
どうやら、640×480など、大きなサイズだと、上半分の画像しかサーバ側では受信できない事象があり、
サイズ制限とかあるのかな?とまだ未解決状態
また、chromeではどうやら、カメラを取得するAPIがhttpsのみでしか動作しないようです...
なので、自分はEdgeで試しました。
サーバからbase64でエンコードされた文字列を返却しているので、下記のようにすることで、
画像を表示できるみたい。
エンコードとか不要なので、便利ですね。
pred_img.src = "data:image/png;base64," + event.data;