python+opencv实现左侧顺时针播放右侧逆时针播放。视频分割与逆序合并处理
文章目录
功能介绍
在项目测试过程中,有时候需要测试某一时刻,左侧右侧的画面是否同步,这是一个简单脚本,把视频分成的左侧和右侧,通过输入列坐标控制划分,为了制作不同步视频,左侧右侧就按照一个顺序,一个逆序,进行排序后重新组成一个新的视频。
在视频处理中,有时我们需要对视频帧进行特殊处理以达到特定效果。本文将介绍一个实用的Python脚本,该脚本能够将视频每一帧按照指定列分割为左右两部分,然后将右侧部分替换为逆序帧序列的对应右侧部分,最终合并输出新的视频。这种处理方式可以实现类似“左右部分时间反向”的视觉效果,适用于创意视频制作、特殊视觉效果实现等场景。
实现思路
该脚本的核心思路如下:
- 读取输入视频并获取其基本信息(帧数、宽高、帧率等)
- 验证分割列坐标的有效性
- 读取视频所有帧并保存
- 生成帧序列的逆序列表(用于右侧部分)
- 逐帧处理:左侧保留当前帧部分,右侧替换为逆序帧的对应部分
- 合并处理后的帧并写入输出视频文件
代码实现
以下是完整的实现代码,包含详细注释:
import cv2
import numpy as np
import os
import tempfile
def process_video(input_path, output_path, split_col):
"""
处理视频,将每一帧分割为左右两部分,右侧按帧数逆序排列后合并
参数:
input_path: 输入视频路径
output_path: 输出视频路径
split_col: 分割列的坐标
"""
# 打开输入视频
cap = cv2.VideoCapture(input_path)
if not cap.isOpened():
raise Exception(f"无法打开视频文件: {input_path}")
# 获取视频基本信息
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
# 验证分割列是否有效
if split_col < 0 or split_col >= frame_width:
raise ValueError(f"分割列坐标 {split_col} 超出视频宽度范围 [0, {frame_width - 1}]")
print(f"视频信息: 帧数={frame_count}, 宽度={frame_width}, 高度={frame_height}, FPS={fps}")
print(f"使用分割列: {split_col}")
# 读取所有帧
frames = []
for i in range(frame_count):
ret, frame = cap.read()
if not ret:
raise Exception(f"读取第 {i} 帧失败")
frames.append(frame)
# 显示进度
if (i + 1) % 100 == 0 or i + 1 == frame_count:
print(f"已读取 {i + 1}/{frame_count} 帧")
cap.release()
# 创建逆序的帧列表(用于右侧)
reversed_frames = frames[::-1]
# 处理每一帧,合并左右部分
processed_frames = []
for i in range(frame_count):
# 当前帧的左侧部分
left_part = frames[i][:, :split_col]
# 逆序帧的右侧部分
right_part = reversed_frames[i][:, split_col:]
# 确保左右部分宽度合适(处理可能的边缘情况)
if left_part.shape[1] + right_part.shape[1] != frame_width:
# 调整右侧部分宽度以匹配原始宽度
right_part = right_part[:, :frame_width - left_part.shape[1]]
# 合并左右部分
processed_frame = np.hstack((left_part, right_part))
processed_frames.append(processed_frame)
# 显示进度
if (i + 1) % 100 == 0 or i + 1 == frame_count:
print(f"已处理 {i + 1}/{frame_count} 帧")
# 定义输出视频编码器并创建VideoWriter对象
# 尝试不同的编码器以确保兼容性
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 对于MP4格式
out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height))
if not out.isOpened():
# 尝试其他编码器
fourcc = cv2.VideoWriter_fourcc(*'avc1')
out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height))
if not out.isOpened():
raise Exception("无法创建输出视频文件,请检查编码器是否支持")
# 写入处理后的帧
for i, frame in enumerate(processed_frames):
out.write(frame)
# 显示进度
if (i + 1) % 100 == 0 or i + 1 == frame_count:
print(f"已写入 {i + 1}/{frame_count} 帧")
# 释放资源
out.release()
print(f"视频处理完成,已保存至: {output_path}")
def main():
# 示例用法
input_video = r"right.mp4" # 输入视频路径
output_video = r"right_r.mp4" # 输出视频路径
# split_column = 1700 # 分割列的坐标,根据实际视频宽度调整
split_column = 1000 # 分割列的坐标,根据实际视频宽度调整
try:
process_video(input_video, output_video, split_column)
except Exception as e:
print(f"处理过程中出错: {str(e)}")
if __name__ == "__main__":
main()
代码解析
1. 依赖库导入
脚本使用了以下几个关键库:
cv2:OpenCV库,用于视频的读取、处理和写入numpy:用于数组操作,实现帧的合并os和tempfile:提供文件系统相关功能
2. 核心函数process_video
该函数是整个脚本的核心,接收三个参数:输入视频路径、输出视频路径和分割列坐标,实现视频的分割与逆序合并功能。
2.1 视频读取与信息获取
首先通过cv2.VideoCapture打开视频文件,并获取视频的基本信息:
- 帧数:
cv2.CAP_PROP_FRAME_COUNT - 宽度:
cv2.CAP_PROP_FRAME_WIDTH - 高度:
cv2.CAP_PROP_FRAME_HEIGHT - 帧率:
cv2.CAP_PROP_FPS
同时对分割列坐标进行有效性验证,确保其在合理范围内。
2.2 帧数据处理
读取所有帧并存储在列表中,然后创建帧列表的逆序副本(reversed_frames = frames[::-1]),用于右侧部分的替换。
对于每一帧,执行以下操作:
- 提取当前帧的左侧部分(
frames[i][:, :split_col]) - 提取逆序帧列表中对应位置帧的右侧部分(
reversed_frames[i][:, split_col:]) - 处理可能的宽度不匹配问题
- 使用
np.hstack合并左右两部分,形成新的帧
2.3 视频输出
为了提高兼容性,脚本尝试了两种编码器(mp4v和avc1)来创建视频写入对象。将处理后的所有帧写入输出视频文件,完成后释放资源。
3. 主函数main
主函数提供了示例用法,用户可以通过修改以下参数来使用脚本:
input_video:输入视频的路径output_video:输出视频的路径split_column:分割列的坐标(根据视频实际宽度调整)
使用方法
- 确保已安装必要的依赖库:
pip install opencv-python numpy
-
修改
main函数中的参数:- 将
input_video改为你的输入视频路径 - 设置
output_video为输出视频的保存路径 - 根据视频宽度设置合适的
split_column分割列坐标
- 将
-
运行脚本,程序会显示处理进度,完成后输出视频文件将保存到指定路径。
注意事项
- 分割列坐标需要根据视频实际宽度进行调整,确保在
[0, 视频宽度-1]范围内 - 脚本支持MP4格式视频,其他格式可能需要调整编码器
- 处理大型视频时可能需要较多内存,因为会一次性读取所有帧
- 若输出视频无法打开,可能是编码器不支持,可以尝试修改
fourcc参数使用其他编码器 - 视频处理时间与视频帧数和计算机性能有关,帧数较多时需要耐心等待
总结
本文介绍的视频分割与逆序合并工具能够实现特殊的视频视觉效果,通过将视频帧左右分割并对右侧部分进行逆序处理,创造出独特的画面效果。脚本具有较好的兼容性和容错处理,适合用于创意视频制作等场景。根据实际需求调整分割列坐标,可以获得不同的视觉效果,有兴趣的读者可以尝试不同的参数设置,探索更多可能性。
更多推荐
所有评论(0)