Python フォルダを再帰的に探索し、フォルダ別に複数の画像ファイルを動画にする

# '20/02/29更新:新しいフォルダを作成して、そこに動画を格納する仕様に変更しました。
多数の画像ファイルが、例えば、下図のようなフォルダ構成である場合に適応する。フォルダ名とファイル名は何でも良い。

 カレントフォルダ
├─17
│ ├─meat
│ │ 画像1
│ │ 画像2
│ │ 画像3
│ │ …
│ └─noodles
│  画像1
│  画像2
│  画像3
│  …
├─18
│ ├─meat
│ │ 画像1
│ │ 画像2
│ │ 画像3
│ │ …
│ └─noodles
│  画像1
│  画像2
│  画像3
│  …

▼本プログラム実行前

フォルダ名17, 18の中には上記のような構成のサブフォルダがある。

f:id:HK29:20191207000044p:plain

各々のサブフォルダ内には下図のように複数の画像ファイルがある。

f:id:HK29:20191207000650p:plain

f:id:HK29:20191207001359p:plain

▼本プログラム実行後

下図のようにフォルダ「new_dirMovie」を作成する

f:id:HK29:20200229142549p:plain

そのフォルダ内に下図のように動画を作成する

f:id:HK29:20200229142613p:plain
■本プログラム

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import glob
import shutil
import cv2
from PIL import Image, ImageFont, ImageDraw

def del_existing_file(my_path):
    for f in glob.glob(my_path + "*.jpg"):
        os.remove(f)
    for f in glob.glob(my_path + "*.mp4"):
        os.remove(f)

def del_existing_folder(new_dir_name):
    shutil.rmtree(new_dir_name)

def jpg2mp4(input_folder, outmovie, my_time):
    img_list = glob.glob(input_folder + '/*.jpg') # 見つかったファイルをリストへ格納
    if img_list: # フォルダ内に画像ファイルがあった場合に処理する
        fps = len(img_list) / my_time # fpsを計算する。ファイル数/再生時間

        new_file_list = []
        for i, e in enumerate(img_list):
            ### ファイル名を連番へリネームする
            e2 = str(i).zfill(4) + '.jpg'  # zfillの型は文字列。0000.jpg, 0001.jpg, …
            shutil.copy2(e, e2) # ファイルをカレントディレクトリへコピー
            img = cv2.imread(e2)
            height, width = img.shape[:2]
            cv2.imwrite(e2 , img)
            new_file_list.append(e2)
            
        cap = cv2.VideoCapture('%04d.jpg')
        fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
        writer = cv2.VideoWriter(outmovie, fourcc, fps, (width, height))
        while True:
           ret, frame = cap.read()
           if not ret:
               break
           writer.write(frame)
        writer.release()
        cap.release()
        print("fps -> " + str(fps))
        for e2 in new_file_list:
            os.remove(e2)
    else:
        print('file not found in ' + input_folder)

def main():
    del_existing_file(my_path)
    try:
        del_existing_folder(new_dir_name)
    except OSError as e:
        pass
    os.mkdir(new_dir_name)
    
    check_list.sort() # リスト内を並び替える(破壊的ソート)。
    i=0
    for dirpath, dirnames, fnames in os.walk(my_path):
        if check_list[i] in dirpath: # ディレクトリ名に指定したディレクトリ名があった場合
            parent_dirname = dirpath.split(os.path.sep)[-2] # 親ディレクトリ名を取得
            #print(parent_dirname)
            new_file_path_list = [new_dir_name, parent_dirname + '_' + check_list[i] + '.mp4']
            outmovie = os.path.join(*new_file_path_list) # リストからパスを作成。*はその場でリストを展開する
            print(outmovie)
            jpg2mp4(dirpath, outmovie, my_time)
            i += 1 # 次のチェックリストへ
            if i == len(check_list):
                i = 0

if __name__ == '__main__':
    ### parameter
    my_path = os.getcwd() # カレントディレクトリの取得
    new_dir_name = os.path.join(my_path, 'new_dirMovie') # 新フォルダのパス作成
    check_list = ['noodles', 'meat']
    my_time = 5 #[second]
    
    ### call function
    main()
    
    print('finished')

以上

<広告>