如何将三个视频处理相关的.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
相关产品推荐
相关产品推荐

