tejani commited on
Commit
82a4cce
·
verified ·
1 Parent(s): f3436bc

Upload 9 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ input/example.png filter=lfs diff=lfs merge=lfs -text
37
+ output/example_Normal.png filter=lfs diff=lfs merge=lfs -text
architecture/architecture.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import torch.nn as nn
3
+ import utils.architecture.block as B
4
+
5
+ ####################
6
+ # Generator
7
+ ####################
8
+
9
+ class RRDB_Net(nn.Module):
10
+ def __init__(self, in_nc, out_nc, nf, nb, gc=32, upscale=4, norm_type=None, act_type='leakyrelu', \
11
+ mode='CNA', res_scale=1, upsample_mode='upconv'):
12
+ super(RRDB_Net, self).__init__()
13
+ n_upscale = int(math.log(upscale, 2))
14
+ if upscale == 3:
15
+ n_upscale = 1
16
+
17
+ fea_conv = B.conv_block(in_nc, nf, kernel_size=3, norm_type=None, act_type=None)
18
+ rb_blocks = [B.RRDB(nf, kernel_size=3, gc=32, stride=1, bias=True, pad_type='zero', \
19
+ norm_type=norm_type, act_type=act_type, mode='CNA') for _ in range(nb)]
20
+ LR_conv = B.conv_block(nf, nf, kernel_size=3, norm_type=norm_type, act_type=None, mode=mode)
21
+
22
+ if upsample_mode == 'upconv':
23
+ upsample_block = B.upconv_blcok
24
+ elif upsample_mode == 'pixelshuffle':
25
+ upsample_block = B.pixelshuffle_block
26
+ else:
27
+ raise NotImplementedError('upsample mode [%s] is not found' % upsample_mode)
28
+ if upscale == 3:
29
+ upsampler = upsample_block(nf, nf, 3, act_type=act_type)
30
+ else:
31
+ upsampler = [upsample_block(nf, nf, act_type=act_type) for _ in range(n_upscale)]
32
+ HR_conv0 = B.conv_block(nf, nf, kernel_size=3, norm_type=None, act_type=act_type)
33
+ HR_conv1 = B.conv_block(nf, out_nc, kernel_size=3, norm_type=None, act_type=None)
34
+
35
+ self.model = B.sequential(fea_conv, B.ShortcutBlock(B.sequential(*rb_blocks, LR_conv)),\
36
+ *upsampler, HR_conv0, HR_conv1)
37
+
38
+ def forward(self, x):
39
+ x = self.model(x)
40
+ return x
architecture/block.py ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections import OrderedDict
2
+ import torch
3
+ import torch.nn as nn
4
+
5
+ ####################
6
+ # Basic blocks
7
+ ####################
8
+
9
+
10
+ def act(act_type, inplace=True, neg_slope=0.2, n_prelu=1):
11
+ # helper selecting activation
12
+ # neg_slope: for leakyrelu and init of prelu
13
+ # n_prelu: for p_relu num_parameters
14
+ act_type = act_type.lower()
15
+ if act_type == 'relu':
16
+ layer = nn.ReLU(inplace)
17
+ elif act_type == 'leakyrelu':
18
+ layer = nn.LeakyReLU(neg_slope, inplace)
19
+ elif act_type == 'prelu':
20
+ layer = nn.PReLU(num_parameters=n_prelu, init=neg_slope)
21
+ else:
22
+ raise NotImplementedError('activation layer [{:s}] is not found'.format(act_type))
23
+ return layer
24
+
25
+
26
+ def norm(norm_type, nc):
27
+ # helper selecting normalization layer
28
+ norm_type = norm_type.lower()
29
+ if norm_type == 'batch':
30
+ layer = nn.BatchNorm2d(nc, affine=True)
31
+ elif norm_type == 'instance':
32
+ layer = nn.InstanceNorm2d(nc, affine=False)
33
+ else:
34
+ raise NotImplementedError('normalization layer [{:s}] is not found'.format(norm_type))
35
+ return layer
36
+
37
+
38
+ def pad(pad_type, padding):
39
+ # helper selecting padding layer
40
+ # if padding is 'zero', do by conv layers
41
+ pad_type = pad_type.lower()
42
+ if padding == 0:
43
+ return None
44
+ if pad_type == 'reflect':
45
+ layer = nn.ReflectionPad2d(padding)
46
+ elif pad_type == 'replicate':
47
+ layer = nn.ReplicationPad2d(padding)
48
+ else:
49
+ raise NotImplementedError('padding layer [{:s}] is not implemented'.format(pad_type))
50
+ return layer
51
+
52
+
53
+ def get_valid_padding(kernel_size, dilation):
54
+ kernel_size = kernel_size + (kernel_size - 1) * (dilation - 1)
55
+ padding = (kernel_size - 1) // 2
56
+ return padding
57
+
58
+
59
+ class ConcatBlock(nn.Module):
60
+ # Concat the output of a submodule to its input
61
+ def __init__(self, submodule):
62
+ super(ConcatBlock, self).__init__()
63
+ self.sub = submodule
64
+
65
+ def forward(self, x):
66
+ output = torch.cat((x, self.sub(x)), dim=1)
67
+ return output
68
+
69
+ def __repr__(self):
70
+ tmpstr = 'Identity .. \n|'
71
+ modstr = self.sub.__repr__().replace('\n', '\n|')
72
+ tmpstr = tmpstr + modstr
73
+ return tmpstr
74
+
75
+
76
+ class ShortcutBlock(nn.Module):
77
+ #Elementwise sum the output of a submodule to its input
78
+ def __init__(self, submodule):
79
+ super(ShortcutBlock, self).__init__()
80
+ self.sub = submodule
81
+
82
+ def forward(self, x):
83
+ output = x + self.sub(x)
84
+ return output
85
+
86
+ def __repr__(self):
87
+ tmpstr = 'Identity + \n|'
88
+ modstr = self.sub.__repr__().replace('\n', '\n|')
89
+ tmpstr = tmpstr + modstr
90
+ return tmpstr
91
+
92
+
93
+ class ShortcutBlockSPSR(nn.Module):
94
+ #Elementwise sum the output of a submodule to its input
95
+ def __init__(self, submodule):
96
+ super(ShortcutBlockSPSR, self).__init__()
97
+ self.sub = submodule
98
+
99
+ def forward(self, x):
100
+ return x, self.sub
101
+
102
+ def __repr__(self):
103
+ tmpstr = 'Identity + \n|'
104
+ modstr = self.sub.__repr__().replace('\n', '\n|')
105
+ tmpstr = tmpstr + modstr
106
+ return tmpstr
107
+
108
+
109
+ def sequential(*args):
110
+ # Flatten Sequential. It unwraps nn.Sequential.
111
+ if len(args) == 1:
112
+ if isinstance(args[0], OrderedDict):
113
+ raise NotImplementedError('sequential does not support OrderedDict input.')
114
+ return args[0] # No sequential is needed.
115
+ modules = []
116
+ for module in args:
117
+ if isinstance(module, nn.Sequential):
118
+ for submodule in module.children():
119
+ modules.append(submodule)
120
+ elif isinstance(module, nn.Module):
121
+ modules.append(module)
122
+ return nn.Sequential(*modules)
123
+
124
+
125
+ def conv_block(in_nc, out_nc, kernel_size, stride=1, dilation=1, groups=1, bias=True, \
126
+ pad_type='zero', norm_type=None, act_type='relu', mode='CNA'):
127
+ '''
128
+ Conv layer with padding, normalization, activation
129
+ mode: CNA --> Conv -> Norm -> Act
130
+ NAC --> Norm -> Act --> Conv (Identity Mappings in Deep Residual Networks, ECCV16)
131
+ '''
132
+ assert mode in ['CNA', 'NAC', 'CNAC'], 'Wrong conv mode [{:s}]'.format(mode)
133
+ padding = get_valid_padding(kernel_size, dilation)
134
+ p = pad(pad_type, padding) if pad_type and pad_type != 'zero' else None
135
+ padding = padding if pad_type == 'zero' else 0
136
+
137
+ c = nn.Conv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding, \
138
+ dilation=dilation, bias=bias, groups=groups)
139
+ a = act(act_type) if act_type else None
140
+ if 'CNA' in mode:
141
+ n = norm(norm_type, out_nc) if norm_type else None
142
+ return sequential(p, c, n, a)
143
+ elif mode == 'NAC':
144
+ if norm_type is None and act_type is not None:
145
+ a = act(act_type, inplace=False)
146
+ # Important!
147
+ # input----ReLU(inplace)----Conv--+----output
148
+ # |________________________|
149
+ # inplace ReLU will modify the input, therefore wrong output
150
+ n = norm(norm_type, in_nc) if norm_type else None
151
+ return sequential(n, a, p, c)
152
+
153
+
154
+ ####################
155
+ # Useful blocks
156
+ ####################
157
+
158
+
159
+ class ResNetBlock(nn.Module):
160
+ '''
161
+ ResNet Block, 3-3 style
162
+ with extra residual scaling used in EDSR
163
+ (Enhanced Deep Residual Networks for Single Image Super-Resolution, CVPRW 17)
164
+ '''
165
+
166
+ def __init__(self, in_nc, mid_nc, out_nc, kernel_size=3, stride=1, dilation=1, groups=1, \
167
+ bias=True, pad_type='zero', norm_type=None, act_type='relu', mode='CNA', res_scale=1):
168
+ super(ResNetBlock, self).__init__()
169
+ conv0 = conv_block(in_nc, mid_nc, kernel_size, stride, dilation, groups, bias, pad_type, \
170
+ norm_type, act_type, mode)
171
+ if mode == 'CNA':
172
+ act_type = None
173
+ if mode == 'CNAC': # Residual path: |-CNAC-|
174
+ act_type = None
175
+ norm_type = None
176
+ conv1 = conv_block(mid_nc, out_nc, kernel_size, stride, dilation, groups, bias, pad_type, \
177
+ norm_type, act_type, mode)
178
+ # if in_nc != out_nc:
179
+ # self.project = conv_block(in_nc, out_nc, 1, stride, dilation, 1, bias, pad_type, \
180
+ # None, None)
181
+ # print('Need a projecter in ResNetBlock.')
182
+ # else:
183
+ # self.project = lambda x:x
184
+ self.res = sequential(conv0, conv1)
185
+ self.res_scale = res_scale
186
+
187
+ def forward(self, x):
188
+ res = self.res(x).mul(self.res_scale)
189
+ return x + res
190
+
191
+
192
+ class ResidualDenseBlock_5C(nn.Module):
193
+ '''
194
+ Residual Dense Block
195
+ style: 5 convs
196
+ The core module of paper: (Residual Dense Network for Image Super-Resolution, CVPR 18)
197
+ '''
198
+
199
+ def __init__(self, nc, kernel_size=3, gc=32, stride=1, bias=True, pad_type='zero', \
200
+ norm_type=None, act_type='leakyrelu', mode='CNA'):
201
+ super(ResidualDenseBlock_5C, self).__init__()
202
+ # gc: growth channel, i.e. intermediate channels
203
+ self.conv1 = conv_block(nc, gc, kernel_size, stride, bias=bias, pad_type=pad_type, \
204
+ norm_type=norm_type, act_type=act_type, mode=mode)
205
+ self.conv2 = conv_block(nc+gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type, \
206
+ norm_type=norm_type, act_type=act_type, mode=mode)
207
+ self.conv3 = conv_block(nc+2*gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type, \
208
+ norm_type=norm_type, act_type=act_type, mode=mode)
209
+ self.conv4 = conv_block(nc+3*gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type, \
210
+ norm_type=norm_type, act_type=act_type, mode=mode)
211
+ if mode == 'CNA':
212
+ last_act = None
213
+ else:
214
+ last_act = act_type
215
+ self.conv5 = conv_block(nc+4*gc, nc, 3, stride, bias=bias, pad_type=pad_type, \
216
+ norm_type=norm_type, act_type=last_act, mode=mode)
217
+
218
+ def forward(self, x):
219
+ x1 = self.conv1(x)
220
+ x2 = self.conv2(torch.cat((x, x1), 1))
221
+ x3 = self.conv3(torch.cat((x, x1, x2), 1))
222
+ x4 = self.conv4(torch.cat((x, x1, x2, x3), 1))
223
+ x5 = self.conv5(torch.cat((x, x1, x2, x3, x4), 1))
224
+ return x5.mul(0.2) + x
225
+
226
+
227
+ class RRDB(nn.Module):
228
+ '''
229
+ Residual in Residual Dense Block
230
+ (ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks)
231
+ '''
232
+
233
+ def __init__(self, nc, kernel_size=3, gc=32, stride=1, bias=True, pad_type='zero', \
234
+ norm_type=None, act_type='leakyrelu', mode='CNA'):
235
+ super(RRDB, self).__init__()
236
+ self.RDB1 = ResidualDenseBlock_5C(nc, kernel_size, gc, stride, bias, pad_type, \
237
+ norm_type, act_type, mode)
238
+ self.RDB2 = ResidualDenseBlock_5C(nc, kernel_size, gc, stride, bias, pad_type, \
239
+ norm_type, act_type, mode)
240
+ self.RDB3 = ResidualDenseBlock_5C(nc, kernel_size, gc, stride, bias, pad_type, \
241
+ norm_type, act_type, mode)
242
+
243
+ def forward(self, x):
244
+ out = self.RDB1(x)
245
+ out = self.RDB2(out)
246
+ out = self.RDB3(out)
247
+ return out.mul(0.2) + x
248
+
249
+
250
+ ####################
251
+ # Upsampler
252
+ ####################
253
+
254
+
255
+ def pixelshuffle_block(in_nc, out_nc, upscale_factor=2, kernel_size=3, stride=1, bias=True, \
256
+ pad_type='zero', norm_type=None, act_type='relu'):
257
+ '''
258
+ Pixel shuffle layer
259
+ (Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional
260
+ Neural Network, CVPR17)
261
+ '''
262
+ conv = conv_block(in_nc, out_nc * (upscale_factor ** 2), kernel_size, stride, bias=bias, \
263
+ pad_type=pad_type, norm_type=None, act_type=None)
264
+ pixel_shuffle = nn.PixelShuffle(upscale_factor)
265
+
266
+ n = norm(norm_type, out_nc) if norm_type else None
267
+ a = act(act_type) if act_type else None
268
+ return sequential(conv, pixel_shuffle, n, a)
269
+
270
+
271
+ def upconv_blcok(in_nc, out_nc, upscale_factor=2, kernel_size=3, stride=1, bias=True, \
272
+ pad_type='zero', norm_type=None, act_type='relu', mode='nearest'):
273
+ # Up conv
274
+ # described in https://distill.pub/2016/deconv-checkerboard/
275
+ upsample = nn.Upsample(scale_factor=upscale_factor, mode=mode)
276
+ conv = conv_block(in_nc, out_nc, kernel_size, stride, bias=bias, \
277
+ pad_type=pad_type, norm_type=norm_type, act_type=act_type)
278
+ return sequential(upsample, conv)
imgops.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import math
3
+
4
+ def crop_seamless(img):
5
+ img_height, img_width = img.shape[:2]
6
+ y, x = 16, 16
7
+ h, w = img_height - 32, img_width - 32
8
+ img = img[y:y+h, x:x+w]
9
+ return img
10
+
11
+ # from https://github.com/ata4/esrgan-launcher/blob/master/upscale.py
12
+ def esrgan_launcher_split_merge(input_image, upscale_function, models, scale_factor=4, tile_size=512, tile_padding=0.125):
13
+ width, height, depth = input_image.shape
14
+ output_width = width * scale_factor
15
+ output_height = height * scale_factor
16
+ output_shape = (output_width, output_height, depth)
17
+
18
+ # start with black image
19
+ output_images = [np.zeros(output_shape, np.uint8) for i in range(len(models))]
20
+
21
+ tile_padding = math.ceil(tile_size * tile_padding)
22
+ tile_size = math.ceil(tile_size / scale_factor)
23
+
24
+ tiles_x = math.ceil(width / tile_size)
25
+ tiles_y = math.ceil(height / tile_size)
26
+
27
+ for y in range(tiles_y):
28
+ for x in range(tiles_x):
29
+ # extract tile from input image
30
+ ofs_x = x * tile_size
31
+ ofs_y = y * tile_size
32
+
33
+ # input tile area on total image
34
+ input_start_x = ofs_x
35
+ input_end_x = min(ofs_x + tile_size, width)
36
+
37
+ input_start_y = ofs_y
38
+ input_end_y = min(ofs_y + tile_size, height)
39
+
40
+ # input tile area on total image with padding
41
+ input_start_x_pad = max(input_start_x - tile_padding, 0)
42
+ input_end_x_pad = min(input_end_x + tile_padding, width)
43
+
44
+ input_start_y_pad = max(input_start_y - tile_padding, 0)
45
+ input_end_y_pad = min(input_end_y + tile_padding, height)
46
+
47
+ # input tile dimensions
48
+ input_tile_width = input_end_x - input_start_x
49
+ input_tile_height = input_end_y - input_start_y
50
+
51
+ input_tile = input_image[input_start_x_pad:input_end_x_pad, input_start_y_pad:input_end_y_pad]
52
+
53
+ for idx, model in enumerate(models):
54
+
55
+ # upscale tile
56
+ output_tile = upscale_function(input_tile, model)
57
+
58
+ # output tile area on total image
59
+ output_start_x = input_start_x * scale_factor
60
+ output_end_x = input_end_x * scale_factor
61
+
62
+ output_start_y = input_start_y * scale_factor
63
+ output_end_y = input_end_y * scale_factor
64
+
65
+ # output tile area without padding
66
+ output_start_x_tile = (input_start_x - input_start_x_pad) * scale_factor
67
+ output_end_x_tile = output_start_x_tile + input_tile_width * scale_factor
68
+
69
+ output_start_y_tile = (input_start_y - input_start_y_pad) * scale_factor
70
+ output_end_y_tile = output_start_y_tile + input_tile_height * scale_factor
71
+
72
+ # put tile into output image
73
+ output_images[idx][output_start_x:output_end_x, output_start_y:output_end_y] = \
74
+ output_tile[output_start_x_tile:output_end_x_tile, output_start_y_tile:output_end_y_tile]
75
+
76
+ return output_images
input/example.png ADDED

Git LFS Details

  • SHA256: de87e5cdec513c560e94fbe18ed11648304a09ecffe11f45ad32c951f8803568
  • Pointer size: 131 Bytes
  • Size of remote file: 197 kB
models/1x_FrankenMapGenerator-CX-Lite_215000_G.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:15405908c94795a13e1c320bda01287b72f76a0b5ed0bd40d00192dd1223326d
3
+ size 20098601
models/1x_NormalMapGenerator-CX-Lite_200000_G.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dce313777fac7b2f98101538f15a153acfa92cbf4bb62a8cd4a89edc0eb313dc
3
+ size 20098601
output/example_Displacement.png ADDED
output/example_Normal.png ADDED

Git LFS Details

  • SHA256: b27285e135eb7611e08de4dba98be7f8fc7eee20d4da3a31474df0838b3b6fb5
  • Pointer size: 131 Bytes
  • Size of remote file: 182 kB
output/example_Roughness.png ADDED