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

基于OpenCV与Python实现视频下方CSV表格同步显示的问题求助

问题与解决方案

问题描述

我正在开发一个项目,需要在视频下方以表格形式展示CSV文件的对应数据。现有代码可读取视频与CSV文件并在窗口中显示视频,同时应在视频下方展示CSV数据表格,且表格数据需随视频进度更新或滚动以匹配时序。但目前代码存在问题:视频播放不流畅,表格行尺寸过大无法正常查看。

需求

  • 确保视频流畅播放无卡顿或缓冲;
  • 调整表格尺寸使其缩小并适配窗口;
  • 实现表格数据随视频时序滚动的功能。

原代码

import cv2
import pandas as pd
import numpy as np

# Function to display video with CSV data in tabular format below the video
def display_video_with_csv(video_path, csv_path):
    cap = cv2.VideoCapture(video_path)
    df = pd.read_csv(csv_path)

    # Set up the display window
    cv2.namedWindow('Video with CSV', cv2.WINDOW_NORMAL)

    # Read the first frame to get video dimensions
    ret, frame = cap.read()
    height, width, _ = frame.shape

    # Calculate the height for the table display
    table_height = int(height * 0.8)

    # Initialize the scrolling position and scrolling step size
    scroll_pos = 0
    scroll_step = int(table_height / 10)  # Adjust the step size as needed

    while True:
        # Read the next frame from the video
        ret, frame = cap.read()

        if not ret:
            break

        # Get the frame number and corresponding data from the CSV file
        frame_number = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
        data = df.iloc[frame_number - 1]

        # Create a table to display the CSV data
        table = pd.DataFrame(data).transpose()

        # Create a blank image to display the table data
        table_image = 255 * np.ones((table_height, width, 3), dtype=np.uint8)

        # Add the table text to the table image
        font = cv2.FONT_HERSHEY_DUPLEX
        font_scale = 0.5
        font_thickness = 1
        text_color = (0, 0, 0)  # Black color

        y_offset = scroll_step
        for i, (col_name, val) in enumerate(table.items()):
            cv2.putText(
                table_image,
                f"{col_name}: {val.values[0]}",
                (10, y_offset),
                font,
                font_scale,
                text_color,
                font_thickness,
                cv2.LINE_AA
            )
            y_offset += scroll_step

        # Display the video frame
        cv2.imshow('Video with CSV', frame)

        # Create a combined image with the video frame and table image
        combined_image = np.vstack((frame, table_image))

        # Display the combined image in the window
        cv2.imshow('Video with CSV', combined_image)

        # Scroll the table if needed
        if frame_number % 30 == 0:  # Adjust the scroll frequency as needed
            scroll_pos += 1

        # Check for user interrupt (press 'q' to exit)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # Release the video stream and close the display window
    cap.release()
    cv2.destroyAllWindows()

# Provide the paths to the video and CSV file
video_path = r"Main.mp4"
csv_path = r"Test_1.csv"

# Call the function to display the video with CSV data
display_video_with_csv(video_path, csv_path)

修改后的代码与解决方案

1. 解决视频卡顿问题

  • 移除重复的cv2.imshow调用,只显示最终的合并图像;
  • 根据视频帧率设置waitKey的延迟时间,避免固定1ms导致的过快或卡顿;
  • 预先将CSV数据转换为字典列表,避免每次循环创建DataFrame的开销。

2. 调整表格尺寸适配窗口

  • 缩小表格高度比例(改为视频高度的30%),避免占用过多空间;
  • 根据字体大小计算合适的行高,确保每行内容紧凑且清晰;
  • 限制表格内文本的显示长度,避免内容溢出。

3. 实现时序滚动功能

  • 根据当前帧对应的CSV行索引,计算滚动偏移量,让当前帧的数据始终显示在表格的顶部区域;
  • 限制滚动范围,避免超出CSV数据的上下边界。
import cv2
import pandas as pd
import numpy as np

def display_video_with_csv(video_path, csv_path):
    cap = cv2.VideoCapture(video_path)
    df = pd.read_csv(csv_path)
    # 预先转换为字典列表,提升访问速度
    csv_data = df.to_dict('records')
    total_frames = len(csv_data)

    # 获取视频帧率,用于设置waitKey延迟
    fps = cap.get(cv2.CAP_PROP_FPS)
    wait_delay = int(1000 / fps) if fps > 0 else 1

    # 读取第一帧获取尺寸
    ret, frame = cap.read()
    if not ret:
        print("无法读取视频")
        return
    height, width, _ = frame.shape

    # 调整表格高度为视频高度的30%
    table_height = int(height * 0.3)
    # 计算每行的高度(基于字体大小)
    font = cv2.FONT_HERSHEY_DUPLEX
    font_scale = 0.4
    font_thickness = 1
    # 获取字体行高
    (text_width, text_height), _ = cv2.getTextSize("Test", font, font_scale, font_thickness)
    row_height = text_height + 8  # 增加少量间距
    # 表格可显示的最大行数
    max_display_rows = table_height // row_height

    cv2.namedWindow('Video with CSV', cv2.WINDOW_NORMAL)

    while True:
        ret, frame = cap.read()
        if not ret:
            break

        # 获取当前帧索引(确保不超出CSV数据范围)
        frame_idx = min(int(cap.get(cv2.CAP_PROP_POS_FRAMES)) - 1, total_frames - 1)
        current_data = csv_data[frame_idx]

        # 创建表格背景
        table_image = 255 * np.ones((table_height, width, 3), dtype=np.uint8)

        # 计算滚动位置:让当前数据行显示在表格顶部附近,超出范围则滚动
        scroll_start = max(0, frame_idx - (max_display_rows // 2))
        scroll_end = min(total_frames, scroll_start + max_display_rows)

        # 绘制表格内容
        y_offset = row_height
        for row_idx in range(scroll_start, scroll_end):
            row_data = csv_data[row_idx]
            # 拼接该行的所有列内容(可根据需求调整显示格式)
            text_parts = [f"{k}: {v}" for k, v in row_data.items()]
            # 限制单行长度,避免超出窗口
            text = ", ".join(text_parts[:5]) + ("..." if len(text_parts) >5 else "")
            # 高亮当前帧对应的行
            color = (0, 0, 255) if row_idx == frame_idx else (0, 0, 0)
            cv2.putText(
                table_image,
                text,
                (10, y_offset),
                font,
                font_scale,
                color,
                font_thickness,
                cv2.LINE_AA
            )
            y_offset += row_height
            if y_offset > table_height:
                break

        # 合并视频帧和表格
        combined_image = np.vstack((frame, table_image))
        cv2.imshow('Video with CSV', combined_image)

        # 处理退出和延迟
        if cv2.waitKey(wait_delay) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

# 路径设置
video_path = r"Main.mp4"
csv_path = r"Test_1.csv"

display_video_with_csv(video_path, csv_path)

关键修改说明

  • 流畅播放:通过匹配视频帧率设置waitKey延迟,移除冗余的imshow调用,预先处理CSV数据减少循环内计算;
  • 表格适配:缩小表格高度,根据字体自动计算行高,限制单行显示内容避免溢出;
  • 时序滚动:基于当前帧索引计算滚动起始位置,让对应数据始终处于可视区域,同时高亮当前行提升辨识度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:35:03