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

OpenCV(四):视频采集与保存

核心函数

cv2.VideoCapture 是 OpenCV 中用于视频采集的核心对象。它抽象了视频输入源,无论是来自硬件摄像头、视频文件,还是网络流(如 IP 摄像机)。

构造函数(初始化)

创建 VideoCapture 对象的关键在于传入正确的参数,以指定视频源。

语法说明
cap = cv2.VideoCapture(index)实时流: 传入整数 index。通常 0 代表系统默认摄像头,1 代表第二个摄像头,以此类推。
cap = cv2.VideoCapture(filename)文件流: 传入视频文件的路径字符串 filename(如 'video.mp4''C:/path/to/video.avi')。
cap = cv2.VideoCapture(url)网络流: 传入网络视频流的 URL 字符串(需确保 OpenCV 编译时支持相应的后端,如 GStreamer)。

核心方法

方法功能返回值/说明
cap.isOpened()检查视频源是否成功初始化和打开。True (成功) 或 False (失败)
ret, frame = cap.read()从视频流中读取下一帧ret (bool): 表示是否成功读取帧;frame (numpy.ndarray): 读取到的帧图像(BGR 格式)。
cap.release()释放视频采集资源。在完成视频操作后必须调用。
cap.get(propId)获取视频属性,如帧宽度、高度、FPS 等。返回属性值(通常为 float)。
cap.set(propId, value)设置视频属性。True (成功) 或 False (失败)。

关键属性标识符(propId

cap.get()cap.set() 中使用的常量,用于指定操作的视频属性:

标识符说明
cv2.CAP_PROP_FRAME_WIDTH帧的宽度(像素)
cv2.CAP_PROP_FRAME_HEIGHT帧的高度(像素)
cv2.CAP_PROP_FPS视频帧率(Frames Per Second)
cv2.CAP_PROP_FRAME_COUNT视频文件中的总帧数
cv2.CAP_PROP_POS_FRAMES当前帧的位置(基于 0 的索引)

示例

示例1:实时摄像头视频采集(实时流)

import cv2# 1. 初始化 VideoCapture 对象,参数 0 表示默认摄像头
cap = cv2.VideoCapture(0)# 检查摄像头是否成功打开
if not cap.isOpened():print("错误:无法打开摄像头。请检查设备索引或驱动。")exit()print("摄像头已打开,按 'q' 键退出...")# 实时流处理循环
while True:# 2. 读取一帧# ret 为布尔值,表示是否成功读取# frame 为读取到的帧图像(numpy 数组)ret, frame = cap.read()# 如果未成功读取帧(如流结束或读取错误),则退出循环if not ret:print("无法接收帧(可能是流结束)。退出...")break# *** 在这里可以对 frame 进行各种图像处理操作 ***# 例如:转换为灰度图gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 3. 显示结果帧# 显示原始彩色帧cv2.imshow('Live Camera Feed', frame)# 也可以显示处理后的灰度帧# cv2.imshow('Gray Frame', gray_frame)# 4. 设置退出条件# cv2.waitKey(1) 等待按键 1 毫秒# 0xFF == ord('q') 检查按下的键是否是 'q'if cv2.waitKey(1) & 0xFF == ord('q'):break# 5. 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()
print("资源已释放,程序退出。")

示例2:读取视频文件(文件流)

import cv2
import time# 假设你的视频文件名为 'test_video.mp4' 且在当前目录下
video_path = 'test_video.mp4'# 1. 初始化 VideoCapture 对象,参数为视频文件路径
cap = cv2.VideoCapture(video_path)# 检查视频文件是否成功打开
if not cap.isOpened():print(f"错误:无法打开视频文件: {video_path}")exit()# 2. 获取视频属性
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)print(f"视频分辨率: {frame_width}x{frame_height}")
print(f"视频帧率 (FPS): {fps:.2f}")# 计算每帧应等待的毫秒数 (播放速度控制)
# 默认 FPS,如果读取失败,则使用 25 毫秒/帧 (约 40 FPS)
delay = int(1000 / fps) if fps > 0 else 25 print(f"每帧等待时间: {delay} 毫秒")# 文件流处理循环
while cap.isOpened():# 3. 读取一帧ret, frame = cap.read()if ret:# 4. 显示帧cv2.imshow('Video File Player', frame)# 5. 等待按键# waitKey(delay) 控制播放速度# 按 'q' 退出if cv2.waitKey(delay) & 0xFF == ord('q'):breakelse:# 如果读取失败(通常是文件末尾),则退出循环print("视频播放结束。")break# 6. 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()
print("资源已释放,程序退出。")

示例3:拉取 RTSP 网络实时流

import cv2
import time# !!!重要!!!
# 请替换为您实际的 RTSP URL
# 格式通常为: rtsp://用户名:密码@IP地址:端口/路径
RTSP_URL = 'rtsp://guest:password@192.168.1.100:554/live/ch0' # 替换为您的实际地址# 1. 初始化 VideoCapture 对象,传入 RTSP URL
# 注意:网络流的初始化时间可能较长,程序会阻塞直到连接尝试结束
cap = cv2.VideoCapture(RTSP_URL, cv2.CAP_FFMPEG) # 明确指定使用 FFmpeg 后端,增强兼容性# 检查流是否成功打开
if not cap.isOpened():print(f"错误:无法打开 RTSP 流:{RTSP_URL}")print("请检查 URL 格式、用户名密码、网络连通性以及 OpenCV 的 FFmpeg 支持。")exit()print(f"RTSP 流已成功连接,分辨率:{int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))}x{int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))}")
print("按 'q' 键退出...")# RTSP 实时流处理循环
while True:# 2. 读取一帧# 网络流可能会因为网络延迟或断开导致读取失败ret, frame = cap.read()# 如果未成功读取帧,可能是网络中断或流结束if not ret:print("警告:无法从 RTSP 流接收帧。尝试重新连接或退出...")# 尝试等待并重新读取time.sleep(0.1)continue# *** 在这里可以进行实时处理,例如绘制文本、目标检测等 ***cv2.putText(frame, 'RTSP Live Stream', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)# 3. 显示结果帧cv2.imshow('RTSP Stream Player', frame)# 4. 设置退出条件# 对于实时流,waitKey(1) 保证了尽可能快的帧率显示if cv2.waitKey(1) & 0xFF == ord('q'):break# 5. 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()
print("RTSP 资源已释放,程序退出。")

保存视频:cv2.VideoWriter

虽然请求是关于采集,但在实际应用中,采集往往伴随着处理和保存。cv2.VideoWriter 类用于将处理后的帧写入视频文件。

核心 API

语法说明
out = cv2.VideoWriter(filename, fourcc, fps, frame_size)构造函数:创建一个 VideoWriter 对象,准备写入视频文件。
out.write(frame)一帧图像写入视频文件。
out.release()关闭视频文件并释放资源。

参数说明:

  1. filename:输出视频文件的路径,例如 'output.avi'
  2. fourcc:四字符代码 (FourCC),用于指定视频编码器。
  3. fps:输出视频的帧率。
  4. frame_size:帧的宽度和高度,格式为 (width, height) 元组。

视频编码格式参考(FourCC)

格式FourCC文件扩展名说明
MPEG-4'mp4v'.mp4通用、兼容性好
XVID'XVID'.avi常用 AVI 格式
MJPG'MJPG'.avi运动JPEG编码
H.264'X264'.mp4需要系统支持 H.264 编码器
DIVX'DIVX'.avi常见编码

示例

示例1:采集实时流并保存视频

import cv2# 1. 初始化 VideoCapture 对象,参数 0 表示默认摄像头
cap = cv2.VideoCapture(0)# 检查摄像头是否成功打开
if not cap.isOpened():print("错误:无法打开摄像头。请检查设备索引或驱动。")exit()print("摄像头已打开,按 'q' 键退出...")# 获取帧的尺寸和 FPS
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = 20.0 # 设置保存视频的帧率# 1. 定义 FourCC 编码和 VideoWriter 对象
# 使用 mp4v 编码,保存为 MP4 文件
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output.mp4', fourcc, fps, (frame_width, frame_height))while True:ret, frame = cap.read()if ret:# 2. 将原始帧写入输出文件out.write(frame)# 显示帧 (与前例相同)cv2.imshow('Live Camera Feed and Saving', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:break# 3. 释放 VideoCapture 和 VideoWriter 资源
cap.release()
out.release()
cv2.destroyAllWindows()
print("视频已保存到 output.mp4。")

示例2:拉取rtsp实时流并保存视频

import cv2
import time# !!!重要!!!
# 请替换为您实际的 RTSP URL
# 格式通常为: rtsp://用户名:密码@IP地址:端口/路径
RTSP_URL = 'rtsp://admin:Gzd@791369209@192.168.0.111:554/Streaming/Channels/101' # 替换为您的实际地址# 初始化 VideoCapture 对象,传入 RTSP URL
# 注意:网络流的初始化时间可能较长,程序会阻塞直到连接尝试结束
cap = cv2.VideoCapture(RTSP_URL, cv2.CAP_FFMPEG) # 明确指定使用 FFmpeg 后端,增强兼容性# 检查流是否成功打开
if not cap.isOpened():print(f"错误:无法打开 RTSP 流:{RTSP_URL}")print("请检查 URL 格式、用户名密码、网络连通性以及 OpenCV 的 FFmpeg 支持。")exit()print(f"RTSP 流已成功连接,分辨率:{int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))}x{int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))}")
print("按 'q' 键退出...")# 获取帧的尺寸和 FPS
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = 20.0 # 设置保存视频的帧率# 1. 定义 FourCC 编码和 VideoWriter 对象
# 使用 mp4v 编码,保存为 MP4 文件
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output_rtsp.mp4', fourcc, fps, (frame_width, frame_height))while True:ret, frame = cap.read()if ret:# 2. 将原始帧写入输出文件out.write(frame)# 显示帧 (与前例相同)cv2.imshow('Live Camera Feed and Saving', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:break# 3. 释放 VideoCapture 和 VideoWriter 资源
cap.release()
out.release()
cv2.destroyAllWindows()
print("视频已保存到 output.mp4。")
http://www.dtcms.com/a/453458.html

相关文章:

  • 证券业智能化投研与分布式交易系统架构:全球发展现状、技术创新与未来趋势研究
  • AI Agent竞争进入下半场:模型只是入场券,系统架构决定胜负
  • 图书商城网站开发的目的网页设计实训报告总结1500字
  • 做俄语网站做网站傻瓜软件
  • 兼具本地式与分布式优势、针对大类通用型Web漏洞、插件外部动态化导入的轻量级主被动扫描器
  • 第4章 文件管理
  • JavaScript初识及基本语法讲解
  • RabbitMQ中Consumer的可靠性
  • 自学网站建设作业抖音代运营公司收费
  • drupal做虚拟发货网站做网站如何将一张图片直接变体
  • 监控系统1 - 项目框架 | 线程邮箱
  • CTFHub SQL注入通关笔记3:报错注入(手注法+脚本法)
  • 开源UML工具完全指南:从图形化建模到文本驱动绘图
  • 优秀网站设计欣赏北京公司网站建设公司
  • 基于 Python 构建的安全 gRPC 服务——TLS、mTLS 与 Casbin 授权实战
  • 【Java核心技术/IO】35道Java IO面试题与答案
  • ICT 数字测试原理 10 - -VCL 向量如何执行之数字单元
  • 网站目录爬行wordpress怎么做信息分类
  • 专题三:二分查找~
  • 360小工具合集,用39个小工具
  • GreenTuber 0.1.7.6| 纯净无广的油管第三方,支持4K下载
  • UVa 235 Typesetting
  • 东莞营销网站建设哪个平台好十大app排行榜
  • asp网站开发工具现在的企业一般用的什么邮箱
  • 企业区块链重新崛起
  • 【SSH】同一局域网下windows使用Xshell SSH连接另一台 ubuntu 22.04 电脑
  • [随手记] docker 镜像拉取记录
  • Ruoyi 赋能,百度天气不止当下:打造面向未来的预报实战
  • 网站搭建流程负责人长春制作网站哪家好
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(7):语法 +考え方20+2022年7月N1