連番画像から動画を作成する

未分類

概要

計算結果を連番の画像ファイルで出力したあと,アニメーションを描画したい時が多々あるのでPythonで使いまわせるようにしました.

前提条件

OS:Windows10 / 11
言語:Python (3以上でのみテストしています)
<備考>
Windows環境をメインに作業をしているためLinux環境ではテストしていません.

環境構築

著者のPythonの環境はAnacondaで作成していますが,次の2つのライブラリが入っていれば問題ありません.

  • numpy
  • OpenCV
    すでに両方入っている方はこのブロックは読み飛ばしてください.

Numpyのインストール方法

anacondaを利用する方法,pipを利用する方法,どちらでも問題ありません(私はanacondaでインストールしすることが多いです)

  • anacondaを利用する場合
    conda install numpy
    
  • pipを利用する場合
    pip install numpy
    

OpenCVのインストール方法

anacondaを利用してインストールすることができるという記事を散見しましたが,私の環境ではうまくいった試しがありません.
PCを入れ替えたときや新しい環境を作る場合には,pipを利用してインストールしています.

pip install opencv-python

処理プログラム

# * * * * * * * * * * * * * * * * * * * * * * * *
#   ani.py
# * * * * * * * * * * * * * * * * * * * * * * * *

import numpy as np
import glob
import os, sys
import cv2

#
#--- 日本語を含む画像ファイルを読み込む
# 
def imread_jp(filename, flags=cv2.IMREAD_COLOR, dtype=np.uint8):
    try:
        n = np.fromfile(filename, dtype)
        img = cv2.imdecode(n, flags)
        return img
    except Exception as e:
        print(e)
        return None

# 
#--- MAIN
#

# execution directory
with open( "control.txt", 'r', encoding='utf-8') as f:
    fdir_img  = f.readline().split()[0]        # 連番画像のフォルダ
    videofile = f.readline().split()[0]        # 出力する動画ファイル名
    fname     = f.readline().split()[0]        # 連番画像名
    NminNmax  = f.readline().split()           # 処理するフレーム
    fps       = int(f.readline().split()[0])   # 1秒間の画像枚数


Nmin = int(NminNmax[0])
Nmax = int(NminNmax[1])
extension = fname.split('.')[-1]
fileList = glob.glob( os.path.join(fdir_img, 'frame.*.%s' % extension) )

# Nmaxが負の場合, フォルダ内の画像ファイルより数字が大きい場合は,画像ファイル数に合わせる
if Nmax<0  or Nmax>len(fileList):
    Nmax = len(fileList)
N = np.arange(Nmin, Nmax+0.001, 1)

# 出力はMP4
fcode = cv2.VideoWriter.fourcc('m','p','4','v')

# Get Image Size
tempIMG = imread_jp( fileList[0] )
Height, Width, color = tempIMG.shape

# Set Video  
video = cv2.VideoWriter(videofile, fcode, fps, (Width, Height))

# 動画作成
for file_img in fileList[Nmin:Nmax+1]:
    print( os.path.basename( file_img ) )
    img = imread_jp( file_img )
    video.write(img)

video.release()

print("Video completed.\n")
img_path
ani.mp4
frame.%04d.png
0   100
10

解説

OpenCVでは読み込む画像ファイルのパスに日本語が含まれているとエラーになります.
こちらを参考に日本語ファイルも読み込むことができるようにしています.

少しうまくいっていないのですが,ファイル名をframe.000000.pngのような形式で指定する必要があります.
もし,Part*****.pngのようなファイル名を処理する場合には,以下の箇所を修正してください.
(修正でき次第更新します・・・)

fileList = glob.glob( os.path.join(fdir_img, 'frame.*.%s' % extension) )
                                              # ↑ここを任意のファイル名に変更してください

参考サイト

Python OpenCV の cv2.imread 及び cv2.imwrite で日本語を含むファイルパスを取り扱う際の問題への対処について

コメント

タイトルとURLをコピーしました