[OpenCV DNN] Flask ビデオ監視ターゲット検出チュートリアル 09

継続的に更新されている「OpenCV DNN @ Youcans」シリーズへようこそ


このシリーズはゼロから始まり、Flask フレームワークを使用して OpenCV DNN モデルの Web アプリケーションを構築する方法を詳細に説明します。このセクションでは、マルチスレッドまたは非同期フレームワークを使用して、ビデオ フレームの取得と顔認識を処理します。

このルーチンは、1 つのスレッドを使用してビデオ フレームをリアルタイムで取得し、顔認識と画像エンコードのためにメイン スレッドでビデオ フレームを処理します。したがって、顔認識によってビデオ フレームの読み取りがブロックされることはありません。


3.9 OpenCV+Flask マルチスレッド処理 リアルタイム監視 顔認識

顔認識は計算負荷の高いタスクであるため、ビデオ ストリームの処理が遅くなる可能性があります。この問題を解決するには、マルチスレッドまたは非同期フレームワークを使用して、ビデオ フレームの取得と顔認識を処理します。

このルーチンは、1 つのスレッドを使用してビデオ フレームをリアルタイムで取得し、顔認識と画像エンコードのためにメイン スレッドでビデオ フレームを処理します。したがって、顔認識によってビデオ フレームの読み取りがブロックされることはありません。

新しいメソッド update_frame を VideoStream クラスに追加し、クラスの初期化時にこのメソッドを実行するための新しいスレッドを開きました。ビデオ更新関数 update_frame() は、新しいビデオ フレームをリアルタイムで取得し、クラスの属性として保存します。

メインスレッドでは、ジェネレーター関数 get_frame() は顔認識と画像エンコーディングのみを担当します。gen_frames() はフレームごとに画像を取得し、Haar カスケード分類器の事前トレーニング モデルを使用して顔検出を行い、画像をエンコードしてクライアントに返します。クライアントのブラウザはビデオストリームを受信すると、imgタグで定義されたピクチャ内にフレーム単位で表示することで、ビデオ再生を実現します。顔認識や画像エンコードに時間がかかっても、ビデオの更新が妨げられることはありません。


新しい Flask プロジェクト cvFlask09 を作成する

新しい Flask プロジェクト cvFlask09 を作成します。このプロジェクトのフレームワークは cvFlask08 と同じです。
cvFlask09プロジェクトのファイルツリーは以下のとおりです。


---文件名\
    |---models\
    |    |---haarcascade_frontalface_alt2.xml
    |---templates\
    |    |---index4.html
    |    |---index5.html
    |--- cvFlask09.py
    |--- vedio_01.mp4

Pythonプログラムファイル

タスク ロジックは Python プログラム ファイル cvFlask09.py によって実装され、完全なコードは次のとおりです。

# cvFlask09.py
# OpenCV+Flask 图像处理例程 09
# 通过浏览器播放摄像头实时监控视频+人脸识别,多线程处理
# Copyright 2023 Youcans, XUPT
# Crated:2023-5-18

# coding:utf-8

from flask import Flask, Response, request, render_template
import threading
import cv2

app = Flask(__name__)  # 实例化 Flask 对象

# 定义视频流类
class VideoStream:
    def __init__(self, source):  # 传入视频源
        self.video_cap = cv2.VideoCapture(0)  # 创建视频读取对象
        # 加载 Haar 级联分类器 预训练模型
        model_path = "./models/haarcascade_frontalface_alt2.xml"
        # 加载人脸检测级联分类器
        self.face_cascade = cv2.CascadeClassifier(model_path)
        self.success, self.frame = self.video_cap.read()  # 读取视频帧
        threading.Thread(target=self.update_frame, args=()).start()

    def __del__(self):
        self.video_cap.release()  # 释放视频流

    def update_frame(self):
        while True:
            self.success, self.frame = self.video_cap.read()

    def get_frame(self):
        gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
        # 使用级联分类器检测人脸
        faces = self.face_cascade.detectMultiScale(gray, scaleFactor=1.2,
                                  minNeighbors=5, minSize=(30, 30), maxSize=(300, 300))
        # 绘制人脸检测框
        for (x, y, w, h) in faces:
            cv2.rectangle(self.frame, (x, y), (x+w, y+h), (255,0,0), 2)

        ret, buffer = cv2.imencode('.jpg', self.frame)  # 编码为 jpg 格式
        frame_byte = buffer.tobytes()  # 转换为 bytes 类型
        return frame_byte

# 生成视频流的帧
def gen_frames(video_source):
    video_stream = VideoStream(video_source)  # 从视频文件获取视频流
    while True:
        frame = video_stream.get_frame()  # 获取视频帧
        if frame is None:
            # video_stream.__del__()  # 释放视频流
            break
        yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n'
               + frame + b'\r\n')  # 生成视频流的帧


@app.route('/video_feed')
def video_feed():
    video_source = request.args.get('video_source', 'camera')  # 从网页获取视频源

    # 通过将一帧帧的图像返回,就达到了看视频的目的。multipart/x-mixed-replace是单次的http请求-响应模式,如果网络中断,会导致视频流异常终止,必须重新连接才能恢复
    return Response(gen_frames(video_source), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/')
def index_camera():  # 实时视频监控
    # <img src="{
    
    { url_for('video_feed', video_source='camera') }}">
    return render_template('index4.html')

@app.route('/vidfile')
def index_vidfile():  # 播放视频文件
    # <img src="{
    
    { url_for('video_feed', video_source='vedio_01.mp4') }}">
    return render_template('index5.html')

if __name__ == '__main__':
    # 启动一个本地开发服务器,激活该网页
    print("URL: http://127.0.0.1:5000")
    app.run(host='0.0.0.0', port=5000, debug=True, threaded=True)  # 绑定 IP 地址和端口号


ビデオストリーミング用のWebページテンプレート

ビデオストリームのWebページテンプレートindex4.htmlとindex5.htmlはテンプレートフォルダーにあり、その内容はcvFlask08プロジェクトの内容とまったく同じです。

Web ページのindex4.html は templates フォルダーにあり、具体的な内容は次のとおりです。

<!DOCTYPE html>
<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <h2  align="center">OpenCV+Flask 例程:实时视频监控</h2>
    <div style="text-align:center; padding-top:inherit">
      <img src="{
    
    { url_for('video_feed', video_source='camera') }}" width="600"; height="360">
    </div>
  </body>
</html>

Web ページのindex5.html は templates フォルダーにあり、具体的な内容は次のとおりです。

<!DOCTYPE html>
<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <h2  align="center">OpenCV+Flask 例程:播放视频文件</h2>
    <div style="text-align:center; padding-top:inherit">
      <img src="{
    
    { url_for('video_feed', video_source='vedio_01.mp4') }}" width="600"; height="360">
    </div>
  </body>
</html>

プログラムの実行中

cvFlask09 プロジェクトのルート ディレクトリに入り、プログラム cvFlask09.py を実行し、ストリーミング サーバーを起動します。
LAN 内のデバイス (携帯電話を含む) のブラウザで http://192.168.3.249:5000 を開き、リアルタイム ビデオ監視画面を再生します。

ここに画像の説明を挿入


【この項の終わり】

次のセクションでは、OpenCV DNN を使用したリアルタイム ビデオのオブジェクト検出について説明します。


著作権に関する声明: "OpenCV DNN @ Youcans"シリーズの youcans@xupt のオリジナル作品
にようこそ。転載にはオリジナルのリンクをマークする必要があります: [OpenCV DNN] Flask Video Surveillance Target Detection Tutorial 09 (https:// blog.csdn.net/youcans/article/details/131270693)著作権 2023 youcans、XUPTクレート: 2023-06-18





おすすめ

転載: blog.csdn.net/youcans/article/details/131270693