自分でモノクロ映像をカラー化したい。最近そのような相談を、映像関係の方からよく頂くようになった。今のところすべてお断りしているが、APIを使えば簡単そうなのでやってみた。
こちらでカラー化してお渡しするならまだしも、プログラミング経験のない人を対象に、遠隔で指示しながら相手のPC上にDockerやらUbuntuやらTensorFlowやらの環境を構築するのは至難の業なので、今後できればこちらの方法を検討したほうが良いかもしれない。
#参考
今回、gifの分解、連結にはこちらのサイト様を参考にさせていただいた。
というかほとんどそのまま。。。
感謝です。
https://www.lifewithpython.com/2017/10/python-extract-gif-frames.html
https://chayarokurokuro.hatenablog.com/entry/2019/06/03/Python%E3%81%A7png%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89gif%E3%82%A2%E3%83%8B%E3%83%A1%E7%94%BB%E5%83%8F%E4%BD%9C%E6%88%90
DeOldifyというものを使った。こちらはDeepAIでAPIが無料公開されている。
チュートリアルにquickstart用のAPI-Keyが埋め込まれているが、こちらは数回利用すると使えなくなるため、アカウントを作成してAPI-Keyを取得しておくとよい。基本的に無料で使える。
カラー化できる画像には以下のような制限がある。
HDとかの画質はちょっと無理なので注意。
それでもカラー化する系のやつなのかでは大きい方だと思う。
the max file upload size is 1200px for any dimension. That being said, If you upload an image with a dimension larger than 1200px, we shrink the image so no dimension is large than that.
#ソースコード
ソースコードはこちら。
API-Keyは適宜取得して書き換えてほしい。
今回はgifで行ったが、OpenCVを使えばmp4とかでもいけるかもしれない。
ただし、無料で公開してくれているものなので、数千枚分のリクエストを一気に投げるとかしないように。。
マナーは守って利用したほうがいいと思う。
(なんか、1分間に何枚まで、みたいな利用規約が見つけられなかった。)
# coding: utf-8
from pathlib import Path
from PIL import Image, ImageSequence
import cv2
import glob
import requests
# モノクロgifへのパス
IMAGE_MONO_PATH = 'mono.gif'
# 生成されるカラーgifへのパス
IMAGE_COLOR_PATH = 'color.gif'
# 分割したモノクロ画像生成フォルダ
DESTINATION_MONO = 'splitted_mono'
# 分割したカラー画像生成フォルダ
DESTINATION_COLOR = 'splitted_color'
gif = cv2.VideoCapture(IMAGE_MONO_PATH)
fps = gif.get(cv2.CAP_PROP_FPS)
DURATION = round(1000/fps)
def main():
frames = get_frames(IMAGE_MONO_PATH)
write_frames(frames, IMAGE_MONO_PATH, DESTINATION_MONO)
get_color(DESTINATION_MONO, DESTINATION_COLOR)
join_images(DESTINATION_COLOR, IMAGE_COLOR_PATH, DURATION)
def get_frames(path):
im = Image.open(path)
return (frame.copy() for frame in ImageSequence.Iterator(im))
def write_frames(frames, name_original, destination):
path = Path(name_original)
stem = path.stem
# extension = path.suffix
extension = '.png'
dir_dest = Path(destination)
if not dir_dest.is_dir():
dir_dest.mkdir(0o700)
print('Destionation directory is created: "{}".'.format(destination))
for i, f in enumerate(frames):
name = '{}/{}-{}{}'.format(destination, stem, i + 1, extension)
f.save(name)
print('A frame is saved as "{}".'.format(name))
def get_color(mono_destination, color_destination):
dir_dest = Path(color_destination)
if not dir_dest.is_dir():
dir_dest.mkdir(0o700)
print('Destionation directory is created: "{}".'.format(color_destination))
files = sorted(glob.glob(mono_destination + '/*.png'))
for i, file in enumerate(files):
r = requests.post(
"https://api.deepai.org/api/colorizer",
files={
'image': open(file, 'rb'),
},
headers={'api-key': 'quickstart-QUdJIGlzIGNvbWluZy4uLi4K'}
)
url = r.json()['output_url']
file_name = color_destination + '/' + str(i) + ".png"
response = requests.get(url)
image = response.content
with open(file_name, "wb") as f:
f.write(image)
def join_images(color_destination, color_filename, duration):
files = sorted(glob.glob(color_destination + '/*.png'))
images = list(map(lambda file : Image.open(file) , files))
images[0].save(color_filename , save_all = True , append_images = images[1:] , duration = duration , loop = 0)
if __name__ == '__main__':
main()
#最後に
動かすとこんな感じです。
モノクロ動画に色つけるやつ意外とうまいこといった。
— たくみ@スカジャンのエンジニア (@hatt_takumi) June 20, 2020
てんさーふろーとかいう難しいやつはAPIに任せますた。#エンジニアと繋がりたい#駆け出しエンジニアと繋がりたい pic.twitter.com/311K4wd7Bc
実際に変換したgifをお見せしたかったが、そのままアップロードしても大丈夫そうなモノクロ素材が見つけられなかった。
画像だけど、DeOldifyにあったサンプルはこんな感じ。