程序代码篇---Python视频流

news2025/5/11 13:09:24

文章目录

  • 前言
  • 一、OpenCV 视频流处理
    • 1. 视频捕获基础
    • 2. 视频流属性设置与获取
    • 3. 视频写入
  • 二、高级视频流操作
    • 1. 多摄像头处理
    • 2. 视频流帧处理
    • 3. 视频流分析与统计
  • 三、其他视频处理库
    • 1. PyAV (FFmpeg 的 Python 绑定)
    • 2. imageio
  • 四、视频流处理优化技巧
    • 1. 多线程视频处理
    • 2. 视频流分辨率动态调整
    • 3. 硬件加速
  • 五、特殊视频流处理
    • 1. RTSP 视频流
    • 2. 视频流截图与保存
    • 3. 视频流叠加信息
  • 六、视频流处理常见问题解决
    • 1.视频延迟问题
    • 2.视频无法打开
    • 3.内存泄漏
    • 4.性能瓶颈
    • 5.视频写入问题


前言

视频流处理是计算机视觉应用的基础,Python 通过 OpenCV、PyAV、imageio 等库提供了强大的视频处理能力。下面我将简单较为全面介绍 Python 中视频流的相关操作。


一、OpenCV 视频流处理

1. 视频捕获基础

import cv2

# 从摄像头捕获视频流
cap = cv2.VideoCapture(0)  # 0 表示默认摄像头

# 从视频文件捕获
# cap = cv2.VideoCapture('video.mp4')

while True:
    # 读取帧
    ret, frame = cap.read()
    
    if not ret:
        print("无法读取视频流")
        break
    
    # 显示帧
    cv2.imshow('Video Stream', frame)
    
    # 按'q'退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
cap.release()
cv2.destroyAllWindows()

2. 视频流属性设置与获取

# 获取视频属性
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

print(f"分辨率: {width}x{height}")
print(f"帧率: {fps}")
print(f"总帧数: {frame_count}")

# 设置视频属性
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
cap.set(cv2.CAP_PROP_FPS, 30)

3. 视频写入

# 定义视频编码器
fourcc = cv2.VideoWriter_fourcc(*'XVID')  # 也可以使用 'MJPG', 'MP4V' 等

# 创建 VideoWriter 对象
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    # 处理帧 (可选)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # 写入帧
    out.write(frame)
    
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
cap.release()
out.release()
cv2.destroyAllWindows()

二、高级视频流操作

1. 多摄像头处理

# 同时从多个摄像头捕获
cap1 = cv2.VideoCapture(0)  # 主摄像头
cap2 = cv2.VideoCapture(1)  # 外接摄像头

while True:
    ret1, frame1 = cap1.read()
    ret2, frame2 = cap2.read()
    
    if not ret1 or not ret2:
        break
    
    # 水平拼接两个视频流
    combined = cv2.hconcat([frame1, frame2])
    cv2.imshow('Multi Camera', combined)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap1.release()
cap2.release()
cv2.destroyAllWindows()

2. 视频流帧处理

def 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 processed

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # 处理帧
    result = process_frame(frame)
    
    cv2.imshow('Processed Video', result)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

3. 视频流分析与统计

import time

frame_count = 0
start_time = time.time()

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_count += 1
    
    # 计算实时FPS
    elapsed_time = time.time() - start_time
    fps = frame_count / elapsed_time
    
    # 在帧上显示FPS
    cv2.putText(frame, f"FPS: {fps:.2f}", (10, 30), 
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    
    cv2.imshow('Video with FPS', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

print(f"平均FPS: {fps:.2f}")

三、其他视频处理库

1. PyAV (FFmpeg 的 Python 绑定)

import av

# 打开视频文件
container = av.open('video.mp4')

# 遍历视频帧
for frame in container.decode(video=0):
    # 转换为numpy数组
    img = frame.to_ndarray(format='bgr24')
    
    cv2.imshow('PyAV Video', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

container.close()
cv2.destroyAllWindows()

2. imageio

import imageio

# 读取视频
reader = imageio.get_reader('video.mp4')

for i, frame in enumerate(reader):
    cv2.imshow('imageio Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

reader.close()
cv2.destroyAllWindows()

# 写入视频
writer = imageio.get_writer('output.mp4', fps=30)

for i in range(100):
    # 生成或获取帧
    frame = generate_frame(i)
    writer.append_data(frame)

writer.close()

四、视频流处理优化技巧

1. 多线程视频处理

from threading import Thread
import queue

class VideoStream:
    def __init__(self, src=0):
        self.stream = cv2.VideoCapture(src)
        self.stopped = False
        self.queue = queue.Queue(maxsize=128)  # 限制队列大小防止内存溢出

    def start(self):
        Thread(target=self.update, args=()).start()
        return self

    def update(self):
        while True:
            if self.stopped:
                return
            
            if not self.queue.full():
                ret, frame = self.stream.read()
                if not ret:
                    self.stop()
                    return
                self.queue.put(frame)

    def read(self):
        return self.queue.get()

    def stop(self):
        self.stopped = True
        self.stream.release()

# 使用
vs = VideoStream(0).start()

while True:
    frame = vs.read()
    cv2.imshow("Threaded Video", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

vs.stop()
cv2.destroyAllWindows()

2. 视频流分辨率动态调整

def rescale_frame(frame, percent=75):
    """按百分比缩放帧"""
    width = int(frame.shape[1] * percent / 100)
    height = int(frame.shape[0] * percent / 100)
    dim = (width, height)
    return cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # 根据处理需求动态调整分辨率
    if perform_heavy_processing:
        frame = rescale_frame(frame, percent=50)
    else:
        frame = rescale_frame(frame, percent=100)
    
    cv2.imshow('Dynamic Scaling', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

3. 硬件加速

# 使用CUDA加速 (需要支持CUDA的OpenCV版本)
def setup_cuda():
    net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
    net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
    net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
    return net

# 使用Intel OpenVINO加速
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap.set(cv2.CAP_PROP_FPS, 30)

五、特殊视频流处理

1. RTSP 视频流

rtsp_url = "rtsp://username:password@ip_address:port/path"
cap = cv2.VideoCapture(rtsp_url)

# 设置缓冲区大小减少延迟
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)

while True:
    ret, frame = cap.read()
    if not ret:
        print("连接中断,尝试重连...")
        cap.release()
        cap = cv2.VideoCapture(rtsp_url)
        continue
    
    cv2.imshow('RTSP Stream', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

2. 视频流截图与保存

save_count = 0

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    cv2.imshow('Video', frame)
    
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    elif key == ord('s'):  # 按's'保存当前帧
        save_count += 1
        filename = f"frame_{save_count}.jpg"
        cv2.imwrite(filename, frame)
        print(f"已保存: {filename}")

3. 视频流叠加信息

from datetime import datetime

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # 添加时间戳
    now = datetime.now()
    timestamp = now.strftime("%Y-%m-%d %H:%M:%S")
    cv2.putText(frame, timestamp, (10, 30), 
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
    
    # 添加边框
    cv2.rectangle(frame, (10, 10), (630, 470), (0, 0, 255), 2)
    
    cv2.imshow('Annotated Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

六、视频流处理常见问题解决

1.视频延迟问题

  1. 减少处理操作或优化代码
  2. 降低分辨率
  3. 使用多线程处理
  4. 设置 cv2.CAP_PROP_BUFFERSIZE 为 1

2.视频无法打开

  1. 检查文件路径或URL是否正确
  2. 检查视频编码格式是否支持
  3. 尝试使用不同的后端(如 cv2.CAP_DSHOW 等)

3.内存泄漏

  1. 确保正确释放资源(release())
  2. 避免在循环中不必要地创建对象
  3. 使用 with 语句管理资源

4.性能瓶颈

  1. 使用性能分析工具(如 cProfile)找出瓶颈
  2. 考虑使用Cython或Numba加速关键部分
  3. 启用硬件加速

5.视频写入问题

  1. 确保帧的大小与VideoWriter指定的尺寸匹配
  2. 检查编码器是否可用
  3. 尝试不同的文件扩展名(如 .avi, .mp4 等)

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

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

相关文章

如何利用 QuickAPI 生成 PostgreSQL 样本测试数据:全面解析与实用指南

目录 一、什么是 QuickAPI? 二、为什么需要生成样本测试数据? 三、如何在 QuickAPI 中生成 PostgreSQL 样本测试数据? 1. 登录 QuickAPI 平台 2. 选择 PostgreSQL 数据库和目标表 3. 配置样本数据生成规则 4. 导出或直接插入数据 四、…

DeepSeek API接口调用示例(开发语言C#,替换其中key值为自己的key值即可)

示例: DeepSeek官方接口说明文档:对话补全 | DeepSeek API Docs 官网暂未提供C#代码实现:(以下为根据CURL接口C#代码调用) using System; using System.Collections.Generic; using System.Linq; using System.Text; …

远程调试---在电脑上devtools调试运行在手机上的应用

1、启动项目–以vite项目为例:先ipconfig查看ip地址 ,然后在vite中配置host为ip地址 2、手机上查看项目:保证手机和电脑在同一局域网, 在手机浏览器打开我们vite启动的项目地址, 3、使用chii进行远程调试 (1) 安装 npm install chii -g (2)启动 chii start -p 8080 (3)在…

[git]如何关联本地分支和远程分支

主题 本文总结如何关联git本地分支和远程分支的相关知识点。 详情 查看本地分支 git branch 查看远程分支 git branch -r 查看所有分支(本地远程) git branch -a 查看本地分支及其关联的远程分支(如有) git branch -vv 关联本地分支到远程分支: git branch …

跨境电商生死局:动态IP如何重塑数据生态与运营效率

凌晨三点的深圳跨境电商产业园,某品牌独立站运营总监李明(化名)正盯着突然中断的广告投放系统。后台日志显示,过去24小时内遭遇了17次IP封禁,直接导致黑五促销期间损失23%的预期流量。这并非个案——2023年跨境电商行业…

springboot3+vue3融合项目实战-大事件文章管理系统-更新用户信息

在一下三个代码处进行修改 在UserController里面增加uadate方法 PutMapping ("/update")public Result update(RequestBody Validated User user){userService.update(user);return Result.success();}在userservice中增加update方法 void update(User user); 然…

气象大模型光伏功率预测中的应用:从短期,超短期,中长期的实现与开源代码详解

1. 引言 光伏功率预测对于电力系统调度、能源管理和电网稳定性至关重要。随着深度学习技术的发展,大模型(如Transformer、LSTM等)在时间序列预测领域展现出强大能力。本文将详细介绍基于大模型的光伏功率预测方法,涵盖短期(1-6小时)、超短期(15分钟-1小时)和中长期(1天-1周…

深度学习:智能车牌识别系统(python)

这是一个基于opencv的智能车牌识别系统,有GUI界面。程序能自动识别图片中的车牌号码,并支持中文和英文字符识别,支持选择本地图片文件,支持多种图片格式(jpg、jpeg、png、bmp、gif)。 下面,我将按模块功能对代码进行分段说明: 1. 导入模块部分 import tkinter as tk…

DNS服务实验

该文章将介绍DNS服务的正向和反向解析实验、主从实验、转发服务器实验以及Web解析实验 正向解析实验:将域名解析为对应的IP地址 反向解析实验:将IP地址解析为对应的域名 主从实验:主服务器区域数据文件发送给从服务器,从服务器…

visual studio 2015 安装闪退问题

参考链接: VS2012安装时启动界面一闪而过问题解决办法 visual studio 2015 安装闪退问题

C语言复习--动态内存管理

下面我们来看C语言中的动态内存管理,在之后的数据结构中会运用到C语言中的指针,结构体和动态内存管理,所以这部分还是比较重要的.下面进入正题. 为什么要有动态内存分配 但是上面的两种方式开辟的内存的大小都是固定的.数组也是,在数组开辟之前一定要确定好数组大小,并且数组开…

青藏高原七大河流源区径流深、蒸散发数据集(TPRED)

时间分辨率 月空间分辨率 1km - 10km共享方式 开放获取数据大小 83.27 MB数据时间范围 1998-07-01 — 2017-12-31元数据更新时间 2024-07-22 数据集摘要 通过构建耦合积雪、冻土、冰川等冰冻圈水文物理过程的WEB-DHM模型(Water and Energy Budget-based Distribute…

串口屏调试 1.0

http://wiki.tjc1688.com 先把商家的链接贴过来 淘晶驰T1系列3.2寸串口屏tft液晶屏显示屏HMI触摸屏超12864液晶屏 这是主包的型号 打开这个玩意 有十个基本的功能区 新建工程 在界面的右边,指令一定要写在page前面,这里的波特率等等什么的都可以…

windows 环境下 python环境安装与配置

运行环境安装 第一步安装包下载 python开发工具安装包下载官网: https://www.python.org/ 根据自己的实际需求选择。 这里记录了各个版本的区别和差异。根据区别和差异选择适合自己的版本。 Windows Installer和Windows embeddable package是两种不同的软件包类…

浅谈装饰模式

一、前言 hello大家好,本次打算简单聊一下装饰者模式,其实写有关设计模式的内容还是蛮有挑战性的,首先呢就是小永哥实力有限担心说不明白,其次设计模式是为了解决某些问题场景,在当前技术生态圈如此完善的情况下&#…

LeetCode 270:在二叉搜索树中寻找最接近的值(Swift 实战解析)

文章目录 摘要描述题解答案题解代码分析示例测试及结果时间复杂度空间复杂度总结 摘要 在日常开发中,我们经常需要在一组有序的数据中快速找到最接近某个目标值的元素。LeetCode 第 270 题“Closest Binary Search Tree Value”正是这样一个问题。本文将深入解析该…

WPF 3D图形编程核心技术解析

一、三维坐标系系统 WPF采用右手坐标系系统,空间定位遵循: X 轴 → 右 Y 轴 → 上 Z 轴 → 观察方向 X轴 \rightarrow 右\quad Y轴 \rightarrow 上\quad Z轴 \rightarrow 观察方向 X轴→右Y轴→上Z轴→观察方向 三维坐标值表示为 ( x , y , z ) (x, y,…

暗物质卯引力挂载技术

1、物体质量以及其所受到的引力约束(暗物质压力差) 自然界的所有物体,其本身都是没有质量的。我们所理解的质量,其实是物体球周空间的暗物质对物体的挤压,压力差。 对于宇宙空间中的单个星球而言,它的球周各处压力是相同的,所以,它处于平衡状态,漂浮在宇宙中。 对于星…

comfyui 如何优雅的从Hugging Face 下载模型,文件夹

如下图所示 使用git 下载整个仓库然后把需要的放到对应的位置

通过user-agent来源判断阻止爬虫访问网站,并防止生成[ error ] NULL日志

一、TP5.0通过行为&#xff08;Behavior&#xff09;拦截爬虫并避免生成 [ error ] NULL 错误日志 1. 创建行为类&#xff08;拦截爬虫&#xff09; 在 application/common/behavior 目录下新建BlockBot.php &#xff0c;用于识别并拦截爬虫请求&#xff1a; <?php name…