動画から画像を作成します。1フレームだけで画像にするのではなく、時系列にサムネイルを並べた画像を作りたいと思いました。先に結果だけ見せるとこんな画像です。
最初のフレームをメインの画像にして、その下にサムネイルを並べています。
これは昔作った以下の動画をもとに作成した画像です。画像がぼやけてるのは動画の質が悪いのかも。
こういう画像を動画ファイルから生成するPythonコードを書きました。
OpenCVを使っています。OpenCVについては昨日も記事にしました。
以下がPythonコードです。
import cv2
def buildVideoCaptures(videoPath, outputPath):
cap = cv2.VideoCapture(videoPath)
if not cap.isOpened(): return
# 最初のフレームの画像を取得
_, first_img = cap.read()
# 動画のフレーム数を取得
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 連続サムネイルを作成
n = 9 # サムネイルの数
thumbnail_imgs = []
for i in range(n):
# フレームの番号を設定
cap.set(cv2.CAP_PROP_POS_FRAMES, (i+1) * frame_count / (n+1))
# 設定したフレーム番号の画像を取得
_, img = cap.read()
thumbnail_imgs.append(img)
# 9つのサムネイルを横に結合
thumbnails_img = cv2.hconcat(thumbnail_imgs)
# 画像サイズを取得
first_width = first_img.shape[1]
first_height = first_img.shape[0]
thumbnails_width = thumbnails_img.shape[1]
thumbnails_height = thumbnails_img.shape[0]
# 連続サムネイルのリサイズ後のサイズを決定
new_width = first_width
new_height = int(thumbnails_height * new_width / thumbnails_width)
# 連続サムネイルをリサイズ
thumbnails_img = cv2.resize(thumbnails_img, (new_width, new_height))
# 最初のフレーム画像と連続サムネイルを縦に結合
# 最初のフレーム画像の下に連続サムネイル
concat_img = cv2.vconcat([first_img, thumbnails_img])
# 画像ファイルで書き出す
cv2.imwrite(outputPath, concat_img)
buildVideoCaptures("./sample.mp4", "./thumbnail.jpg")
最初と途中の全部で10個のフレームを画像として抜き出して、OpenCVの resize
, hconcat
, vconcat
でリサイズや結合しているだけです。