【OpenCV DNN】Flask 视频监控目标检测教程 10

欢迎关注『OpenCV DNN @ Youcans』系列,持续更新中

【OpenCV DNN】Flask 视频监控目标检测教程 10

    • 3.10 OpenCV DNN+Flask实时监控目标检测
      • 1、加载MobileNet SSD模型
      • 2、导入分类名称文件
      • 3、处理视频帧进行目标检测
      • 4、新建一个Flask项目
      • 5、Python 程序文件
      • 6、视频流的网页模板
      • 7、Flask 视频监控目标检测程序运行


本系列从零开始,详细讲解使用 Flask 框架构建 OpenCV DNN 模型的 Web 应用程序。

在上节的基础上,本节介绍使用OpenCV DNN对实时视频进行目标检测。DNN目标检测的基本步骤也是加载图像、模型设置和模型推理。


3.10 OpenCV DNN+Flask实时监控目标检测

在上节的基础上,本节介绍使用OpenCV DNN对实时视频进行目标检测。DNN目标检测的基本步骤也是加载图像、模型设置和模型推理。

我们使用TensorFlow深度学习框架在MS COCO数据集上训练的MobileNet SSD(单次检测器)模型。与其他目标检测模型相比,SSD 模型通常更快。此外,MobileNet 主干网还降低了计算密集度。因此,对于使用OpenCV DNN进行目标检测,MobileNet是一个很好的模型。

MS COCO数据集(https://cocodataset.org/)是当前基于深度学习的对象检测模型的基准数据集。MS COCO包括80类日常物品,从人到汽车,再到牙刷。可以使用文本文件加载 MS COCO 数据集中的所有标签。


1、加载MobileNet SSD模型

在VideoStream类初始化程序中,使用readNet()函数加载MobileNet SSD模型。model为预训练权重文件的路径,即冻结计算图(frozen graph)的路径。Config为模型配置文件的路径,即protobuf文本文件的路径。Framework为加载模型的框架名称,本例中是TensorFlow。

# 加载 DNN 模型:MobileNet SSD 模型
model = cv2.dnn.readNet(model='./models/frozen_inference_graph.pb',config='./models/ssd_mobilenet_v2_coco.pbtxt',framework='TensorFlow')

2、导入分类名称文件

然后导入读取分类名称文件object_detection_classes_coco.txt,该文件将每个类别名称存储在列表class_names中,用新行分隔每个类别。例如:

[‘person’, ‘bicycle’, ‘car’, ‘motorcycle’, ‘airplane’, ‘bus’, ‘train’, ‘truck’, ‘boat’, ‘traffic light’, … ‘book’, ‘clock’, ‘vase’, ‘scissors’, ‘teddy bear’, ‘hair drier’, ‘toothbrush’, ‘’]

为每个类别随机设置不同颜色COLORS,用于使用指定颜色为每个类别绘制边界框,以便在图像中通过边界框的颜色来区分不同类别。元组COLORS包括3个整数值,表示颜色分量。

# 读取 COCO 类别名称
with open('object_detection_classes_coco.txt', 'r') as f:class_names = f.read().split('\n')# 为每个类别随机设置不同的颜色
COLORS = np.random.uniform(0, 255, size=(len(class_names), 3))

3、处理视频帧进行目标检测

本例程在主线程中处理视频帧进行目标检测,使用一个线程update_frame()实时获取新的视频帧。

在主线程中的生成器函数gen_frames()逐帧获取图片,使用MobileNet SSD(单次检测器)模型进行目标检测,将图像编码后返回给客户端。客户端浏览器收到视频流以后,在img标签定义的图片中逐帧显示,从而实现视频播放。

生成器函数gen_frames() 处理视频帧进行目标检测的步骤如下:
(1)由视频帧 frame 创建blob对象;
(2)使用MobileNet SSD模型,进行目标检测;
(3)对检测到的目标进行筛选,确定目标类别和边界框;
(4)在视频帧上绘制边界框,并标注类别名称;
(5)将图像编码后返回给客户端。

例程如下。

# 创建 blob
blob = cv2.dnn.blobFromImage(image=image, size=(300, 300), mean=(104, 117, 123), swapRB=True)# 基于 DNN 模型的目标检测
start = time.time()
self.model.setInput(blob)  # 模型输入图像
output = self.model.forward()  # 模型前向推理
end = time.time()
fps = 1 / (end - start)  # 计算帧处理速率 FPS# 目标检测结果的后处理
for detection in output[0, 0, :, :]:# 提取检测的置信度confidence = detection[2]# 当置信度高于阈值时才绘制边界框if confidence > 0.5:class_id = detection[1]  # 获取类别的idif class_id >= 90:  class_id = 89  # 防止类别id超出范围class_name = self.class_names[int(class_id) - 1]  # 将id映射为类别标签color = self.COLORS[int(class_id)]  # 该类别的颜色设置# color = (0, 255, 0)# 获取矩形边界框的参数 (x, y, w, h)x_box = int(detection[3] * w_img)y_box = int(detection[4] * h_img)w_box = int(detection[5] * w_img)h_box = int(detection[6] * h_img)# 在图像上绘制检测目标的矩形边界框cv2.rectangle(image, (x_box, y_box), (w_box, h_box), color, thickness=2)# 在图像上添加类别名称cv2.putText(image, class_name, (x_box, y_box - 5), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)# 在图像上添加 FPS 文本# cv2.putText(image, f"{fps:.2f} FPS", (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

4、新建一个Flask项目

新建一个Flask项目cvFlask10,本项目的框架与cvFlask09相同。
cvFlask10项目的文件树如下。

---文件名\|---models\|    |--- object_detection_classes_coco.txt|    |--- ssd_mobilenet_v2_coco.pbtxt|    |--- ssd_mobilenet_v2_coco_frozen.pb|---templates\|    |---index4.html|    |---index5.html
|--- cvFlask10.py
|--- vedio_01.mp4

5、Python 程序文件

任务逻辑由Python程序文件cvFlask10.py实现,完整代码如下。

# cvFlask10.py
# OpenCV+Flask 图像处理例程 10
# OpenCV+Flask+threading+MobileNet SSD
# OpenCV 实时读取摄像头,MobileNetSSD 模型目标检测,浏览器实时播放监控视频
# Copyright 2023 Youcans, XUPT
# Crated:2023-5-18# coding:utf-8from flask import Flask, Response, request, render_template
import threading
import time
import numpy as np
import cv2app = Flask(__name__)  # 实例化 Flask 对象# 定义视频流类
class VideoStream:def __init__(self, source):  # 传入视频源# 创建视频捕获对象,调用笔记本摄像头# cam = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # 修改 API 设置为视频输入 DirectShowself.video_cap = cv2.VideoCapture(0)  # 创建视频读取对象self.success, self.frame = self.video_cap.read()  # 读取视频帧threading.Thread(target=self.update_frame, args=()).start()# 加载 DNN 模型:MobileNet SSD V2 模型self.model = cv2.dnn.readNet(model="./models/ssd_mobilenet_v2_coco_frozen.pb",config="./models/ssd_mobilenet_v2_coco.pbtxt",framework='TensorFlow')# 读取 COCO 类别名称文件with open("./models/object_detection_classes_coco.txt", 'r') as f:self.class_names = f.read().split('\n')# 为每个类别随机设置不同的颜色self.COLORS = np.random.uniform(0, 255, size=(len(self.class_names), 3))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):image = self.frameh_img, w_img, _ = image.shape# 创建 blobblob = cv2.dnn.blobFromImage(image=image, size=(300, 300), mean=(104, 117, 123), swapRB=True)# 基于 DNN 模型的目标检测start = time.time()self.model.setInput(blob)  # 模型输入图像output = self.model.forward()  # 模型前向推理end = time.time()fps = 1 / (end - start)  # 计算帧处理速率 FPS# 目标检测结果的后处理for detection in output[0, 0, :, :]:# 提取检测的置信度confidence = detection[2]# 当置信度高于阈值时才绘制边界框if confidence > 0.5:class_id = detection[1]  # 获取类别的idif class_id >= 90:  class_id = 89  # 防止类别id超出范围class_name = self.class_names[int(class_id)-1]  # 将id映射为类别标签color = self.COLORS[int(class_id)]  # 该类别的颜色设置# color = (0, 255, 0)# 获取矩形边界框的参数 (x, y, w, h)x_box = int(detection[3] * w_img)y_box = int(detection[4] * h_img)w_box = int(detection[5] * w_img)h_box = int(detection[6] * h_img)# 在图像上绘制检测目标的矩形边界框cv2.rectangle(image, (x_box,y_box), (w_box,h_box), color, thickness=2)# 在图像上添加类别名称cv2.putText(image, class_name, (x_box,y_box-5), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)# 在图像上添加 FPS 文本# cv2.putText(image, f"{fps:.2f} FPS", (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)ret, buffer = cv2.imencode('.jpg', image)  # 编码为 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__()  # 释放视频流breakyield (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 地址和端口号

6、视频流的网页模板

视频流的网页模板index4.html和index5.html位于templates文件夹,内容与cvFlask09项目完全相同。

网页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>

网页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>

7、Flask 视频监控目标检测程序运行

进入cvFlask10项目的根目录,运行程序cvFlask10.py,启动流媒体服务器。

在局域网内设备(包括移动手机)的浏览器打开http://192.168.3.249:5000就可以播放实时视频监控画面。

在这里插入图片描述

进一步地,我们添加两个控制按钮“Start”和“Stop”,用来控制开始和停止播放视频流。
在 Flask 应用中添加控制按钮需要修改前端和后端代码。前端需要添加按钮以及发送请求的 JavaScript 代码,后端则需要添加处理这些请求的路由。
我们在前端添加 “start” 和 “stop” 按钮,这两个按钮在被点击时会发送请求到 “/start” 和 “/stop” 路由。


【本节完】


版权声明:
欢迎关注『OpenCV DNN @ Youcans』系列
youcans@xupt 原创作品,转载必须标注原文链接:
【OpenCV DNN】Flask 视频监控目标检测教程 10
(https://blog.csdn.net/youcans/article/details/131365824)
Copyright 2023 youcans, XUPT
Crated:2023-06-24


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/3015.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用KoodousFinder搜索和分析Android应用程序中的安全威胁

关于KoodousFinder KoodousFinder是一款功能强大的Android应用程序安全工具,在该工具的帮助下,广大研究人员可以轻松对目标Android应用程序执行安全研究和分析任务,并寻找出目标应用程序中潜在的安全威胁和安全漏洞。 账号和API密钥 在使用该工具之前,我们首选需要访问该…

np.averag的运算规则

今天写代码的时候&#xff0c;计算加权平均&#xff0c;一直没有搞懂np.average是怎么运算的&#xff0c;做个笔记记录一下&#xff1a; 创建一个&#xff08;3,4,5&#xff09;维度的np数组&#xff0c;然后在创建一个[1,0.5,1]的权重数组&#xff0c;计算他们的加权平均&…

6月人工智能论文推荐

Prompt Space Optimizing Few-shot Reasoning Success with Large Language Models https://arxiv.org/abs/2306.03799 Prompt engineering 是通过提供明确和具体的指令来增强大型语言模型(llm)能力的基本技术。它使LLM能够在各种任务中脱颖而出&#xff0c;例如算术推理、问…

RTMPose

RTMPose 1. 人体姿态估计简介2. RTMPose2.1 网络结构2.2 基于SimCC的优化路线2.2.1 SimCC&#xff1a;2.2.2 RTMPose 1. 人体姿态估计简介 多人姿态估计框架包括5个方面&#xff1a; paradigm&#xff1a;范式 top-down&#xff1a; 用于人数不多于6人的场景使用现成的检测器提…

Android Studio 配置 DCL 单例脚本

DCL&#xff08;Double-Checked Locking&#xff09;单例是一种用于创建单例对象的设计模式。单例模式是一种创建型模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供全局访问点。 DCL单例的核心思想是使用双重检查来保证只有在需要时才对实例进行实例化。它结合…

Nginx服务器的六个修改小实验

一、Nginx虚拟主机配置 1.基于域名 &#xff08;1&#xff09;为虚拟主机提供域名解析 配置DNS 修改/etc/hosts文件 &#xff08;2&#xff09;为虚拟主机准备网页文档 #创建网页目录 mkdir -p /var/www/html/abc mkdir -p /var/www/html/def ​ #编写简易首页html文件 ec…

MySQL 字符集与比较规则

字符集与比较规则 一. 字符集相关操作1. 查看字符集1.1 查看数据库当前字符集配置1.2 查看某数据库/数据表字符集 2. 修改字符集2.1 全局修改字符集2.2 修改已有库表字符集 3. 字符集级别二. 比较规则1.1 后缀表示含义1.2 查看指定数据集比较规则1.3 查看/修改数据库/表比较规则…

ffmpeg+nginx-rtmp转发视频流

本篇博客最早发布于实验室公共博客&#xff0c;但已无人维护&#xff0c;现迁移至个人博客 nginx与nginx-rtmp-module安装 画了好几天图&#xff0c;实在有些乏力&#xff0c;找点有意思的事情做做 觉得视频流传输挺有意思&#xff0c;B站找了些视频&#xff0c;但感觉有些大…

python爬虫—selenium获取csdn质量分并用echarts可视化分析

文章目录 ⭐前言⭐selenium&#x1f496; 获取所有的文章url&#x1f496; 根据url查询分数&#x1f496; inscode结合echarts展示结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于python自动化获取个人博客质量分并可视化。 该系列文章&#xff1a; python爬…

机器学习笔记 - 结合深度学习的基于内容的图像实例检索 利用现成的DCNN模型进行检索

一、简述 上一篇,基于内容的图像实例检索综述。 https://mp.csdn.net/mp_blog/creation/editor/131415155https://mp.csdn.net/mp_blog/creation/editor/131415155 一种方案是,为分类任务而进行大规模训练的DCNN直接充当图像检索任务的现成特征检测器,也就是说,可以…

CVPR 23 | 高分辨率缺陷异常定位新范式:PyramidFlow

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://arxiv.org/abs/2303.02595 论文代码&#xff1a;暂未发布 0. 背景 由于复杂的工业制造过程中的不可控因素&#xff0c;不可避免地会给产品带来不可预见的缺陷。由于人类视觉系…

NFTScan 与 Sender Wallet 达成合作伙伴,双方在多链 NFT 数据方面展开合作!

近日&#xff0c;NFT 数据基础设施 NFTScan 与 Web3 钱包 Sender Wallet 达成合作伙伴关系&#xff0c;成为其官方 NFT 数据供应商。NFTScan 将为 Sender Wallet 的 NFT 部分提供专业的多链 NFT 数据支持&#xff0c;确保用户可以跨多个区块链获得全面和实时的 NFT 数据。 Sen…