| import os | |
| from pathlib import Path | |
| from typing import Union | |
| import cv2 | |
| import numpy as np | |
| from basicsr.archs.rrdbnet_arch import RRDBNet | |
| from basicsr.utils.download_util import load_file_from_url | |
| from PIL import Image | |
| from realesrgan import RealESRGANer | |
| from util.commons import read_url | |
| class Upscaler: | |
| __model_esrgan_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth" | |
| __model_esrgan_anime_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth" | |
| def load(self): | |
| download_dir = Path(Path.home() / ".cache" / "realesrgan") | |
| download_dir.mkdir(parents=True, exist_ok=True) | |
| self.__model_path = self.__preload_model(self.__model_esrgan_url, download_dir) | |
| self.__model_path_anime = self.__preload_model( | |
| self.__model_esrgan_anime_url, download_dir | |
| ) | |
| def upscale(self, image: Union[str, bytes]) -> bytes: | |
| model = RRDBNet( | |
| num_in_ch=3, | |
| num_out_ch=3, | |
| num_feat=64, | |
| num_block=23, | |
| num_grow_ch=32, | |
| scale=4, | |
| ) | |
| return self.__internal_upscale(image, self.__model_path, model) | |
| def upscale_anime(self, image: Union[str, bytes]) -> bytes: | |
| model = RRDBNet( | |
| num_in_ch=3, | |
| num_out_ch=3, | |
| num_feat=64, | |
| num_block=23, | |
| num_grow_ch=32, | |
| scale=4, | |
| ) | |
| return self.__internal_upscale(image, self.__model_path_anime, model) | |
| def __preload_model(self, url: str, download_dir: Path): | |
| name = url.split("/")[-1] | |
| if not os.path.exists(str(download_dir / name)): | |
| return load_file_from_url( | |
| url=url, | |
| model_dir=str(download_dir), | |
| progress=True, | |
| file_name=None, | |
| ) | |
| else: | |
| return str(download_dir / name) | |
| def __internal_upscale( | |
| self, | |
| image: Union[str, bytes], | |
| model_path: str, | |
| rrbdnet: RRDBNet, | |
| ) -> bytes: | |
| if type(image) is str: | |
| image = read_url(image) | |
| upsampler = RealESRGANer( | |
| scale=4, model_path=model_path, model=rrbdnet, half="fp16", gpu_id="0" | |
| ) | |
| image_array = np.frombuffer(image, dtype=np.uint8) | |
| input_image = cv2.imdecode(image_array, cv2.IMREAD_COLOR) | |
| output, _ = upsampler.enhance(input_image, outscale=4) | |
| out_bytes = cv2.imencode(".png", output)[1].tobytes() | |
| return out_bytes | |