使用Flask和OpenCV 实现树莓派与客户端的视频流传输与显示
使用 Python 和 OpenCV 实现树莓派与客户端的视频流传输与显示
在计算机视觉和物联网领域,经常需要将树莓派作为视频流服务器,通过网络将摄像头画面传输到客户端进行处理和显示。本文将详细介绍如何利用picamera2库、Flask 框架以及 OpenCV 库,实现树莓派端的视频流推送和客户端的视频流接收与显示。
一、前期准备
硬件准备
树莓派(建议树莓派 3 及以上版本),确保已安装操作系统(如 Raspbian)。
树莓派摄像头模块,正确连接到树莓派的 CSI 接口。我这里使用的是Zero 2W和Camera Module 3

客户端电脑,操作系统可以是 Windows、MacOS 或 Linux。
软件准备
在树莓派上:
确保系统已更新到最新版本,在终端执行sudo apt update和sudo apt upgrade -y。
安装picamera2库,执行pip install picamera2。
安装 Flask 框架,执行pip install flask。
安装Pillow库(用于图像格式转换),执行pip install pillow。
在客户端电脑上:
安装 Python 环境,建议使用 Python 3.x 版本。
安装OpenCV库,对于不同操作系统安装方式略有不同:
在 Windows 上,打开命令提示符,执行pip install opencv - python。
在 MacOS 上,打开终端,执行pip install opencv - python。
在 Linux 上,根据不同发行版,可能需要使用sudo apt - get install python3 - opencv等命令安装。
二、树莓派端操作
树莓派服务器端代码(使用 picamera2 库和 Flask 框架)
树莓派作为视频流服务器,利用picamera2库获取摄像头画面,并通过 Flask 框架将视频流以 HTTP 的形式提供给客户端。
import io
from flask import Flask, Response
from picamera2 import Picamera2app = Flask(__name__)def generate_frames():picam2 = Picamera2()# 将格式改为RGB888,后续再转换为JPEGpicam2.configure(picam2.create_preview_configuration(main={"format": "RGB888", "size": (640, 480)}))picam2.start()while True:stream = io.BytesIO()buffer = picam2.capture_array()from PIL import Imageimg = Image.fromarray(buffer)img.save(stream, format='JPEG')stream.seek(0)yield b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + stream.read() + b'\r\n'stream.close()@app.route('/video_feed')
def video_feed():return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')if __name__ == '__main__':app.run(host='0.0.0.0', port=5000, threaded=True)
代码说明:
导入库:导入io、Flask、Response、Picamera2等必要的库。io用于处理字节流,Flask和Response用于构建 Web 服务器,Picamera2用于控制树莓派摄像头。
摄像头配置与初始化:使用Picamera2创建摄像头对象picam2,配置其输出格式为RGB888,分辨率为(640, 480),并启动摄像头。
生成视频帧:在generate_frames函数中,通过picam2.capture_array获取摄像头的图像数组,使用PIL库将数组转换为图像对象并保存为 JPEG 格式到字节流stream中,然后将字节流数据以特定格式作为视频帧输出。
定义路由:使用@app.route装饰器定义/video_feed路由,返回由generate_frames函数生成的视频流响应。
启动 Flask 应用:在if __name__ == '__main__':条件下,启动 Flask 应用,监听所有 IP 地址(host='0.0.0.0),端口为5000。
操作步骤
打开树莓派的终端。
使用文本编辑器(如nano)创建一个新的 Python 文件,例如video_server.py,命令为nano ``video_server.py。
将上述代码逐行复制粘贴到video_server.py文件中。
按下Ctrl + X,然后按Y,再按Enter保存并退出文件。
在终端中执行python3 ``video_server.py运行该程序。此时树莓派开始通过摄像头采集视频流,并通过 Flask 应用将其提供在http://0.0.0.0:5000/video_feed地址上。注意记录树莓派的 IP 地址,可在终端执行hostname -I查看。
三、电脑端操作
客户端代码(使用 OpenCV 和 urllib 库)
客户端电脑通过 Python 的cv2(OpenCV)库和urllib.request库从树莓派服务器获取视频流并进行显示。
import cv2
import urllib.request
import numpy as np# 视频流的URL,即树莓派的IP地址
url = 'http://192.168.3.90:5000/video_feed'# 打开URL
stream = urllib.request.urlopen(url)# 用于存储视频流数据的字节数组
bytes_data = bytearray()while True:# 读取视频流数据bytes_data += stream.read(1024)# 查找帧的起始位置a = bytes_data.find(b'\xff\xd8')b = bytes_data.find(b'\xff\xd9')if a != -1 and b != -1:# 提取一帧图像数据frame_data = bytes_data[a:b+2]# 从字节数据中删除已处理的部分bytes_data = bytes_data[b+2:]# 将字节数据转换为numpy数组frame = np.asarray(bytearray(frame_data), dtype=np.uint8)# 解码图像帧frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)# 显示图像帧cv2.imshow('Video Stream', frame)# 等待按键事件,25毫秒if cv2.waitKey(25) & 0xFF == ord('q'):break# 关闭窗口
cv2.destroyAllWindows()
代码说明:
导入库:导入cv2、urllib.request、numpy库。cv2用于图像和视频处理,urllib.request用于网络请求,numpy用于处理数组数据。
设置视频流 URL:将url变量设置为树莓派服务器提供的视频流 URL。需将http://192.168.3.90:5000/video_feed中的 IP 地址替换为树莓派实际的 IP 地址。
打开 URL:使用urllib.request.urlopen打开 URL,获取视频流数据的流对象stream。
读取和处理视频流数据:循环读取stream中的数据并添加到bytes_data中,查找 JPEG 图像帧的起始和结束标记(\xff\xd8和\xff\xd9),提取一帧图像数据,转换为numpy数组并使用cv2.imdecode解码为 OpenCV 可处理的格式。
显示视频帧:使用cv2.imshow显示解码后的图像帧,并通过cv2.waitKey等待按键事件,按下q键时退出循环。
关闭窗口:循环结束后,使用cv2.destroyAllWindows关闭所有 OpenCV 窗口。
操作步骤
- 通过 Python 代码接收视频流
打开客户端电脑的命令行终端(Windows 下为命令提示符或 PowerShell,MacOS 和 Linux 下为终端)。
使用文本编辑器(如 Windows 的 Notepad++、MacOS 的 TextEdit 需设置为纯文本模式、Linux 的gedit等)创建一个新的 Python 文件,例如video_client.py。
将上述代码逐行复制粘贴到video_client.py文件中,特别注意将url变量中的 IP 地址替换为树莓派的实际 IP 地址。
保存video_client.py文件。
在终端中切换到保存video_client.py文件的目录,执行python ``video_client.py(如果使用的是 Python 3,可能需要执行python3 ``video_client.py)。此时客户端电脑将从树莓派服务器获取视频流,并在 OpenCV 窗口中显示树莓派摄像头捕捉到的画面。按q键可关闭视频显示窗口。
- 通过浏览器查看视频流
打开客户端电脑上的任意浏览器,如 Chrome、Firefox 等。
在浏览器地址栏中输入树莓派的视频流地址,格式为http://树莓派IP地址:5000/video_feed。例如,如果树莓派的 IP 地址是192.168.1.100,则输入http://192.168.1.100:5000/video_feed。
按下回车键,浏览器将尝试加载树莓派摄像头的视频流画面。如果网络连接正常且树莓派服务器运行正常,应该能看到实时的视频画面。
部分浏览器可能会对视频流显示有兼容性问题。如果遇到无法正常显示的情况,可以尝试更换浏览器,或者检查浏览器是否阻止了某些内容加载。另外,确保树莓派服务器的防火墙设置允许外部访问端口5000。如果树莓派开启了防火墙,可能需要执行sudo ufw allow 5000命令(适用于使用ufw防火墙的情况)来允许外部访问该端口。
在实际应用中,确保树莓派和客户端电脑处于同一网络环境,并且客户端电脑能够访问树莓派的 IP 地址。通过上述代码及操作步骤,即可实现树莓派到客户端的视频流传输与显示功能。
相关文章:
使用Flask和OpenCV 实现树莓派与客户端的视频流传输与显示
使用 Python 和 OpenCV 实现树莓派与客户端的视频流传输与显示 在计算机视觉和物联网领域,经常需要将树莓派作为视频流服务器,通过网络将摄像头画面传输到客户端进行处理和显示。本文将详细介绍如何利用picamera2库、Flask 框架以及 OpenCV 库ÿ…...
fs的proxy_media模式失效
概述 freeswitch是一款简单好用的VOIP开源软交换平台。 在fs的使用过程中,某些场景只需要对rtp媒体做透传,又不需要任何处理。 在fs1.6的版本中,我们可以使用proxy_media来代理媒体的转发,媒体的协商由AB路端对端处理ÿ…...
Linux 命名管道
文章目录 🚀 深入理解命名管道(FIFO)及其C实现一、命名管道核心特性1.1 🧩 基本概念 二、💻 代码实现解析2.1 📁 公共头文件(common.hpp)2.2 🖥️ 服务器端(s…...
HDU 学数数导致的
题目解析 首先,数对是有序的,<1,2>和<2,1>被视为不同的两组数字。 其次,数对<p,q>的p和q可以相等。 子序列为 p 0 p q,观察到,中间要出现一个0。那么,我们只需要找到第一个 p 满足与前…...
pjsip pjsua_media_config 结构体说明
clock_rate 描述:设置会议桥(conference bridge)的时钟频率(采样率)。 默认值:0(使用默认值 PJSUA_DEFAULT_CLOCK_RATE,通常为 16kHz)。 作用:影响音频的采样率,常见值有 8000(8kHz)、16000(16kHz)、48000(48kHz)等。snd_clock_rate 描述:设置音频设备的时钟…...
软件/硬件I2C读写MPU6050
MPU6050简介 6轴:3轴加速度,3轴角速度 9轴:3轴加速度,3轴角速度和3轴磁场强度 10轴:3轴加速度,3轴角速度和3轴磁场强度和一个气压强度 加速度计具有静态稳定性,不具有动态稳定性 欧拉角&…...
c++ union使用笔记
c union使用笔记 一、联合的简单使用二、联合与枚举结合三、匿名联合(Anonymous Union)四、关键注意事项五、C17 扩展:std::variant C联合(union)是一种特殊的数据结构,允许在相同内存位置存储不同的数据类…...
Android中的Wifi框架系列
Android wifi框架图 Android WIFI系统引入了wpa_supplicant,它的整个WIFI系统以wpa_supplicant为核心来定义上层接口和下层驱动接口。 Android WIFI主要分为六大层,分别是WiFi Settings层,Wifi Framework层,Wifi JNI 层ÿ…...
react(一):特点-基本使用-JSX语法
初识React React是一个用于构建用户界面的 JavaScript 库,由 Facebook 开发和维护。 官网文档:React 官方中文文档 特点 1.声明式编程 2.组件化开发 3.多平台适配 开发依赖 开发React必须依赖三个库: 1.react:包含react所必…...
【Go】无法访问 proxy.golang.org 进行依赖下载
golang.org/x/net/context: golang.org/x/netv0.37.0: Get "https://proxy.golang.org/golang.org/x/net/v/v0.37.0.zip": dial tcp 142.251.215.241:443: connect: connection refused解决方案: 使用国内的 Go 代理,如 goproxy.cn 或 gopro…...
鸿蒙 @ohos.arkui.observer (无感监听)
鸿蒙 ohos.arkui.observer (无感监听) 在鸿蒙开发中,ohos.arkui.observer 模块提供了一种强大的无感监听机制,允许开发者监听组件的状态变化、滚动事件、页面切换等事件。这些功能对于实现复杂的交互逻辑和优化性能非常有帮助。本文将详细介绍 ohos.ark…...
一键爬取b站视频
同学们。废话不多说, b站视频素材多, 二次加工就归你, 三话不说爬起来, 犯法违纪咱不干 代码 import json import requests from bs4 import BeautifulSoup import re# 目标网址bvnane"BV1hUQEYCEyY" pp("0&q…...
【含文档+PPT+源码】基于Python的图书管理系统的设计与实现
项目介绍 本课程演示的是一款基于Python的图书管理系统的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 带你从零开始部署运行本套系统 该项目附…...
开源工具利器:Mermaid助力知识图谱可视化与分享
在现代 web 开发中,可视化工具对于展示流程、结构和数据关系至关重要。Mermaid 是一款强大的 JavaScript 工具,它使用基于 Markdown 的语法来呈现可定制的图表、图表和可视化。对于展示流程、结构和数据关系至关重要。通过简单的文本描述,你可…...
Mysql的utf8mb4_general_ci 与 utf8mb4_bin 的具体区别是什么?中文适合哪个?
1. utf8mb4_general_ci vs utf8mb4_bin 的具体区别 utf8mb4_general_ci 和 utf8mb4_bin 都是 utf8mb4 编码的排序规则(collation),它们主要在 排序(ORDER BY) 和 比较(WHERE) 时的行为不同&…...
茂捷M1001电感式编码器芯片TSSOP28管脚,国产电感式编码器IC
简述: M1001 电感式编码器芯片是一款专为高精度位置检测而设计的芯片产品,采用先进的电感技术,能够精确测量旋转物体的位置和角度。芯片具有 SIN/COS、模拟、PWM、SENT、SPI、I2C等多种角度输出功能,具有高分辨率、宽工作温度范围…...
LeetCode-跳跃游戏 II
方法一:反向查找出发位置 我们的目标是到达数组的最后一个位置,因此我们可以考虑最后一步跳跃前所在的位置,该位置通过跳跃能够到达最后一个位置。 如果有多个位置通过跳跃都能够到达最后一个位置,那么我们应该如何进行选择呢&a…...
【后端】【django】Django DRF `@action` 详解:自定义 ViewSet 方法
Django DRF action 详解:自定义 ViewSet 方法 在 Django REST Framework(DRF)中,action 装饰器用于为 ViewSet 添加自定义的 API 端点。相比于 update、create 等默认方法,action 允许我们定义 更加清晰、语义化 的 A…...
数据结构——双向链表dlist
前言:大家好😍,本文主要介绍了数据结构——双向链表dlist 一 双向链表定义 1. 双向链表的节点结构 二 双向链表操作 2.1 定义 2.2 初始化 2.3 插入 2.3.1 头插 2.3.2 尾插 2.3.3 按位置插 2.4 删除 2.4.1 头删 2.4.2 尾删 2.4.3 按…...
IDEA 一键完成:打包 + 推送 + 部署docker镜像
1、本方案要解决场景? 想直接通过本地 IDEA 将最新的代码部署到远程服务器上。 2、本方案适用于什么样的项目? 项目是一个 Spring Boot 的 Java 项目。项目用 maven 进行管理。项目的运行基于 docker 容器(即项目将被打成 docker image&am…...
图像分类数据集
《动手学深度学习》-3.5-学习笔记 # 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式, # 并除以255使得所有像素的数值均在0~1之间 trans transforms.ToTensor()#用于将图像数据从 PIL 图像格式(Python Imaging Libraryÿ…...
设计模式之美
UML建模 统一建模语言(UML)是用来设计软件的可视化建模语言。它的语言特点是简单 统一 图形化 能表达软件设计中的动态与静态信息。 UML的分类 动态结构图: 类图 对象图 组件图 部署图 动态行为图: 状态图 活动图 时序图 协作…...
2025-03-15 学习记录--C/C++-PTA 练习3-4 统计字符
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、题目描述 ⭐️ 练习3-4 统计字符 本题要求编写程序,输入10个字符,统计其中英文字母、空格或回车、…...
802.11标准
系列文章目录 文章目录 系列文章目录一、相关知识二、使用步骤1.802.11修正比较2.802.11ac 三、杂记 一、相关知识 跳频扩频:射频信号可分为窄带信号和扩频信号。如果射频信号的带宽大于承载数据所需的带宽,该信号就属于扩频信号。跳频扩频(FHSS)是一种…...
母婴商城系统Springboot设计与实现
项目概述 《母婴商城系统Springboot》是一款基于Springboot框架开发的母婴类电商平台,旨在为母婴产品提供高效、便捷的在线购物体验。该系统功能全面,涵盖用户管理、商品分类、商品信息、商品资讯等核心模块,适合母婴电商企业或个人开发者快…...
C#通过API接口返回流式响应内容---分块编码方式
1、背景 上一篇文章《C#通过API接口返回流式响应内容—SSE方式》阐述了通过SSE(Server Send Event)方式,由服务器端推送数据到浏览器。本篇是通过分块编码的方式实现 2、效果 3、具体代码 3.1 API端实现 [HttpGet] public async Task Chu…...
游戏引擎学习第158天
回顾和今天的计划 我们在这里会实时编码一个完整的游戏,没有使用引擎或库,一切都由我们自己做所有的编程工作,游戏中的每一部分,无论需要做什么,我们都亲自实现,并展示如何完成这些任务。今天,…...
如何在电脑上使用 Jupyter Notebook 通过 SSH 远程连接树莓派Zero
有无数种方式通过SSH远程连接树莓派,但对于树莓派Zero 2W这种硬件资源有限的板子,因为内存有限Pycharm干脆不能通过SSH连接树莓派Zero 2W。VScode通过SSH连接时,也会因为资源有限时常断线。因此,我们就要用轻量级的编辑器Jupyter …...
[新能源]新能源汽车快充与慢充说明
接口示意图 慢充接口为交流充电口(七孔),快充接口为直流充电口(九孔)。 引脚说明 上图给的是充电口的引脚图,充电枪的为镜像的。 慢充接口引脚说明 快充接口引脚说明 充电流程 慢充示意图 慢充&…...
《解锁华为黑科技:MindSpore+鸿蒙深度集成奥秘》
在数字化浪潮汹涌澎湃的当下,人工智能与操作系统的融合已成为推动科技发展的核心驱动力。华为作为科技领域的先锋,其AI开发框架MindSpore与鸿蒙系统的深度集成备受瞩目,开启了智能生态的新篇章。 华为MindSpore:AI框架的创新先锋…...
