视频缩放与帧提取技术方案
本文介绍如何使用Python对视频进行缩放处理,以及如何按帧截取视频片段。
视频缩放保存
以下代码实现视频分辨率的自动调整功能,当视频尺寸超过指定阈值时进行等比例缩小:
import glob
import os
import cv2
import imageio
import numpy as np
def adjust_video_resolution(source_path, target_folder):
"""调整视频分辨率并保存到目标目录"""
file_name = os.path.basename(source_path)
destination_path = os.path.join(target_folder, file_name)
capture = cv2.VideoCapture(source_path)
# 获取原始视频的帧率和尺寸信息
frame_rate = capture.get(cv2.CAP_PROP_FPS)
original_width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
original_height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 初始化图像写入器
writer = imageio.get_writer(destination_path, fps=frame_rate)
frame_count = 0
while True:
success, frame = capture.read()
if not success:
break
# 当分辨率超过1280x720时进行缩放处理
pixel_count = original_width * original_height
if pixel_count > 1280 * 720:
scale_factor = np.sqrt((1280 * 720) / pixel_count)
frame = cv2.resize(frame, None, fx=scale_factor, fy=scale_factor,
interpolation=cv2.INTER_AREA)
# 转换色彩空间:OpenCV使用BGR,imageio需要RGB
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
writer.append_data(frame_rgb)
frame_count += 1
capture.release()
writer.close()
if __name__ == '__main__':
source_directory = r"C:\Videos\source_files"
output_directory = r"C:\Videos\processed_files"
os.makedirs(output_directory, exist_ok=True)
video_files = glob.glob(os.path.join(source_directory, "*.mp4"))
for video_file in video_files:
print(f'正在处理: {video_file}')
adjust_video_resolution(video_file, output_directory)
使用ffmpeg按帧截取视频
ffmpeg支持精确的帧级别视频截取,以下命令从第18帧开始提取视频:
ffmpeg -i input.mp4 -vf "select='gte(n,18)',setpts=N/FRAME_RATE/TB" -c:v libx264 -crf 18 -preset veryslow -a:c copy output.mp4
参数说明:
-vf "select='gte(n,18)'": 筛选第18帧及之后的帧-crf 18: 控制输出质量,数值越小质量越高-preset veryslow: 使用最慢的编码预设以获得更好的压缩效果
按帧截取视频片段
使用Python和OpenCV可以实现更灵活的帧提取功能:
import cv2
import imageio
def extract_video_frames(input_path, output_path, start_frame=0):
"""从指定帧开始提取视频"""
capture = cv2.VideoCapture(input_path)
# 获取视频基础信息
frame_rate = capture.get(cv2.CAP_PROP_FPS)
video_width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
video_height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
total_frames = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
# 创建视频写入对象
writer = imageio.get_writer(output_path, fps=frame_rate)
current_frame = 0
while True:
ret, frame = capture.read()
if not ret:
break
# 从指定帧开始写入
if current_frame >= start_frame:
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
writer.append_data(frame_rgb)
current_frame += 1
capture.release()
writer.close()
if __name__ == '__main__':
source_video = r"E:\videos\sample\input.mp4"
result_video = r"E:\videos\sample\output.mp4"
extract_video_frames(source_video, result_video, start_frame=18)
上述代码实现了从指定帧位置开始截取视频的功能,可以根据实际需求调整起始帧位置。