【OpenCV】OpenCV 视频裁剪实现
使用 OpenCV 实现视频裁剪,同时保留原始视频的编码器、帧率和其他参数
·
OpenCV 视频裁剪实现(保留原始视频编码和参数)
使用 OpenCV 实现视频裁剪,同时保留原始视频的编码器、帧率和其他参数。
import cv2
import numpy as np
import sys
def crop_video(input_path, output_path, crop_region):
"""
裁剪视频并保留原始编码参数
:param input_path: 输入视频路径
:param output_path: 输出视频路径
:param crop_region: 裁剪区域 (x, y, width, height)
"""
# 打开视频文件
cap = cv2.VideoCapture(input_path)
if not cap.isOpened():
print(f"错误: 无法打开视频文件 {input_path}")
return False
print(f"成功打开视频: {input_path}")
# 获取原始视频参数
original_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
original_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
codec = int(cap.get(cv2.CAP_PROP_FOURCC))
codec_str = "".join([chr((codec >> 8 * i) & 0xFF) for i in range(4)])
print("\n原始视频参数:")
print(f" 分辨率: {original_width}x{original_height}")
print(f" 帧率: {fps:.2f} FPS")
print(f" 总帧数: {total_frames}")
print(f" 编码器: {codec_str} (FourCC: {codec})")
# 解析裁剪区域
x, y, width, height = crop_region
# 验证裁剪参数有效性
if (x < 0 or y < 0 or
width <= 0 or height <= 0 or
x + width > original_width or
y + height > original_height):
print("\n错误: 裁剪区域超出视频边界")
print(f" 视频尺寸: {original_width}x{original_height}")
print(f" 裁剪区域: x={x}, y={y}, width={width}, height={height}")
cap.release()
return False
print("\n裁剪区域参数:")
print(f" 起始坐标: ({x}, {y})")
print(f" 裁剪尺寸: {width}x{height}")
print(f" 保留原始编码器: {codec_str}")
# 创建视频编码器 - 使用原始编码器
fourcc = cv2.VideoWriter_fourcc(*codec_str)
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
if not out.isOpened():
# 如果原始编码器失败,尝试使用MP4V作为备选
print(f"警告: 无法使用原始编码器 {codec_str} 创建输出,尝试使用 'mp4v'")
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
if not out.isOpened():
print("错误: 无法创建输出视频文件")
cap.release()
return False
frame_count = 0
success = True
print("\n开始处理视频...")
while success:
# 读取视频帧
success, frame = cap.read()
if not success:
# 视频结束或读取失败
break
# 裁剪当前帧
cropped_frame = frame[y:y+height, x:x+width]
# 写入输出视频
out.write(cropped_frame)
frame_count += 1
# 每处理10%的帧显示一次进度
if frame_count % max(1, total_frames // 10) == 0 or frame_count == total_frames:
progress = (frame_count / total_frames) * 100
print(f"处理进度: {frame_count}/{total_frames} 帧 ({progress:.1f}%)")
# 释放资源
cap.release()
out.release()
cv2.destroyAllWindows()
print(f"\n视频裁剪完成! 保存至: {output_path}")
print(f"输出视频参数:")
print(f" 分辨率: {width}x{height}")
print(f" 帧率: {fps:.2f} FPS")
print(f" 总帧数: {frame_count}")
print(f" 编码器: {codec_str}")
return True
def get_video_info(input_path):
"""获取视频信息而不进行处理"""
cap = cv2.VideoCapture(input_path)
if not cap.isOpened():
print(f"错误: 无法打开视频文件 {input_path}")
return
# 获取原始视频参数
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
codec = int(cap.get(cv2.CAP_PROP_FOURCC))
codec_str = "".join([chr((codec >> 8 * i) & 0xFF) for i in range(4)])
print("\n视频信息:")
print(f" 文件路径: {input_path}")
print(f" 分辨率: {width}x{height}")
print(f" 帧率: {fps:.2f} FPS")
print(f" 总帧数: {total_frames}")
print(f" 编码器: {codec_str} (FourCC: {codec})")
cap.release()
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "-info":
# 显示视频信息模式
if len(sys.argv) < 3:
print("用法: python video_crop.py -info <视频文件路径>")
sys.exit(1)
input_video = sys.argv[2]
get_video_info(input_video)
sys.exit(0)
# 正常裁剪模式
input_video = "input.mp4" # 输入视频路径
output_video = "output.mp4" # 输出视频路径
# 裁剪参数设置 (x, y, width, height)
# 示例: 从(100, 150)开始,裁剪400x300的区域
crop_region = (100, 150, 400, 300)
# 执行裁剪
result = crop_video(input_video, output_video, crop_region)
if not result:
print("\n裁剪过程失败,请检查错误信息")
sys.exit(1)
功能特点
-
保留原始编码参数:
- 自动检测原始视频的FourCC编码器
- 使用相同的编码器创建输出视频
- 保留原始帧率、色彩空间等参数
-
详细的参数输出:
- 显示原始视频的分辨率、帧率、总帧数和编码器
- 显示裁剪区域参数
- 显示处理进度(每10%更新一次)
-
错误处理:
- 验证裁剪区域是否在视频范围内
- 处理视频打开失败的情况
- 如果原始编码器不可用,自动回退到mp4v编码器
-
辅助功能:
- 添加了
-info参数来查看视频信息而不进行处理 - 示例:
python video_crop.py -info input.mp4
- 添加了
使用说明
-
安装依赖:
pip install opencv-python numpy -
基本使用:
- 修改脚本中的
input_video、output_video和crop_region变量 - 运行脚本:
python video_crop.py
- 修改脚本中的
-
查看视频信息:
python video_crop.py -info input.mp4 -
自定义裁剪区域:
# 格式: (x, y, width, height) crop_region = (起始X坐标, 起始Y坐标, 裁剪宽度, 裁剪高度)
技术细节
-
保留原始编码器:
# 获取原始编码器的FourCC代码 codec = int(cap.get(cv2.CAP_PROP_FOURCC)) codec_str = "".join([chr((codec >> 8 * i) & 0xFF) for i in range(4)]) # 使用相同的编码器创建输出 fourcc = cv2.VideoWriter_fourcc(*codec_str) out = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) -
边界检查:
if (x < 0 or y < 0 or width <= 0 or height <= 0 or x + width > original_width or y + height > original_height): # 显示错误信息并退出 -
进度显示:
# 每处理10%的帧显示一次进度 if frame_count % max(1, total_frames // 10) == 0 or frame_count == total_frames: progress = (frame_count / total_frames) * 100 print(f"处理进度: {frame_count}/{total_frames} 帧 ({progress:.1f}%)")
常见问题解决方案
-
输出视频无法播放:
- 尝试使用
-info参数查看原始编码器 - 如果原始编码器不支持,脚本会自动回退到mp4v
- 可以手动指定编码器:修改
fourcc = cv2.VideoWriter_fourcc(*'H264')
- 尝试使用
-
处理速度慢:
- 某些编码器(如H.264)处理速度较慢但文件小
- 对于测试可以使用
'mp4v'或'XVID'
-
裁剪区域不正确:
- 使用
-info查看视频分辨率 - 确保裁剪区域在视频范围内
- 注意坐标系:左上角为(0,0),右下角为(width, height)
- 使用
-
处理大视频内存不足:
- 脚本逐帧处理,内存占用低
- 对于超大视频,可能需要增加系统可用内存
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)