当前位置: 首页 > 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摄像头的视频流,并根据需要进行各种图像处理和分析


相关文章:

  • Taro 编译不平不同平台小程序
  • 《类和对象(中)》
  • 分布式事务快速入门
  • Ubuntu 与 Windows 双系统环境下 NTFS 分区挂载教程
  • Autoware message_filters::Synchronizer链接错误问题
  • 如何删除网上下载的资源后面的文字
  • 数字孪生实战笔记(1)数字孪生的含义、应用及技术体系
  • zdir3个人网盘dockerfile打包
  • 深入解析:如何基于开源p-net快速开发Profinet从站服务
  • C# WinForm DataGridView 非常频繁地更新或重新绘制慢问题及解决
  • WPF 性能 UI 虚拟化 软件开发人员的思考
  • gvm安装go报错ERROR: Failed to use installed version
  • C++GO语言微服务之用户信息处理
  • 深圳SMT贴片加工厂制造流程解析
  • 4.分布式锁
  • Pale Moon:速度优化的Firefox定制浏览器
  • vue访问后端接口,实现用户注册
  • 【金仓数据库征文】_金仓数据库在金融行业的两地三中心容灾架构实践
  • Linux 内核链表宏的详细解释
  • 前端开发实战:用React Hooks优化你的组件性能
  • 宣布停火后,印控克什米尔地区再次传出爆炸声
  • 巴基斯坦外长:近期军事回应是自卫措施
  • 广西钦州:坚决拥护自治区党委对钟恒钦进行审查调查的决定
  • 5天完成1000多万元交易额,“一张手机膜”畅销海内外的启示
  • 14岁女生瞒报年龄文身后洗不掉,法院判店铺承担六成责任
  • 印度外交秘书:“朱砂行动”不针对军事设施,无意升级事态