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

如何将三个视频处理相关的.py文件合并为单个脚本?

合并后的视频显著性处理方案

我们可以将三个独立脚本的功能整合到一个文件中,同时优化流程提升效率。以下提供两种实现方式:


方式一:保留中间文件(与原流程一致)

该版本保留原有的"拆帧→处理→合并"步骤,将功能封装为函数,结构更清晰且避免报错:

import cv2
import os
from glob import glob

def split_video(video_path, output_frame_dir):
    # 自动创建输出目录
    os.makedirs(output_frame_dir, exist_ok=True)
    capture = cv2.VideoCapture(video_path)
    fps = capture.get(cv2.CAP_PROP_FPS)
    print(f"原视频帧率: {fps}")
    frameNr = 0

    while True:
        success, frame = capture.read()
        if success:
            cv2.imwrite(f'{output_frame_dir}/frame_{frameNr}.jpg', frame)
        else:
            break
        frameNr += 1
    capture.release()
    return fps

def apply_saliency(frame_dir, saliency_output_dir):
    os.makedirs(saliency_output_dir, exist_ok=True)
    saliency = cv2.saliency.StaticSaliencyFineGrained_create()
    i = 0
    for fn in glob(f'{frame_dir}/*.jpg'):
        image = cv2.imread(fn)
        (ret, img_sal) = saliency.computeSaliency(image)
        saliencyMap = (img_sal * 255).astype('uint8')
        cv2.imwrite(f'{saliency_output_dir}/test_salient_tm_{i}.jpg', saliencyMap)
        i += 1

def merge_frames_to_video(saliency_dir, output_video_path, fps):
    # 对帧文件排序,避免顺序混乱
    images = sorted([img for img in os.listdir(saliency_dir) if img.endswith('.jpg')], 
                   key=lambda x: int(x.split('_')[-1].split('.')[0]))
    if not images:
        print("没有找到处理后的帧")
        return
    frame = cv2.imread(os.path.join(saliency_dir, images[0]))
    height, width = frame.shape[:2]

    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    video = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))

    for image in images:
        video.write(cv2.imread(os.path.join(saliency_dir, image)))

    cv2.destroyAllWindows()
    video.release()

if __name__ == '__main__':
    # 配置参数
    INPUT_VIDEO = 'vids/tm_test.mp4'
    FRAME_OUTPUT_DIR = 'Output'
    SALIENCY_OUTPUT_DIR = 'images'
    FINAL_VIDEO = 'vids/tm_test_salient.mp4'

    # 按顺序执行流程
    original_fps = split_video(INPUT_VIDEO, FRAME_OUTPUT_DIR)
    apply_saliency(FRAME_OUTPUT_DIR, SALIENCY_OUTPUT_DIR)
    merge_frames_to_video(SALIENCY_OUTPUT_DIR, FINAL_VIDEO, original_fps)

关键修改说明:

  • 将三个功能封装为独立函数,代码结构更清晰
  • 添加自动创建目录的逻辑,避免因目录不存在报错
  • 合并帧时对文件排序,解决原代码中帧顺序混乱的问题
  • 传递原视频帧率到合并步骤,替代硬编码的56.0,保证输出视频帧率匹配原视频

方式二:无中间文件(高效优化版)

该版本省略中间文件读写,直接在内存中逐帧处理并写入视频,大幅提升速度且节省磁盘空间:

import cv2

def process_video_with_saliency(input_video_path, output_video_path):
    # 读取输入视频
    capture = cv2.VideoCapture(input_video_path)
    if not capture.isOpened():
        print("无法打开输入视频")
        return
    
    # 获取原视频参数
    fps = capture.get(cv2.CAP_PROP_FPS)
    width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
    print(f"原视频参数: 帧率{fps}, 分辨率{width}x{height}")

    # 初始化显著性检测器
    saliency = cv2.saliency.StaticSaliencyFineGrained_create()

    # 初始化视频写入器(设置isColor=False适配单通道显著性图)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    video_writer = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height), isColor=False)
    if not video_writer.isOpened():
        print("无法初始化视频写入器")
        capture.release()
        return

    # 逐帧处理并写入
    while True:
        success, frame = capture.read()
        if not success:
            break
        
        # 计算显著性图
        ret, img_sal = saliency.computeSaliency(frame)
        if ret:
            saliency_map = (img_sal * 255).astype('uint8')
            video_writer.write(saliency_map)

    # 释放资源
    capture.release()
    video_writer.release()
    cv2.destroyAllWindows()
    print("处理完成,输出视频已保存")

if __name__ == '__main__':
    INPUT_VIDEO = 'vids/tm_test.mp4'
    OUTPUT_VIDEO = 'vids/tm_test_salient.mp4'
    process_video_with_saliency(INPUT_VIDEO, OUTPUT_VIDEO)

优化点说明:

  • 完全省略中间文件的磁盘读写,处理速度提升明显
  • 直接复用原视频的分辨率和帧率,保证输出视频与原视频匹配
  • 添加视频打开/写入失败的判断,提升代码鲁棒性
  • 适配显著性图的单通道特性,无需额外转换为三通道

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:10:30