質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

3989閲覧

FlaskでIPカメラの映像をリアルタイムに解析、加工して表示し、任意のキャプチャ画像も同じ画面上に表示したい

iruka-s

総合スコア12

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/07/14 07:59

編集2020/07/14 08:28

前提・実現したいこと

現在以下の環境にてWebアプリケーションを開発しています。
・OS:Ubuntu18.04
・使用言語:JavaScript、HTML、Python3.6.9
・フレームワーク等:Flask、OpenCV、Flask-SocketIO

本Webアプリは以下の機能を持ちます。

  1. Flaskにて、OpenCVでIPカメラから映像をリアルタイムに取得
  2. リアルタイム映像からフレームを取得し、AIモジュールにより解析し、画像を加工
  3. 加工された画像を随時HTML上に表示(以下、リアルタイム表示機能)
  4. 2で解析した結果、表示したいフレームを同じ画面の別タグ内に表示(以下、任意画像表示機能)

試したことその1〜リアルタイム映像取得、画像加工、表示方法〜

IPカメラから取得した映像の解析とリアルタイム表示機能は以下のサイトを参考に実現できそうです。
参考にしたサイト
上記サイトを参考に作成したプログラム

作成したプログラムでは使用する映像をself.video = cv2.VideoCapture("mov_hts-samp009.mp4")で指定しています。
ここを適切に変更することで、IPカメラ映像のリアルタイム取得が可能です。
また、yieldでフレームを返している部分の直前に画像を加工する記述を加えることで、
IPカメラから取得した映像に加工を加えた映像をリアルタイム表示することが可能になると考えています。

試したことその2〜解析の結果表示したい画像を表示する方法〜

いくつかのサイトをググった結果、ソケット通信を用いることで任意画像表示機能を実現できることがわかりました。
作成したプログラム

このサンプルでは、取得した映像を50フレームごとに表示しています。
この部分を50フレームごとではなく、任意の条件式を満たすときに表示するよう変更することで、
任意のタイミングで、フレーム画像を表示することが可能になると考えています。

試したことその3〜その1とその2の組み合わせ〜

リアルタイム表示機能をyieldにより実現し、任意画像表示機能をsocket通信により実現しようとしました。
こちらが作成したプログラムです

実行した結果、以下のようなエラーが発生します。
二重にリクエストを飛ばすなと。flaskのルートを指定した関数実行中にソケットのemitをするなという意味でしょうか。

This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem.

試したこと4〜毎フレームSocket通信する〜

「試したことその2」で作成したプログラムを変更し、リアルタイム表示機能もSocket通信により実現しようとしました。
例えば/sample2/app.pyを以下のように修正すればできるのではと考えました。
しかし、実際にやってみるとめちゃくちゃ重たくて使い物になりません。

----------略---------- 25 camera = Camera() 26 count = 0 27 while True: 28 frame = camera.get_frame() 29 count += 1 30 31 32 if frame is not None: 33 emit('capture-send', { 'dataURL': prefix+base64.b64encode(frame).decode('utf-8')}) # 追加 34 # if count % 20 == 0: # 削除 35 # emit('capture-send', { 'dataURL': prefix+base64.b64encode(frame).decode('utf-8')}) # 削除 36 else: 37 break ----------略----------

お伺いしたいこと

以下のような解決手段をご教授いただけないでしょうか。

  • 「試したこと3」のエラーを回避する方法
  • 「試したこと4」の処理を軽くし、毎フレームSocket通信で実現する方法
  • 別の方法で目的のアプリケーションを実現する技術(フレームワーク等)

よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

「試したこと3」のエラーを回避する方法について:

flask_executorを使い、ソケット通信する際にキューを通してデータをやりとりしてみました

app.py

lang

1 2from flask import Flask, jsonify, render_template, Response; 3(略) 4from flask_executor import Executor # <=追加 5from queue import Queue # <=追加 6 7app = Flask(__name__) 8app.config['SECRET_KEY'] = 'mysecret' 9 10app.config['EXECUTOR_TYPE'] = 'thread' # <=追加 11executor = Executor(app) # <=追加 ソケットをやり取りするためのスレッドプール 12que = Queue() # <=追加 ソケットをやり取りするためのキュー 13 14socketIo = SocketIO(app, cors_allowed_origins="*") 15 16app.debug = True 17app.host = 'localhost' 18 19#以下2つの関数を追加 20@socketIo.on("start") 21def start(): 22 executor.submit(event_polling, que) 23 24def event_polling(q: Queue): 25 '''キューからソケットに送るデータを取り出すループ''' 26 while True: 27 item = q.get() 28 emit(item['command'], item['data']) 29 30@app.route('/') 31def index(): 32 return render_template('index.html') 33 34def gen(camera): 35 prefix = 'data:image/png;base64,' 36 37 count = 0 38 while True: 39 frame = camera.get_frame() 40 41 count += 1 42 if frame is not None: 43 yield (b'--frame\r\n' 44 b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n') 45 46 if count % 20 == 0: 47 # 画像データをキューに送る 48 que.put({'count':count, 'command':'capture-send', 49 'data':{ 'dataURL': prefix+base64.b64encode(frame).decode('utf-8')} 50 }) 51 time.sleep(0.05) # <=右側のキャプチャ画面が途中で更新されなくなる場合はここの数値を少し大きく(0.1等)にする、ただし大きくしすぎると左側の動画のカクツキが顕著になる。 52 else: 53 break 54

index.html

lang

1<html> 2<head> 3 4(略) 5 socket.on('capture-send', function(data){ 6 remoteCapture.setAttribute('src', data.dataURL); 7 }); 8 // 下の1行をここに追加 9 socket.emit("start"); 10 } 11 12 window.addEventListener('load', initialize); 13 14 </script> 15 16(略)

投稿2020/07/14 16:24

patapi

総合スコア820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iruka-s

2020/07/15 00:47

一度キューに保管してemitのタイミングはプログラムに任せて都合の良きタイミングでやってもらうと! なるほど! 思いつきませんでした。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問