Fabrice-TIERCELIN commited on
Commit
5a8a838
1 Parent(s): a6c349f

Upload 2 files

Browse files
Files changed (2) hide show
  1. SUPIR/__init__.py +0 -0
  2. SUPIR/util.py +179 -0
SUPIR/__init__.py ADDED
File without changes
SUPIR/util.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import numpy as np
4
+ import cv2
5
+ from PIL import Image
6
+ from torch.nn.functional import interpolate
7
+ from omegaconf import OmegaConf
8
+ from sgm.util import instantiate_from_config
9
+
10
+
11
+ def get_state_dict(d):
12
+ return d.get('state_dict', d)
13
+
14
+
15
+ def load_state_dict(ckpt_path, location='cpu'):
16
+ _, extension = os.path.splitext(ckpt_path)
17
+ if extension.lower() == ".safetensors":
18
+ import safetensors.torch
19
+ state_dict = safetensors.torch.load_file(ckpt_path, device=location)
20
+ else:
21
+ state_dict = get_state_dict(torch.load(ckpt_path, map_location=torch.device(location)))
22
+ state_dict = get_state_dict(state_dict)
23
+ print(f'Loaded state_dict from [{ckpt_path}]')
24
+ return state_dict
25
+
26
+
27
+ def create_model(config_path):
28
+ config = OmegaConf.load(config_path)
29
+ model = instantiate_from_config(config.model).cpu()
30
+ print(f'Loaded model config from [{config_path}]')
31
+ return model
32
+
33
+
34
+ def create_SUPIR_model(config_path, SUPIR_sign=None, load_default_setting=False):
35
+ config = OmegaConf.load(config_path)
36
+ model = instantiate_from_config(config.model).cpu()
37
+ print(f'Loaded model config from [{config_path}]')
38
+ if config.SDXL_CKPT is not None:
39
+ model.load_state_dict(load_state_dict(config.SDXL_CKPT), strict=False)
40
+ if config.SUPIR_CKPT is not None:
41
+ model.load_state_dict(load_state_dict(config.SUPIR_CKPT), strict=False)
42
+ if SUPIR_sign is not None:
43
+ assert SUPIR_sign in ['F', 'Q']
44
+ if SUPIR_sign == 'F':
45
+ model.load_state_dict(load_state_dict(config.SUPIR_CKPT_F), strict=False)
46
+ elif SUPIR_sign == 'Q':
47
+ model.load_state_dict(load_state_dict(config.SUPIR_CKPT_Q), strict=False)
48
+ if load_default_setting:
49
+ default_setting = config.default_setting
50
+ return model, default_setting
51
+ return model
52
+
53
+ def load_QF_ckpt(config_path):
54
+ config = OmegaConf.load(config_path)
55
+ ckpt_F = torch.load(config.SUPIR_CKPT_F, map_location='cpu')
56
+ ckpt_Q = torch.load(config.SUPIR_CKPT_Q, map_location='cpu')
57
+ return ckpt_Q, ckpt_F
58
+
59
+
60
+ def PIL2Tensor(img, upsacle=1, min_size=1024, fix_resize=None):
61
+ '''
62
+ PIL.Image -> Tensor[C, H, W], RGB, [-1, 1]
63
+ '''
64
+ # size
65
+ w, h = img.size
66
+ w *= upsacle
67
+ h *= upsacle
68
+ w0, h0 = round(w), round(h)
69
+ if min(w, h) < min_size:
70
+ _upsacle = min_size / min(w, h)
71
+ w *= _upsacle
72
+ h *= _upsacle
73
+ if fix_resize is not None:
74
+ _upsacle = fix_resize / min(w, h)
75
+ w *= _upsacle
76
+ h *= _upsacle
77
+ w0, h0 = round(w), round(h)
78
+ w = int(np.round(w / 64.0)) * 64
79
+ h = int(np.round(h / 64.0)) * 64
80
+ x = img.resize((w, h), Image.BICUBIC)
81
+ x = np.array(x).round().clip(0, 255).astype(np.uint8)
82
+ x = x / 255 * 2 - 1
83
+ x = torch.tensor(x, dtype=torch.float32).permute(2, 0, 1)
84
+ return x, h0, w0
85
+
86
+
87
+ def Tensor2PIL(x, h0, w0):
88
+ '''
89
+ Tensor[C, H, W], RGB, [-1, 1] -> PIL.Image
90
+ '''
91
+ x = x.unsqueeze(0)
92
+ x = interpolate(x, size=(h0, w0), mode='bicubic')
93
+ x = (x.squeeze(0).permute(1, 2, 0) * 127.5 + 127.5).cpu().numpy().clip(0, 255).astype(np.uint8)
94
+ return Image.fromarray(x)
95
+
96
+
97
+ def HWC3(x):
98
+ assert x.dtype == np.uint8
99
+ if x.ndim == 2:
100
+ x = x[:, :, None]
101
+ assert x.ndim == 3
102
+ H, W, C = x.shape
103
+ assert C == 1 or C == 3 or C == 4
104
+ if C == 3:
105
+ return x
106
+ if C == 1:
107
+ return np.concatenate([x, x, x], axis=2)
108
+ if C == 4:
109
+ color = x[:, :, 0:3].astype(np.float32)
110
+ alpha = x[:, :, 3:4].astype(np.float32) / 255.0
111
+ y = color * alpha + 255.0 * (1.0 - alpha)
112
+ y = y.clip(0, 255).astype(np.uint8)
113
+ return y
114
+
115
+
116
+ def upscale_image(input_image, upscale, min_size=None, unit_resolution=64):
117
+ H, W, C = input_image.shape
118
+ H = float(H)
119
+ W = float(W)
120
+ H *= upscale
121
+ W *= upscale
122
+ if min_size is not None:
123
+ if min(H, W) < min_size:
124
+ _upsacle = min_size / min(W, H)
125
+ W *= _upsacle
126
+ H *= _upsacle
127
+ H = int(np.round(H / unit_resolution)) * unit_resolution
128
+ W = int(np.round(W / unit_resolution)) * unit_resolution
129
+ img = cv2.resize(input_image, (W, H), interpolation=cv2.INTER_LANCZOS4 if upscale > 1 else cv2.INTER_AREA)
130
+ img = img.round().clip(0, 255).astype(np.uint8)
131
+ return img
132
+
133
+
134
+ def fix_resize(input_image, size=512, unit_resolution=64):
135
+ H, W, C = input_image.shape
136
+ H = float(H)
137
+ W = float(W)
138
+ upscale = size / min(H, W)
139
+ H *= upscale
140
+ W *= upscale
141
+ H = int(np.round(H / unit_resolution)) * unit_resolution
142
+ W = int(np.round(W / unit_resolution)) * unit_resolution
143
+ img = cv2.resize(input_image, (W, H), interpolation=cv2.INTER_LANCZOS4 if upscale > 1 else cv2.INTER_AREA)
144
+ img = img.round().clip(0, 255).astype(np.uint8)
145
+ return img
146
+
147
+
148
+
149
+ def Numpy2Tensor(img):
150
+ '''
151
+ np.array[H, w, C] [0, 255] -> Tensor[C, H, W], RGB, [-1, 1]
152
+ '''
153
+ # size
154
+ img = np.array(img) / 255 * 2 - 1
155
+ img = torch.tensor(img, dtype=torch.float32).permute(2, 0, 1)
156
+ return img
157
+
158
+
159
+ def Tensor2Numpy(x, h0=None, w0=None):
160
+ '''
161
+ Tensor[C, H, W], RGB, [-1, 1] -> PIL.Image
162
+ '''
163
+ if h0 is not None and w0 is not None:
164
+ x = x.unsqueeze(0)
165
+ x = interpolate(x, size=(h0, w0), mode='bicubic')
166
+ x = x.squeeze(0)
167
+ x = (x.permute(1, 2, 0) * 127.5 + 127.5).cpu().numpy().clip(0, 255).astype(np.uint8)
168
+ return x
169
+
170
+
171
+ def convert_dtype(dtype_str):
172
+ if dtype_str == 'fp32':
173
+ return torch.float32
174
+ elif dtype_str == 'fp16':
175
+ return torch.float16
176
+ elif dtype_str == 'bf16':
177
+ return torch.bfloat16
178
+ else:
179
+ raise NotImplementedError