使用Python实现视频均匀抽帧预览
最近组了一个磁盘阵列,存储了大量的素材视频,需要分类,挨个预览属实麻烦,于是写了个基于间隔帧的合并摘要代码
import os
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
class VideoImageSummary:
def __init__(self, path, cols=3, rows=8):
self._cap = cv2.VideoCapture(path)
self._frame_count = int(self._cap.get(cv2.CAP_PROP_FRAME_COUNT))
self._fps = self._cap.get(cv2.CAP_PROP_FPS)
self._frame_width = int(self._cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self._frame_height = int(self._cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 视频秒数
self._duration = self._frame_count / self._fps
# 期望排列内容
self._cols = cols
self._rows = rows
# 间隔像素
self._space = 10
self.filepath, self.filename = os.path.split(path)
self.filesize = round(os.path.getsize(path) / 1024 / 1024, 2)
# 截取数量
@property
def frames_intercepted_count(self):
return int(self._frame_count // (self._cols * self._rows))
def create_background_image(self, height=0, width=0):
# 创建画布
img_height = self._frame_height * self._rows + self._space * (self._rows + 1) + height
img_width = self._frame_width * self._cols + self._space * (self._cols + 1) + width
img = np.zeros((img_height, img_width), np.uint8)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img[:, :, :] = 255
return img
def add_image_to_background(self, background_image, frame, x, y):
background_image[y:y + self._frame_height, x:x + self._frame_width] = frame
return background_image
def img_add_text_utf8(self, img, text, xOffset=0, yOffset=0, size=20):
img_cv2_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中颜色的hex码的储存顺序不同
img_PIL = Image.fromarray(img_cv2_RGB)
draw = ImageDraw.Draw(img_PIL)
font = ImageFont.truetype("SimHei.ttf", size, encoding="utf-8") # 参数1:字体文件路径,参数2:字体大小
draw.text((xOffset, yOffset), text, (255, 255, 255), font=font) # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
# PIL图片转cv2 图片
img_cv2_textAdded = cv2.cvtColor(np.array(img_PIL), cv2.COLOR_RGB2BGR)
return img_cv2_textAdded
def write_video(self, img):
img = self.img_add_text_utf8(img, "视频名称: %s" % self.filename, 5, 5, size=30)
img = self.img_add_text_utf8(img, "视频时长: %s秒" % self._duration, 5, 37)
img = self.img_add_text_utf8(img, "视频大小: %sMB" % self.filesize, 5, 58)
img = self.img_add_text_utf8(img, "分辨率: %dx%d" % (self._frame_width, self._frame_height), 5, 80)
return img
def main(self):
background_image = self.create_background_image(height=300)
# 基础信息写入
background_image = self.write_video(background_image)
current_row, current_col = 0, 0
for i in range(self._frame_count):
if i == self._fps - (self._fps // 2):
self._cap.set(cv2.CAP_PROP_POS_FRAMES, i)
ret, frame = self._cap.read()
cv2.imwrite('cover.png', frame)
if i % self.frames_intercepted_count != 0 or i == 0:
continue
self._cap.set(cv2.CAP_PROP_POS_FRAMES, i)
ret, frame = self._cap.read()
if not ret:
break
x = current_col * (self._frame_width + self._space)
y = current_row * (self._frame_height + self._space) + 100
current_col += 1
if current_col >= self._cols:
current_col = 0
current_row += 1
if current_row >= self._rows:
current_row = 0
# 多少秒
seconds = i / self._fps
# 多少分钟
minutes = seconds / 60
# 多少小时
hours = minutes / 60
text = f'{hours:.0f}:{minutes:.0f}:{seconds:.0f}'
frame = self.img_add_text_utf8(frame, text, 10, 10)
background_image = self.add_image_to_background(background_image, frame, x, y)
cv2.imwrite('test.png', background_image)
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Tioit Wang
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果