File size: 6,978 Bytes
1565811
172e426
99e421f
52962c0
99e421f
1353ca3
 
 
 
 
52962c0
172e426
1565811
 
 
 
 
 
 
 
 
172e426
 
 
827d87f
172e426
 
 
 
1565811
 
172e426
1565811
172e426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1565811
29b44e9
715fe0c
 
 
 
0775a2e
1565811
d2763b3
648d463
d341489
648d463
 
 
 
172e426
1565811
648d463
3c57a21
1565811
648d463
abd7620
d2763b3
1565811
 
 
6ab882a
 
172e426
6a818b8
715fe0c
172e426
 
d341489
 
172e426
 
 
 
 
8b0d051
172e426
 
 
 
648d463
c9f5c91
648d463
 
 
 
1565811
 
 
 
1ec9d51
1565811
 
 
 
172e426
35b21aa
1565811
 
 
 
172e426
 
 
 
1565811
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import os
 
os.system("pip uninstall -y gradio")
os.system("pip install gradio==3.50")

os.system('wget "https://public-vigen-video.oss-cn-shanghai.aliyuncs.com/robin/models/RetinaFace-R50.pth" -O weights/RetinaFace-R50.pth')
os.system('wget "https://public-vigen-video.oss-cn-shanghai.aliyuncs.com/robin/models/GPEN-BFR-512.pth" -O weights/GPEN-512.pth')
os.system('wget "https://public-vigen-video.oss-cn-shanghai.aliyuncs.com/robin/models/GPEN-Colorization-1024.pth" -O weights/GPEN-1024-Color.pth ')
os.system('wget "https://public-vigen-video.oss-cn-shanghai.aliyuncs.com/robin/models/realesrnet_x2.pth" -O weights/realesrnet_x2.pth ')
os.system('wget "https://public-vigen-video.oss-cn-shanghai.aliyuncs.com/robin/models/GPEN-Inpainting-1024.pth" -O weights/GPEN-Inpainting-1024.pth ')
jksp= os.environ['SELFIE']
os.system(f'wget "{jksp}" -O weights/GPEN-BFR-2048.pth')

import gradio as gr

'''
@paper: GAN Prior Embedded Network for Blind Face Restoration in the Wild (CVPR2021)
@author: yangxy (yangtao9009@gmail.com)
'''
import os
import cv2
import glob
import time
import math
import imutils
import argparse
import numpy as np
from PIL import Image, ImageDraw
import __init_paths
from face_enhancement import FaceEnhancement 
from face_colorization import FaceColorization 
from face_inpainting import FaceInpainting 
  
def brush_stroke_mask(img, color=(255,255,255)):
    min_num_vertex = 8
    max_num_vertex = 28
    mean_angle = 2*math.pi / 5
    angle_range = 2*math.pi / 15
    min_width = 12
    max_width = 80
    def generate_mask(H, W, img=None):
        average_radius = math.sqrt(H*H+W*W) / 8
        mask = Image.new('RGB', (W, H), 0)
        if img is not None: mask = img #Image.fromarray(img)

        for _ in range(np.random.randint(1, 4)):
            num_vertex = np.random.randint(min_num_vertex, max_num_vertex)
            angle_min = mean_angle - np.random.uniform(0, angle_range)
            angle_max = mean_angle + np.random.uniform(0, angle_range)
            angles = []
            vertex = []
            for i in range(num_vertex):
                if i % 2 == 0:
                    angles.append(2*math.pi - np.random.uniform(angle_min, angle_max))
                else:
                    angles.append(np.random.uniform(angle_min, angle_max))

            h, w = mask.size
            vertex.append((int(np.random.randint(0, w)), int(np.random.randint(0, h))))
            for i in range(num_vertex):
                r = np.clip(
                    np.random.normal(loc=average_radius, scale=average_radius//2),
                    0, 2*average_radius)
                new_x = np.clip(vertex[-1][0] + r * math.cos(angles[i]), 0, w)
                new_y = np.clip(vertex[-1][1] + r * math.sin(angles[i]), 0, h)
                vertex.append((int(new_x), int(new_y)))

            draw = ImageDraw.Draw(mask)
            width = int(np.random.uniform(min_width, max_width))
            draw.line(vertex, fill=color, width=width)
            for v in vertex:
                draw.ellipse((v[0] - width//2,
                              v[1] - width//2,
                              v[0] + width//2,
                              v[1] + width//2),
                             fill=color)

        return mask

    width, height = img.size
    mask = generate_mask(height, width, img)
    return mask

def resize(image, width = 1024):
    aspect_ratio = float(image.shape[1])/float(image.shape[0])
    height = width/aspect_ratio
    image = cv2.resize(image, (int(height),int(width)))
    return image

def inference(file, mode):

    im = cv2.imread(file, cv2.IMREAD_COLOR)
    im = cv2.resize(im, (0,0), fx=2, fy=2)
    faceenhancer = FaceEnhancement(size=512, model='GPEN-512', channel_multiplier=2, device='cpu', u=False)
    img, orig_faces, enhanced_faces = faceenhancer.process(im)
    cv2.imwrite(os.path.join("e.png"), img)
    
    
    if mode == "enhance":
        return os.path.join("e.png")
    elif mode == "colorize":
        model = {'name':'GPEN-1024-Color', 'size':1024}
        grayf = cv2.imread("e.png", cv2.IMREAD_GRAYSCALE)
        grayf = cv2.cvtColor(grayf, cv2.COLOR_GRAY2BGR) # channel: 1->3
        facecolorizer = FaceColorization(size=model['size'], model=model['name'], channel_multiplier=2, device='cpu')
        colorf = facecolorizer.process(grayf)

        colorf = cv2.resize(colorf, (grayf.shape[1], grayf.shape[0]))
        cv2.imwrite(os.path.join("output.png"), colorf)
        return os.path.join("output.png")
    elif mode == "inpainting":
        im1 = cv2.imread(file, cv2.IMREAD_COLOR)
        im2 = resize(im1, width = 1024)
        model = {'name':'GPEN-Inpainting-1024', 'size':1024}
        faceinpainter = FaceInpainting(size=model['size'], model=model['name'], channel_multiplier=2, device='cpu')
        im3 = np.asarray(brush_stroke_mask(Image.fromarray(im2)))
        inpaint = faceinpainter.process(im3)

        cv2.imwrite(os.path.join("output.png"), inpaint)
        return os.path.join("output.png")
    elif mode == "selfie":
        model = {'name':'GPEN-BFR-2048', 'size':2048}
        im = cv2.resize(im, (0,0), fx=2, fy=2)
        faceenhancer = FaceEnhancement(size=model['size'], model=model['name'], channel_multiplier=2, device='cpu')
        img, orig_faces, enhanced_faces = faceenhancer.process(im)
        cv2.imwrite(os.path.join("output.png"), img)
        return os.path.join("output.png")
    else:
        faceenhancer = FaceEnhancement(size=512, model='GPEN-512', channel_multiplier=2, device='cpu', u=True)
        img, orig_faces, enhanced_faces = faceenhancer.process(im)
        cv2.imwrite(os.path.join("output.png"), img)
        return os.path.join("output.png")
        
        
title = "GPEN"
description = "Gradio demo for GAN Prior Embedded Network for Blind Face Restoration in the Wild. This version of gradio demo includes face colorization from GPEN. To use it, simply upload your image, or click one of the examples to load them. Read more at the links below."

article = "<p style='text-align: center;'><a href='https://arxiv.org/abs/2105.06070' target='_blank'>GAN Prior Embedded Network for Blind Face Restoration in the Wild</a> | <a href='https://github.com/yangxy/GPEN' target='_blank'>Github Repo</a></p><p style='text-align: center;'><img src='https://img.shields.io/badge/Hugging%20Face-Original%20demo-blue' alt='https://huggingface.co/spaces/akhaliq/GPEN' width='172' height='20' /></p>"


gr.Interface(
    inference, 
    [gr.inputs.Image(type="filepath", label="Input"),gr.inputs.Radio(["enhance", "colorize", "inpainting", "selfie", "enhanced+background"], type="value", default="enhance", label="Type")], 
    gr.outputs.Image(type="filepath", label="Output"),
    title=title,
    description=description,
    article=article,
    examples=[
    ['enhance.png', 'enhance'],
    ['color.png', 'colorize'],
    ['inpainting.png', 'inpainting'],
    ['selfie.png', 'selfie']
    ],
    enable_queue=True
    ).launch()