記事の概要
Stable DiffusionのAnimateDiffを使っている時に、インプットの画像を判定させたり、出力後に解像度を上げたりなどの操作を行うことがあるので、その時に使っているプログラムを記載します。
環境
OS:Windows 11
GPU:GeForce RTX 4090
CPU:i9-13900KF
memory:64G
python:3.10.10
pytorch:2.0.1
CUDA:11.8
cuDNN:8.8
環境構築
以下のコマンドでライブラリをインストールする。
pip install transformers
pip install moviepy
プログラム
画像反転
以下のプログラムを実行するディレクトリに「folder」を作成し、その中に判定対象の画像(複数可)を配置し。プログラムを実行すると、「folder/super_resolved」反転した画像が出力される。
from PIL import Image
from pathlib import Path
# 処理するフォルダの相対パス
folder_path = Path("folder")
output_folder = folder_path / "super_resolved"
# 出力フォルダがなければ作成
output_folder.mkdir(exist_ok=True)
# フォルダ内の全てのPNGとJPEGファイルに対して処理を行う
for image_format in ["*.png", "*.jpg", "*.jpeg"]:
for image_path in folder_path.glob(image_format):
# 画像ファイルを開く
original_image = Image.open(image_path)
# 画像を左右反転する
flipped_image = original_image.transpose(Image.FLIP_LEFT_RIGHT)
# 反転した画像を元のフォーマットで保存する
# 保存するファイル名を元のファイル名に基づいて決定
flipped_file_path = output_folder / f"flipped_{image_path.name}"
flipped_image.save(flipped_file_path)
高解像度化
以下の学習済みモデルを利用し、解像度を2倍にする。
import torch
from PIL import Image
from pathlib import Path
from transformers import AutoImageProcessor, Swin2SRForImageSuperResolution
# GPUが利用可能か確認し、利用可能なら使用する
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
# モデルとプロセッサのロード、モデルをデバイスに移動
processor = AutoImageProcessor.from_pretrained("caidas/swin2SR-classical-sr-x2-64")
model = Swin2SRForImageSuperResolution.from_pretrained("caidas/swin2SR-classical-sr-x2-64").to(device)
# 処理するフォルダのパス
folder_path = Path(r"folder")
output_folder = folder_path / "super_resolved"
# 出力フォルダがなければ作成
output_folder.mkdir(exist_ok=True)
# フォルダ内の全てのPNGファイルに対して処理を行う
for image_path in folder_path.glob("*.png"):
# 入力画像のロード(RGBに変換)
image = Image.open(image_path).convert("RGB")
# 画像をモデルが期待するサイズに変換
inputs = processor(image, return_tensors="pt").to(device)
# スーパーリゾリューションの実行
with torch.no_grad():
outputs = model(**inputs)
# 出力画像の取得
output = outputs["reconstruction"].permute(0, 2, 3, 1)[0].cpu().numpy()
output = (output * 255).astype("uint8")
# PIL Imageに変換
output_image = Image.fromarray(output)
# 画像を保存
output_image_path = output_folder / f"super_resolved_{image_path.name}"
output_image.save(output_image_path)
print(f"Processed and saved: {output_image_path}")
画像を統合してgifを作成
フォルダ内のファイルを統合し、gifファイルを作成する。(ファイル名順位統合する。)
from PIL import Image
import os
from pathlib import Path
# 画像が保存されているフォルダのパス
image_folder = Path("folder\super_resolved")
# 出力するGIFの名前
output_gif = image_folder / "output.gif"
# 画像フォルダからすべての画像ファイルのパスを取得
images = [os.path.join(image_folder, img) for img in os.listdir(image_folder) if img.endswith((".png", ".jpg", ".jpeg"))]
# ファイル名に基づいて画像をソート
images.sort(key=lambda x: os.path.basename(x))
# 画像ファイルを開く
frames = [Image.open(image) for image in images]
# 8FPSでGIFを保存するための遅延時間を設定(125ミリ秒)
# duration_per_frame = 125
# 24FPSでGIFを保存するための遅延時間を設定(41.6ミリ秒)
duration_per_frame = 41.6
# 最初の画像を基準にしてGIFを保存
frames[0].save(output_gif, format='GIF', append_images=frames[1:], save_all=True, duration=duration_per_frame, loop=0)
# print(f"GIF saved as {output_gif} with 8 FPS.")
print(f"GIF saved as {output_gif} with 24 FPS.")
gifをmp4に変換
gifファイルをmp4ファイルに変換する。
from moviepy.editor import VideoFileClip
# GIFファイルのパス
gif_path = r'folder\super_resolved\output.gif'
# 出力するMP4ファイルのパス
mp4_path = r'folder\super_resolved\mp4.mp4'
# GIFを読み込み
clip = VideoFileClip(gif_path)
# MP4として書き出し
clip.write_videofile(mp4_path, fps=24) # FPSは必要に応じて調整できます
# clip.write_videofile(mp4_path, fps=8) # FPSは必要に応じて調整できます
全処理実行(高解像度化→gif統合→mp4変換)
複数のpngファイルを高解像度化し、gif・mp4ファイルを作成する。
import torch
from PIL import Image
from pathlib import Path
from transformers import AutoImageProcessor, Swin2SRForImageSuperResolution
# GPUが利用可能か確認し、利用可能なら使用する
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
# モデルとプロセッサのロード、モデルをデバイスに移動
processor = AutoImageProcessor.from_pretrained("caidas/swin2SR-classical-sr-x2-64")
model = Swin2SRForImageSuperResolution.from_pretrained("caidas/swin2SR-classical-sr-x2-64").to(device)
# 処理するフォルダのパス
folder_path = Path(r"folder")
output_folder = folder_path / "super_resolved"
# 出力フォルダがなければ作成
output_folder.mkdir(exist_ok=True)
# フォルダ内の全てのPNGファイルに対して処理を行う
for image_path in folder_path.glob("*.png"):
# 入力画像のロード(RGBに変換)
image = Image.open(image_path).convert("RGB")
# 画像をモデルが期待するサイズに変換
inputs = processor(image, return_tensors="pt").to(device)
# スーパーリゾリューションの実行
with torch.no_grad():
outputs = model(**inputs)
# 出力画像の取得
output = outputs["reconstruction"].permute(0, 2, 3, 1)[0].cpu().numpy()
output = (output * 255).astype("uint8")
# PIL Imageに変換
output_image = Image.fromarray(output)
# 画像を保存
output_image_path = output_folder / f"super_resolved_{image_path.name}"
output_image.save(output_image_path)
print(f"Processed and saved: {output_image_path}")
import os
# 画像が保存されているフォルダのパス
image_folder = Path(r'folder\super_resolved')
# 出力するGIFの名前
output_gif = image_folder / "output.gif"
# 画像フォルダからすべての画像ファイルのパスを取得
images = [os.path.join(image_folder, img) for img in os.listdir(image_folder) if img.endswith((".png", ".jpg", ".jpeg"))]
# ファイル名に基づいて画像をソート
images.sort(key=lambda x: os.path.basename(x))
# 画像ファイルを開く
frames = [Image.open(image) for image in images]
# 8FPSでGIFを保存するための遅延時間を設定(125ミリ秒)
# duration_per_frame = 125
# 24FPSでGIFを保存するための遅延時間を設定(41.6ミリ秒)
duration_per_frame = 41.6
# 最初の画像を基準にしてGIFを保存
frames[0].save(output_gif, format='GIF', append_images=frames[1:], save_all=True, duration=duration_per_frame, loop=0)
# print(f"GIF saved as {output_gif} with 8 FPS.")
print(f"GIF saved as {output_gif} with 24 FPS.")
from moviepy.editor import VideoFileClip
# GIFファイルのパス
gif_path = r'folder\super_resolved\output.gif'
# 出力するMP4ファイルのパス
mp4_path = r'folder\super_resolved\mp4.mp4'
# GIFを読み込み
clip = VideoFileClip(gif_path)
# MP4として書き出し
clip.write_videofile(mp4_path, fps=24) # FPSは必要に応じて調整できます
# clip.write_videofile(mp4_path, fps=8) # FPSは必要に応じて調整できます