【Video2Video】リアルな動画をアニメ風に変えるならわざわざ拡散モデルを使わなくても以前からあるGAN(敵対的生成ネットワーク)の技術で十分な気がしたので実際にやってみました

はじめに

Stable Diffusionなどの拡散モデルを使ったVideo2Videoが盛んに開発されています。

GAN(敵対的生成ネットワーク)を使っても同様のことができる気がするのですが、すでに古い技術になってしまったのかあまりそれに言及する人がいません。

GANを使ったVideo2Videoを実際にやってみました。

使ったのは「CartoonGAN」というモデルです。

以前に使ったことがあります。
touch-sp.hatenablog.com
touch-sp.hatenablog.com
最初の記事から4年も経っています。

環境

Windows 11
CUDA 11.7
Python 3.10

Python環境構築

以下の1行です。

pip install -r https://raw.githubusercontent.com/dai-ichiro/cartoongan_webcam/main/new_requirements.txt

実行プログラム

モデルのダウンロードなどは自動的に行われます。

import os
import sys 
import argparse
import numpy as np
import cv2
import torch
from  torchvision import transforms
from torchvision.datasets.utils import download_url

parser = argparse.ArgumentParser()
parser.add_argument(
    '--style',
    type=str,
    default='Hayao',
    choices=['Hayao', 'Hosoda', 'Paprika', 'Shinkai']
)
parser.add_argument(
    '--video',
    type=str,
    required=True,
)
opt = parser.parse_args()

style = opt.style
video = opt.video

pth_url = f"http://vllab1.ucmerced.edu/~yli62/CartoonGAN/pytorch_pth/{style}_net_G_float.pth"
download_url(pth_url, root = 'models', filename = os.path.basename(pth_url))

transformer_url = 'https://github.com/Yijunmaverick/CartoonGAN-Test-Pytorch-Torch/raw/master/network/Transformer.py'
transformer_fname = os.path.basename(transformer_url)

download_url(transformer_url, root = './network', filename = transformer_fname)
from network.Transformer import Transformer

max_size = 512
model_path = 'models'

device = 'cuda' if torch.cuda.is_available() else 'cpu'

model = Transformer()
model.load_state_dict(torch.load(os.path.join(model_path, f"{style}_net_G_float.pth")))
model.eval().to(device)

cap = cv2.VideoCapture(video)

w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)

aspect = w / h
if aspect > 1:
    h = round(max_size / aspect)
    w = max_size
else:
    h = max_size
    w = round(max_size * aspect)

fourcc = cv2.VideoWriter_fourcc('m','p','4','v')
out = cv2.VideoWriter('output.mp4',fourcc, fps, (w,h))

while True:
    ret, frame = cap.read()

    if not ret:
        break

    input_array = cv2.resize(frame, dsize=(w, h), interpolation = cv2.INTER_CUBIC)

    input_tensor = transforms.ToTensor()(input_array).unsqueeze(0)
    input_tensor = -1 + 2 * input_tensor

    with torch.no_grad():
        output_tensor = model(input_tensor.to(device))

    output_image = output_tensor[0]
    output_image = (output_image * 0.5 + 0.5).to('cpu')

    output_array = (output_image.numpy() * 255).clip(0,255).astype('uint8')
    output_array = np.transpose(output_array, (1, 2, 0))

    out.write(output_array)  

cap.release()
out.release()

使い方

python video2video.py --video sample.mp4 --style Hayao
options:
  -h, --help            show this help message and exit
  --style {Hayao,Hosoda,Paprika,Shinkai}
  --video VIDEO

結果

結果はGoogle Bloggerに載せています。
support-touchsp.blogspot.com




このエントリーをはてなブックマークに追加