You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OpenCV VideoWriter录制与YOLO模型实时推理速率一致的视频?

保留YOLO实时推理卡顿效果的录制方案

问题说明

运行YOLO实时推理代码时,窗口显示的画面会因模型推理耗时出现明显卡顿,但直接用OpenCV VideoWriter录制时,视频会按照固定帧率输出,无法还原这种真实的卡顿效果。

解决方案

以下两种方案可实现需求,根据场景选择:

方案1:录制显示窗口(直观还原卡顿)

直接录制YOLO推理时的显示窗口,完整保留实时卡顿效果,操作简单。

步骤:

  1. 安装依赖:
pip install mss ultralytics opencv-python
  1. 运行代码:
import cv2
import time
from ultralytics import YOLO
import mss
import numpy as np

# 加载YOLO模型
model = YOLO('yolov8n.pt')

# 打开目标视频
video_path = "path/to/your/video/file.mp4"
cap = cv2.VideoCapture(video_path)

# 创建显示窗口并获取窗口位置
window_name = "YOLOv8 Inference"
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)

# 先渲染一帧以确定窗口位置
success, frame = cap.read()
if success:
    results = model(frame)
    annotated_frame = results[0].plot()
    cv2.imshow(window_name, annotated_frame)
    cv2.waitKey(1)

# 获取窗口坐标与尺寸
x, y, w, h = cv2.getWindowImageRect(window_name)

# 初始化屏幕录制器
sct = mss.mss()
monitor = {"top": y, "left": x, "width": w, "height": h}

# 初始化视频写入器,帧率沿用原视频帧率
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_writer = cv2.VideoWriter('recorded_lag_effect.mp4', fourcc, cap.get(cv2.CAP_PROP_FPS), (w, h))

# 开始推理、显示与录制
while cap.isOpened():
    success, frame = cap.read()
    if success:
        # YOLO推理与标注
        results = model(frame)
        annotated_frame = results[0].plot()
        # 显示卡顿画面
        cv2.imshow(window_name, annotated_frame)
        # 录制当前窗口画面
        sct_img = sct.grab(monitor)
        frame_np = np.array(sct_img)
        frame_bgr = cv2.cvtColor(frame_np, cv2.COLOR_BGRA2BGR)
        # 写入视频文件
        video_writer.write(frame_bgr)
        # 按q键退出
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        break

# 释放所有资源
cap.release()
video_writer.release()
cv2.destroyAllWindows()
sct.close()

注意:录制期间需保持窗口在前台,避免被其他窗口遮挡。


方案2:基于推理耗时生成可变帧率视频(后台处理)

记录每帧的实际推理耗时,通过FFmpeg合成可变帧率视频,无需显示窗口,适合后台批量处理场景。

步骤:

  1. 确保已安装FFmpeg(需自行下载配置到系统环境变量)
  2. 运行代码:
import cv2
import time
import os
from ultralytics import YOLO

# 加载YOLO模型
model = YOLO('yolov8n.pt')
video_path = "path/to/your/video/file.mp4"
cap = cv2.VideoCapture(video_path)

# 创建临时文件夹保存单帧图像
temp_dir = "temp_frames"
os.makedirs(temp_dir, exist_ok=True)

frame_times = []
frame_idx = 0

# 批量处理视频帧并记录耗时
while cap.isOpened():
    success, frame = cap.read()
    if success:
        start_time = time.time()
        # YOLO推理与标注
        results = model(frame)
        annotated_frame = results[0].plot()
        # 记录单帧处理耗时
        frame_time = time.time() - start_time
        frame_times.append(frame_time)
        # 保存帧到临时文件夹
        frame_path = os.path.join(temp_dir, f"frame_{frame_idx:04d}.jpg")
        cv2.imwrite(frame_path, annotated_frame)
        frame_idx += 1
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        break

cap.release()
cv2.destroyAllWindows()

# 生成FFmpeg所需的时间戳配置文件
with open("timestamps.txt", "w", encoding="utf-8") as f:
    total_time = 0.0
    for idx, t in enumerate(frame_times):
        f.write(f"file '{os.path.abspath(os.path.join(temp_dir, f'frame_{idx:04d}.jpg'))}'\n")
        f.write(f"duration {t}\n")
    # FFmpeg要求最后一帧重复写入一次
    f.write(f"file '{os.path.abspath(os.path.join(temp_dir, f'frame_{frame_idx-1:04d}.jpg'))}'\n")

# 调用FFmpeg合成可变帧率视频
os.system('ffmpeg -f concat -safe 0 -i timestamps.txt -c:v libx264 -crf 23 -vf "fps=60" output_lag_effect.mp4')

# 可选:清理临时文件
# import shutil
# shutil.rmtree(temp_dir)
# os.remove("timestamps.txt")

优缺点:无需显示窗口,视频帧率完全匹配实际推理耗时,但依赖FFmpeg,且涉及文件IO,处理速度较慢。


内容的提问来源于stack exchange,提问作者ailauli69

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:04:54