2022-09-13 17:17:14 +00:00
|
|
|
import torch
|
|
|
|
import warnings
|
|
|
|
import numpy as np
|
2022-11-18 19:29:29 +00:00
|
|
|
import os
|
2022-09-13 17:17:14 +00:00
|
|
|
|
2022-11-18 19:29:29 +00:00
|
|
|
from ldm.invoke.globals import Globals
|
2022-09-13 17:17:14 +00:00
|
|
|
from PIL import Image
|
|
|
|
|
|
|
|
|
|
|
|
class ESRGAN():
|
|
|
|
def __init__(self, bg_tile_size=400) -> None:
|
|
|
|
self.bg_tile_size = bg_tile_size
|
|
|
|
|
2022-10-07 00:52:38 +00:00
|
|
|
if not torch.cuda.is_available(): # CPU or MPS on M1
|
|
|
|
use_half_precision = False
|
|
|
|
else:
|
|
|
|
use_half_precision = True
|
|
|
|
|
|
|
|
def load_esrgan_bg_upsampler(self):
|
|
|
|
if not torch.cuda.is_available(): # CPU or MPS on M1
|
|
|
|
use_half_precision = False
|
|
|
|
else:
|
|
|
|
use_half_precision = True
|
2022-09-13 17:17:14 +00:00
|
|
|
|
2022-09-25 22:11:59 +00:00
|
|
|
from realesrgan.archs.srvgg_arch import SRVGGNetCompact
|
|
|
|
from realesrgan import RealESRGANer
|
|
|
|
|
|
|
|
model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu')
|
2022-11-18 19:29:29 +00:00
|
|
|
model_path = os.path.join(Globals.root,'models/realesrgan/realesr-general-x4v3.pth')
|
2022-09-25 22:11:59 +00:00
|
|
|
scale = 4
|
|
|
|
|
|
|
|
bg_upsampler = RealESRGANer(
|
|
|
|
scale=scale,
|
|
|
|
model_path=model_path,
|
|
|
|
model=model,
|
|
|
|
tile=self.bg_tile_size,
|
|
|
|
tile_pad=10,
|
|
|
|
pre_pad=0,
|
|
|
|
half=use_half_precision,
|
|
|
|
)
|
2022-09-13 17:17:14 +00:00
|
|
|
|
|
|
|
return bg_upsampler
|
|
|
|
|
2022-10-07 00:52:38 +00:00
|
|
|
def process(self, image, strength: float, seed: str = None, upsampler_scale: int = 2):
|
2022-09-13 17:17:14 +00:00
|
|
|
with warnings.catch_warnings():
|
|
|
|
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
|
|
|
warnings.filterwarnings('ignore', category=UserWarning)
|
|
|
|
|
|
|
|
try:
|
2022-10-07 00:52:38 +00:00
|
|
|
upsampler = self.load_esrgan_bg_upsampler()
|
2022-09-13 17:17:14 +00:00
|
|
|
except Exception:
|
|
|
|
import traceback
|
|
|
|
import sys
|
|
|
|
print('>> Error loading Real-ESRGAN:', file=sys.stderr)
|
|
|
|
print(traceback.format_exc(), file=sys.stderr)
|
|
|
|
|
2022-09-25 22:11:59 +00:00
|
|
|
if upsampler_scale == 0:
|
|
|
|
print('>> Real-ESRGAN: Invalid scaling option. Image not upscaled.')
|
|
|
|
return image
|
|
|
|
|
|
|
|
if seed is not None:
|
|
|
|
print(
|
|
|
|
f'>> Real-ESRGAN Upscaling seed:{seed} : scale:{upsampler_scale}x'
|
|
|
|
)
|
2022-10-20 07:59:00 +00:00
|
|
|
|
|
|
|
# REALSRGAN expects a BGR np array; make array and flip channels
|
|
|
|
bgr_image_array = np.array(image, dtype=np.uint8)[...,::-1]
|
2022-09-25 22:11:59 +00:00
|
|
|
|
2022-09-13 17:17:14 +00:00
|
|
|
output, _ = upsampler.enhance(
|
2022-10-20 07:59:00 +00:00
|
|
|
bgr_image_array,
|
2022-09-13 17:17:14 +00:00
|
|
|
outscale=upsampler_scale,
|
|
|
|
alpha_upsampler='realesrgan',
|
|
|
|
)
|
|
|
|
|
2022-10-20 07:59:00 +00:00
|
|
|
# Flip the channels back to RGB
|
|
|
|
res = Image.fromarray(output[...,::-1])
|
2022-09-13 17:17:14 +00:00
|
|
|
|
|
|
|
if strength < 1.0:
|
|
|
|
# Resize the image to the new image if the sizes have changed
|
|
|
|
if output.size != image.size:
|
|
|
|
image = image.resize(res.size)
|
|
|
|
res = Image.blend(image, res, strength)
|
|
|
|
|
|
|
|
if torch.cuda.is_available():
|
|
|
|
torch.cuda.empty_cache()
|
|
|
|
upsampler = None
|
|
|
|
|
|
|
|
return res
|