Skip to main content

视频转图片

用于将视频文件切割成一系列图片,并允许您通过参数指定输出图片的大小,您可以使用opencv-python库来实现。

准备

首先,您需要确保安装了opencv-python。您可以通过运行以下命令来安装它:

pip install opencv-python
执行方法
# Usage: python video_to_frames.py [video_file] [output_dir] [target_width] [target_height] [frames_per_second] [roi_x] [roi_y] [roi_width] [roi_height]
# video_file 视频路径
# output_dir 图片输出路径
# target_width 图片输出宽度
# target_height 图片输出高度
# frames_per_second 每秒钟输出多少张图片
# roi_x 截图图片的开始位置x 一般为0
# roi_y 截图图片的开始位置y 一般为0
# roi_width 高度 视频本身的高度就好
# roi_height 宽度 视频本身的宽度就好
python3 video_to_frames.py mm.mkv images/ 640 640 1 0 0 1067 600

实现方法

视频切割代码,直接保存为py文件即可执行
import cv2
import os
import sys

def resize_with_aspect_ratio(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image

if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))

resized = cv2.resize(image, dim, interpolation=inter)
return resized

def add_padding(image, target_width, target_height):
(h, w) = image.shape[:2]
top = bottom = left = right = 0

if h < target_height:
delta = target_height - h
top, bottom = delta // 2, delta // 2

if w < target_width:
delta = target_width - w
left, right = delta // 2, delta // 2

color = [0, 0, 0]
new_image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
return new_image

def video_to_frames(video_file, output_dir, target_width=None, target_height=None, frames_per_second=None, roi_x=0, roi_y=0, roi_width=None, roi_height=None):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
cap = cv2.VideoCapture(video_file)
frame_count = 0
output_frame_count = 0

# 获取视频的原始帧率
original_fps = cap.get(cv2.CAP_PROP_FPS)
frame_interval = 1 if frames_per_second is None else int(original_fps / frames_per_second)
while True:
success, frame = cap.read()
if not success:
break
# 根据设定的帧率跳过一些帧
if frame_count % frame_interval == 0:
if roi_width and roi_height:
frame = frame[roi_y:roi_y + roi_height, roi_x:roi_x + roi_width]
frame = resize_with_aspect_ratio(frame, width=target_width, height=target_height)
frame = add_padding(frame, target_width, target_height)
frame_file = os.path.join(output_dir, f"frame_{output_frame_count:05d}.jpg")
cv2.imwrite(frame_file, frame)
output_frame_count += 1
frame_count += 1
cap.release()
print(f"Total frames extracted: {output_frame_count}")

if __name__ == "__main__":
if len(sys.argv) != 10:
# Usage: python video_to_frames.py [video_file] [output_dir] [target_width] [target_height] [frames_per_second] [roi_x] [roi_y] [roi_width] [roi_height]
# video_file 视频路径
# output_dir 图片输出路径
# target_width 图片输出宽度
# target_height 图片输出高度
# frames_per_second 每秒钟输出多少张图片
# roi_x 截图图片的开始位置x
# roi_y 截图图片的开始位置y
# roi_width 高度
# roi_height 宽度
print("Usage: python video_to_frames.py [video_file] [output_dir] [target_width] [target_height] [frames_per_second] [roi_x] [roi_y] [roi_width] [roi_height]")
sys.exit(1)

video_file = sys.argv[1]
output_dir = sys.argv[2]
target_width = int(sys.argv[3])
target_height = int(sys.argv[4])
frames_per_second = int(sys.argv[5])
roi_x = int(sys.argv[6])
roi_y = int(sys.argv[7])
roi_width = int(sys.argv[8])
roi_height = int(sys.argv[9])
video_to_frames(video_file, output_dir, target_width, target_height, frames_per_second, roi_x, roi_y, roi_width, roi_height)

用图片转视频

# -framerate 24
ffmpeg -framerate 24 -i test_results/%06d.jpg -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p output.mp4

参数说明

  • -framerate 24:这指定了输入帧率。在这个例子中,它设置为每秒24帧。这意味着在生成视频时,每秒将显示24张图片。
  • -i test_results/%06d.jpg:这部分指定了输入文件。

    -i:这是输入文件的标志。 test_results/%06d.jpg:指定了图片序列的位置和命名格式。%06d 表示数字序列,其中06代表数字是零填充的,直到六位数(例如,000001, 000002, ..., 000010, ..., 123456等)。这意味着FFmpeg会从test_results目录下按顺序读取命名为000001.jpg, 000002.jpg, ..., 的图片文件。

  • -c:v libx264:这指定了视频编码器。

    -c:v:指定视频编解码器的标志。 libx264:这是一个非常流行的高效视频编码器,用于编码H.264/MPEG-4 AVC视频流。

  • -profile:v high:这指定了编码配置文件(profile)。

    -profile:v:用于指定视频的编码配置文件。 high:这是H.264编码的一种配置文件,提供比“baseline”或“main”更高的压缩效率和质量。

  • -crf 20:设置了常量速率因子(CRF)。

    crf:代表常量速率因子,用于控制视频的质量和压缩率。数值范围通常是0-51,其中0是无损压缩,23是默认值,51是最差质量。20通常被认为是高质量输出的好选择。

  • -pix_fmt yuv420p:指定像素格式。

    pix_fmt:设置像素格式。

  • yuv420p:这是一种广泛兼容的像素格式,它使用4:2:0色度子采样。这种格式与许多设备和播放器兼容。
  • output.mp4:这是输出文件的名称和格式。在这个例子中,生成的视频将被保存为名为output.mp4的文件。