Self-Transfer Learning 을 통한 동영상 Super Resolution
Abstract
기존의 동영상 Super Resolution 연구는 프레임 단위로 영상을 분할 한 뒤 각 프레임에 대해 Image Super Resolution 을 수행하고, SR 된 프레임을 다시 영상으로 합치는 방법을 주로 사용하였다. 인접한 프레임에 대한 초해상화 결과의 차이가 크다면 영상이 부자연스럽게 보일 수 있기 때문에 이를 개선하기 위해 인접한 5-7 프레임 가량을 RNN 등의 인공신경망을 통해 학습하여 초해상화에 사용하는 기법은 연구되어 왔으나, 인접하지 않은 한 동영상 내의 다른 프레임을 영상의 초해상화에 사용하는 연구는 이루어지지 않았다. 본 프로젝트는 하나의 영상은 하나의 주제에 대한 영상이며 그 안에서 다수의 중복된 장면이 확대되어 여러번 나타난다는 관찰에서 출발하여, 이러한 중복된 프레임이 영상의 초해상화에 사용될 수 있음을 입증하는 것을 목표로 한다.
Project Process
GPU
동영상을 소스로 사용하는 머신러닝 프로젝트 특성상 성능 좋은 GPU가 필요하다. 본 프로젝트를 진행하면서 우리들은 GPU 사용 문제를 다음과 같이 해결했다.
- 개인적으로 가지고 있는 GPU 사용.
- GCP (Google Cloud Platform)에서 GPU 할당 요청 후 사용.
Requirements
- Python 3
- PyTorch (0.4.0), torchvision
- Numpy, Scipy
- Pillow, Scikit-image
- h5py
- importlib
- ffmpeg
Project Scenario
본 프로젝트에선 성능이 뛰어나고 경량화가 잘되었다고 평가받는 CARN 모델을 사용한다.
우선 초해상화를 진행할 동영상을 대상으로 frame을 추출한다.
ffmpeg -i [추출한 동영상 파일 이름].mp4
-vf "select=eq(pict_type\,I),scale=1280:720" // scale을 해당 영상의 크기에 맞춰, keyframe으로 추출
-vsync 0 [추출한 frame 저장할 디렉토리]/%06d.png
추출한 frame들로 dataset을 구성한다.
from glob import glob
import cv2
images = sorted(glob("./[추출한 frame 저장할 디렉토리]/*.png"))
dataset 디렉토리를 만들어주고
from pathlib import Path
Path("./dataset/DIV2K/DIV2K_train_HR").mkdir(parents=True, exist_ok=True)
Path("./dataset/DIV2K/DIV2K_train_LR_bicubic/X2").mkdir(parents=True, exist_ok=True)
추출한 frame들을 decrease size해서 dataset으로 구성한다.
from tqdm import tqdm
for image in tqdm(images):
hr = cv2.imread(image, cv2.IMREAD_COLOR)
lr = cv2.resize(hr, dsize=(640, 360), interpolation=cv2.INTER_CUBIC)
cv2.imwrite("./dataset/DIV2K/DIV2K_train_HR/" + Path(image).name, hr)
cv2.imwrite("./dataset/DIV2K/DIV2K_train_LR_bicubic/X2/" + Path(image).stem + "x2.png", lr)
그 후 div2h5.py 실행
import os
import glob
import h5py
import scipy.misc as misc
import numpy as np
dataset_dir = "DIV2K/"
dataset_type = "train"
f = h5py.File("DIV2K_{}.h5".format(dataset_type), "w")
dt = h5py.special_dtype(vlen=np.dtype('uint8'))
for subdir in ["HR", "X2"]:
if subdir in ["HR"]:
im_paths = glob.glob(os.path.join(dataset_dir,
"DIV2K_{}_HR".format(dataset_type),
"*.png"))
else:
im_paths = glob.glob(os.path.join(dataset_dir,
"DIV2K_{}_LR_bicubic".format(dataset_type),
subdir, "*.png"))
im_paths.sort()
grp = f.create_group(subdir)
for i, path in enumerate(im_paths):
im = misc.imread(path)
print(path)
grp.create_dataset(str(i), data=im)
다음과 같이 구성된 dataset 을 가지고 carn-m 모델로 동영상의 초해상화를 진행한다.
!python carn/train.py --patch_size 64
--batch_size 64
--max_steps 600000
--decay 400000
--model carn_m
--ckpt_name [체크포인트 이름]
--ckpt_dir [체크포인트 디렉토리]
--scale 2
--group 4