当前位置: 首页 > news >正文

程序代码篇---esp32视频流处理


文章目录

  • 前言
  • 一、ESP32摄像头设置
    • 1.HTTP视频流(最常见)
    • 2.RTSP视频流
    • 3.MJPEG流
  • 二、使用OpenCV读取视频流
    • 1. 读取HTTP视频流
    • 2. 读取RTSP视频流
  • 三、使用requests库读取MJPEG流
  • 四、处理常见问题
    • 1. 连接不稳定或断流
    • 2. 提高视频流性能
      • 2.1降低分辨率
      • 2.2跳过部分帧
  • 五、使用FFmpeg作为后端
  • 六、使用PyAV库(高级选项)
  • 七、实际应用示例 - 视频流处理
  • 八、注意事项
    • 1.网络延迟
    • 2.带宽限制
    • 3.认证
    • 4.编码格式
    • 5.稳定性


前言

ESP32摄像头模块可以通过Wi-Fi提供视频流,通常使用RTSP或HTTP协议。下面将简单介绍如何使用Python读取和处理ESP32摄像头的视频流。


一、ESP32摄像头设置

在开始之前,确保你的ESP32摄像头已经正确配置并可以输出视频流。常见的ESP32摄像头流媒体方式有:

1.HTTP视频流(最常见)

通常地址为 http://[ESP32_IP]/video
或 http://[ESP32_IP]/stream

2.RTSP视频流

通常地址为 rtsp://[ESP32_IP]:554/mjpeg/1

3.MJPEG流

通常地址为 http://[ESP32_IP]/mjpeg/1

二、使用OpenCV读取视频流

1. 读取HTTP视频流

import cv2# ESP32摄像头的IP地址
esp32_ip = "192.168.1.100"  # 替换为你的ESP32 IP
stream_url = f"http://{esp32_ip}/video"# 创建视频捕获对象
cap = cv2.VideoCapture(stream_url)# 设置缓冲区大小为1以减少延迟
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)while True:ret, frame = cap.read()if not ret:print("无法获取视频流,尝试重新连接...")cap.release()cap = cv2.VideoCapture(stream_url)continue# 显示视频cv2.imshow('ESP32 Camera Stream', frame)# 按'q'退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放资源
cap.release()
cv2.destroyAllWindows()

2. 读取RTSP视频流

import cv2esp32_ip = "192.168.1.100"  # 替换为你的ESP32 IP
rtsp_url = f"rtsp://{esp32_ip}:554/mjpeg/1"cap = cv2.VideoCapture(rtsp_url)# 对于RTSP流,可能需要添加这些参数
cap.set(cv2.CAP_PROP_FPS, 30)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))while True:ret, frame = cap.read()if not ret:print("RTSP流中断,尝试重新连接...")cap.release()cap = cv2.VideoCapture(rtsp_url)continuecv2.imshow('ESP32 RTSP Stream', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()

三、使用requests库读取MJPEG流

对于MJPEG格式的视频流,可以使用requests库:
import cv2
import numpy as np
import requests
from io import BytesIOesp32_ip = "192.168.1.100"  # 替换为你的ESP32 IP
stream_url = f"http://{esp32_ip}/mjpeg/1"# 创建请求会话
session = requests.Session()
stream = session.get(stream_url, stream=True)bytes_data = bytes()
for chunk in stream.iter_content(chunk_size=1024):bytes_data += chunka = bytes_data.find(b'\xff\xd8')  # JPEG开始标记b = bytes_data.find(b'\xff\xd9')  # JPEG结束标记if a != -1 and b != -1:jpg = bytes_data[a:b+2]bytes_data = bytes_data[b+2:]# 转换为numpy数组img = cv2.imdecode(np.frombuffer(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)if img is not None:cv2.imshow('ESP32 MJPEG Stream', img)if cv2.waitKey(1) & 0xFF == ord('q'):breakcv2.destroyAllWindows()
session.close()

四、处理常见问题

1. 连接不稳定或断流

python
import time

def connect_to_stream(url, max_retries=5, retry_delay=1):
for i in range(max_retries):
cap = cv2.VideoCapture(url)
if cap.isOpened():
return cap
print(f"连接失败,尝试 {i+1}/{max_retries}…")
time.sleep(retry_delay)
return None

esp32_ip = “192.168.1.100”
stream_url = f"http://{esp32_ip}/video"

cap = connect_to_stream(stream_url)
if cap is None:
print(“无法连接到摄像头”)
exit()

while True:
ret, frame = cap.read()
if not ret:
print(“视频流中断,尝试重新连接…”)
cap.release()
cap = connect_to_stream(stream_url)
if cap is None:
break
continue

cv2.imshow('Stream', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):break

cap.release()
cv2.destroyAllWindows()

2. 提高视频流性能

2.1降低分辨率

def resize_frame(frame, scale_percent=50):width = int(frame.shape[1] * scale_percent / 100)height = int(frame.shape[0] * scale_percent / 100)return cv2.resize(frame, (width, height))

2.2跳过部分帧

frame_counter = 0
frame_skip = 2  # 每3帧处理1帧while True:ret, frame = cap.read()if not ret:# 处理断流...continueframe_counter += 1if frame_counter % (frame_skip + 1) != 0:continue# 处理帧frame = resize_frame(frame, 50)cv2.imshow('Optimized Stream', frame)if cv2.waitKey(1) & 0xFF == ord('q'):break

五、使用FFmpeg作为后端

对于某些ESP32摄像头流,使用FFmpeg作为后端可能更稳定:import cv2
import subprocessesp32_ip = "192.168.1.100"
stream_url = f"http://{esp32_ip}/video"# 使用FFmpeg作为视频捕获后端
command = ['ffmpeg','-i', stream_url,'-f', 'image2pipe','-pix_fmt', 'bgr24','-vcodec', 'rawvideo', '-'
]pipe = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=10**8)while True:# 读取原始视频数据raw_image = pipe.stdout.read(640*480*3)# 转换为numpy数组image = np.frombuffer(raw_image, dtype='uint8')if image.size == 0:breakimage = image.reshape((480, 640, 3))cv2.imshow('FFmpeg Stream', image)if cv2.waitKey(1) & 0xFF == ord('q'):breakpipe.terminate()
cv2.destroyAllWindows()

六、使用PyAV库(高级选项)

import av
import cv2
import numpy as npesp32_ip = "192.168.1.100"
stream_url = f"http://{esp32_ip}/video"container = av.open(stream_url)for frame in container.decode(video=0):img = frame.to_ndarray(format='bgr24')cv2.imshow('PyAV Stream', img)if cv2.waitKey(1) & 0xFF == ord('q'):breakcontainer.close()
cv2.destroyAllWindows()

七、实际应用示例 - 视频流处理

import cv2
import numpy as npdef process_frame(frame):"""帧处理函数示例"""# 转换为灰度图gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 边缘检测edges = cv2.Canny(gray, 100, 200)# 转换为3通道以便与原图拼接edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)# 水平拼接原图和边缘图processed = cv2.hconcat([frame, edges])return processedesp32_ip = "192.168.1.100"
stream_url = f"http://{esp32_ip}/video"cap = cv2.VideoCapture(stream_url)while True:ret, frame = cap.read()if not ret:print("视频流中断")break# 处理帧result = process_frame(frame)# 显示FPSfps = cap.get(cv2.CAP_PROP_FPS)cv2.putText(result, f"FPS: {fps:.1f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)cv2.imshow('Processed ESP32 Stream', result)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()

八、注意事项

1.网络延迟

网络延迟:Wi-Fi视频流通常有100-500ms的延迟

2.带宽限制

带宽限制:高清视频流可能需要较大的带宽

3.认证

认证:如果ESP32摄像头需要认证,URL格式为 http://username:password@ip/video

4.编码格式

编码格式:确认ESP32摄像头的视频编码格式**(通常是MJPEG)**

5.稳定性

稳定性:无线连接可能不稳定,需要添加重连逻辑
通过以上方法,你可以灵活地使用Python读取和处理ESP32摄像头的视频流,并根据需要进行各种图像处理和分析


http://www.xdnf.cn/news/373897.html

相关文章:

  • Hive表JOIN性能问
  • 质量保证计划,软件质量计划书,软件质量方案(word原件)
  • 在线SQL转ER图工具
  • java命令行打包class为jar并运行
  • 使用FastAPI和React以及MongoDB构建全栈Web应用03 全栈开发快速入门
  • 51c大模型~合集126
  • Pyhton生活手册-NumPy数据类型:从快递单到智能家居的数据变形术
  • 高精度之加减乘除之多解总结(加与减篇)
  • C++GO语言微服务和服务发现②
  • Java—— 泛型详解
  • PLC可编程控制器在接地电阻柜接触器柜中的智能化控制实践
  • 最大公约数gcd和最小公倍数lcm
  • `RotationTransition` 是 Flutter 中的一个动画组件,用于实现旋转动画效果
  • 跨境热销产品安全危机:一场召回事件背后的全球合规挑战
  • 提高工作效率的新选择[特殊字符]——Element Plus UI库
  • 基于小波神经网络(WNN)的回归预测模型【MATLAB】
  • 精品,第22章 Python3 数据类型与文件操作详解
  • Jmeter中的Json提取器如何使用?
  • 数据分析2
  • C.printf 函数基础
  • (51单片机)LCD显示红外遥控相关数字(Delay延时函数)(LCD1602教程)(Int0和Timer0外部中断教程)(IR红外遥控模块教程)
  • 2025数维杯数学建模A题完整参考论文(共36页)(含模型、可运行代码、数据)
  • `C_PiperInterface` 类接口功能列表
  • Shell编程之正则表达式与文本处理器
  • 数字果园管理系统的设计与实现(Tensorflow的害虫识别结合高德API的害虫定位与Websocket的在线聊天室)
  • springboot生成二维码到海报模板上
  • 【计算机视觉】OpenCV项目实战:基于OpenCV的图像分割技术深度解析与实践指南
  • Linux系统:虚拟文件系统与文件缓冲区(语言级内核级)
  • 深度解析 MySQL 与 Spring Boot 长耗时进程:从故障现象到根治方案(含 Tomcat 重启必要性分析)
  • 关于一些平时操作系统或者软件的步骤转载