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

news2024/11/27 1:21:14

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

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

    • 3.4 用Flask构建流媒体服务器
      • 3.4.1 流媒体服务器基本知识
      • 3.4.2 用Flask搭建流媒体服务器
    • Flask04 完整例程
      • cvFlask04 项目的文件树
      • cvFlask04.py
      • index1.html


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

本节介绍用Flask构建流媒体服务器,向服务器发送请求可以获取模拟视频源产生的视频图像。


3.4 用Flask构建流媒体服务器

我们的第四个例程,使用Flask框架构建一个视频流服务器,向服务器发送请求可以获取模拟视频源产生的视频图像。本例使用模拟视频源,是为了避免硬件配置和视频延迟的影响,构建一个极简的视频流服务器。


3.4.1 流媒体服务器基本知识

我们首先介绍流媒体服务器的基本知识。

流是一种让服务器在响应请求时将响应数据分块的技术。针对视频数据量大、实时性要求高的特点,把应答数据分成小块数据,服务器以数据块的形式响应请求,分块传输给客户端来实现流媒体服务器,因此响应返回请求就不会随视频数据而变大

另外,在视频流的返回播放时,视频流可以让每个块替换页面中的前一个块,来实现在浏览器窗口中的“播放”。

Multipart响应包含一个multipart媒体类型的标头,后面跟着多块独立的数据,每块数据有自己的Content-Type。Multipart有多种不同类型,针对流媒体我们使用multipart/x-mixed-replace。以下是Multipart视频流的结构:

HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace; boundary=frame

--frame
Content-Type: image/jpeg

<jpeg data here>
--frame
Content-Type: image/jpeg

<jpeg data here>
...

3.4.2 用Flask搭建流媒体服务器

下面我们使用Flask搭建一个简单的流媒体服务器。

Flask使用生成器(generator function)原生支持流式响应,生成器可以中断和恢复,可以一次返回多个值。一个返回流式响应的路由,需要返回参数为生成器的Response对象。Flask负责调用生成器,将Response对象分成数据块,使用Multipart Responses来组装一个HTTP应答,将数据块发送给客户端。

使用Motion JPEG方法,将视频画面逐帧发送给浏览器,浏览器逐帧替换来实现视频的播放功能。这也是很多IP Camera的流媒体播放方式,实时性很好,但视频质量不是很理想。

新建一个Flask项目。cvFlask04项目的文件树如下。

---项目文件名\
    |---templates\
    |    |---index1.html
|--- cvFlask04.py

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

# cvFlask04.py
# OpenCV+Flask 图像处理例程 04
# 在网页上显示模拟视频源的图像
# Copyright 2023 Youcans, XUPT
# Crated:2023-4-30

from flask import Flask, Response, render_template, request
import cv2
import numpy as np
import time

app = Flask(__name__)

# 定义视频流类
class VideoStream(object):
    def get_frame(self):  # 模拟视频源
        time.sleep(0.1)
        ct = time.time()
        sec_str = str(round(ct - int(ct), 3))
        img = np.ones((400, 600, 3), np.uint8) * 128
        cv2.putText(img, sec_str, (100, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255,255,0), 1)

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

# 视频流的网页 HTML 模板
@app.route('/')
def index():
    return render_template('index1.html')

# 生成视频流的帧
def gen_frames(camera):
    while True:
        frame = camera.get_frame()  # 获取视频帧
        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():
    return Response(gene_frames(VideoStream()),
            content_type='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    # 启动本地视频流服务器,激活该网页
    app.run(host='0.0.0.0', port=5000, debug=True, threaded=True)  # 绑定 IP 地址和端口号

程序cvFlask04.py定义了一个视频流VideoStream类,用于持续地提供视频帧的数据。在本例中使用模拟视频源,将系统时间写在空白画布上来生成模拟视频图像。

程序的index()中指定了视频流的网页模板index1.html。网页index1.html位于templates文件夹,具体内容如下。

<!DOCTYPE html>
<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <h1>Video Streaming Demonstration</h1>
    <img src="{{ url_for('video_feed') }}">
  </body>
</html>

其中,img标签定义了图片使用的url,是由url_for()函数返回的、利用视图函数的名字’video_feed’获取的动态url。
/video_feed路径由video_feed()方法提供服务,返回一个multipart应答。生成器函数gen_frames()不断地从VideoStream逐帧获取图片,通过生成器返回给客户端。客户端浏览器收到流媒体时,在img标签定义的图片中逐帧显示,从而实现视频播放。

下面运行cvFlask03的项目脚本。进入cvFlask04项目的根目录,运行程序cvFlask04.py,启动流媒体服务器。

 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.3.249:5000

在本地浏览器打开http://127.0.0.1:5000,或在局域网内设备(包括移动手机)浏览器打开http://192.168.3.249:5000,就可以看到模拟视频源生成的视频流。

在这里插入图片描述


Flask04 完整例程

cvFlask04 项目的文件树

---项目文件名\
    |---templates\
    |    |---index1.html
|--- cvFlask04.py


cvFlask04.py

# cvFlask04.py
# OpenCV+Flask 图像处理例程 04
# 在网页上显示模拟视频源的图像
# Copyright 2023 Youcans, XUPT
# Crated:2023-4-30

from flask import Flask, Response, render_template, request
import cv2
import numpy as np
import time

app = Flask(__name__)

# 定义视频流类
class VideoStream(object):
    def get_frame(self):  # 模拟视频源
        time.sleep(0.1)
        ct = time.time()
        sec_str = str(round(ct - int(ct), 3))
        img = np.ones((400, 600, 3), np.uint8) * 128
        cv2.putText(img, sec_str, (100, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255,255,0), 1)

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

# 视频流的网页 HTML 模板
@app.route('/')
def index():
    return render_template('index1.html')

# 生成视频流的帧
def gen_frames(camera):
    while True:
        frame = camera.get_frame()  # 获取视频帧
        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():
    return Response(gene_frames(VideoStream()),
            content_type='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    # 启动本地视频流服务器,激活该网页
    app.run(host='0.0.0.0', port=5000, debug=True, threaded=True)  # 绑定 IP 地址和端口号


index1.html

<!DOCTYPE html>
<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <h1>Video Streaming Demonstration</h1>
    <img src="{{ url_for('video_feed') }}">
  </body>
</html>

【本节完】

下节我们将讨论:使用Flask框架构建一个视频流服务器。


版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:
【OpenCV DNN】Flask 视频监控目标检测教程 04(https://blog.csdn.net/youcans/article/details/130865522)
Copyright 2023 youcans, XUPT
Crated:2023-05-25

欢迎关注『OpenCV DNN @ Youcans』系列,持续更新中
【OpenCV DNN】Flask 视频监控目标检测教程 01
【OpenCV DNN】Flask 视频监控目标检测教程 02
【OpenCV DNN】Flask 视频监控目标检测教程 03


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零基础web安全入门学习路线

相信很多新手都会遇到以下几个问题 1.零基础想学渗透怎么入手&#xff1f; 2.学习web渗透需要从哪里开始&#xff1f; 这让很多同学都处于迷茫状态而迟迟不下手&#xff0c;小编就在此贴给大家说一下web渗透的学习路线&#xff0c;希望对大家有帮助 同时本博客也会按照学习路…

【Java EE 初阶】网络编程套接字TCP的实现

目录 1.实现一个TCP的回显服务 1.Sever Socket API 1.SeverSocket 构造方法 2.Sever Socket方法 2.Socket API 1.Socket的构造方法 2.Socket 方法 那么怎么实现让服务器可以处理多个客户端呢&#xff1f; 服务端代码&#xff1a; 客户端代码&#xff1a; 1.实现一个TC…

【Python】玩转lambda表达式

知识目录 一、写在前面✨二、lambda匿名函数三、泛化函数四、总结撒花&#x1f60a; 一、写在前面✨ 大家好&#xff01;我是初心&#xff0c;又见面了&#xff01; 今天跟大家分享的文章是 玩转Python中的lambda表达式 &#xff0c;希望能帮助到大家&#xff01;本篇文章收录…

三十三、数学知识——质数(朴素筛法 + 埃氏筛法 + 线性筛法)

质数与质数筛法算法主要内容 一、基本思路1、质数质数的判定——试除法&#xff08;复杂度固定位 O(sqrt(n)) &#xff09; 2、分解质因数——试除法&#xff08;最坏是O(sqrt(n))&#xff09;3、朴素筛法——筛的是倍数4、埃氏筛法——朴素筛法优化5、线性筛法——n&#xff0…

刷题---C语言

目录 前言&#xff1a; 一.刷题&#xff08;1&#xff09; 1.1打印X图案 1.2打印带空格直角三角形图案 1.3小乐乐改数字 1.4牛牛的线段 2.刷题&#xff08;2&#xff09; 2.1判断奇偶性 2.2及格分数 2.3kiki算术 2.4&#xff08;ab-c&#xff09;*d 2.5KiKi算期末成…

亿级大表拆分过程记录

两年前接手公司的财务系统的开发和维护工作。在系统移交的初期&#xff0c;笔者和团队就发现&#xff0c;系统内有一张5000W的大表。 跟踪代码发现&#xff0c;该表是用于存储资金流水的表格&#xff0c;关联着众多功能点&#xff0c;同时也有众多的下游系统在使用这张表的数据…

Doris-----Aggregate 聚合模型及案例实现

Aggregate 模型 是相同key的数据进行自动聚合的表模型。表中的列按照是否设置了 AggregationType&#xff0c;分为 Key&#xff08;维度列&#xff09;和 Value&#xff08;指标列&#xff09;&#xff0c;没有设置 AggregationType 的称为 Key&#xff0c;设置了 Aggregation…

外包实在是太坑了,干了三年,感觉人都废了

先说一下自己的情况&#xff0c;专科生&#xff0c;19年通过校招进入杭州某个外包软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了3年的功…

【JMeter中的View Result Tree显示中文乱码】

JMeter中的View Result Tree显示中文乱码 检查JMeter的安装目录下的bin文件夹中的jmeter.properties配置文件 用记事本打开并搜索&#xff1a;sampleresult.default.encoding 找到该行 改成sampleresult.default.encodingutf-8 修改后重启JMeter ok, 解决乱码 附加 : 下载 J…

【Linux高级 I/O(7)】初识文件锁——fcntl()方法及其独占性、共享性实验(附全文代码)

fcntl()函数在前面系列内容中已经多次用到了&#xff0c;它是一个多功能文件描述符管理工具箱&#xff0c;通过配合不同的 cmd 操作命令来实现不同的功能。为了方便述说&#xff0c;这里再重申一次&#xff1a; #include <unistd.h> #include <fcntl.h>int fcntl(…

大模型对世界的改变,从一时一地,到无处不在、无时不有

作者 | 曾响铃 文 | 响铃说 大模型正在中国遍地开花&#xff0c;做过的没做过的都要过来参合一下。 汹涌浪潮中&#xff0c;不免有更多人开始关注那个最先发布的文心一言。 全球科技大厂中第一个发布GPT大模型产品的百度&#xff0c;在刚刚的中关村论坛上透露了一些文心一言…

nodejs连接mysql

npm i express #node后端框架npm i corsnpm i mysqlconst app require(express)(); const cors require(cors); const port 5000; const mysql require(mysql) //引入mysql 模块app.use(cors({}))const conn mysql.createConnection({user: root,password: qwertyuiop…

普通人想自学软件测试?我还是劝你算了吧。。。

本人7年测试经验&#xff0c;在学测试之前对电脑的认知也就只限于上个网&#xff0c;玩个办公软件。这里不能跑题&#xff0c;我为啥说&#xff1a;自学软件测试&#xff0c;一般人我还是劝你算了吧&#xff1f;因为我就是那个一般人&#xff01; 软件测试基础真的很简单&…

gtest单元测试

gtest单元测试 1. gtest是什么&#xff1f;简答&#xff1a;做测试用的2. gtest的优点3. 搭建测试框架4. gtest_范例演示 1. gtest是什么&#xff1f;简答&#xff1a;做测试用的 gtest是Google的一套用于编写C测试的框架&#xff0c;可以运行在很多平台上&#xff08;包括Lin…

【JavaSE】Java基础语法(十四):Static

文章目录 概述特点与应用注意事项为什么一个静态方法中只能访问用static修饰的成员? 概述 Java中的static是一个修饰符&#xff08;也可称关键字&#xff09;&#xff0c;可以用于修饰变量、方法和代码块。 特点与应用 static修饰的成员具有以下特点&#xff1a; 被类的所有对…

如何在Mac上抓取安卓设备的日志

要在 Mac 上抓取 Android 设备的日志&#xff0c;您可以使用 Android SDK 中的 adb 工具。以下是一个简单的步骤&#xff1a; 1.您需要在 Mac 上安装 Android SDK。您可以从 Android 开发者网站上下载最新版本的 Android SDK&#xff0c;并按照说明进行安装。 2.将您的 Andro…

重学 Symbol

重学 Symbol 之前在写基础类型的笔记时暂时性的先跳过了 symbol&#xff0c;现在也有了一些项目的使用经验后&#xff0c;觉得还是需要重新回滚并且学习一下&#xff0c;温故而知新。 首先依旧回顾一下 symbol 的特点&#xff1a; 是原始值 唯一 不可变 可以提供私有属性&…

javaWeb ssh沙发销售系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh沙发销售系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Mye…

【SUMO】SUMO运行自带的OSM入门教程

文章目录 一、运行CMD命令行二、进入OSM选择地图位置 首先给出官网教程&#xff1a; https://sumo.dlr.de/docs/Tutorials/OSMWebWizard.html 一、运行CMD命令行 代码&#xff1a; 先进入osmWebWizard.py文件地址 cd /d D:\SUMO\sumo-1.17.0\tools&#xff08;替换成自己的…

智慧PG(pgting),一款拖拽式智能页面搭建系统

目录 前言 一、介绍 二、设计理念 1&#xff0c;资源整合&#xff0c;开箱即用 2&#xff0c;降低系统颗粒度 3&#xff0c;组件共享 4&#xff0c;简化配置 三、系统功能 1&#xff0c;可视化大屏搭建&#xff1a; 四、技术架构 1&#xff0c;技术栈 2&#xff0c;整体架构 五…