gokaygokay commited on
Commit
23ce364
1 Parent(s): 67d5cbe
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. app.py +0 -107
  2. basicsr/__init__.py +0 -12
  3. basicsr/archs/__init__.py +0 -24
  4. basicsr/archs/arch_util.py +0 -313
  5. basicsr/archs/basicvsr_arch.py +0 -336
  6. basicsr/archs/basicvsrpp_arch.py +0 -417
  7. basicsr/archs/dfdnet_arch.py +0 -169
  8. basicsr/archs/dfdnet_util.py +0 -162
  9. basicsr/archs/discriminator_arch.py +0 -150
  10. basicsr/archs/duf_arch.py +0 -276
  11. basicsr/archs/ecbsr_arch.py +0 -275
  12. basicsr/archs/edsr_arch.py +0 -61
  13. basicsr/archs/edvr_arch.py +0 -382
  14. basicsr/archs/hifacegan_arch.py +0 -260
  15. basicsr/archs/hifacegan_util.py +0 -255
  16. basicsr/archs/inception.py +0 -307
  17. basicsr/archs/rcan_arch.py +0 -135
  18. basicsr/archs/ridnet_arch.py +0 -180
  19. basicsr/archs/rrdbnet_arch.py +0 -119
  20. basicsr/archs/spynet_arch.py +0 -96
  21. basicsr/archs/srresnet_arch.py +0 -65
  22. basicsr/archs/srvgg_arch.py +0 -70
  23. basicsr/archs/stylegan2_arch.py +0 -799
  24. basicsr/archs/stylegan2_bilinear_arch.py +0 -614
  25. basicsr/archs/swinir_arch.py +0 -956
  26. basicsr/archs/tof_arch.py +0 -172
  27. basicsr/archs/vgg_arch.py +0 -161
  28. basicsr/data/__init__.py +0 -101
  29. basicsr/data/data_sampler.py +0 -48
  30. basicsr/data/data_util.py +0 -315
  31. basicsr/data/degradations.py +0 -764
  32. basicsr/data/ffhq_dataset.py +0 -80
  33. basicsr/data/imagent_dataset.py +0 -460
  34. basicsr/data/meta_info/meta_info_DIV2K800sub_GT.txt +0 -0
  35. basicsr/data/meta_info/meta_info_REDS4_test_GT.txt +0 -4
  36. basicsr/data/meta_info/meta_info_REDS_GT.txt +0 -270
  37. basicsr/data/meta_info/meta_info_REDSofficial4_test_GT.txt +0 -4
  38. basicsr/data/meta_info/meta_info_REDSval_official_test_GT.txt +0 -30
  39. basicsr/data/meta_info/meta_info_Vimeo90K_test_GT.txt +0 -0
  40. basicsr/data/meta_info/meta_info_Vimeo90K_test_fast_GT.txt +0 -1225
  41. basicsr/data/meta_info/meta_info_Vimeo90K_test_medium_GT.txt +0 -0
  42. basicsr/data/meta_info/meta_info_Vimeo90K_test_slow_GT.txt +0 -1613
  43. basicsr/data/meta_info/meta_info_Vimeo90K_train_GT.txt +0 -0
  44. basicsr/data/paired_image_dataset.py +0 -106
  45. basicsr/data/prefetch_dataloader.py +0 -122
  46. basicsr/data/realesrgan_dataset.py +0 -193
  47. basicsr/data/realesrgan_paired_dataset.py +0 -106
  48. basicsr/data/reds_dataset.py +0 -352
  49. basicsr/data/single_image_dataset.py +0 -68
  50. basicsr/data/transforms.py +0 -179
app.py DELETED
@@ -1,107 +0,0 @@
1
-
2
- import spaces
3
- import gradio as gr
4
- from gradio_imageslider import ImageSlider
5
- import numpy as np
6
- from huggingface_hub import hf_hub_download
7
- import torch
8
- from PIL import Image
9
- from diffusers import DDPMScheduler
10
- from schedulers.lcm_single_step_scheduler import LCMSingleStepScheduler
11
- from module.ip_adapter.utils import load_adapter_to_pipe
12
- from pipelines.sdxl_instantir import InstantIRPipeline
13
- import os
14
-
15
- os.makedirs('./models', exist_ok=True)
16
- # Download model files if not present
17
- for filename in ["adapter.pt", "aggregator.pt", "previewer_lora_weights.bin"]:
18
- hf_hub_download(repo_id="InstantX/InstantIR", filename=f"models/{filename}", local_dir=".", force_download=True)
19
-
20
- # Initialize the pipeline and models
21
- def initialize_pipeline():
22
- pipe = InstantIRPipeline.from_pretrained('stabilityai/stable-diffusion-xl-base-1.0', torch_dtype=torch.float16)
23
-
24
- # load adapter
25
- load_adapter_to_pipe(
26
- pipe,
27
- './models/adapter.pt',
28
- image_encoder_path = 'facebook/dinov2-large',
29
- )
30
-
31
- # load previewer lora and schedulers
32
- pipe.prepare_previewers('./models')
33
- pipe.scheduler = DDPMScheduler.from_pretrained('stabilityai/stable-diffusion-xl-base-1.0', subfolder="scheduler")
34
- lcm_scheduler = LCMSingleStepScheduler.from_config(pipe.scheduler.config)
35
-
36
- # load aggregator weights
37
- pretrained_state_dict = torch.load('./models/aggregator.pt')
38
- pipe.aggregator.load_state_dict(pretrained_state_dict)
39
-
40
- # send to GPU and fp16
41
- pipe.to(dtype=torch.float16)
42
- pipe.to('cuda')
43
-
44
- return pipe, lcm_scheduler
45
-
46
- pipe, lcm_scheduler = initialize_pipeline()
47
-
48
- @spaces.GPU
49
- def process_image(input_image):
50
- if input_image is None:
51
- raise gr.Error("Please provide an image to restore.")
52
-
53
- # Convert to PIL Image
54
- pil_image = Image.fromarray(input_image)
55
-
56
- # Process image
57
- restored_image = pipe(
58
- prompt='',
59
- image=pil_image,
60
- ip_adapter_image=[pil_image],
61
- negative_prompt='',
62
- guidance_scale=7.0,
63
- previewer_scheduler=lcm_scheduler,
64
- return_dict=False,
65
- )[0]
66
-
67
- # Convert result to numpy array
68
- result_array = np.array(restored_image)
69
-
70
- return (input_image, result_array)
71
-
72
- title = """<h1 align="center">InstantIR Image Restoration</h1>
73
- <p><center>Restore and enhance your images</center></p>
74
- <p><center>
75
- <a href="https://huggingface.co/InstantX/InstantIR" target="_blank">[Model Page]</a>
76
- </center></p>
77
- """
78
-
79
- with gr.Blocks() as demo:
80
- gr.HTML(title)
81
-
82
- with gr.Row():
83
- with gr.Column(scale=1):
84
- input_image = gr.Image(label="Input Image", type="numpy")
85
- process_btn = gr.Button(value="Restore Image", variant="primary")
86
- with gr.Column(scale=1):
87
- output_slider = ImageSlider(label="Before / After", type="numpy")
88
-
89
- process_btn.click(
90
- fn=process_image,
91
- inputs=[input_image],
92
- outputs=output_slider
93
- )
94
-
95
- # Add examples
96
- gr.Examples(
97
- examples=[
98
- "examples/image1.jpg",
99
- "examples/image2.jpg"
100
- ],
101
- inputs=input_image,
102
- outputs=output_slider,
103
- fn=process_image,
104
- cache_examples=True,
105
- )
106
-
107
- demo.launch(debug=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/__init__.py DELETED
@@ -1,12 +0,0 @@
1
- # https://github.com/xinntao/BasicSR
2
- # flake8: noqa
3
- from .archs import *
4
- from .data import *
5
- from .losses import *
6
- from .metrics import *
7
- from .models import *
8
- from .ops import *
9
- from .test import *
10
- from .train import *
11
- from .utils import *
12
- # from .version import __gitsha__, __version__
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/__init__.py DELETED
@@ -1,24 +0,0 @@
1
- import importlib
2
- from copy import deepcopy
3
- from os import path as osp
4
-
5
- from basicsr.utils import get_root_logger, scandir
6
- from basicsr.utils.registry import ARCH_REGISTRY
7
-
8
- __all__ = ['build_network']
9
-
10
- # automatically scan and import arch modules for registry
11
- # scan all the files under the 'archs' folder and collect files ending with '_arch.py'
12
- arch_folder = osp.dirname(osp.abspath(__file__))
13
- arch_filenames = [osp.splitext(osp.basename(v))[0] for v in scandir(arch_folder) if v.endswith('_arch.py')]
14
- # import all the arch modules
15
- _arch_modules = [importlib.import_module(f'basicsr.archs.{file_name}') for file_name in arch_filenames]
16
-
17
-
18
- def build_network(opt):
19
- opt = deepcopy(opt)
20
- network_type = opt.pop('type')
21
- net = ARCH_REGISTRY.get(network_type)(**opt)
22
- logger = get_root_logger()
23
- logger.info(f'Network [{net.__class__.__name__}] is created.')
24
- return net
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/arch_util.py DELETED
@@ -1,313 +0,0 @@
1
- import collections.abc
2
- import math
3
- import torch
4
- import torchvision
5
- import warnings
6
- from distutils.version import LooseVersion
7
- from itertools import repeat
8
- from torch import nn as nn
9
- from torch.nn import functional as F
10
- from torch.nn import init as init
11
- from torch.nn.modules.batchnorm import _BatchNorm
12
-
13
- from basicsr.ops.dcn import ModulatedDeformConvPack, modulated_deform_conv
14
- from basicsr.utils import get_root_logger
15
-
16
-
17
- @torch.no_grad()
18
- def default_init_weights(module_list, scale=1, bias_fill=0, **kwargs):
19
- """Initialize network weights.
20
-
21
- Args:
22
- module_list (list[nn.Module] | nn.Module): Modules to be initialized.
23
- scale (float): Scale initialized weights, especially for residual
24
- blocks. Default: 1.
25
- bias_fill (float): The value to fill bias. Default: 0
26
- kwargs (dict): Other arguments for initialization function.
27
- """
28
- if not isinstance(module_list, list):
29
- module_list = [module_list]
30
- for module in module_list:
31
- for m in module.modules():
32
- if isinstance(m, nn.Conv2d):
33
- init.kaiming_normal_(m.weight, **kwargs)
34
- m.weight.data *= scale
35
- if m.bias is not None:
36
- m.bias.data.fill_(bias_fill)
37
- elif isinstance(m, nn.Linear):
38
- init.kaiming_normal_(m.weight, **kwargs)
39
- m.weight.data *= scale
40
- if m.bias is not None:
41
- m.bias.data.fill_(bias_fill)
42
- elif isinstance(m, _BatchNorm):
43
- init.constant_(m.weight, 1)
44
- if m.bias is not None:
45
- m.bias.data.fill_(bias_fill)
46
-
47
-
48
- def make_layer(basic_block, num_basic_block, **kwarg):
49
- """Make layers by stacking the same blocks.
50
-
51
- Args:
52
- basic_block (nn.module): nn.module class for basic block.
53
- num_basic_block (int): number of blocks.
54
-
55
- Returns:
56
- nn.Sequential: Stacked blocks in nn.Sequential.
57
- """
58
- layers = []
59
- for _ in range(num_basic_block):
60
- layers.append(basic_block(**kwarg))
61
- return nn.Sequential(*layers)
62
-
63
-
64
- class ResidualBlockNoBN(nn.Module):
65
- """Residual block without BN.
66
-
67
- Args:
68
- num_feat (int): Channel number of intermediate features.
69
- Default: 64.
70
- res_scale (float): Residual scale. Default: 1.
71
- pytorch_init (bool): If set to True, use pytorch default init,
72
- otherwise, use default_init_weights. Default: False.
73
- """
74
-
75
- def __init__(self, num_feat=64, res_scale=1, pytorch_init=False):
76
- super(ResidualBlockNoBN, self).__init__()
77
- self.res_scale = res_scale
78
- self.conv1 = nn.Conv2d(num_feat, num_feat, 3, 1, 1, bias=True)
79
- self.conv2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1, bias=True)
80
- self.relu = nn.ReLU(inplace=True)
81
-
82
- if not pytorch_init:
83
- default_init_weights([self.conv1, self.conv2], 0.1)
84
-
85
- def forward(self, x):
86
- identity = x
87
- out = self.conv2(self.relu(self.conv1(x)))
88
- return identity + out * self.res_scale
89
-
90
-
91
- class Upsample(nn.Sequential):
92
- """Upsample module.
93
-
94
- Args:
95
- scale (int): Scale factor. Supported scales: 2^n and 3.
96
- num_feat (int): Channel number of intermediate features.
97
- """
98
-
99
- def __init__(self, scale, num_feat):
100
- m = []
101
- if (scale & (scale - 1)) == 0: # scale = 2^n
102
- for _ in range(int(math.log(scale, 2))):
103
- m.append(nn.Conv2d(num_feat, 4 * num_feat, 3, 1, 1))
104
- m.append(nn.PixelShuffle(2))
105
- elif scale == 3:
106
- m.append(nn.Conv2d(num_feat, 9 * num_feat, 3, 1, 1))
107
- m.append(nn.PixelShuffle(3))
108
- else:
109
- raise ValueError(f'scale {scale} is not supported. Supported scales: 2^n and 3.')
110
- super(Upsample, self).__init__(*m)
111
-
112
-
113
- def flow_warp(x, flow, interp_mode='bilinear', padding_mode='zeros', align_corners=True):
114
- """Warp an image or feature map with optical flow.
115
-
116
- Args:
117
- x (Tensor): Tensor with size (n, c, h, w).
118
- flow (Tensor): Tensor with size (n, h, w, 2), normal value.
119
- interp_mode (str): 'nearest' or 'bilinear'. Default: 'bilinear'.
120
- padding_mode (str): 'zeros' or 'border' or 'reflection'.
121
- Default: 'zeros'.
122
- align_corners (bool): Before pytorch 1.3, the default value is
123
- align_corners=True. After pytorch 1.3, the default value is
124
- align_corners=False. Here, we use the True as default.
125
-
126
- Returns:
127
- Tensor: Warped image or feature map.
128
- """
129
- assert x.size()[-2:] == flow.size()[1:3]
130
- _, _, h, w = x.size()
131
- # create mesh grid
132
- grid_y, grid_x = torch.meshgrid(torch.arange(0, h).type_as(x), torch.arange(0, w).type_as(x))
133
- grid = torch.stack((grid_x, grid_y), 2).float() # W(x), H(y), 2
134
- grid.requires_grad = False
135
-
136
- vgrid = grid + flow
137
- # scale grid to [-1,1]
138
- vgrid_x = 2.0 * vgrid[:, :, :, 0] / max(w - 1, 1) - 1.0
139
- vgrid_y = 2.0 * vgrid[:, :, :, 1] / max(h - 1, 1) - 1.0
140
- vgrid_scaled = torch.stack((vgrid_x, vgrid_y), dim=3)
141
- output = F.grid_sample(x, vgrid_scaled, mode=interp_mode, padding_mode=padding_mode, align_corners=align_corners)
142
-
143
- # TODO, what if align_corners=False
144
- return output
145
-
146
-
147
- def resize_flow(flow, size_type, sizes, interp_mode='bilinear', align_corners=False):
148
- """Resize a flow according to ratio or shape.
149
-
150
- Args:
151
- flow (Tensor): Precomputed flow. shape [N, 2, H, W].
152
- size_type (str): 'ratio' or 'shape'.
153
- sizes (list[int | float]): the ratio for resizing or the final output
154
- shape.
155
- 1) The order of ratio should be [ratio_h, ratio_w]. For
156
- downsampling, the ratio should be smaller than 1.0 (i.e., ratio
157
- < 1.0). For upsampling, the ratio should be larger than 1.0 (i.e.,
158
- ratio > 1.0).
159
- 2) The order of output_size should be [out_h, out_w].
160
- interp_mode (str): The mode of interpolation for resizing.
161
- Default: 'bilinear'.
162
- align_corners (bool): Whether align corners. Default: False.
163
-
164
- Returns:
165
- Tensor: Resized flow.
166
- """
167
- _, _, flow_h, flow_w = flow.size()
168
- if size_type == 'ratio':
169
- output_h, output_w = int(flow_h * sizes[0]), int(flow_w * sizes[1])
170
- elif size_type == 'shape':
171
- output_h, output_w = sizes[0], sizes[1]
172
- else:
173
- raise ValueError(f'Size type should be ratio or shape, but got type {size_type}.')
174
-
175
- input_flow = flow.clone()
176
- ratio_h = output_h / flow_h
177
- ratio_w = output_w / flow_w
178
- input_flow[:, 0, :, :] *= ratio_w
179
- input_flow[:, 1, :, :] *= ratio_h
180
- resized_flow = F.interpolate(
181
- input=input_flow, size=(output_h, output_w), mode=interp_mode, align_corners=align_corners)
182
- return resized_flow
183
-
184
-
185
- # TODO: may write a cpp file
186
- def pixel_unshuffle(x, scale):
187
- """ Pixel unshuffle.
188
-
189
- Args:
190
- x (Tensor): Input feature with shape (b, c, hh, hw).
191
- scale (int): Downsample ratio.
192
-
193
- Returns:
194
- Tensor: the pixel unshuffled feature.
195
- """
196
- b, c, hh, hw = x.size()
197
- out_channel = c * (scale**2)
198
- assert hh % scale == 0 and hw % scale == 0
199
- h = hh // scale
200
- w = hw // scale
201
- x_view = x.view(b, c, h, scale, w, scale)
202
- return x_view.permute(0, 1, 3, 5, 2, 4).reshape(b, out_channel, h, w)
203
-
204
-
205
- class DCNv2Pack(ModulatedDeformConvPack):
206
- """Modulated deformable conv for deformable alignment.
207
-
208
- Different from the official DCNv2Pack, which generates offsets and masks
209
- from the preceding features, this DCNv2Pack takes another different
210
- features to generate offsets and masks.
211
-
212
- ``Paper: Delving Deep into Deformable Alignment in Video Super-Resolution``
213
- """
214
-
215
- def forward(self, x, feat):
216
- out = self.conv_offset(feat)
217
- o1, o2, mask = torch.chunk(out, 3, dim=1)
218
- offset = torch.cat((o1, o2), dim=1)
219
- mask = torch.sigmoid(mask)
220
-
221
- offset_absmean = torch.mean(torch.abs(offset))
222
- if offset_absmean > 50:
223
- logger = get_root_logger()
224
- logger.warning(f'Offset abs mean is {offset_absmean}, larger than 50.')
225
-
226
- if LooseVersion(torchvision.__version__) >= LooseVersion('0.9.0'):
227
- return torchvision.ops.deform_conv2d(x, offset, self.weight, self.bias, self.stride, self.padding,
228
- self.dilation, mask)
229
- else:
230
- return modulated_deform_conv(x, offset, mask, self.weight, self.bias, self.stride, self.padding,
231
- self.dilation, self.groups, self.deformable_groups)
232
-
233
-
234
- def _no_grad_trunc_normal_(tensor, mean, std, a, b):
235
- # From: https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/layers/weight_init.py
236
- # Cut & paste from PyTorch official master until it's in a few official releases - RW
237
- # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf
238
- def norm_cdf(x):
239
- # Computes standard normal cumulative distribution function
240
- return (1. + math.erf(x / math.sqrt(2.))) / 2.
241
-
242
- if (mean < a - 2 * std) or (mean > b + 2 * std):
243
- warnings.warn(
244
- 'mean is more than 2 std from [a, b] in nn.init.trunc_normal_. '
245
- 'The distribution of values may be incorrect.',
246
- stacklevel=2)
247
-
248
- with torch.no_grad():
249
- # Values are generated by using a truncated uniform distribution and
250
- # then using the inverse CDF for the normal distribution.
251
- # Get upper and lower cdf values
252
- low = norm_cdf((a - mean) / std)
253
- up = norm_cdf((b - mean) / std)
254
-
255
- # Uniformly fill tensor with values from [low, up], then translate to
256
- # [2l-1, 2u-1].
257
- tensor.uniform_(2 * low - 1, 2 * up - 1)
258
-
259
- # Use inverse cdf transform for normal distribution to get truncated
260
- # standard normal
261
- tensor.erfinv_()
262
-
263
- # Transform to proper mean, std
264
- tensor.mul_(std * math.sqrt(2.))
265
- tensor.add_(mean)
266
-
267
- # Clamp to ensure it's in the proper range
268
- tensor.clamp_(min=a, max=b)
269
- return tensor
270
-
271
-
272
- def trunc_normal_(tensor, mean=0., std=1., a=-2., b=2.):
273
- r"""Fills the input Tensor with values drawn from a truncated
274
- normal distribution.
275
-
276
- From: https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/layers/weight_init.py
277
-
278
- The values are effectively drawn from the
279
- normal distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)`
280
- with values outside :math:`[a, b]` redrawn until they are within
281
- the bounds. The method used for generating the random values works
282
- best when :math:`a \leq \text{mean} \leq b`.
283
-
284
- Args:
285
- tensor: an n-dimensional `torch.Tensor`
286
- mean: the mean of the normal distribution
287
- std: the standard deviation of the normal distribution
288
- a: the minimum cutoff value
289
- b: the maximum cutoff value
290
-
291
- Examples:
292
- >>> w = torch.empty(3, 5)
293
- >>> nn.init.trunc_normal_(w)
294
- """
295
- return _no_grad_trunc_normal_(tensor, mean, std, a, b)
296
-
297
-
298
- # From PyTorch
299
- def _ntuple(n):
300
-
301
- def parse(x):
302
- if isinstance(x, collections.abc.Iterable):
303
- return x
304
- return tuple(repeat(x, n))
305
-
306
- return parse
307
-
308
-
309
- to_1tuple = _ntuple(1)
310
- to_2tuple = _ntuple(2)
311
- to_3tuple = _ntuple(3)
312
- to_4tuple = _ntuple(4)
313
- to_ntuple = _ntuple
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/basicvsr_arch.py DELETED
@@ -1,336 +0,0 @@
1
- import torch
2
- from torch import nn as nn
3
- from torch.nn import functional as F
4
-
5
- from basicsr.utils.registry import ARCH_REGISTRY
6
- from .arch_util import ResidualBlockNoBN, flow_warp, make_layer
7
- from .edvr_arch import PCDAlignment, TSAFusion
8
- from .spynet_arch import SpyNet
9
-
10
-
11
- @ARCH_REGISTRY.register()
12
- class BasicVSR(nn.Module):
13
- """A recurrent network for video SR. Now only x4 is supported.
14
-
15
- Args:
16
- num_feat (int): Number of channels. Default: 64.
17
- num_block (int): Number of residual blocks for each branch. Default: 15
18
- spynet_path (str): Path to the pretrained weights of SPyNet. Default: None.
19
- """
20
-
21
- def __init__(self, num_feat=64, num_block=15, spynet_path=None):
22
- super().__init__()
23
- self.num_feat = num_feat
24
-
25
- # alignment
26
- self.spynet = SpyNet(spynet_path)
27
-
28
- # propagation
29
- self.backward_trunk = ConvResidualBlocks(num_feat + 3, num_feat, num_block)
30
- self.forward_trunk = ConvResidualBlocks(num_feat + 3, num_feat, num_block)
31
-
32
- # reconstruction
33
- self.fusion = nn.Conv2d(num_feat * 2, num_feat, 1, 1, 0, bias=True)
34
- self.upconv1 = nn.Conv2d(num_feat, num_feat * 4, 3, 1, 1, bias=True)
35
- self.upconv2 = nn.Conv2d(num_feat, 64 * 4, 3, 1, 1, bias=True)
36
- self.conv_hr = nn.Conv2d(64, 64, 3, 1, 1)
37
- self.conv_last = nn.Conv2d(64, 3, 3, 1, 1)
38
-
39
- self.pixel_shuffle = nn.PixelShuffle(2)
40
-
41
- # activation functions
42
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
43
-
44
- def get_flow(self, x):
45
- b, n, c, h, w = x.size()
46
-
47
- x_1 = x[:, :-1, :, :, :].reshape(-1, c, h, w)
48
- x_2 = x[:, 1:, :, :, :].reshape(-1, c, h, w)
49
-
50
- flows_backward = self.spynet(x_1, x_2).view(b, n - 1, 2, h, w)
51
- flows_forward = self.spynet(x_2, x_1).view(b, n - 1, 2, h, w)
52
-
53
- return flows_forward, flows_backward
54
-
55
- def forward(self, x):
56
- """Forward function of BasicVSR.
57
-
58
- Args:
59
- x: Input frames with shape (b, n, c, h, w). n is the temporal dimension / number of frames.
60
- """
61
- flows_forward, flows_backward = self.get_flow(x)
62
- b, n, _, h, w = x.size()
63
-
64
- # backward branch
65
- out_l = []
66
- feat_prop = x.new_zeros(b, self.num_feat, h, w)
67
- for i in range(n - 1, -1, -1):
68
- x_i = x[:, i, :, :, :]
69
- if i < n - 1:
70
- flow = flows_backward[:, i, :, :, :]
71
- feat_prop = flow_warp(feat_prop, flow.permute(0, 2, 3, 1))
72
- feat_prop = torch.cat([x_i, feat_prop], dim=1)
73
- feat_prop = self.backward_trunk(feat_prop)
74
- out_l.insert(0, feat_prop)
75
-
76
- # forward branch
77
- feat_prop = torch.zeros_like(feat_prop)
78
- for i in range(0, n):
79
- x_i = x[:, i, :, :, :]
80
- if i > 0:
81
- flow = flows_forward[:, i - 1, :, :, :]
82
- feat_prop = flow_warp(feat_prop, flow.permute(0, 2, 3, 1))
83
-
84
- feat_prop = torch.cat([x_i, feat_prop], dim=1)
85
- feat_prop = self.forward_trunk(feat_prop)
86
-
87
- # upsample
88
- out = torch.cat([out_l[i], feat_prop], dim=1)
89
- out = self.lrelu(self.fusion(out))
90
- out = self.lrelu(self.pixel_shuffle(self.upconv1(out)))
91
- out = self.lrelu(self.pixel_shuffle(self.upconv2(out)))
92
- out = self.lrelu(self.conv_hr(out))
93
- out = self.conv_last(out)
94
- base = F.interpolate(x_i, scale_factor=4, mode='bilinear', align_corners=False)
95
- out += base
96
- out_l[i] = out
97
-
98
- return torch.stack(out_l, dim=1)
99
-
100
-
101
- class ConvResidualBlocks(nn.Module):
102
- """Conv and residual block used in BasicVSR.
103
-
104
- Args:
105
- num_in_ch (int): Number of input channels. Default: 3.
106
- num_out_ch (int): Number of output channels. Default: 64.
107
- num_block (int): Number of residual blocks. Default: 15.
108
- """
109
-
110
- def __init__(self, num_in_ch=3, num_out_ch=64, num_block=15):
111
- super().__init__()
112
- self.main = nn.Sequential(
113
- nn.Conv2d(num_in_ch, num_out_ch, 3, 1, 1, bias=True), nn.LeakyReLU(negative_slope=0.1, inplace=True),
114
- make_layer(ResidualBlockNoBN, num_block, num_feat=num_out_ch))
115
-
116
- def forward(self, fea):
117
- return self.main(fea)
118
-
119
-
120
- @ARCH_REGISTRY.register()
121
- class IconVSR(nn.Module):
122
- """IconVSR, proposed also in the BasicVSR paper.
123
-
124
- Args:
125
- num_feat (int): Number of channels. Default: 64.
126
- num_block (int): Number of residual blocks for each branch. Default: 15.
127
- keyframe_stride (int): Keyframe stride. Default: 5.
128
- temporal_padding (int): Temporal padding. Default: 2.
129
- spynet_path (str): Path to the pretrained weights of SPyNet. Default: None.
130
- edvr_path (str): Path to the pretrained EDVR model. Default: None.
131
- """
132
-
133
- def __init__(self,
134
- num_feat=64,
135
- num_block=15,
136
- keyframe_stride=5,
137
- temporal_padding=2,
138
- spynet_path=None,
139
- edvr_path=None):
140
- super().__init__()
141
-
142
- self.num_feat = num_feat
143
- self.temporal_padding = temporal_padding
144
- self.keyframe_stride = keyframe_stride
145
-
146
- # keyframe_branch
147
- self.edvr = EDVRFeatureExtractor(temporal_padding * 2 + 1, num_feat, edvr_path)
148
- # alignment
149
- self.spynet = SpyNet(spynet_path)
150
-
151
- # propagation
152
- self.backward_fusion = nn.Conv2d(2 * num_feat, num_feat, 3, 1, 1, bias=True)
153
- self.backward_trunk = ConvResidualBlocks(num_feat + 3, num_feat, num_block)
154
-
155
- self.forward_fusion = nn.Conv2d(2 * num_feat, num_feat, 3, 1, 1, bias=True)
156
- self.forward_trunk = ConvResidualBlocks(2 * num_feat + 3, num_feat, num_block)
157
-
158
- # reconstruction
159
- self.upconv1 = nn.Conv2d(num_feat, num_feat * 4, 3, 1, 1, bias=True)
160
- self.upconv2 = nn.Conv2d(num_feat, 64 * 4, 3, 1, 1, bias=True)
161
- self.conv_hr = nn.Conv2d(64, 64, 3, 1, 1)
162
- self.conv_last = nn.Conv2d(64, 3, 3, 1, 1)
163
-
164
- self.pixel_shuffle = nn.PixelShuffle(2)
165
-
166
- # activation functions
167
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
168
-
169
- def pad_spatial(self, x):
170
- """Apply padding spatially.
171
-
172
- Since the PCD module in EDVR requires that the resolution is a multiple
173
- of 4, we apply padding to the input LR images if their resolution is
174
- not divisible by 4.
175
-
176
- Args:
177
- x (Tensor): Input LR sequence with shape (n, t, c, h, w).
178
- Returns:
179
- Tensor: Padded LR sequence with shape (n, t, c, h_pad, w_pad).
180
- """
181
- n, t, c, h, w = x.size()
182
-
183
- pad_h = (4 - h % 4) % 4
184
- pad_w = (4 - w % 4) % 4
185
-
186
- # padding
187
- x = x.view(-1, c, h, w)
188
- x = F.pad(x, [0, pad_w, 0, pad_h], mode='reflect')
189
-
190
- return x.view(n, t, c, h + pad_h, w + pad_w)
191
-
192
- def get_flow(self, x):
193
- b, n, c, h, w = x.size()
194
-
195
- x_1 = x[:, :-1, :, :, :].reshape(-1, c, h, w)
196
- x_2 = x[:, 1:, :, :, :].reshape(-1, c, h, w)
197
-
198
- flows_backward = self.spynet(x_1, x_2).view(b, n - 1, 2, h, w)
199
- flows_forward = self.spynet(x_2, x_1).view(b, n - 1, 2, h, w)
200
-
201
- return flows_forward, flows_backward
202
-
203
- def get_keyframe_feature(self, x, keyframe_idx):
204
- if self.temporal_padding == 2:
205
- x = [x[:, [4, 3]], x, x[:, [-4, -5]]]
206
- elif self.temporal_padding == 3:
207
- x = [x[:, [6, 5, 4]], x, x[:, [-5, -6, -7]]]
208
- x = torch.cat(x, dim=1)
209
-
210
- num_frames = 2 * self.temporal_padding + 1
211
- feats_keyframe = {}
212
- for i in keyframe_idx:
213
- feats_keyframe[i] = self.edvr(x[:, i:i + num_frames].contiguous())
214
- return feats_keyframe
215
-
216
- def forward(self, x):
217
- b, n, _, h_input, w_input = x.size()
218
-
219
- x = self.pad_spatial(x)
220
- h, w = x.shape[3:]
221
-
222
- keyframe_idx = list(range(0, n, self.keyframe_stride))
223
- if keyframe_idx[-1] != n - 1:
224
- keyframe_idx.append(n - 1) # last frame is a keyframe
225
-
226
- # compute flow and keyframe features
227
- flows_forward, flows_backward = self.get_flow(x)
228
- feats_keyframe = self.get_keyframe_feature(x, keyframe_idx)
229
-
230
- # backward branch
231
- out_l = []
232
- feat_prop = x.new_zeros(b, self.num_feat, h, w)
233
- for i in range(n - 1, -1, -1):
234
- x_i = x[:, i, :, :, :]
235
- if i < n - 1:
236
- flow = flows_backward[:, i, :, :, :]
237
- feat_prop = flow_warp(feat_prop, flow.permute(0, 2, 3, 1))
238
- if i in keyframe_idx:
239
- feat_prop = torch.cat([feat_prop, feats_keyframe[i]], dim=1)
240
- feat_prop = self.backward_fusion(feat_prop)
241
- feat_prop = torch.cat([x_i, feat_prop], dim=1)
242
- feat_prop = self.backward_trunk(feat_prop)
243
- out_l.insert(0, feat_prop)
244
-
245
- # forward branch
246
- feat_prop = torch.zeros_like(feat_prop)
247
- for i in range(0, n):
248
- x_i = x[:, i, :, :, :]
249
- if i > 0:
250
- flow = flows_forward[:, i - 1, :, :, :]
251
- feat_prop = flow_warp(feat_prop, flow.permute(0, 2, 3, 1))
252
- if i in keyframe_idx:
253
- feat_prop = torch.cat([feat_prop, feats_keyframe[i]], dim=1)
254
- feat_prop = self.forward_fusion(feat_prop)
255
-
256
- feat_prop = torch.cat([x_i, out_l[i], feat_prop], dim=1)
257
- feat_prop = self.forward_trunk(feat_prop)
258
-
259
- # upsample
260
- out = self.lrelu(self.pixel_shuffle(self.upconv1(feat_prop)))
261
- out = self.lrelu(self.pixel_shuffle(self.upconv2(out)))
262
- out = self.lrelu(self.conv_hr(out))
263
- out = self.conv_last(out)
264
- base = F.interpolate(x_i, scale_factor=4, mode='bilinear', align_corners=False)
265
- out += base
266
- out_l[i] = out
267
-
268
- return torch.stack(out_l, dim=1)[..., :4 * h_input, :4 * w_input]
269
-
270
-
271
- class EDVRFeatureExtractor(nn.Module):
272
- """EDVR feature extractor used in IconVSR.
273
-
274
- Args:
275
- num_input_frame (int): Number of input frames.
276
- num_feat (int): Number of feature channels
277
- load_path (str): Path to the pretrained weights of EDVR. Default: None.
278
- """
279
-
280
- def __init__(self, num_input_frame, num_feat, load_path):
281
-
282
- super(EDVRFeatureExtractor, self).__init__()
283
-
284
- self.center_frame_idx = num_input_frame // 2
285
-
286
- # extract pyramid features
287
- self.conv_first = nn.Conv2d(3, num_feat, 3, 1, 1)
288
- self.feature_extraction = make_layer(ResidualBlockNoBN, 5, num_feat=num_feat)
289
- self.conv_l2_1 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
290
- self.conv_l2_2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
291
- self.conv_l3_1 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
292
- self.conv_l3_2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
293
-
294
- # pcd and tsa module
295
- self.pcd_align = PCDAlignment(num_feat=num_feat, deformable_groups=8)
296
- self.fusion = TSAFusion(num_feat=num_feat, num_frame=num_input_frame, center_frame_idx=self.center_frame_idx)
297
-
298
- # activation function
299
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
300
-
301
- if load_path:
302
- self.load_state_dict(torch.load(load_path, map_location=lambda storage, loc: storage)['params'])
303
-
304
- def forward(self, x):
305
- b, n, c, h, w = x.size()
306
-
307
- # extract features for each frame
308
- # L1
309
- feat_l1 = self.lrelu(self.conv_first(x.view(-1, c, h, w)))
310
- feat_l1 = self.feature_extraction(feat_l1)
311
- # L2
312
- feat_l2 = self.lrelu(self.conv_l2_1(feat_l1))
313
- feat_l2 = self.lrelu(self.conv_l2_2(feat_l2))
314
- # L3
315
- feat_l3 = self.lrelu(self.conv_l3_1(feat_l2))
316
- feat_l3 = self.lrelu(self.conv_l3_2(feat_l3))
317
-
318
- feat_l1 = feat_l1.view(b, n, -1, h, w)
319
- feat_l2 = feat_l2.view(b, n, -1, h // 2, w // 2)
320
- feat_l3 = feat_l3.view(b, n, -1, h // 4, w // 4)
321
-
322
- # PCD alignment
323
- ref_feat_l = [ # reference feature list
324
- feat_l1[:, self.center_frame_idx, :, :, :].clone(), feat_l2[:, self.center_frame_idx, :, :, :].clone(),
325
- feat_l3[:, self.center_frame_idx, :, :, :].clone()
326
- ]
327
- aligned_feat = []
328
- for i in range(n):
329
- nbr_feat_l = [ # neighboring feature list
330
- feat_l1[:, i, :, :, :].clone(), feat_l2[:, i, :, :, :].clone(), feat_l3[:, i, :, :, :].clone()
331
- ]
332
- aligned_feat.append(self.pcd_align(nbr_feat_l, ref_feat_l))
333
- aligned_feat = torch.stack(aligned_feat, dim=1) # (b, t, c, h, w)
334
-
335
- # TSA fusion
336
- return self.fusion(aligned_feat)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/basicvsrpp_arch.py DELETED
@@ -1,417 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.nn.functional as F
4
- import torchvision
5
- import warnings
6
-
7
- from basicsr.archs.arch_util import flow_warp
8
- from basicsr.archs.basicvsr_arch import ConvResidualBlocks
9
- from basicsr.archs.spynet_arch import SpyNet
10
- from basicsr.ops.dcn import ModulatedDeformConvPack
11
- from basicsr.utils.registry import ARCH_REGISTRY
12
-
13
-
14
- @ARCH_REGISTRY.register()
15
- class BasicVSRPlusPlus(nn.Module):
16
- """BasicVSR++ network structure.
17
-
18
- Support either x4 upsampling or same size output. Since DCN is used in this
19
- model, it can only be used with CUDA enabled. If CUDA is not enabled,
20
- feature alignment will be skipped. Besides, we adopt the official DCN
21
- implementation and the version of torch need to be higher than 1.9.
22
-
23
- ``Paper: BasicVSR++: Improving Video Super-Resolution with Enhanced Propagation and Alignment``
24
-
25
- Args:
26
- mid_channels (int, optional): Channel number of the intermediate
27
- features. Default: 64.
28
- num_blocks (int, optional): The number of residual blocks in each
29
- propagation branch. Default: 7.
30
- max_residue_magnitude (int): The maximum magnitude of the offset
31
- residue (Eq. 6 in paper). Default: 10.
32
- is_low_res_input (bool, optional): Whether the input is low-resolution
33
- or not. If False, the output resolution is equal to the input
34
- resolution. Default: True.
35
- spynet_path (str): Path to the pretrained weights of SPyNet. Default: None.
36
- cpu_cache_length (int, optional): When the length of sequence is larger
37
- than this value, the intermediate features are sent to CPU. This
38
- saves GPU memory, but slows down the inference speed. You can
39
- increase this number if you have a GPU with large memory.
40
- Default: 100.
41
- """
42
-
43
- def __init__(self,
44
- mid_channels=64,
45
- num_blocks=7,
46
- max_residue_magnitude=10,
47
- is_low_res_input=True,
48
- spynet_path=None,
49
- cpu_cache_length=100):
50
-
51
- super().__init__()
52
- self.mid_channels = mid_channels
53
- self.is_low_res_input = is_low_res_input
54
- self.cpu_cache_length = cpu_cache_length
55
-
56
- # optical flow
57
- self.spynet = SpyNet(spynet_path)
58
-
59
- # feature extraction module
60
- if is_low_res_input:
61
- self.feat_extract = ConvResidualBlocks(3, mid_channels, 5)
62
- else:
63
- self.feat_extract = nn.Sequential(
64
- nn.Conv2d(3, mid_channels, 3, 2, 1), nn.LeakyReLU(negative_slope=0.1, inplace=True),
65
- nn.Conv2d(mid_channels, mid_channels, 3, 2, 1), nn.LeakyReLU(negative_slope=0.1, inplace=True),
66
- ConvResidualBlocks(mid_channels, mid_channels, 5))
67
-
68
- # propagation branches
69
- self.deform_align = nn.ModuleDict()
70
- self.backbone = nn.ModuleDict()
71
- modules = ['backward_1', 'forward_1', 'backward_2', 'forward_2']
72
- for i, module in enumerate(modules):
73
- if torch.cuda.is_available():
74
- self.deform_align[module] = SecondOrderDeformableAlignment(
75
- 2 * mid_channels,
76
- mid_channels,
77
- 3,
78
- padding=1,
79
- deformable_groups=16,
80
- max_residue_magnitude=max_residue_magnitude)
81
- self.backbone[module] = ConvResidualBlocks((2 + i) * mid_channels, mid_channels, num_blocks)
82
-
83
- # upsampling module
84
- self.reconstruction = ConvResidualBlocks(5 * mid_channels, mid_channels, 5)
85
-
86
- self.upconv1 = nn.Conv2d(mid_channels, mid_channels * 4, 3, 1, 1, bias=True)
87
- self.upconv2 = nn.Conv2d(mid_channels, 64 * 4, 3, 1, 1, bias=True)
88
-
89
- self.pixel_shuffle = nn.PixelShuffle(2)
90
-
91
- self.conv_hr = nn.Conv2d(64, 64, 3, 1, 1)
92
- self.conv_last = nn.Conv2d(64, 3, 3, 1, 1)
93
- self.img_upsample = nn.Upsample(scale_factor=4, mode='bilinear', align_corners=False)
94
-
95
- # activation function
96
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
97
-
98
- # check if the sequence is augmented by flipping
99
- self.is_mirror_extended = False
100
-
101
- if len(self.deform_align) > 0:
102
- self.is_with_alignment = True
103
- else:
104
- self.is_with_alignment = False
105
- warnings.warn('Deformable alignment module is not added. '
106
- 'Probably your CUDA is not configured correctly. DCN can only '
107
- 'be used with CUDA enabled. Alignment is skipped now.')
108
-
109
- def check_if_mirror_extended(self, lqs):
110
- """Check whether the input is a mirror-extended sequence.
111
-
112
- If mirror-extended, the i-th (i=0, ..., t-1) frame is equal to the (t-1-i)-th frame.
113
-
114
- Args:
115
- lqs (tensor): Input low quality (LQ) sequence with shape (n, t, c, h, w).
116
- """
117
-
118
- if lqs.size(1) % 2 == 0:
119
- lqs_1, lqs_2 = torch.chunk(lqs, 2, dim=1)
120
- if torch.norm(lqs_1 - lqs_2.flip(1)) == 0:
121
- self.is_mirror_extended = True
122
-
123
- def compute_flow(self, lqs):
124
- """Compute optical flow using SPyNet for feature alignment.
125
-
126
- Note that if the input is an mirror-extended sequence, 'flows_forward'
127
- is not needed, since it is equal to 'flows_backward.flip(1)'.
128
-
129
- Args:
130
- lqs (tensor): Input low quality (LQ) sequence with
131
- shape (n, t, c, h, w).
132
-
133
- Return:
134
- tuple(Tensor): Optical flow. 'flows_forward' corresponds to the flows used for forward-time propagation \
135
- (current to previous). 'flows_backward' corresponds to the flows used for backward-time \
136
- propagation (current to next).
137
- """
138
-
139
- n, t, c, h, w = lqs.size()
140
- lqs_1 = lqs[:, :-1, :, :, :].reshape(-1, c, h, w)
141
- lqs_2 = lqs[:, 1:, :, :, :].reshape(-1, c, h, w)
142
-
143
- flows_backward = self.spynet(lqs_1, lqs_2).view(n, t - 1, 2, h, w)
144
-
145
- if self.is_mirror_extended: # flows_forward = flows_backward.flip(1)
146
- flows_forward = flows_backward.flip(1)
147
- else:
148
- flows_forward = self.spynet(lqs_2, lqs_1).view(n, t - 1, 2, h, w)
149
-
150
- if self.cpu_cache:
151
- flows_backward = flows_backward.cpu()
152
- flows_forward = flows_forward.cpu()
153
-
154
- return flows_forward, flows_backward
155
-
156
- def propagate(self, feats, flows, module_name):
157
- """Propagate the latent features throughout the sequence.
158
-
159
- Args:
160
- feats dict(list[tensor]): Features from previous branches. Each
161
- component is a list of tensors with shape (n, c, h, w).
162
- flows (tensor): Optical flows with shape (n, t - 1, 2, h, w).
163
- module_name (str): The name of the propgation branches. Can either
164
- be 'backward_1', 'forward_1', 'backward_2', 'forward_2'.
165
-
166
- Return:
167
- dict(list[tensor]): A dictionary containing all the propagated \
168
- features. Each key in the dictionary corresponds to a \
169
- propagation branch, which is represented by a list of tensors.
170
- """
171
-
172
- n, t, _, h, w = flows.size()
173
-
174
- frame_idx = range(0, t + 1)
175
- flow_idx = range(-1, t)
176
- mapping_idx = list(range(0, len(feats['spatial'])))
177
- mapping_idx += mapping_idx[::-1]
178
-
179
- if 'backward' in module_name:
180
- frame_idx = frame_idx[::-1]
181
- flow_idx = frame_idx
182
-
183
- feat_prop = flows.new_zeros(n, self.mid_channels, h, w)
184
- for i, idx in enumerate(frame_idx):
185
- feat_current = feats['spatial'][mapping_idx[idx]]
186
- if self.cpu_cache:
187
- feat_current = feat_current.cuda()
188
- feat_prop = feat_prop.cuda()
189
- # second-order deformable alignment
190
- if i > 0 and self.is_with_alignment:
191
- flow_n1 = flows[:, flow_idx[i], :, :, :]
192
- if self.cpu_cache:
193
- flow_n1 = flow_n1.cuda()
194
-
195
- cond_n1 = flow_warp(feat_prop, flow_n1.permute(0, 2, 3, 1))
196
-
197
- # initialize second-order features
198
- feat_n2 = torch.zeros_like(feat_prop)
199
- flow_n2 = torch.zeros_like(flow_n1)
200
- cond_n2 = torch.zeros_like(cond_n1)
201
-
202
- if i > 1: # second-order features
203
- feat_n2 = feats[module_name][-2]
204
- if self.cpu_cache:
205
- feat_n2 = feat_n2.cuda()
206
-
207
- flow_n2 = flows[:, flow_idx[i - 1], :, :, :]
208
- if self.cpu_cache:
209
- flow_n2 = flow_n2.cuda()
210
-
211
- flow_n2 = flow_n1 + flow_warp(flow_n2, flow_n1.permute(0, 2, 3, 1))
212
- cond_n2 = flow_warp(feat_n2, flow_n2.permute(0, 2, 3, 1))
213
-
214
- # flow-guided deformable convolution
215
- cond = torch.cat([cond_n1, feat_current, cond_n2], dim=1)
216
- feat_prop = torch.cat([feat_prop, feat_n2], dim=1)
217
- feat_prop = self.deform_align[module_name](feat_prop, cond, flow_n1, flow_n2)
218
-
219
- # concatenate and residual blocks
220
- feat = [feat_current] + [feats[k][idx] for k in feats if k not in ['spatial', module_name]] + [feat_prop]
221
- if self.cpu_cache:
222
- feat = [f.cuda() for f in feat]
223
-
224
- feat = torch.cat(feat, dim=1)
225
- feat_prop = feat_prop + self.backbone[module_name](feat)
226
- feats[module_name].append(feat_prop)
227
-
228
- if self.cpu_cache:
229
- feats[module_name][-1] = feats[module_name][-1].cpu()
230
- torch.cuda.empty_cache()
231
-
232
- if 'backward' in module_name:
233
- feats[module_name] = feats[module_name][::-1]
234
-
235
- return feats
236
-
237
- def upsample(self, lqs, feats):
238
- """Compute the output image given the features.
239
-
240
- Args:
241
- lqs (tensor): Input low quality (LQ) sequence with
242
- shape (n, t, c, h, w).
243
- feats (dict): The features from the propagation branches.
244
-
245
- Returns:
246
- Tensor: Output HR sequence with shape (n, t, c, 4h, 4w).
247
- """
248
-
249
- outputs = []
250
- num_outputs = len(feats['spatial'])
251
-
252
- mapping_idx = list(range(0, num_outputs))
253
- mapping_idx += mapping_idx[::-1]
254
-
255
- for i in range(0, lqs.size(1)):
256
- hr = [feats[k].pop(0) for k in feats if k != 'spatial']
257
- hr.insert(0, feats['spatial'][mapping_idx[i]])
258
- hr = torch.cat(hr, dim=1)
259
- if self.cpu_cache:
260
- hr = hr.cuda()
261
-
262
- hr = self.reconstruction(hr)
263
- hr = self.lrelu(self.pixel_shuffle(self.upconv1(hr)))
264
- hr = self.lrelu(self.pixel_shuffle(self.upconv2(hr)))
265
- hr = self.lrelu(self.conv_hr(hr))
266
- hr = self.conv_last(hr)
267
- if self.is_low_res_input:
268
- hr += self.img_upsample(lqs[:, i, :, :, :])
269
- else:
270
- hr += lqs[:, i, :, :, :]
271
-
272
- if self.cpu_cache:
273
- hr = hr.cpu()
274
- torch.cuda.empty_cache()
275
-
276
- outputs.append(hr)
277
-
278
- return torch.stack(outputs, dim=1)
279
-
280
- def forward(self, lqs):
281
- """Forward function for BasicVSR++.
282
-
283
- Args:
284
- lqs (tensor): Input low quality (LQ) sequence with
285
- shape (n, t, c, h, w).
286
-
287
- Returns:
288
- Tensor: Output HR sequence with shape (n, t, c, 4h, 4w).
289
- """
290
-
291
- n, t, c, h, w = lqs.size()
292
-
293
- # whether to cache the features in CPU
294
- self.cpu_cache = True if t > self.cpu_cache_length else False
295
-
296
- if self.is_low_res_input:
297
- lqs_downsample = lqs.clone()
298
- else:
299
- lqs_downsample = F.interpolate(
300
- lqs.view(-1, c, h, w), scale_factor=0.25, mode='bicubic').view(n, t, c, h // 4, w // 4)
301
-
302
- # check whether the input is an extended sequence
303
- self.check_if_mirror_extended(lqs)
304
-
305
- feats = {}
306
- # compute spatial features
307
- if self.cpu_cache:
308
- feats['spatial'] = []
309
- for i in range(0, t):
310
- feat = self.feat_extract(lqs[:, i, :, :, :]).cpu()
311
- feats['spatial'].append(feat)
312
- torch.cuda.empty_cache()
313
- else:
314
- feats_ = self.feat_extract(lqs.view(-1, c, h, w))
315
- h, w = feats_.shape[2:]
316
- feats_ = feats_.view(n, t, -1, h, w)
317
- feats['spatial'] = [feats_[:, i, :, :, :] for i in range(0, t)]
318
-
319
- # compute optical flow using the low-res inputs
320
- assert lqs_downsample.size(3) >= 64 and lqs_downsample.size(4) >= 64, (
321
- 'The height and width of low-res inputs must be at least 64, '
322
- f'but got {h} and {w}.')
323
- flows_forward, flows_backward = self.compute_flow(lqs_downsample)
324
-
325
- # feature propgation
326
- for iter_ in [1, 2]:
327
- for direction in ['backward', 'forward']:
328
- module = f'{direction}_{iter_}'
329
-
330
- feats[module] = []
331
-
332
- if direction == 'backward':
333
- flows = flows_backward
334
- elif flows_forward is not None:
335
- flows = flows_forward
336
- else:
337
- flows = flows_backward.flip(1)
338
-
339
- feats = self.propagate(feats, flows, module)
340
- if self.cpu_cache:
341
- del flows
342
- torch.cuda.empty_cache()
343
-
344
- return self.upsample(lqs, feats)
345
-
346
-
347
- class SecondOrderDeformableAlignment(ModulatedDeformConvPack):
348
- """Second-order deformable alignment module.
349
-
350
- Args:
351
- in_channels (int): Same as nn.Conv2d.
352
- out_channels (int): Same as nn.Conv2d.
353
- kernel_size (int or tuple[int]): Same as nn.Conv2d.
354
- stride (int or tuple[int]): Same as nn.Conv2d.
355
- padding (int or tuple[int]): Same as nn.Conv2d.
356
- dilation (int or tuple[int]): Same as nn.Conv2d.
357
- groups (int): Same as nn.Conv2d.
358
- bias (bool or str): If specified as `auto`, it will be decided by the
359
- norm_cfg. Bias will be set as True if norm_cfg is None, otherwise
360
- False.
361
- max_residue_magnitude (int): The maximum magnitude of the offset
362
- residue (Eq. 6 in paper). Default: 10.
363
- """
364
-
365
- def __init__(self, *args, **kwargs):
366
- self.max_residue_magnitude = kwargs.pop('max_residue_magnitude', 10)
367
-
368
- super(SecondOrderDeformableAlignment, self).__init__(*args, **kwargs)
369
-
370
- self.conv_offset = nn.Sequential(
371
- nn.Conv2d(3 * self.out_channels + 4, self.out_channels, 3, 1, 1),
372
- nn.LeakyReLU(negative_slope=0.1, inplace=True),
373
- nn.Conv2d(self.out_channels, self.out_channels, 3, 1, 1),
374
- nn.LeakyReLU(negative_slope=0.1, inplace=True),
375
- nn.Conv2d(self.out_channels, self.out_channels, 3, 1, 1),
376
- nn.LeakyReLU(negative_slope=0.1, inplace=True),
377
- nn.Conv2d(self.out_channels, 27 * self.deformable_groups, 3, 1, 1),
378
- )
379
-
380
- self.init_offset()
381
-
382
- def init_offset(self):
383
-
384
- def _constant_init(module, val, bias=0):
385
- if hasattr(module, 'weight') and module.weight is not None:
386
- nn.init.constant_(module.weight, val)
387
- if hasattr(module, 'bias') and module.bias is not None:
388
- nn.init.constant_(module.bias, bias)
389
-
390
- _constant_init(self.conv_offset[-1], val=0, bias=0)
391
-
392
- def forward(self, x, extra_feat, flow_1, flow_2):
393
- extra_feat = torch.cat([extra_feat, flow_1, flow_2], dim=1)
394
- out = self.conv_offset(extra_feat)
395
- o1, o2, mask = torch.chunk(out, 3, dim=1)
396
-
397
- # offset
398
- offset = self.max_residue_magnitude * torch.tanh(torch.cat((o1, o2), dim=1))
399
- offset_1, offset_2 = torch.chunk(offset, 2, dim=1)
400
- offset_1 = offset_1 + flow_1.flip(1).repeat(1, offset_1.size(1) // 2, 1, 1)
401
- offset_2 = offset_2 + flow_2.flip(1).repeat(1, offset_2.size(1) // 2, 1, 1)
402
- offset = torch.cat([offset_1, offset_2], dim=1)
403
-
404
- # mask
405
- mask = torch.sigmoid(mask)
406
-
407
- return torchvision.ops.deform_conv2d(x, offset, self.weight, self.bias, self.stride, self.padding,
408
- self.dilation, mask)
409
-
410
-
411
- # if __name__ == '__main__':
412
- # spynet_path = 'experiments/pretrained_models/flownet/spynet_sintel_final-3d2a1287.pth'
413
- # model = BasicVSRPlusPlus(spynet_path=spynet_path).cuda()
414
- # input = torch.rand(1, 2, 3, 64, 64).cuda()
415
- # output = model(input)
416
- # print('===================')
417
- # print(output.shape)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/dfdnet_arch.py DELETED
@@ -1,169 +0,0 @@
1
- import numpy as np
2
- import torch
3
- import torch.nn as nn
4
- import torch.nn.functional as F
5
- from torch.nn.utils.spectral_norm import spectral_norm
6
-
7
- from basicsr.utils.registry import ARCH_REGISTRY
8
- from .dfdnet_util import AttentionBlock, Blur, MSDilationBlock, UpResBlock, adaptive_instance_normalization
9
- from .vgg_arch import VGGFeatureExtractor
10
-
11
-
12
- class SFTUpBlock(nn.Module):
13
- """Spatial feature transform (SFT) with upsampling block.
14
-
15
- Args:
16
- in_channel (int): Number of input channels.
17
- out_channel (int): Number of output channels.
18
- kernel_size (int): Kernel size in convolutions. Default: 3.
19
- padding (int): Padding in convolutions. Default: 1.
20
- """
21
-
22
- def __init__(self, in_channel, out_channel, kernel_size=3, padding=1):
23
- super(SFTUpBlock, self).__init__()
24
- self.conv1 = nn.Sequential(
25
- Blur(in_channel),
26
- spectral_norm(nn.Conv2d(in_channel, out_channel, kernel_size, padding=padding)),
27
- nn.LeakyReLU(0.04, True),
28
- # The official codes use two LeakyReLU here, so 0.04 for equivalent
29
- )
30
- self.convup = nn.Sequential(
31
- nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False),
32
- spectral_norm(nn.Conv2d(out_channel, out_channel, kernel_size, padding=padding)),
33
- nn.LeakyReLU(0.2, True),
34
- )
35
-
36
- # for SFT scale and shift
37
- self.scale_block = nn.Sequential(
38
- spectral_norm(nn.Conv2d(in_channel, out_channel, 3, 1, 1)), nn.LeakyReLU(0.2, True),
39
- spectral_norm(nn.Conv2d(out_channel, out_channel, 3, 1, 1)))
40
- self.shift_block = nn.Sequential(
41
- spectral_norm(nn.Conv2d(in_channel, out_channel, 3, 1, 1)), nn.LeakyReLU(0.2, True),
42
- spectral_norm(nn.Conv2d(out_channel, out_channel, 3, 1, 1)), nn.Sigmoid())
43
- # The official codes use sigmoid for shift block, do not know why
44
-
45
- def forward(self, x, updated_feat):
46
- out = self.conv1(x)
47
- # SFT
48
- scale = self.scale_block(updated_feat)
49
- shift = self.shift_block(updated_feat)
50
- out = out * scale + shift
51
- # upsample
52
- out = self.convup(out)
53
- return out
54
-
55
-
56
- @ARCH_REGISTRY.register()
57
- class DFDNet(nn.Module):
58
- """DFDNet: Deep Face Dictionary Network.
59
-
60
- It only processes faces with 512x512 size.
61
-
62
- Args:
63
- num_feat (int): Number of feature channels.
64
- dict_path (str): Path to the facial component dictionary.
65
- """
66
-
67
- def __init__(self, num_feat, dict_path):
68
- super().__init__()
69
- self.parts = ['left_eye', 'right_eye', 'nose', 'mouth']
70
- # part_sizes: [80, 80, 50, 110]
71
- channel_sizes = [128, 256, 512, 512]
72
- self.feature_sizes = np.array([256, 128, 64, 32])
73
- self.vgg_layers = ['relu2_2', 'relu3_4', 'relu4_4', 'conv5_4']
74
- self.flag_dict_device = False
75
-
76
- # dict
77
- self.dict = torch.load(dict_path)
78
-
79
- # vgg face extractor
80
- self.vgg_extractor = VGGFeatureExtractor(
81
- layer_name_list=self.vgg_layers,
82
- vgg_type='vgg19',
83
- use_input_norm=True,
84
- range_norm=True,
85
- requires_grad=False)
86
-
87
- # attention block for fusing dictionary features and input features
88
- self.attn_blocks = nn.ModuleDict()
89
- for idx, feat_size in enumerate(self.feature_sizes):
90
- for name in self.parts:
91
- self.attn_blocks[f'{name}_{feat_size}'] = AttentionBlock(channel_sizes[idx])
92
-
93
- # multi scale dilation block
94
- self.multi_scale_dilation = MSDilationBlock(num_feat * 8, dilation=[4, 3, 2, 1])
95
-
96
- # upsampling and reconstruction
97
- self.upsample0 = SFTUpBlock(num_feat * 8, num_feat * 8)
98
- self.upsample1 = SFTUpBlock(num_feat * 8, num_feat * 4)
99
- self.upsample2 = SFTUpBlock(num_feat * 4, num_feat * 2)
100
- self.upsample3 = SFTUpBlock(num_feat * 2, num_feat)
101
- self.upsample4 = nn.Sequential(
102
- spectral_norm(nn.Conv2d(num_feat, num_feat, 3, 1, 1)), nn.LeakyReLU(0.2, True), UpResBlock(num_feat),
103
- UpResBlock(num_feat), nn.Conv2d(num_feat, 3, kernel_size=3, stride=1, padding=1), nn.Tanh())
104
-
105
- def swap_feat(self, vgg_feat, updated_feat, dict_feat, location, part_name, f_size):
106
- """swap the features from the dictionary."""
107
- # get the original vgg features
108
- part_feat = vgg_feat[:, :, location[1]:location[3], location[0]:location[2]].clone()
109
- # resize original vgg features
110
- part_resize_feat = F.interpolate(part_feat, dict_feat.size()[2:4], mode='bilinear', align_corners=False)
111
- # use adaptive instance normalization to adjust color and illuminations
112
- dict_feat = adaptive_instance_normalization(dict_feat, part_resize_feat)
113
- # get similarity scores
114
- similarity_score = F.conv2d(part_resize_feat, dict_feat)
115
- similarity_score = F.softmax(similarity_score.view(-1), dim=0)
116
- # select the most similar features in the dict (after norm)
117
- select_idx = torch.argmax(similarity_score)
118
- swap_feat = F.interpolate(dict_feat[select_idx:select_idx + 1], part_feat.size()[2:4])
119
- # attention
120
- attn = self.attn_blocks[f'{part_name}_' + str(f_size)](swap_feat - part_feat)
121
- attn_feat = attn * swap_feat
122
- # update features
123
- updated_feat[:, :, location[1]:location[3], location[0]:location[2]] = attn_feat + part_feat
124
- return updated_feat
125
-
126
- def put_dict_to_device(self, x):
127
- if self.flag_dict_device is False:
128
- for k, v in self.dict.items():
129
- for kk, vv in v.items():
130
- self.dict[k][kk] = vv.to(x)
131
- self.flag_dict_device = True
132
-
133
- def forward(self, x, part_locations):
134
- """
135
- Now only support testing with batch size = 0.
136
-
137
- Args:
138
- x (Tensor): Input faces with shape (b, c, 512, 512).
139
- part_locations (list[Tensor]): Part locations.
140
- """
141
- self.put_dict_to_device(x)
142
- # extract vggface features
143
- vgg_features = self.vgg_extractor(x)
144
- # update vggface features using the dictionary for each part
145
- updated_vgg_features = []
146
- batch = 0 # only supports testing with batch size = 0
147
- for vgg_layer, f_size in zip(self.vgg_layers, self.feature_sizes):
148
- dict_features = self.dict[f'{f_size}']
149
- vgg_feat = vgg_features[vgg_layer]
150
- updated_feat = vgg_feat.clone()
151
-
152
- # swap features from dictionary
153
- for part_idx, part_name in enumerate(self.parts):
154
- location = (part_locations[part_idx][batch] // (512 / f_size)).int()
155
- updated_feat = self.swap_feat(vgg_feat, updated_feat, dict_features[part_name], location, part_name,
156
- f_size)
157
-
158
- updated_vgg_features.append(updated_feat)
159
-
160
- vgg_feat_dilation = self.multi_scale_dilation(vgg_features['conv5_4'])
161
- # use updated vgg features to modulate the upsampled features with
162
- # SFT (Spatial Feature Transform) scaling and shifting manner.
163
- upsampled_feat = self.upsample0(vgg_feat_dilation, updated_vgg_features[3])
164
- upsampled_feat = self.upsample1(upsampled_feat, updated_vgg_features[2])
165
- upsampled_feat = self.upsample2(upsampled_feat, updated_vgg_features[1])
166
- upsampled_feat = self.upsample3(upsampled_feat, updated_vgg_features[0])
167
- out = self.upsample4(upsampled_feat)
168
-
169
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/dfdnet_util.py DELETED
@@ -1,162 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.nn.functional as F
4
- from torch.autograd import Function
5
- from torch.nn.utils.spectral_norm import spectral_norm
6
-
7
-
8
- class BlurFunctionBackward(Function):
9
-
10
- @staticmethod
11
- def forward(ctx, grad_output, kernel, kernel_flip):
12
- ctx.save_for_backward(kernel, kernel_flip)
13
- grad_input = F.conv2d(grad_output, kernel_flip, padding=1, groups=grad_output.shape[1])
14
- return grad_input
15
-
16
- @staticmethod
17
- def backward(ctx, gradgrad_output):
18
- kernel, _ = ctx.saved_tensors
19
- grad_input = F.conv2d(gradgrad_output, kernel, padding=1, groups=gradgrad_output.shape[1])
20
- return grad_input, None, None
21
-
22
-
23
- class BlurFunction(Function):
24
-
25
- @staticmethod
26
- def forward(ctx, x, kernel, kernel_flip):
27
- ctx.save_for_backward(kernel, kernel_flip)
28
- output = F.conv2d(x, kernel, padding=1, groups=x.shape[1])
29
- return output
30
-
31
- @staticmethod
32
- def backward(ctx, grad_output):
33
- kernel, kernel_flip = ctx.saved_tensors
34
- grad_input = BlurFunctionBackward.apply(grad_output, kernel, kernel_flip)
35
- return grad_input, None, None
36
-
37
-
38
- blur = BlurFunction.apply
39
-
40
-
41
- class Blur(nn.Module):
42
-
43
- def __init__(self, channel):
44
- super().__init__()
45
- kernel = torch.tensor([[1, 2, 1], [2, 4, 2], [1, 2, 1]], dtype=torch.float32)
46
- kernel = kernel.view(1, 1, 3, 3)
47
- kernel = kernel / kernel.sum()
48
- kernel_flip = torch.flip(kernel, [2, 3])
49
-
50
- self.kernel = kernel.repeat(channel, 1, 1, 1)
51
- self.kernel_flip = kernel_flip.repeat(channel, 1, 1, 1)
52
-
53
- def forward(self, x):
54
- return blur(x, self.kernel.type_as(x), self.kernel_flip.type_as(x))
55
-
56
-
57
- def calc_mean_std(feat, eps=1e-5):
58
- """Calculate mean and std for adaptive_instance_normalization.
59
-
60
- Args:
61
- feat (Tensor): 4D tensor.
62
- eps (float): A small value added to the variance to avoid
63
- divide-by-zero. Default: 1e-5.
64
- """
65
- size = feat.size()
66
- assert len(size) == 4, 'The input feature should be 4D tensor.'
67
- n, c = size[:2]
68
- feat_var = feat.view(n, c, -1).var(dim=2) + eps
69
- feat_std = feat_var.sqrt().view(n, c, 1, 1)
70
- feat_mean = feat.view(n, c, -1).mean(dim=2).view(n, c, 1, 1)
71
- return feat_mean, feat_std
72
-
73
-
74
- def adaptive_instance_normalization(content_feat, style_feat):
75
- """Adaptive instance normalization.
76
-
77
- Adjust the reference features to have the similar color and illuminations
78
- as those in the degradate features.
79
-
80
- Args:
81
- content_feat (Tensor): The reference feature.
82
- style_feat (Tensor): The degradate features.
83
- """
84
- size = content_feat.size()
85
- style_mean, style_std = calc_mean_std(style_feat)
86
- content_mean, content_std = calc_mean_std(content_feat)
87
- normalized_feat = (content_feat - content_mean.expand(size)) / content_std.expand(size)
88
- return normalized_feat * style_std.expand(size) + style_mean.expand(size)
89
-
90
-
91
- def AttentionBlock(in_channel):
92
- return nn.Sequential(
93
- spectral_norm(nn.Conv2d(in_channel, in_channel, 3, 1, 1)), nn.LeakyReLU(0.2, True),
94
- spectral_norm(nn.Conv2d(in_channel, in_channel, 3, 1, 1)))
95
-
96
-
97
- def conv_block(in_channels, out_channels, kernel_size=3, stride=1, dilation=1, bias=True):
98
- """Conv block used in MSDilationBlock."""
99
-
100
- return nn.Sequential(
101
- spectral_norm(
102
- nn.Conv2d(
103
- in_channels,
104
- out_channels,
105
- kernel_size=kernel_size,
106
- stride=stride,
107
- dilation=dilation,
108
- padding=((kernel_size - 1) // 2) * dilation,
109
- bias=bias)),
110
- nn.LeakyReLU(0.2),
111
- spectral_norm(
112
- nn.Conv2d(
113
- out_channels,
114
- out_channels,
115
- kernel_size=kernel_size,
116
- stride=stride,
117
- dilation=dilation,
118
- padding=((kernel_size - 1) // 2) * dilation,
119
- bias=bias)),
120
- )
121
-
122
-
123
- class MSDilationBlock(nn.Module):
124
- """Multi-scale dilation block."""
125
-
126
- def __init__(self, in_channels, kernel_size=3, dilation=(1, 1, 1, 1), bias=True):
127
- super(MSDilationBlock, self).__init__()
128
-
129
- self.conv_blocks = nn.ModuleList()
130
- for i in range(4):
131
- self.conv_blocks.append(conv_block(in_channels, in_channels, kernel_size, dilation=dilation[i], bias=bias))
132
- self.conv_fusion = spectral_norm(
133
- nn.Conv2d(
134
- in_channels * 4,
135
- in_channels,
136
- kernel_size=kernel_size,
137
- stride=1,
138
- padding=(kernel_size - 1) // 2,
139
- bias=bias))
140
-
141
- def forward(self, x):
142
- out = []
143
- for i in range(4):
144
- out.append(self.conv_blocks[i](x))
145
- out = torch.cat(out, 1)
146
- out = self.conv_fusion(out) + x
147
- return out
148
-
149
-
150
- class UpResBlock(nn.Module):
151
-
152
- def __init__(self, in_channel):
153
- super(UpResBlock, self).__init__()
154
- self.body = nn.Sequential(
155
- nn.Conv2d(in_channel, in_channel, 3, 1, 1),
156
- nn.LeakyReLU(0.2, True),
157
- nn.Conv2d(in_channel, in_channel, 3, 1, 1),
158
- )
159
-
160
- def forward(self, x):
161
- out = x + self.body(x)
162
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/discriminator_arch.py DELETED
@@ -1,150 +0,0 @@
1
- from torch import nn as nn
2
- from torch.nn import functional as F
3
- from torch.nn.utils import spectral_norm
4
-
5
- from basicsr.utils.registry import ARCH_REGISTRY
6
-
7
-
8
- @ARCH_REGISTRY.register()
9
- class VGGStyleDiscriminator(nn.Module):
10
- """VGG style discriminator with input size 128 x 128 or 256 x 256.
11
-
12
- It is used to train SRGAN, ESRGAN, and VideoGAN.
13
-
14
- Args:
15
- num_in_ch (int): Channel number of inputs. Default: 3.
16
- num_feat (int): Channel number of base intermediate features.Default: 64.
17
- """
18
-
19
- def __init__(self, num_in_ch, num_feat, input_size=128):
20
- super(VGGStyleDiscriminator, self).__init__()
21
- self.input_size = input_size
22
- assert self.input_size == 128 or self.input_size == 256, (
23
- f'input size must be 128 or 256, but received {input_size}')
24
-
25
- self.conv0_0 = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1, bias=True)
26
- self.conv0_1 = nn.Conv2d(num_feat, num_feat, 4, 2, 1, bias=False)
27
- self.bn0_1 = nn.BatchNorm2d(num_feat, affine=True)
28
-
29
- self.conv1_0 = nn.Conv2d(num_feat, num_feat * 2, 3, 1, 1, bias=False)
30
- self.bn1_0 = nn.BatchNorm2d(num_feat * 2, affine=True)
31
- self.conv1_1 = nn.Conv2d(num_feat * 2, num_feat * 2, 4, 2, 1, bias=False)
32
- self.bn1_1 = nn.BatchNorm2d(num_feat * 2, affine=True)
33
-
34
- self.conv2_0 = nn.Conv2d(num_feat * 2, num_feat * 4, 3, 1, 1, bias=False)
35
- self.bn2_0 = nn.BatchNorm2d(num_feat * 4, affine=True)
36
- self.conv2_1 = nn.Conv2d(num_feat * 4, num_feat * 4, 4, 2, 1, bias=False)
37
- self.bn2_1 = nn.BatchNorm2d(num_feat * 4, affine=True)
38
-
39
- self.conv3_0 = nn.Conv2d(num_feat * 4, num_feat * 8, 3, 1, 1, bias=False)
40
- self.bn3_0 = nn.BatchNorm2d(num_feat * 8, affine=True)
41
- self.conv3_1 = nn.Conv2d(num_feat * 8, num_feat * 8, 4, 2, 1, bias=False)
42
- self.bn3_1 = nn.BatchNorm2d(num_feat * 8, affine=True)
43
-
44
- self.conv4_0 = nn.Conv2d(num_feat * 8, num_feat * 8, 3, 1, 1, bias=False)
45
- self.bn4_0 = nn.BatchNorm2d(num_feat * 8, affine=True)
46
- self.conv4_1 = nn.Conv2d(num_feat * 8, num_feat * 8, 4, 2, 1, bias=False)
47
- self.bn4_1 = nn.BatchNorm2d(num_feat * 8, affine=True)
48
-
49
- if self.input_size == 256:
50
- self.conv5_0 = nn.Conv2d(num_feat * 8, num_feat * 8, 3, 1, 1, bias=False)
51
- self.bn5_0 = nn.BatchNorm2d(num_feat * 8, affine=True)
52
- self.conv5_1 = nn.Conv2d(num_feat * 8, num_feat * 8, 4, 2, 1, bias=False)
53
- self.bn5_1 = nn.BatchNorm2d(num_feat * 8, affine=True)
54
-
55
- self.linear1 = nn.Linear(num_feat * 8 * 4 * 4, 100)
56
- self.linear2 = nn.Linear(100, 1)
57
-
58
- # activation function
59
- self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True)
60
-
61
- def forward(self, x):
62
- assert x.size(2) == self.input_size, (f'Input size must be identical to input_size, but received {x.size()}.')
63
-
64
- feat = self.lrelu(self.conv0_0(x))
65
- feat = self.lrelu(self.bn0_1(self.conv0_1(feat))) # output spatial size: /2
66
-
67
- feat = self.lrelu(self.bn1_0(self.conv1_0(feat)))
68
- feat = self.lrelu(self.bn1_1(self.conv1_1(feat))) # output spatial size: /4
69
-
70
- feat = self.lrelu(self.bn2_0(self.conv2_0(feat)))
71
- feat = self.lrelu(self.bn2_1(self.conv2_1(feat))) # output spatial size: /8
72
-
73
- feat = self.lrelu(self.bn3_0(self.conv3_0(feat)))
74
- feat = self.lrelu(self.bn3_1(self.conv3_1(feat))) # output spatial size: /16
75
-
76
- feat = self.lrelu(self.bn4_0(self.conv4_0(feat)))
77
- feat = self.lrelu(self.bn4_1(self.conv4_1(feat))) # output spatial size: /32
78
-
79
- if self.input_size == 256:
80
- feat = self.lrelu(self.bn5_0(self.conv5_0(feat)))
81
- feat = self.lrelu(self.bn5_1(self.conv5_1(feat))) # output spatial size: / 64
82
-
83
- # spatial size: (4, 4)
84
- feat = feat.view(feat.size(0), -1)
85
- feat = self.lrelu(self.linear1(feat))
86
- out = self.linear2(feat)
87
- return out
88
-
89
-
90
- @ARCH_REGISTRY.register(suffix='basicsr')
91
- class UNetDiscriminatorSN(nn.Module):
92
- """Defines a U-Net discriminator with spectral normalization (SN)
93
-
94
- It is used in Real-ESRGAN: Training Real-World Blind Super-Resolution with Pure Synthetic Data.
95
-
96
- Arg:
97
- num_in_ch (int): Channel number of inputs. Default: 3.
98
- num_feat (int): Channel number of base intermediate features. Default: 64.
99
- skip_connection (bool): Whether to use skip connections between U-Net. Default: True.
100
- """
101
-
102
- def __init__(self, num_in_ch, num_feat=64, skip_connection=True):
103
- super(UNetDiscriminatorSN, self).__init__()
104
- self.skip_connection = skip_connection
105
- norm = spectral_norm
106
- # the first convolution
107
- self.conv0 = nn.Conv2d(num_in_ch, num_feat, kernel_size=3, stride=1, padding=1)
108
- # downsample
109
- self.conv1 = norm(nn.Conv2d(num_feat, num_feat * 2, 4, 2, 1, bias=False))
110
- self.conv2 = norm(nn.Conv2d(num_feat * 2, num_feat * 4, 4, 2, 1, bias=False))
111
- self.conv3 = norm(nn.Conv2d(num_feat * 4, num_feat * 8, 4, 2, 1, bias=False))
112
- # upsample
113
- self.conv4 = norm(nn.Conv2d(num_feat * 8, num_feat * 4, 3, 1, 1, bias=False))
114
- self.conv5 = norm(nn.Conv2d(num_feat * 4, num_feat * 2, 3, 1, 1, bias=False))
115
- self.conv6 = norm(nn.Conv2d(num_feat * 2, num_feat, 3, 1, 1, bias=False))
116
- # extra convolutions
117
- self.conv7 = norm(nn.Conv2d(num_feat, num_feat, 3, 1, 1, bias=False))
118
- self.conv8 = norm(nn.Conv2d(num_feat, num_feat, 3, 1, 1, bias=False))
119
- self.conv9 = nn.Conv2d(num_feat, 1, 3, 1, 1)
120
-
121
- def forward(self, x):
122
- # downsample
123
- x0 = F.leaky_relu(self.conv0(x), negative_slope=0.2, inplace=True)
124
- x1 = F.leaky_relu(self.conv1(x0), negative_slope=0.2, inplace=True)
125
- x2 = F.leaky_relu(self.conv2(x1), negative_slope=0.2, inplace=True)
126
- x3 = F.leaky_relu(self.conv3(x2), negative_slope=0.2, inplace=True)
127
-
128
- # upsample
129
- x3 = F.interpolate(x3, scale_factor=2, mode='bilinear', align_corners=False)
130
- x4 = F.leaky_relu(self.conv4(x3), negative_slope=0.2, inplace=True)
131
-
132
- if self.skip_connection:
133
- x4 = x4 + x2
134
- x4 = F.interpolate(x4, scale_factor=2, mode='bilinear', align_corners=False)
135
- x5 = F.leaky_relu(self.conv5(x4), negative_slope=0.2, inplace=True)
136
-
137
- if self.skip_connection:
138
- x5 = x5 + x1
139
- x5 = F.interpolate(x5, scale_factor=2, mode='bilinear', align_corners=False)
140
- x6 = F.leaky_relu(self.conv6(x5), negative_slope=0.2, inplace=True)
141
-
142
- if self.skip_connection:
143
- x6 = x6 + x0
144
-
145
- # extra convolutions
146
- out = F.leaky_relu(self.conv7(x6), negative_slope=0.2, inplace=True)
147
- out = F.leaky_relu(self.conv8(out), negative_slope=0.2, inplace=True)
148
- out = self.conv9(out)
149
-
150
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/duf_arch.py DELETED
@@ -1,276 +0,0 @@
1
- import numpy as np
2
- import torch
3
- from torch import nn as nn
4
- from torch.nn import functional as F
5
-
6
- from basicsr.utils.registry import ARCH_REGISTRY
7
-
8
-
9
- class DenseBlocksTemporalReduce(nn.Module):
10
- """A concatenation of 3 dense blocks with reduction in temporal dimension.
11
-
12
- Note that the output temporal dimension is 6 fewer the input temporal dimension, since there are 3 blocks.
13
-
14
- Args:
15
- num_feat (int): Number of channels in the blocks. Default: 64.
16
- num_grow_ch (int): Growing factor of the dense blocks. Default: 32
17
- adapt_official_weights (bool): Whether to adapt the weights translated from the official implementation.
18
- Set to false if you want to train from scratch. Default: False.
19
- """
20
-
21
- def __init__(self, num_feat=64, num_grow_ch=32, adapt_official_weights=False):
22
- super(DenseBlocksTemporalReduce, self).__init__()
23
- if adapt_official_weights:
24
- eps = 1e-3
25
- momentum = 1e-3
26
- else: # pytorch default values
27
- eps = 1e-05
28
- momentum = 0.1
29
-
30
- self.temporal_reduce1 = nn.Sequential(
31
- nn.BatchNorm3d(num_feat, eps=eps, momentum=momentum), nn.ReLU(inplace=True),
32
- nn.Conv3d(num_feat, num_feat, (1, 1, 1), stride=(1, 1, 1), padding=(0, 0, 0), bias=True),
33
- nn.BatchNorm3d(num_feat, eps=eps, momentum=momentum), nn.ReLU(inplace=True),
34
- nn.Conv3d(num_feat, num_grow_ch, (3, 3, 3), stride=(1, 1, 1), padding=(0, 1, 1), bias=True))
35
-
36
- self.temporal_reduce2 = nn.Sequential(
37
- nn.BatchNorm3d(num_feat + num_grow_ch, eps=eps, momentum=momentum), nn.ReLU(inplace=True),
38
- nn.Conv3d(
39
- num_feat + num_grow_ch,
40
- num_feat + num_grow_ch, (1, 1, 1),
41
- stride=(1, 1, 1),
42
- padding=(0, 0, 0),
43
- bias=True), nn.BatchNorm3d(num_feat + num_grow_ch, eps=eps, momentum=momentum), nn.ReLU(inplace=True),
44
- nn.Conv3d(num_feat + num_grow_ch, num_grow_ch, (3, 3, 3), stride=(1, 1, 1), padding=(0, 1, 1), bias=True))
45
-
46
- self.temporal_reduce3 = nn.Sequential(
47
- nn.BatchNorm3d(num_feat + 2 * num_grow_ch, eps=eps, momentum=momentum), nn.ReLU(inplace=True),
48
- nn.Conv3d(
49
- num_feat + 2 * num_grow_ch,
50
- num_feat + 2 * num_grow_ch, (1, 1, 1),
51
- stride=(1, 1, 1),
52
- padding=(0, 0, 0),
53
- bias=True), nn.BatchNorm3d(num_feat + 2 * num_grow_ch, eps=eps, momentum=momentum),
54
- nn.ReLU(inplace=True),
55
- nn.Conv3d(
56
- num_feat + 2 * num_grow_ch, num_grow_ch, (3, 3, 3), stride=(1, 1, 1), padding=(0, 1, 1), bias=True))
57
-
58
- def forward(self, x):
59
- """
60
- Args:
61
- x (Tensor): Input tensor with shape (b, num_feat, t, h, w).
62
-
63
- Returns:
64
- Tensor: Output with shape (b, num_feat + num_grow_ch * 3, 1, h, w).
65
- """
66
- x1 = self.temporal_reduce1(x)
67
- x1 = torch.cat((x[:, :, 1:-1, :, :], x1), 1)
68
-
69
- x2 = self.temporal_reduce2(x1)
70
- x2 = torch.cat((x1[:, :, 1:-1, :, :], x2), 1)
71
-
72
- x3 = self.temporal_reduce3(x2)
73
- x3 = torch.cat((x2[:, :, 1:-1, :, :], x3), 1)
74
-
75
- return x3
76
-
77
-
78
- class DenseBlocks(nn.Module):
79
- """ A concatenation of N dense blocks.
80
-
81
- Args:
82
- num_feat (int): Number of channels in the blocks. Default: 64.
83
- num_grow_ch (int): Growing factor of the dense blocks. Default: 32.
84
- num_block (int): Number of dense blocks. The values are:
85
- DUF-S (16 layers): 3
86
- DUF-M (18 layers): 9
87
- DUF-L (52 layers): 21
88
- adapt_official_weights (bool): Whether to adapt the weights translated from the official implementation.
89
- Set to false if you want to train from scratch. Default: False.
90
- """
91
-
92
- def __init__(self, num_block, num_feat=64, num_grow_ch=16, adapt_official_weights=False):
93
- super(DenseBlocks, self).__init__()
94
- if adapt_official_weights:
95
- eps = 1e-3
96
- momentum = 1e-3
97
- else: # pytorch default values
98
- eps = 1e-05
99
- momentum = 0.1
100
-
101
- self.dense_blocks = nn.ModuleList()
102
- for i in range(0, num_block):
103
- self.dense_blocks.append(
104
- nn.Sequential(
105
- nn.BatchNorm3d(num_feat + i * num_grow_ch, eps=eps, momentum=momentum), nn.ReLU(inplace=True),
106
- nn.Conv3d(
107
- num_feat + i * num_grow_ch,
108
- num_feat + i * num_grow_ch, (1, 1, 1),
109
- stride=(1, 1, 1),
110
- padding=(0, 0, 0),
111
- bias=True), nn.BatchNorm3d(num_feat + i * num_grow_ch, eps=eps, momentum=momentum),
112
- nn.ReLU(inplace=True),
113
- nn.Conv3d(
114
- num_feat + i * num_grow_ch,
115
- num_grow_ch, (3, 3, 3),
116
- stride=(1, 1, 1),
117
- padding=(1, 1, 1),
118
- bias=True)))
119
-
120
- def forward(self, x):
121
- """
122
- Args:
123
- x (Tensor): Input tensor with shape (b, num_feat, t, h, w).
124
-
125
- Returns:
126
- Tensor: Output with shape (b, num_feat + num_block * num_grow_ch, t, h, w).
127
- """
128
- for i in range(0, len(self.dense_blocks)):
129
- y = self.dense_blocks[i](x)
130
- x = torch.cat((x, y), 1)
131
- return x
132
-
133
-
134
- class DynamicUpsamplingFilter(nn.Module):
135
- """Dynamic upsampling filter used in DUF.
136
-
137
- Reference: https://github.com/yhjo09/VSR-DUF
138
-
139
- It only supports input with 3 channels. And it applies the same filters to 3 channels.
140
-
141
- Args:
142
- filter_size (tuple): Filter size of generated filters. The shape is (kh, kw). Default: (5, 5).
143
- """
144
-
145
- def __init__(self, filter_size=(5, 5)):
146
- super(DynamicUpsamplingFilter, self).__init__()
147
- if not isinstance(filter_size, tuple):
148
- raise TypeError(f'The type of filter_size must be tuple, but got type{filter_size}')
149
- if len(filter_size) != 2:
150
- raise ValueError(f'The length of filter size must be 2, but got {len(filter_size)}.')
151
- # generate a local expansion filter, similar to im2col
152
- self.filter_size = filter_size
153
- filter_prod = np.prod(filter_size)
154
- expansion_filter = torch.eye(int(filter_prod)).view(filter_prod, 1, *filter_size) # (kh*kw, 1, kh, kw)
155
- self.expansion_filter = expansion_filter.repeat(3, 1, 1, 1) # repeat for all the 3 channels
156
-
157
- def forward(self, x, filters):
158
- """Forward function for DynamicUpsamplingFilter.
159
-
160
- Args:
161
- x (Tensor): Input image with 3 channels. The shape is (n, 3, h, w).
162
- filters (Tensor): Generated dynamic filters. The shape is (n, filter_prod, upsampling_square, h, w).
163
- filter_prod: prod of filter kernel size, e.g., 1*5*5=25.
164
- upsampling_square: similar to pixel shuffle, upsampling_square = upsampling * upsampling.
165
- e.g., for x 4 upsampling, upsampling_square= 4*4 = 16
166
-
167
- Returns:
168
- Tensor: Filtered image with shape (n, 3*upsampling_square, h, w)
169
- """
170
- n, filter_prod, upsampling_square, h, w = filters.size()
171
- kh, kw = self.filter_size
172
- expanded_input = F.conv2d(
173
- x, self.expansion_filter.to(x), padding=(kh // 2, kw // 2), groups=3) # (n, 3*filter_prod, h, w)
174
- expanded_input = expanded_input.view(n, 3, filter_prod, h, w).permute(0, 3, 4, 1,
175
- 2) # (n, h, w, 3, filter_prod)
176
- filters = filters.permute(0, 3, 4, 1, 2) # (n, h, w, filter_prod, upsampling_square]
177
- out = torch.matmul(expanded_input, filters) # (n, h, w, 3, upsampling_square)
178
- return out.permute(0, 3, 4, 1, 2).view(n, 3 * upsampling_square, h, w)
179
-
180
-
181
- @ARCH_REGISTRY.register()
182
- class DUF(nn.Module):
183
- """Network architecture for DUF
184
-
185
- ``Paper: Deep Video Super-Resolution Network Using Dynamic Upsampling Filters Without Explicit Motion Compensation``
186
-
187
- Reference: https://github.com/yhjo09/VSR-DUF
188
-
189
- For all the models below, 'adapt_official_weights' is only necessary when
190
- loading the weights converted from the official TensorFlow weights.
191
- Please set it to False if you are training the model from scratch.
192
-
193
- There are three models with different model size: DUF16Layers, DUF28Layers,
194
- and DUF52Layers. This class is the base class for these models.
195
-
196
- Args:
197
- scale (int): The upsampling factor. Default: 4.
198
- num_layer (int): The number of layers. Default: 52.
199
- adapt_official_weights_weights (bool): Whether to adapt the weights
200
- translated from the official implementation. Set to false if you
201
- want to train from scratch. Default: False.
202
- """
203
-
204
- def __init__(self, scale=4, num_layer=52, adapt_official_weights=False):
205
- super(DUF, self).__init__()
206
- self.scale = scale
207
- if adapt_official_weights:
208
- eps = 1e-3
209
- momentum = 1e-3
210
- else: # pytorch default values
211
- eps = 1e-05
212
- momentum = 0.1
213
-
214
- self.conv3d1 = nn.Conv3d(3, 64, (1, 3, 3), stride=(1, 1, 1), padding=(0, 1, 1), bias=True)
215
- self.dynamic_filter = DynamicUpsamplingFilter((5, 5))
216
-
217
- if num_layer == 16:
218
- num_block = 3
219
- num_grow_ch = 32
220
- elif num_layer == 28:
221
- num_block = 9
222
- num_grow_ch = 16
223
- elif num_layer == 52:
224
- num_block = 21
225
- num_grow_ch = 16
226
- else:
227
- raise ValueError(f'Only supported (16, 28, 52) layers, but got {num_layer}.')
228
-
229
- self.dense_block1 = DenseBlocks(
230
- num_block=num_block, num_feat=64, num_grow_ch=num_grow_ch,
231
- adapt_official_weights=adapt_official_weights) # T = 7
232
- self.dense_block2 = DenseBlocksTemporalReduce(
233
- 64 + num_grow_ch * num_block, num_grow_ch, adapt_official_weights=adapt_official_weights) # T = 1
234
- channels = 64 + num_grow_ch * num_block + num_grow_ch * 3
235
- self.bn3d2 = nn.BatchNorm3d(channels, eps=eps, momentum=momentum)
236
- self.conv3d2 = nn.Conv3d(channels, 256, (1, 3, 3), stride=(1, 1, 1), padding=(0, 1, 1), bias=True)
237
-
238
- self.conv3d_r1 = nn.Conv3d(256, 256, (1, 1, 1), stride=(1, 1, 1), padding=(0, 0, 0), bias=True)
239
- self.conv3d_r2 = nn.Conv3d(256, 3 * (scale**2), (1, 1, 1), stride=(1, 1, 1), padding=(0, 0, 0), bias=True)
240
-
241
- self.conv3d_f1 = nn.Conv3d(256, 512, (1, 1, 1), stride=(1, 1, 1), padding=(0, 0, 0), bias=True)
242
- self.conv3d_f2 = nn.Conv3d(
243
- 512, 1 * 5 * 5 * (scale**2), (1, 1, 1), stride=(1, 1, 1), padding=(0, 0, 0), bias=True)
244
-
245
- def forward(self, x):
246
- """
247
- Args:
248
- x (Tensor): Input with shape (b, 7, c, h, w)
249
-
250
- Returns:
251
- Tensor: Output with shape (b, c, h * scale, w * scale)
252
- """
253
- num_batches, num_imgs, _, h, w = x.size()
254
-
255
- x = x.permute(0, 2, 1, 3, 4) # (b, c, 7, h, w) for Conv3D
256
- x_center = x[:, :, num_imgs // 2, :, :]
257
-
258
- x = self.conv3d1(x)
259
- x = self.dense_block1(x)
260
- x = self.dense_block2(x)
261
- x = F.relu(self.bn3d2(x), inplace=True)
262
- x = F.relu(self.conv3d2(x), inplace=True)
263
-
264
- # residual image
265
- res = self.conv3d_r2(F.relu(self.conv3d_r1(x), inplace=True))
266
-
267
- # filter
268
- filter_ = self.conv3d_f2(F.relu(self.conv3d_f1(x), inplace=True))
269
- filter_ = F.softmax(filter_.view(num_batches, 25, self.scale**2, h, w), dim=1)
270
-
271
- # dynamic filter
272
- out = self.dynamic_filter(x_center, filter_)
273
- out += res.squeeze_(2)
274
- out = F.pixel_shuffle(out, self.scale)
275
-
276
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/ecbsr_arch.py DELETED
@@ -1,275 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.nn.functional as F
4
-
5
- from basicsr.utils.registry import ARCH_REGISTRY
6
-
7
-
8
- class SeqConv3x3(nn.Module):
9
- """The re-parameterizable block used in the ECBSR architecture.
10
-
11
- ``Paper: Edge-oriented Convolution Block for Real-time Super Resolution on Mobile Devices``
12
-
13
- Reference: https://github.com/xindongzhang/ECBSR
14
-
15
- Args:
16
- seq_type (str): Sequence type, option: conv1x1-conv3x3 | conv1x1-sobelx | conv1x1-sobely | conv1x1-laplacian.
17
- in_channels (int): Channel number of input.
18
- out_channels (int): Channel number of output.
19
- depth_multiplier (int): Width multiplier in the expand-and-squeeze conv. Default: 1.
20
- """
21
-
22
- def __init__(self, seq_type, in_channels, out_channels, depth_multiplier=1):
23
- super(SeqConv3x3, self).__init__()
24
- self.seq_type = seq_type
25
- self.in_channels = in_channels
26
- self.out_channels = out_channels
27
-
28
- if self.seq_type == 'conv1x1-conv3x3':
29
- self.mid_planes = int(out_channels * depth_multiplier)
30
- conv0 = torch.nn.Conv2d(self.in_channels, self.mid_planes, kernel_size=1, padding=0)
31
- self.k0 = conv0.weight
32
- self.b0 = conv0.bias
33
-
34
- conv1 = torch.nn.Conv2d(self.mid_planes, self.out_channels, kernel_size=3)
35
- self.k1 = conv1.weight
36
- self.b1 = conv1.bias
37
-
38
- elif self.seq_type == 'conv1x1-sobelx':
39
- conv0 = torch.nn.Conv2d(self.in_channels, self.out_channels, kernel_size=1, padding=0)
40
- self.k0 = conv0.weight
41
- self.b0 = conv0.bias
42
-
43
- # init scale and bias
44
- scale = torch.randn(size=(self.out_channels, 1, 1, 1)) * 1e-3
45
- self.scale = nn.Parameter(scale)
46
- bias = torch.randn(self.out_channels) * 1e-3
47
- bias = torch.reshape(bias, (self.out_channels, ))
48
- self.bias = nn.Parameter(bias)
49
- # init mask
50
- self.mask = torch.zeros((self.out_channels, 1, 3, 3), dtype=torch.float32)
51
- for i in range(self.out_channels):
52
- self.mask[i, 0, 0, 0] = 1.0
53
- self.mask[i, 0, 1, 0] = 2.0
54
- self.mask[i, 0, 2, 0] = 1.0
55
- self.mask[i, 0, 0, 2] = -1.0
56
- self.mask[i, 0, 1, 2] = -2.0
57
- self.mask[i, 0, 2, 2] = -1.0
58
- self.mask = nn.Parameter(data=self.mask, requires_grad=False)
59
-
60
- elif self.seq_type == 'conv1x1-sobely':
61
- conv0 = torch.nn.Conv2d(self.in_channels, self.out_channels, kernel_size=1, padding=0)
62
- self.k0 = conv0.weight
63
- self.b0 = conv0.bias
64
-
65
- # init scale and bias
66
- scale = torch.randn(size=(self.out_channels, 1, 1, 1)) * 1e-3
67
- self.scale = nn.Parameter(torch.FloatTensor(scale))
68
- bias = torch.randn(self.out_channels) * 1e-3
69
- bias = torch.reshape(bias, (self.out_channels, ))
70
- self.bias = nn.Parameter(torch.FloatTensor(bias))
71
- # init mask
72
- self.mask = torch.zeros((self.out_channels, 1, 3, 3), dtype=torch.float32)
73
- for i in range(self.out_channels):
74
- self.mask[i, 0, 0, 0] = 1.0
75
- self.mask[i, 0, 0, 1] = 2.0
76
- self.mask[i, 0, 0, 2] = 1.0
77
- self.mask[i, 0, 2, 0] = -1.0
78
- self.mask[i, 0, 2, 1] = -2.0
79
- self.mask[i, 0, 2, 2] = -1.0
80
- self.mask = nn.Parameter(data=self.mask, requires_grad=False)
81
-
82
- elif self.seq_type == 'conv1x1-laplacian':
83
- conv0 = torch.nn.Conv2d(self.in_channels, self.out_channels, kernel_size=1, padding=0)
84
- self.k0 = conv0.weight
85
- self.b0 = conv0.bias
86
-
87
- # init scale and bias
88
- scale = torch.randn(size=(self.out_channels, 1, 1, 1)) * 1e-3
89
- self.scale = nn.Parameter(torch.FloatTensor(scale))
90
- bias = torch.randn(self.out_channels) * 1e-3
91
- bias = torch.reshape(bias, (self.out_channels, ))
92
- self.bias = nn.Parameter(torch.FloatTensor(bias))
93
- # init mask
94
- self.mask = torch.zeros((self.out_channels, 1, 3, 3), dtype=torch.float32)
95
- for i in range(self.out_channels):
96
- self.mask[i, 0, 0, 1] = 1.0
97
- self.mask[i, 0, 1, 0] = 1.0
98
- self.mask[i, 0, 1, 2] = 1.0
99
- self.mask[i, 0, 2, 1] = 1.0
100
- self.mask[i, 0, 1, 1] = -4.0
101
- self.mask = nn.Parameter(data=self.mask, requires_grad=False)
102
- else:
103
- raise ValueError('The type of seqconv is not supported!')
104
-
105
- def forward(self, x):
106
- if self.seq_type == 'conv1x1-conv3x3':
107
- # conv-1x1
108
- y0 = F.conv2d(input=x, weight=self.k0, bias=self.b0, stride=1)
109
- # explicitly padding with bias
110
- y0 = F.pad(y0, (1, 1, 1, 1), 'constant', 0)
111
- b0_pad = self.b0.view(1, -1, 1, 1)
112
- y0[:, :, 0:1, :] = b0_pad
113
- y0[:, :, -1:, :] = b0_pad
114
- y0[:, :, :, 0:1] = b0_pad
115
- y0[:, :, :, -1:] = b0_pad
116
- # conv-3x3
117
- y1 = F.conv2d(input=y0, weight=self.k1, bias=self.b1, stride=1)
118
- else:
119
- y0 = F.conv2d(input=x, weight=self.k0, bias=self.b0, stride=1)
120
- # explicitly padding with bias
121
- y0 = F.pad(y0, (1, 1, 1, 1), 'constant', 0)
122
- b0_pad = self.b0.view(1, -1, 1, 1)
123
- y0[:, :, 0:1, :] = b0_pad
124
- y0[:, :, -1:, :] = b0_pad
125
- y0[:, :, :, 0:1] = b0_pad
126
- y0[:, :, :, -1:] = b0_pad
127
- # conv-3x3
128
- y1 = F.conv2d(input=y0, weight=self.scale * self.mask, bias=self.bias, stride=1, groups=self.out_channels)
129
- return y1
130
-
131
- def rep_params(self):
132
- device = self.k0.get_device()
133
- if device < 0:
134
- device = None
135
-
136
- if self.seq_type == 'conv1x1-conv3x3':
137
- # re-param conv kernel
138
- rep_weight = F.conv2d(input=self.k1, weight=self.k0.permute(1, 0, 2, 3))
139
- # re-param conv bias
140
- rep_bias = torch.ones(1, self.mid_planes, 3, 3, device=device) * self.b0.view(1, -1, 1, 1)
141
- rep_bias = F.conv2d(input=rep_bias, weight=self.k1).view(-1, ) + self.b1
142
- else:
143
- tmp = self.scale * self.mask
144
- k1 = torch.zeros((self.out_channels, self.out_channels, 3, 3), device=device)
145
- for i in range(self.out_channels):
146
- k1[i, i, :, :] = tmp[i, 0, :, :]
147
- b1 = self.bias
148
- # re-param conv kernel
149
- rep_weight = F.conv2d(input=k1, weight=self.k0.permute(1, 0, 2, 3))
150
- # re-param conv bias
151
- rep_bias = torch.ones(1, self.out_channels, 3, 3, device=device) * self.b0.view(1, -1, 1, 1)
152
- rep_bias = F.conv2d(input=rep_bias, weight=k1).view(-1, ) + b1
153
- return rep_weight, rep_bias
154
-
155
-
156
- class ECB(nn.Module):
157
- """The ECB block used in the ECBSR architecture.
158
-
159
- Paper: Edge-oriented Convolution Block for Real-time Super Resolution on Mobile Devices
160
- Ref git repo: https://github.com/xindongzhang/ECBSR
161
-
162
- Args:
163
- in_channels (int): Channel number of input.
164
- out_channels (int): Channel number of output.
165
- depth_multiplier (int): Width multiplier in the expand-and-squeeze conv. Default: 1.
166
- act_type (str): Activation type. Option: prelu | relu | rrelu | softplus | linear. Default: prelu.
167
- with_idt (bool): Whether to use identity connection. Default: False.
168
- """
169
-
170
- def __init__(self, in_channels, out_channels, depth_multiplier, act_type='prelu', with_idt=False):
171
- super(ECB, self).__init__()
172
-
173
- self.depth_multiplier = depth_multiplier
174
- self.in_channels = in_channels
175
- self.out_channels = out_channels
176
- self.act_type = act_type
177
-
178
- if with_idt and (self.in_channels == self.out_channels):
179
- self.with_idt = True
180
- else:
181
- self.with_idt = False
182
-
183
- self.conv3x3 = torch.nn.Conv2d(self.in_channels, self.out_channels, kernel_size=3, padding=1)
184
- self.conv1x1_3x3 = SeqConv3x3('conv1x1-conv3x3', self.in_channels, self.out_channels, self.depth_multiplier)
185
- self.conv1x1_sbx = SeqConv3x3('conv1x1-sobelx', self.in_channels, self.out_channels)
186
- self.conv1x1_sby = SeqConv3x3('conv1x1-sobely', self.in_channels, self.out_channels)
187
- self.conv1x1_lpl = SeqConv3x3('conv1x1-laplacian', self.in_channels, self.out_channels)
188
-
189
- if self.act_type == 'prelu':
190
- self.act = nn.PReLU(num_parameters=self.out_channels)
191
- elif self.act_type == 'relu':
192
- self.act = nn.ReLU(inplace=True)
193
- elif self.act_type == 'rrelu':
194
- self.act = nn.RReLU(lower=-0.05, upper=0.05)
195
- elif self.act_type == 'softplus':
196
- self.act = nn.Softplus()
197
- elif self.act_type == 'linear':
198
- pass
199
- else:
200
- raise ValueError('The type of activation if not support!')
201
-
202
- def forward(self, x):
203
- if self.training:
204
- y = self.conv3x3(x) + self.conv1x1_3x3(x) + self.conv1x1_sbx(x) + self.conv1x1_sby(x) + self.conv1x1_lpl(x)
205
- if self.with_idt:
206
- y += x
207
- else:
208
- rep_weight, rep_bias = self.rep_params()
209
- y = F.conv2d(input=x, weight=rep_weight, bias=rep_bias, stride=1, padding=1)
210
- if self.act_type != 'linear':
211
- y = self.act(y)
212
- return y
213
-
214
- def rep_params(self):
215
- weight0, bias0 = self.conv3x3.weight, self.conv3x3.bias
216
- weight1, bias1 = self.conv1x1_3x3.rep_params()
217
- weight2, bias2 = self.conv1x1_sbx.rep_params()
218
- weight3, bias3 = self.conv1x1_sby.rep_params()
219
- weight4, bias4 = self.conv1x1_lpl.rep_params()
220
- rep_weight, rep_bias = (weight0 + weight1 + weight2 + weight3 + weight4), (
221
- bias0 + bias1 + bias2 + bias3 + bias4)
222
-
223
- if self.with_idt:
224
- device = rep_weight.get_device()
225
- if device < 0:
226
- device = None
227
- weight_idt = torch.zeros(self.out_channels, self.out_channels, 3, 3, device=device)
228
- for i in range(self.out_channels):
229
- weight_idt[i, i, 1, 1] = 1.0
230
- bias_idt = 0.0
231
- rep_weight, rep_bias = rep_weight + weight_idt, rep_bias + bias_idt
232
- return rep_weight, rep_bias
233
-
234
-
235
- @ARCH_REGISTRY.register()
236
- class ECBSR(nn.Module):
237
- """ECBSR architecture.
238
-
239
- Paper: Edge-oriented Convolution Block for Real-time Super Resolution on Mobile Devices
240
- Ref git repo: https://github.com/xindongzhang/ECBSR
241
-
242
- Args:
243
- num_in_ch (int): Channel number of inputs.
244
- num_out_ch (int): Channel number of outputs.
245
- num_block (int): Block number in the trunk network.
246
- num_channel (int): Channel number.
247
- with_idt (bool): Whether use identity in convolution layers.
248
- act_type (str): Activation type.
249
- scale (int): Upsampling factor.
250
- """
251
-
252
- def __init__(self, num_in_ch, num_out_ch, num_block, num_channel, with_idt, act_type, scale):
253
- super(ECBSR, self).__init__()
254
- self.num_in_ch = num_in_ch
255
- self.scale = scale
256
-
257
- backbone = []
258
- backbone += [ECB(num_in_ch, num_channel, depth_multiplier=2.0, act_type=act_type, with_idt=with_idt)]
259
- for _ in range(num_block):
260
- backbone += [ECB(num_channel, num_channel, depth_multiplier=2.0, act_type=act_type, with_idt=with_idt)]
261
- backbone += [
262
- ECB(num_channel, num_out_ch * scale * scale, depth_multiplier=2.0, act_type='linear', with_idt=with_idt)
263
- ]
264
-
265
- self.backbone = nn.Sequential(*backbone)
266
- self.upsampler = nn.PixelShuffle(scale)
267
-
268
- def forward(self, x):
269
- if self.num_in_ch > 1:
270
- shortcut = torch.repeat_interleave(x, self.scale * self.scale, dim=1)
271
- else:
272
- shortcut = x # will repeat the input in the channel dimension (repeat scale * scale times)
273
- y = self.backbone(x) + shortcut
274
- y = self.upsampler(y)
275
- return y
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/edsr_arch.py DELETED
@@ -1,61 +0,0 @@
1
- import torch
2
- from torch import nn as nn
3
-
4
- from basicsr.archs.arch_util import ResidualBlockNoBN, Upsample, make_layer
5
- from basicsr.utils.registry import ARCH_REGISTRY
6
-
7
-
8
- @ARCH_REGISTRY.register()
9
- class EDSR(nn.Module):
10
- """EDSR network structure.
11
-
12
- Paper: Enhanced Deep Residual Networks for Single Image Super-Resolution.
13
- Ref git repo: https://github.com/thstkdgus35/EDSR-PyTorch
14
-
15
- Args:
16
- num_in_ch (int): Channel number of inputs.
17
- num_out_ch (int): Channel number of outputs.
18
- num_feat (int): Channel number of intermediate features.
19
- Default: 64.
20
- num_block (int): Block number in the trunk network. Default: 16.
21
- upscale (int): Upsampling factor. Support 2^n and 3.
22
- Default: 4.
23
- res_scale (float): Used to scale the residual in residual block.
24
- Default: 1.
25
- img_range (float): Image range. Default: 255.
26
- rgb_mean (tuple[float]): Image mean in RGB orders.
27
- Default: (0.4488, 0.4371, 0.4040), calculated from DIV2K dataset.
28
- """
29
-
30
- def __init__(self,
31
- num_in_ch,
32
- num_out_ch,
33
- num_feat=64,
34
- num_block=16,
35
- upscale=4,
36
- res_scale=1,
37
- img_range=255.,
38
- rgb_mean=(0.4488, 0.4371, 0.4040)):
39
- super(EDSR, self).__init__()
40
-
41
- self.img_range = img_range
42
- self.mean = torch.Tensor(rgb_mean).view(1, 3, 1, 1)
43
-
44
- self.conv_first = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1)
45
- self.body = make_layer(ResidualBlockNoBN, num_block, num_feat=num_feat, res_scale=res_scale, pytorch_init=True)
46
- self.conv_after_body = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
47
- self.upsample = Upsample(upscale, num_feat)
48
- self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
49
-
50
- def forward(self, x):
51
- self.mean = self.mean.type_as(x)
52
-
53
- x = (x - self.mean) * self.img_range
54
- x = self.conv_first(x)
55
- res = self.conv_after_body(self.body(x))
56
- res += x
57
-
58
- x = self.conv_last(self.upsample(res))
59
- x = x / self.img_range + self.mean
60
-
61
- return x
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/edvr_arch.py DELETED
@@ -1,382 +0,0 @@
1
- import torch
2
- from torch import nn as nn
3
- from torch.nn import functional as F
4
-
5
- from basicsr.utils.registry import ARCH_REGISTRY
6
- from .arch_util import DCNv2Pack, ResidualBlockNoBN, make_layer
7
-
8
-
9
- class PCDAlignment(nn.Module):
10
- """Alignment module using Pyramid, Cascading and Deformable convolution
11
- (PCD). It is used in EDVR.
12
-
13
- ``Paper: EDVR: Video Restoration with Enhanced Deformable Convolutional Networks``
14
-
15
- Args:
16
- num_feat (int): Channel number of middle features. Default: 64.
17
- deformable_groups (int): Deformable groups. Defaults: 8.
18
- """
19
-
20
- def __init__(self, num_feat=64, deformable_groups=8):
21
- super(PCDAlignment, self).__init__()
22
-
23
- # Pyramid has three levels:
24
- # L3: level 3, 1/4 spatial size
25
- # L2: level 2, 1/2 spatial size
26
- # L1: level 1, original spatial size
27
- self.offset_conv1 = nn.ModuleDict()
28
- self.offset_conv2 = nn.ModuleDict()
29
- self.offset_conv3 = nn.ModuleDict()
30
- self.dcn_pack = nn.ModuleDict()
31
- self.feat_conv = nn.ModuleDict()
32
-
33
- # Pyramids
34
- for i in range(3, 0, -1):
35
- level = f'l{i}'
36
- self.offset_conv1[level] = nn.Conv2d(num_feat * 2, num_feat, 3, 1, 1)
37
- if i == 3:
38
- self.offset_conv2[level] = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
39
- else:
40
- self.offset_conv2[level] = nn.Conv2d(num_feat * 2, num_feat, 3, 1, 1)
41
- self.offset_conv3[level] = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
42
- self.dcn_pack[level] = DCNv2Pack(num_feat, num_feat, 3, padding=1, deformable_groups=deformable_groups)
43
-
44
- if i < 3:
45
- self.feat_conv[level] = nn.Conv2d(num_feat * 2, num_feat, 3, 1, 1)
46
-
47
- # Cascading dcn
48
- self.cas_offset_conv1 = nn.Conv2d(num_feat * 2, num_feat, 3, 1, 1)
49
- self.cas_offset_conv2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
50
- self.cas_dcnpack = DCNv2Pack(num_feat, num_feat, 3, padding=1, deformable_groups=deformable_groups)
51
-
52
- self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False)
53
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
54
-
55
- def forward(self, nbr_feat_l, ref_feat_l):
56
- """Align neighboring frame features to the reference frame features.
57
-
58
- Args:
59
- nbr_feat_l (list[Tensor]): Neighboring feature list. It
60
- contains three pyramid levels (L1, L2, L3),
61
- each with shape (b, c, h, w).
62
- ref_feat_l (list[Tensor]): Reference feature list. It
63
- contains three pyramid levels (L1, L2, L3),
64
- each with shape (b, c, h, w).
65
-
66
- Returns:
67
- Tensor: Aligned features.
68
- """
69
- # Pyramids
70
- upsampled_offset, upsampled_feat = None, None
71
- for i in range(3, 0, -1):
72
- level = f'l{i}'
73
- offset = torch.cat([nbr_feat_l[i - 1], ref_feat_l[i - 1]], dim=1)
74
- offset = self.lrelu(self.offset_conv1[level](offset))
75
- if i == 3:
76
- offset = self.lrelu(self.offset_conv2[level](offset))
77
- else:
78
- offset = self.lrelu(self.offset_conv2[level](torch.cat([offset, upsampled_offset], dim=1)))
79
- offset = self.lrelu(self.offset_conv3[level](offset))
80
-
81
- feat = self.dcn_pack[level](nbr_feat_l[i - 1], offset)
82
- if i < 3:
83
- feat = self.feat_conv[level](torch.cat([feat, upsampled_feat], dim=1))
84
- if i > 1:
85
- feat = self.lrelu(feat)
86
-
87
- if i > 1: # upsample offset and features
88
- # x2: when we upsample the offset, we should also enlarge
89
- # the magnitude.
90
- upsampled_offset = self.upsample(offset) * 2
91
- upsampled_feat = self.upsample(feat)
92
-
93
- # Cascading
94
- offset = torch.cat([feat, ref_feat_l[0]], dim=1)
95
- offset = self.lrelu(self.cas_offset_conv2(self.lrelu(self.cas_offset_conv1(offset))))
96
- feat = self.lrelu(self.cas_dcnpack(feat, offset))
97
- return feat
98
-
99
-
100
- class TSAFusion(nn.Module):
101
- """Temporal Spatial Attention (TSA) fusion module.
102
-
103
- Temporal: Calculate the correlation between center frame and
104
- neighboring frames;
105
- Spatial: It has 3 pyramid levels, the attention is similar to SFT.
106
- (SFT: Recovering realistic texture in image super-resolution by deep
107
- spatial feature transform.)
108
-
109
- Args:
110
- num_feat (int): Channel number of middle features. Default: 64.
111
- num_frame (int): Number of frames. Default: 5.
112
- center_frame_idx (int): The index of center frame. Default: 2.
113
- """
114
-
115
- def __init__(self, num_feat=64, num_frame=5, center_frame_idx=2):
116
- super(TSAFusion, self).__init__()
117
- self.center_frame_idx = center_frame_idx
118
- # temporal attention (before fusion conv)
119
- self.temporal_attn1 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
120
- self.temporal_attn2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
121
- self.feat_fusion = nn.Conv2d(num_frame * num_feat, num_feat, 1, 1)
122
-
123
- # spatial attention (after fusion conv)
124
- self.max_pool = nn.MaxPool2d(3, stride=2, padding=1)
125
- self.avg_pool = nn.AvgPool2d(3, stride=2, padding=1)
126
- self.spatial_attn1 = nn.Conv2d(num_frame * num_feat, num_feat, 1)
127
- self.spatial_attn2 = nn.Conv2d(num_feat * 2, num_feat, 1)
128
- self.spatial_attn3 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
129
- self.spatial_attn4 = nn.Conv2d(num_feat, num_feat, 1)
130
- self.spatial_attn5 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
131
- self.spatial_attn_l1 = nn.Conv2d(num_feat, num_feat, 1)
132
- self.spatial_attn_l2 = nn.Conv2d(num_feat * 2, num_feat, 3, 1, 1)
133
- self.spatial_attn_l3 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
134
- self.spatial_attn_add1 = nn.Conv2d(num_feat, num_feat, 1)
135
- self.spatial_attn_add2 = nn.Conv2d(num_feat, num_feat, 1)
136
-
137
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
138
- self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False)
139
-
140
- def forward(self, aligned_feat):
141
- """
142
- Args:
143
- aligned_feat (Tensor): Aligned features with shape (b, t, c, h, w).
144
-
145
- Returns:
146
- Tensor: Features after TSA with the shape (b, c, h, w).
147
- """
148
- b, t, c, h, w = aligned_feat.size()
149
- # temporal attention
150
- embedding_ref = self.temporal_attn1(aligned_feat[:, self.center_frame_idx, :, :, :].clone())
151
- embedding = self.temporal_attn2(aligned_feat.view(-1, c, h, w))
152
- embedding = embedding.view(b, t, -1, h, w) # (b, t, c, h, w)
153
-
154
- corr_l = [] # correlation list
155
- for i in range(t):
156
- emb_neighbor = embedding[:, i, :, :, :]
157
- corr = torch.sum(emb_neighbor * embedding_ref, 1) # (b, h, w)
158
- corr_l.append(corr.unsqueeze(1)) # (b, 1, h, w)
159
- corr_prob = torch.sigmoid(torch.cat(corr_l, dim=1)) # (b, t, h, w)
160
- corr_prob = corr_prob.unsqueeze(2).expand(b, t, c, h, w)
161
- corr_prob = corr_prob.contiguous().view(b, -1, h, w) # (b, t*c, h, w)
162
- aligned_feat = aligned_feat.view(b, -1, h, w) * corr_prob
163
-
164
- # fusion
165
- feat = self.lrelu(self.feat_fusion(aligned_feat))
166
-
167
- # spatial attention
168
- attn = self.lrelu(self.spatial_attn1(aligned_feat))
169
- attn_max = self.max_pool(attn)
170
- attn_avg = self.avg_pool(attn)
171
- attn = self.lrelu(self.spatial_attn2(torch.cat([attn_max, attn_avg], dim=1)))
172
- # pyramid levels
173
- attn_level = self.lrelu(self.spatial_attn_l1(attn))
174
- attn_max = self.max_pool(attn_level)
175
- attn_avg = self.avg_pool(attn_level)
176
- attn_level = self.lrelu(self.spatial_attn_l2(torch.cat([attn_max, attn_avg], dim=1)))
177
- attn_level = self.lrelu(self.spatial_attn_l3(attn_level))
178
- attn_level = self.upsample(attn_level)
179
-
180
- attn = self.lrelu(self.spatial_attn3(attn)) + attn_level
181
- attn = self.lrelu(self.spatial_attn4(attn))
182
- attn = self.upsample(attn)
183
- attn = self.spatial_attn5(attn)
184
- attn_add = self.spatial_attn_add2(self.lrelu(self.spatial_attn_add1(attn)))
185
- attn = torch.sigmoid(attn)
186
-
187
- # after initialization, * 2 makes (attn * 2) to be close to 1.
188
- feat = feat * attn * 2 + attn_add
189
- return feat
190
-
191
-
192
- class PredeblurModule(nn.Module):
193
- """Pre-dublur module.
194
-
195
- Args:
196
- num_in_ch (int): Channel number of input image. Default: 3.
197
- num_feat (int): Channel number of intermediate features. Default: 64.
198
- hr_in (bool): Whether the input has high resolution. Default: False.
199
- """
200
-
201
- def __init__(self, num_in_ch=3, num_feat=64, hr_in=False):
202
- super(PredeblurModule, self).__init__()
203
- self.hr_in = hr_in
204
-
205
- self.conv_first = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1)
206
- if self.hr_in:
207
- # downsample x4 by stride conv
208
- self.stride_conv_hr1 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
209
- self.stride_conv_hr2 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
210
-
211
- # generate feature pyramid
212
- self.stride_conv_l2 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
213
- self.stride_conv_l3 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
214
-
215
- self.resblock_l3 = ResidualBlockNoBN(num_feat=num_feat)
216
- self.resblock_l2_1 = ResidualBlockNoBN(num_feat=num_feat)
217
- self.resblock_l2_2 = ResidualBlockNoBN(num_feat=num_feat)
218
- self.resblock_l1 = nn.ModuleList([ResidualBlockNoBN(num_feat=num_feat) for i in range(5)])
219
-
220
- self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False)
221
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
222
-
223
- def forward(self, x):
224
- feat_l1 = self.lrelu(self.conv_first(x))
225
- if self.hr_in:
226
- feat_l1 = self.lrelu(self.stride_conv_hr1(feat_l1))
227
- feat_l1 = self.lrelu(self.stride_conv_hr2(feat_l1))
228
-
229
- # generate feature pyramid
230
- feat_l2 = self.lrelu(self.stride_conv_l2(feat_l1))
231
- feat_l3 = self.lrelu(self.stride_conv_l3(feat_l2))
232
-
233
- feat_l3 = self.upsample(self.resblock_l3(feat_l3))
234
- feat_l2 = self.resblock_l2_1(feat_l2) + feat_l3
235
- feat_l2 = self.upsample(self.resblock_l2_2(feat_l2))
236
-
237
- for i in range(2):
238
- feat_l1 = self.resblock_l1[i](feat_l1)
239
- feat_l1 = feat_l1 + feat_l2
240
- for i in range(2, 5):
241
- feat_l1 = self.resblock_l1[i](feat_l1)
242
- return feat_l1
243
-
244
-
245
- @ARCH_REGISTRY.register()
246
- class EDVR(nn.Module):
247
- """EDVR network structure for video super-resolution.
248
-
249
- Now only support X4 upsampling factor.
250
-
251
- ``Paper: EDVR: Video Restoration with Enhanced Deformable Convolutional Networks``
252
-
253
- Args:
254
- num_in_ch (int): Channel number of input image. Default: 3.
255
- num_out_ch (int): Channel number of output image. Default: 3.
256
- num_feat (int): Channel number of intermediate features. Default: 64.
257
- num_frame (int): Number of input frames. Default: 5.
258
- deformable_groups (int): Deformable groups. Defaults: 8.
259
- num_extract_block (int): Number of blocks for feature extraction.
260
- Default: 5.
261
- num_reconstruct_block (int): Number of blocks for reconstruction.
262
- Default: 10.
263
- center_frame_idx (int): The index of center frame. Frame counting from
264
- 0. Default: Middle of input frames.
265
- hr_in (bool): Whether the input has high resolution. Default: False.
266
- with_predeblur (bool): Whether has predeblur module.
267
- Default: False.
268
- with_tsa (bool): Whether has TSA module. Default: True.
269
- """
270
-
271
- def __init__(self,
272
- num_in_ch=3,
273
- num_out_ch=3,
274
- num_feat=64,
275
- num_frame=5,
276
- deformable_groups=8,
277
- num_extract_block=5,
278
- num_reconstruct_block=10,
279
- center_frame_idx=None,
280
- hr_in=False,
281
- with_predeblur=False,
282
- with_tsa=True):
283
- super(EDVR, self).__init__()
284
- if center_frame_idx is None:
285
- self.center_frame_idx = num_frame // 2
286
- else:
287
- self.center_frame_idx = center_frame_idx
288
- self.hr_in = hr_in
289
- self.with_predeblur = with_predeblur
290
- self.with_tsa = with_tsa
291
-
292
- # extract features for each frame
293
- if self.with_predeblur:
294
- self.predeblur = PredeblurModule(num_feat=num_feat, hr_in=self.hr_in)
295
- self.conv_1x1 = nn.Conv2d(num_feat, num_feat, 1, 1)
296
- else:
297
- self.conv_first = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1)
298
-
299
- # extract pyramid features
300
- self.feature_extraction = make_layer(ResidualBlockNoBN, num_extract_block, num_feat=num_feat)
301
- self.conv_l2_1 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
302
- self.conv_l2_2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
303
- self.conv_l3_1 = nn.Conv2d(num_feat, num_feat, 3, 2, 1)
304
- self.conv_l3_2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
305
-
306
- # pcd and tsa module
307
- self.pcd_align = PCDAlignment(num_feat=num_feat, deformable_groups=deformable_groups)
308
- if self.with_tsa:
309
- self.fusion = TSAFusion(num_feat=num_feat, num_frame=num_frame, center_frame_idx=self.center_frame_idx)
310
- else:
311
- self.fusion = nn.Conv2d(num_frame * num_feat, num_feat, 1, 1)
312
-
313
- # reconstruction
314
- self.reconstruction = make_layer(ResidualBlockNoBN, num_reconstruct_block, num_feat=num_feat)
315
- # upsample
316
- self.upconv1 = nn.Conv2d(num_feat, num_feat * 4, 3, 1, 1)
317
- self.upconv2 = nn.Conv2d(num_feat, 64 * 4, 3, 1, 1)
318
- self.pixel_shuffle = nn.PixelShuffle(2)
319
- self.conv_hr = nn.Conv2d(64, 64, 3, 1, 1)
320
- self.conv_last = nn.Conv2d(64, 3, 3, 1, 1)
321
-
322
- # activation function
323
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
324
-
325
- def forward(self, x):
326
- b, t, c, h, w = x.size()
327
- if self.hr_in:
328
- assert h % 16 == 0 and w % 16 == 0, ('The height and width must be multiple of 16.')
329
- else:
330
- assert h % 4 == 0 and w % 4 == 0, ('The height and width must be multiple of 4.')
331
-
332
- x_center = x[:, self.center_frame_idx, :, :, :].contiguous()
333
-
334
- # extract features for each frame
335
- # L1
336
- if self.with_predeblur:
337
- feat_l1 = self.conv_1x1(self.predeblur(x.view(-1, c, h, w)))
338
- if self.hr_in:
339
- h, w = h // 4, w // 4
340
- else:
341
- feat_l1 = self.lrelu(self.conv_first(x.view(-1, c, h, w)))
342
-
343
- feat_l1 = self.feature_extraction(feat_l1)
344
- # L2
345
- feat_l2 = self.lrelu(self.conv_l2_1(feat_l1))
346
- feat_l2 = self.lrelu(self.conv_l2_2(feat_l2))
347
- # L3
348
- feat_l3 = self.lrelu(self.conv_l3_1(feat_l2))
349
- feat_l3 = self.lrelu(self.conv_l3_2(feat_l3))
350
-
351
- feat_l1 = feat_l1.view(b, t, -1, h, w)
352
- feat_l2 = feat_l2.view(b, t, -1, h // 2, w // 2)
353
- feat_l3 = feat_l3.view(b, t, -1, h // 4, w // 4)
354
-
355
- # PCD alignment
356
- ref_feat_l = [ # reference feature list
357
- feat_l1[:, self.center_frame_idx, :, :, :].clone(), feat_l2[:, self.center_frame_idx, :, :, :].clone(),
358
- feat_l3[:, self.center_frame_idx, :, :, :].clone()
359
- ]
360
- aligned_feat = []
361
- for i in range(t):
362
- nbr_feat_l = [ # neighboring feature list
363
- feat_l1[:, i, :, :, :].clone(), feat_l2[:, i, :, :, :].clone(), feat_l3[:, i, :, :, :].clone()
364
- ]
365
- aligned_feat.append(self.pcd_align(nbr_feat_l, ref_feat_l))
366
- aligned_feat = torch.stack(aligned_feat, dim=1) # (b, t, c, h, w)
367
-
368
- if not self.with_tsa:
369
- aligned_feat = aligned_feat.view(b, -1, h, w)
370
- feat = self.fusion(aligned_feat)
371
-
372
- out = self.reconstruction(feat)
373
- out = self.lrelu(self.pixel_shuffle(self.upconv1(out)))
374
- out = self.lrelu(self.pixel_shuffle(self.upconv2(out)))
375
- out = self.lrelu(self.conv_hr(out))
376
- out = self.conv_last(out)
377
- if self.hr_in:
378
- base = x_center
379
- else:
380
- base = F.interpolate(x_center, scale_factor=4, mode='bilinear', align_corners=False)
381
- out += base
382
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/hifacegan_arch.py DELETED
@@ -1,260 +0,0 @@
1
- import numpy as np
2
- import torch
3
- import torch.nn as nn
4
- import torch.nn.functional as F
5
-
6
- from basicsr.utils.registry import ARCH_REGISTRY
7
- from .hifacegan_util import BaseNetwork, LIPEncoder, SPADEResnetBlock, get_nonspade_norm_layer
8
-
9
-
10
- class SPADEGenerator(BaseNetwork):
11
- """Generator with SPADEResBlock"""
12
-
13
- def __init__(self,
14
- num_in_ch=3,
15
- num_feat=64,
16
- use_vae=False,
17
- z_dim=256,
18
- crop_size=512,
19
- norm_g='spectralspadesyncbatch3x3',
20
- is_train=True,
21
- init_train_phase=3): # progressive training disabled
22
- super().__init__()
23
- self.nf = num_feat
24
- self.input_nc = num_in_ch
25
- self.is_train = is_train
26
- self.train_phase = init_train_phase
27
-
28
- self.scale_ratio = 5 # hardcoded now
29
- self.sw = crop_size // (2**self.scale_ratio)
30
- self.sh = self.sw # 20210519: By default use square image, aspect_ratio = 1.0
31
-
32
- if use_vae:
33
- # In case of VAE, we will sample from random z vector
34
- self.fc = nn.Linear(z_dim, 16 * self.nf * self.sw * self.sh)
35
- else:
36
- # Otherwise, we make the network deterministic by starting with
37
- # downsampled segmentation map instead of random z
38
- self.fc = nn.Conv2d(num_in_ch, 16 * self.nf, 3, padding=1)
39
-
40
- self.head_0 = SPADEResnetBlock(16 * self.nf, 16 * self.nf, norm_g)
41
-
42
- self.g_middle_0 = SPADEResnetBlock(16 * self.nf, 16 * self.nf, norm_g)
43
- self.g_middle_1 = SPADEResnetBlock(16 * self.nf, 16 * self.nf, norm_g)
44
-
45
- self.ups = nn.ModuleList([
46
- SPADEResnetBlock(16 * self.nf, 8 * self.nf, norm_g),
47
- SPADEResnetBlock(8 * self.nf, 4 * self.nf, norm_g),
48
- SPADEResnetBlock(4 * self.nf, 2 * self.nf, norm_g),
49
- SPADEResnetBlock(2 * self.nf, 1 * self.nf, norm_g)
50
- ])
51
-
52
- self.to_rgbs = nn.ModuleList([
53
- nn.Conv2d(8 * self.nf, 3, 3, padding=1),
54
- nn.Conv2d(4 * self.nf, 3, 3, padding=1),
55
- nn.Conv2d(2 * self.nf, 3, 3, padding=1),
56
- nn.Conv2d(1 * self.nf, 3, 3, padding=1)
57
- ])
58
-
59
- self.up = nn.Upsample(scale_factor=2)
60
-
61
- def encode(self, input_tensor):
62
- """
63
- Encode input_tensor into feature maps, can be overridden in derived classes
64
- Default: nearest downsampling of 2**5 = 32 times
65
- """
66
- h, w = input_tensor.size()[-2:]
67
- sh, sw = h // 2**self.scale_ratio, w // 2**self.scale_ratio
68
- x = F.interpolate(input_tensor, size=(sh, sw))
69
- return self.fc(x)
70
-
71
- def forward(self, x):
72
- # In oroginal SPADE, seg means a segmentation map, but here we use x instead.
73
- seg = x
74
-
75
- x = self.encode(x)
76
- x = self.head_0(x, seg)
77
-
78
- x = self.up(x)
79
- x = self.g_middle_0(x, seg)
80
- x = self.g_middle_1(x, seg)
81
-
82
- if self.is_train:
83
- phase = self.train_phase + 1
84
- else:
85
- phase = len(self.to_rgbs)
86
-
87
- for i in range(phase):
88
- x = self.up(x)
89
- x = self.ups[i](x, seg)
90
-
91
- x = self.to_rgbs[phase - 1](F.leaky_relu(x, 2e-1))
92
- x = torch.tanh(x)
93
-
94
- return x
95
-
96
- def mixed_guidance_forward(self, input_x, seg=None, n=0, mode='progressive'):
97
- """
98
- A helper class for subspace visualization. Input and seg are different images.
99
- For the first n levels (including encoder) we use input, for the rest we use seg.
100
-
101
- If mode = 'progressive', the output's like: AAABBB
102
- If mode = 'one_plug', the output's like: AAABAA
103
- If mode = 'one_ablate', the output's like: BBBABB
104
- """
105
-
106
- if seg is None:
107
- return self.forward(input_x)
108
-
109
- if self.is_train:
110
- phase = self.train_phase + 1
111
- else:
112
- phase = len(self.to_rgbs)
113
-
114
- if mode == 'progressive':
115
- n = max(min(n, 4 + phase), 0)
116
- guide_list = [input_x] * n + [seg] * (4 + phase - n)
117
- elif mode == 'one_plug':
118
- n = max(min(n, 4 + phase - 1), 0)
119
- guide_list = [seg] * (4 + phase)
120
- guide_list[n] = input_x
121
- elif mode == 'one_ablate':
122
- if n > 3 + phase:
123
- return self.forward(input_x)
124
- guide_list = [input_x] * (4 + phase)
125
- guide_list[n] = seg
126
-
127
- x = self.encode(guide_list[0])
128
- x = self.head_0(x, guide_list[1])
129
-
130
- x = self.up(x)
131
- x = self.g_middle_0(x, guide_list[2])
132
- x = self.g_middle_1(x, guide_list[3])
133
-
134
- for i in range(phase):
135
- x = self.up(x)
136
- x = self.ups[i](x, guide_list[4 + i])
137
-
138
- x = self.to_rgbs[phase - 1](F.leaky_relu(x, 2e-1))
139
- x = torch.tanh(x)
140
-
141
- return x
142
-
143
-
144
- @ARCH_REGISTRY.register()
145
- class HiFaceGAN(SPADEGenerator):
146
- """
147
- HiFaceGAN: SPADEGenerator with a learnable feature encoder
148
- Current encoder design: LIPEncoder
149
- """
150
-
151
- def __init__(self,
152
- num_in_ch=3,
153
- num_feat=64,
154
- use_vae=False,
155
- z_dim=256,
156
- crop_size=512,
157
- norm_g='spectralspadesyncbatch3x3',
158
- is_train=True,
159
- init_train_phase=3):
160
- super().__init__(num_in_ch, num_feat, use_vae, z_dim, crop_size, norm_g, is_train, init_train_phase)
161
- self.lip_encoder = LIPEncoder(num_in_ch, num_feat, self.sw, self.sh, self.scale_ratio)
162
-
163
- def encode(self, input_tensor):
164
- return self.lip_encoder(input_tensor)
165
-
166
-
167
- @ARCH_REGISTRY.register()
168
- class HiFaceGANDiscriminator(BaseNetwork):
169
- """
170
- Inspired by pix2pixHD multiscale discriminator.
171
-
172
- Args:
173
- num_in_ch (int): Channel number of inputs. Default: 3.
174
- num_out_ch (int): Channel number of outputs. Default: 3.
175
- conditional_d (bool): Whether use conditional discriminator.
176
- Default: True.
177
- num_d (int): Number of Multiscale discriminators. Default: 3.
178
- n_layers_d (int): Number of downsample layers in each D. Default: 4.
179
- num_feat (int): Channel number of base intermediate features.
180
- Default: 64.
181
- norm_d (str): String to determine normalization layers in D.
182
- Choices: [spectral][instance/batch/syncbatch]
183
- Default: 'spectralinstance'.
184
- keep_features (bool): Keep intermediate features for matching loss, etc.
185
- Default: True.
186
- """
187
-
188
- def __init__(self,
189
- num_in_ch=3,
190
- num_out_ch=3,
191
- conditional_d=True,
192
- num_d=2,
193
- n_layers_d=4,
194
- num_feat=64,
195
- norm_d='spectralinstance',
196
- keep_features=True):
197
- super().__init__()
198
- self.num_d = num_d
199
-
200
- input_nc = num_in_ch
201
- if conditional_d:
202
- input_nc += num_out_ch
203
-
204
- for i in range(num_d):
205
- subnet_d = NLayerDiscriminator(input_nc, n_layers_d, num_feat, norm_d, keep_features)
206
- self.add_module(f'discriminator_{i}', subnet_d)
207
-
208
- def downsample(self, x):
209
- return F.avg_pool2d(x, kernel_size=3, stride=2, padding=[1, 1], count_include_pad=False)
210
-
211
- # Returns list of lists of discriminator outputs.
212
- # The final result is of size opt.num_d x opt.n_layers_D
213
- def forward(self, x):
214
- result = []
215
- for _, _net_d in self.named_children():
216
- out = _net_d(x)
217
- result.append(out)
218
- x = self.downsample(x)
219
-
220
- return result
221
-
222
-
223
- class NLayerDiscriminator(BaseNetwork):
224
- """Defines the PatchGAN discriminator with the specified arguments."""
225
-
226
- def __init__(self, input_nc, n_layers_d, num_feat, norm_d, keep_features):
227
- super().__init__()
228
- kw = 4
229
- padw = int(np.ceil((kw - 1.0) / 2))
230
- nf = num_feat
231
- self.keep_features = keep_features
232
-
233
- norm_layer = get_nonspade_norm_layer(norm_d)
234
- sequence = [[nn.Conv2d(input_nc, nf, kernel_size=kw, stride=2, padding=padw), nn.LeakyReLU(0.2, False)]]
235
-
236
- for n in range(1, n_layers_d):
237
- nf_prev = nf
238
- nf = min(nf * 2, 512)
239
- stride = 1 if n == n_layers_d - 1 else 2
240
- sequence += [[
241
- norm_layer(nn.Conv2d(nf_prev, nf, kernel_size=kw, stride=stride, padding=padw)),
242
- nn.LeakyReLU(0.2, False)
243
- ]]
244
-
245
- sequence += [[nn.Conv2d(nf, 1, kernel_size=kw, stride=1, padding=padw)]]
246
-
247
- # We divide the layers into groups to extract intermediate layer outputs
248
- for n in range(len(sequence)):
249
- self.add_module('model' + str(n), nn.Sequential(*sequence[n]))
250
-
251
- def forward(self, x):
252
- results = [x]
253
- for submodel in self.children():
254
- intermediate_output = submodel(results[-1])
255
- results.append(intermediate_output)
256
-
257
- if self.keep_features:
258
- return results[1:]
259
- else:
260
- return results[-1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/hifacegan_util.py DELETED
@@ -1,255 +0,0 @@
1
- import re
2
- import torch
3
- import torch.nn as nn
4
- import torch.nn.functional as F
5
- from torch.nn import init
6
- # Warning: spectral norm could be buggy
7
- # under eval mode and multi-GPU inference
8
- # A workaround is sticking to single-GPU inference and train mode
9
- from torch.nn.utils import spectral_norm
10
-
11
-
12
- class SPADE(nn.Module):
13
-
14
- def __init__(self, config_text, norm_nc, label_nc):
15
- super().__init__()
16
-
17
- assert config_text.startswith('spade')
18
- parsed = re.search('spade(\\D+)(\\d)x\\d', config_text)
19
- param_free_norm_type = str(parsed.group(1))
20
- ks = int(parsed.group(2))
21
-
22
- if param_free_norm_type == 'instance':
23
- self.param_free_norm = nn.InstanceNorm2d(norm_nc)
24
- elif param_free_norm_type == 'syncbatch':
25
- print('SyncBatchNorm is currently not supported under single-GPU mode, switch to "instance" instead')
26
- self.param_free_norm = nn.InstanceNorm2d(norm_nc)
27
- elif param_free_norm_type == 'batch':
28
- self.param_free_norm = nn.BatchNorm2d(norm_nc, affine=False)
29
- else:
30
- raise ValueError(f'{param_free_norm_type} is not a recognized param-free norm type in SPADE')
31
-
32
- # The dimension of the intermediate embedding space. Yes, hardcoded.
33
- nhidden = 128 if norm_nc > 128 else norm_nc
34
-
35
- pw = ks // 2
36
- self.mlp_shared = nn.Sequential(nn.Conv2d(label_nc, nhidden, kernel_size=ks, padding=pw), nn.ReLU())
37
- self.mlp_gamma = nn.Conv2d(nhidden, norm_nc, kernel_size=ks, padding=pw, bias=False)
38
- self.mlp_beta = nn.Conv2d(nhidden, norm_nc, kernel_size=ks, padding=pw, bias=False)
39
-
40
- def forward(self, x, segmap):
41
-
42
- # Part 1. generate parameter-free normalized activations
43
- normalized = self.param_free_norm(x)
44
-
45
- # Part 2. produce scaling and bias conditioned on semantic map
46
- segmap = F.interpolate(segmap, size=x.size()[2:], mode='nearest')
47
- actv = self.mlp_shared(segmap)
48
- gamma = self.mlp_gamma(actv)
49
- beta = self.mlp_beta(actv)
50
-
51
- # apply scale and bias
52
- out = normalized * gamma + beta
53
-
54
- return out
55
-
56
-
57
- class SPADEResnetBlock(nn.Module):
58
- """
59
- ResNet block that uses SPADE. It differs from the ResNet block of pix2pixHD in that
60
- it takes in the segmentation map as input, learns the skip connection if necessary,
61
- and applies normalization first and then convolution.
62
- This architecture seemed like a standard architecture for unconditional or
63
- class-conditional GAN architecture using residual block.
64
- The code was inspired from https://github.com/LMescheder/GAN_stability.
65
- """
66
-
67
- def __init__(self, fin, fout, norm_g='spectralspadesyncbatch3x3', semantic_nc=3):
68
- super().__init__()
69
- # Attributes
70
- self.learned_shortcut = (fin != fout)
71
- fmiddle = min(fin, fout)
72
-
73
- # create conv layers
74
- self.conv_0 = nn.Conv2d(fin, fmiddle, kernel_size=3, padding=1)
75
- self.conv_1 = nn.Conv2d(fmiddle, fout, kernel_size=3, padding=1)
76
- if self.learned_shortcut:
77
- self.conv_s = nn.Conv2d(fin, fout, kernel_size=1, bias=False)
78
-
79
- # apply spectral norm if specified
80
- if 'spectral' in norm_g:
81
- self.conv_0 = spectral_norm(self.conv_0)
82
- self.conv_1 = spectral_norm(self.conv_1)
83
- if self.learned_shortcut:
84
- self.conv_s = spectral_norm(self.conv_s)
85
-
86
- # define normalization layers
87
- spade_config_str = norm_g.replace('spectral', '')
88
- self.norm_0 = SPADE(spade_config_str, fin, semantic_nc)
89
- self.norm_1 = SPADE(spade_config_str, fmiddle, semantic_nc)
90
- if self.learned_shortcut:
91
- self.norm_s = SPADE(spade_config_str, fin, semantic_nc)
92
-
93
- # note the resnet block with SPADE also takes in |seg|,
94
- # the semantic segmentation map as input
95
- def forward(self, x, seg):
96
- x_s = self.shortcut(x, seg)
97
- dx = self.conv_0(self.act(self.norm_0(x, seg)))
98
- dx = self.conv_1(self.act(self.norm_1(dx, seg)))
99
- out = x_s + dx
100
- return out
101
-
102
- def shortcut(self, x, seg):
103
- if self.learned_shortcut:
104
- x_s = self.conv_s(self.norm_s(x, seg))
105
- else:
106
- x_s = x
107
- return x_s
108
-
109
- def act(self, x):
110
- return F.leaky_relu(x, 2e-1)
111
-
112
-
113
- class BaseNetwork(nn.Module):
114
- """ A basis for hifacegan archs with custom initialization """
115
-
116
- def init_weights(self, init_type='normal', gain=0.02):
117
-
118
- def init_func(m):
119
- classname = m.__class__.__name__
120
- if classname.find('BatchNorm2d') != -1:
121
- if hasattr(m, 'weight') and m.weight is not None:
122
- init.normal_(m.weight.data, 1.0, gain)
123
- if hasattr(m, 'bias') and m.bias is not None:
124
- init.constant_(m.bias.data, 0.0)
125
- elif hasattr(m, 'weight') and (classname.find('Conv') != -1 or classname.find('Linear') != -1):
126
- if init_type == 'normal':
127
- init.normal_(m.weight.data, 0.0, gain)
128
- elif init_type == 'xavier':
129
- init.xavier_normal_(m.weight.data, gain=gain)
130
- elif init_type == 'xavier_uniform':
131
- init.xavier_uniform_(m.weight.data, gain=1.0)
132
- elif init_type == 'kaiming':
133
- init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
134
- elif init_type == 'orthogonal':
135
- init.orthogonal_(m.weight.data, gain=gain)
136
- elif init_type == 'none': # uses pytorch's default init method
137
- m.reset_parameters()
138
- else:
139
- raise NotImplementedError(f'initialization method [{init_type}] is not implemented')
140
- if hasattr(m, 'bias') and m.bias is not None:
141
- init.constant_(m.bias.data, 0.0)
142
-
143
- self.apply(init_func)
144
-
145
- # propagate to children
146
- for m in self.children():
147
- if hasattr(m, 'init_weights'):
148
- m.init_weights(init_type, gain)
149
-
150
- def forward(self, x):
151
- pass
152
-
153
-
154
- def lip2d(x, logit, kernel=3, stride=2, padding=1):
155
- weight = logit.exp()
156
- return F.avg_pool2d(x * weight, kernel, stride, padding) / F.avg_pool2d(weight, kernel, stride, padding)
157
-
158
-
159
- class SoftGate(nn.Module):
160
- COEFF = 12.0
161
-
162
- def forward(self, x):
163
- return torch.sigmoid(x).mul(self.COEFF)
164
-
165
-
166
- class SimplifiedLIP(nn.Module):
167
-
168
- def __init__(self, channels):
169
- super(SimplifiedLIP, self).__init__()
170
- self.logit = nn.Sequential(
171
- nn.Conv2d(channels, channels, 3, padding=1, bias=False), nn.InstanceNorm2d(channels, affine=True),
172
- SoftGate())
173
-
174
- def init_layer(self):
175
- self.logit[0].weight.data.fill_(0.0)
176
-
177
- def forward(self, x):
178
- frac = lip2d(x, self.logit(x))
179
- return frac
180
-
181
-
182
- class LIPEncoder(BaseNetwork):
183
- """Local Importance-based Pooling (Ziteng Gao et.al.,ICCV 2019)"""
184
-
185
- def __init__(self, input_nc, ngf, sw, sh, n_2xdown, norm_layer=nn.InstanceNorm2d):
186
- super().__init__()
187
- self.sw = sw
188
- self.sh = sh
189
- self.max_ratio = 16
190
- # 20200310: Several Convolution (stride 1) + LIP blocks, 4 fold
191
- kw = 3
192
- pw = (kw - 1) // 2
193
-
194
- model = [
195
- nn.Conv2d(input_nc, ngf, kw, stride=1, padding=pw, bias=False),
196
- norm_layer(ngf),
197
- nn.ReLU(),
198
- ]
199
- cur_ratio = 1
200
- for i in range(n_2xdown):
201
- next_ratio = min(cur_ratio * 2, self.max_ratio)
202
- model += [
203
- SimplifiedLIP(ngf * cur_ratio),
204
- nn.Conv2d(ngf * cur_ratio, ngf * next_ratio, kw, stride=1, padding=pw),
205
- norm_layer(ngf * next_ratio),
206
- ]
207
- cur_ratio = next_ratio
208
- if i < n_2xdown - 1:
209
- model += [nn.ReLU(inplace=True)]
210
-
211
- self.model = nn.Sequential(*model)
212
-
213
- def forward(self, x):
214
- return self.model(x)
215
-
216
-
217
- def get_nonspade_norm_layer(norm_type='instance'):
218
- # helper function to get # output channels of the previous layer
219
- def get_out_channel(layer):
220
- if hasattr(layer, 'out_channels'):
221
- return getattr(layer, 'out_channels')
222
- return layer.weight.size(0)
223
-
224
- # this function will be returned
225
- def add_norm_layer(layer):
226
- nonlocal norm_type
227
- if norm_type.startswith('spectral'):
228
- layer = spectral_norm(layer)
229
- subnorm_type = norm_type[len('spectral'):]
230
-
231
- if subnorm_type == 'none' or len(subnorm_type) == 0:
232
- return layer
233
-
234
- # remove bias in the previous layer, which is meaningless
235
- # since it has no effect after normalization
236
- if getattr(layer, 'bias', None) is not None:
237
- delattr(layer, 'bias')
238
- layer.register_parameter('bias', None)
239
-
240
- if subnorm_type == 'batch':
241
- norm_layer = nn.BatchNorm2d(get_out_channel(layer), affine=True)
242
- elif subnorm_type == 'sync_batch':
243
- print('SyncBatchNorm is currently not supported under single-GPU mode, switch to "instance" instead')
244
- # norm_layer = SynchronizedBatchNorm2d(
245
- # get_out_channel(layer), affine=True)
246
- norm_layer = nn.InstanceNorm2d(get_out_channel(layer), affine=False)
247
- elif subnorm_type == 'instance':
248
- norm_layer = nn.InstanceNorm2d(get_out_channel(layer), affine=False)
249
- else:
250
- raise ValueError(f'normalization layer {subnorm_type} is not recognized')
251
-
252
- return nn.Sequential(layer, norm_layer)
253
-
254
- print('This is a legacy from nvlabs/SPADE, and will be removed in future versions.')
255
- return add_norm_layer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/inception.py DELETED
@@ -1,307 +0,0 @@
1
- # Modified from https://github.com/mseitzer/pytorch-fid/blob/master/pytorch_fid/inception.py # noqa: E501
2
- # For FID metric
3
-
4
- import os
5
- import torch
6
- import torch.nn as nn
7
- import torch.nn.functional as F
8
- from torch.utils.model_zoo import load_url
9
- from torchvision import models
10
-
11
- # Inception weights ported to Pytorch from
12
- # http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz
13
- FID_WEIGHTS_URL = 'https://github.com/mseitzer/pytorch-fid/releases/download/fid_weights/pt_inception-2015-12-05-6726825d.pth' # noqa: E501
14
- LOCAL_FID_WEIGHTS = 'experiments/pretrained_models/pt_inception-2015-12-05-6726825d.pth' # noqa: E501
15
-
16
-
17
- class InceptionV3(nn.Module):
18
- """Pretrained InceptionV3 network returning feature maps"""
19
-
20
- # Index of default block of inception to return,
21
- # corresponds to output of final average pooling
22
- DEFAULT_BLOCK_INDEX = 3
23
-
24
- # Maps feature dimensionality to their output blocks indices
25
- BLOCK_INDEX_BY_DIM = {
26
- 64: 0, # First max pooling features
27
- 192: 1, # Second max pooling features
28
- 768: 2, # Pre-aux classifier features
29
- 2048: 3 # Final average pooling features
30
- }
31
-
32
- def __init__(self,
33
- output_blocks=(DEFAULT_BLOCK_INDEX),
34
- resize_input=True,
35
- normalize_input=True,
36
- requires_grad=False,
37
- use_fid_inception=True):
38
- """Build pretrained InceptionV3.
39
-
40
- Args:
41
- output_blocks (list[int]): Indices of blocks to return features of.
42
- Possible values are:
43
- - 0: corresponds to output of first max pooling
44
- - 1: corresponds to output of second max pooling
45
- - 2: corresponds to output which is fed to aux classifier
46
- - 3: corresponds to output of final average pooling
47
- resize_input (bool): If true, bilinearly resizes input to width and
48
- height 299 before feeding input to model. As the network
49
- without fully connected layers is fully convolutional, it
50
- should be able to handle inputs of arbitrary size, so resizing
51
- might not be strictly needed. Default: True.
52
- normalize_input (bool): If true, scales the input from range (0, 1)
53
- to the range the pretrained Inception network expects,
54
- namely (-1, 1). Default: True.
55
- requires_grad (bool): If true, parameters of the model require
56
- gradients. Possibly useful for finetuning the network.
57
- Default: False.
58
- use_fid_inception (bool): If true, uses the pretrained Inception
59
- model used in Tensorflow's FID implementation.
60
- If false, uses the pretrained Inception model available in
61
- torchvision. The FID Inception model has different weights
62
- and a slightly different structure from torchvision's
63
- Inception model. If you want to compute FID scores, you are
64
- strongly advised to set this parameter to true to get
65
- comparable results. Default: True.
66
- """
67
- super(InceptionV3, self).__init__()
68
-
69
- self.resize_input = resize_input
70
- self.normalize_input = normalize_input
71
- self.output_blocks = sorted(output_blocks)
72
- self.last_needed_block = max(output_blocks)
73
-
74
- assert self.last_needed_block <= 3, ('Last possible output block index is 3')
75
-
76
- self.blocks = nn.ModuleList()
77
-
78
- if use_fid_inception:
79
- inception = fid_inception_v3()
80
- else:
81
- try:
82
- inception = models.inception_v3(pretrained=True, init_weights=False)
83
- except TypeError:
84
- # pytorch < 1.5 does not have init_weights for inception_v3
85
- inception = models.inception_v3(pretrained=True)
86
-
87
- # Block 0: input to maxpool1
88
- block0 = [
89
- inception.Conv2d_1a_3x3, inception.Conv2d_2a_3x3, inception.Conv2d_2b_3x3,
90
- nn.MaxPool2d(kernel_size=3, stride=2)
91
- ]
92
- self.blocks.append(nn.Sequential(*block0))
93
-
94
- # Block 1: maxpool1 to maxpool2
95
- if self.last_needed_block >= 1:
96
- block1 = [inception.Conv2d_3b_1x1, inception.Conv2d_4a_3x3, nn.MaxPool2d(kernel_size=3, stride=2)]
97
- self.blocks.append(nn.Sequential(*block1))
98
-
99
- # Block 2: maxpool2 to aux classifier
100
- if self.last_needed_block >= 2:
101
- block2 = [
102
- inception.Mixed_5b,
103
- inception.Mixed_5c,
104
- inception.Mixed_5d,
105
- inception.Mixed_6a,
106
- inception.Mixed_6b,
107
- inception.Mixed_6c,
108
- inception.Mixed_6d,
109
- inception.Mixed_6e,
110
- ]
111
- self.blocks.append(nn.Sequential(*block2))
112
-
113
- # Block 3: aux classifier to final avgpool
114
- if self.last_needed_block >= 3:
115
- block3 = [
116
- inception.Mixed_7a, inception.Mixed_7b, inception.Mixed_7c,
117
- nn.AdaptiveAvgPool2d(output_size=(1, 1))
118
- ]
119
- self.blocks.append(nn.Sequential(*block3))
120
-
121
- for param in self.parameters():
122
- param.requires_grad = requires_grad
123
-
124
- def forward(self, x):
125
- """Get Inception feature maps.
126
-
127
- Args:
128
- x (Tensor): Input tensor of shape (b, 3, h, w).
129
- Values are expected to be in range (-1, 1). You can also input
130
- (0, 1) with setting normalize_input = True.
131
-
132
- Returns:
133
- list[Tensor]: Corresponding to the selected output block, sorted
134
- ascending by index.
135
- """
136
- output = []
137
-
138
- if self.resize_input:
139
- x = F.interpolate(x, size=(299, 299), mode='bilinear', align_corners=False)
140
-
141
- if self.normalize_input:
142
- x = 2 * x - 1 # Scale from range (0, 1) to range (-1, 1)
143
-
144
- for idx, block in enumerate(self.blocks):
145
- x = block(x)
146
- if idx in self.output_blocks:
147
- output.append(x)
148
-
149
- if idx == self.last_needed_block:
150
- break
151
-
152
- return output
153
-
154
-
155
- def fid_inception_v3():
156
- """Build pretrained Inception model for FID computation.
157
-
158
- The Inception model for FID computation uses a different set of weights
159
- and has a slightly different structure than torchvision's Inception.
160
-
161
- This method first constructs torchvision's Inception and then patches the
162
- necessary parts that are different in the FID Inception model.
163
- """
164
- try:
165
- inception = models.inception_v3(num_classes=1008, aux_logits=False, pretrained=False, init_weights=False)
166
- except TypeError:
167
- # pytorch < 1.5 does not have init_weights for inception_v3
168
- inception = models.inception_v3(num_classes=1008, aux_logits=False, pretrained=False)
169
-
170
- inception.Mixed_5b = FIDInceptionA(192, pool_features=32)
171
- inception.Mixed_5c = FIDInceptionA(256, pool_features=64)
172
- inception.Mixed_5d = FIDInceptionA(288, pool_features=64)
173
- inception.Mixed_6b = FIDInceptionC(768, channels_7x7=128)
174
- inception.Mixed_6c = FIDInceptionC(768, channels_7x7=160)
175
- inception.Mixed_6d = FIDInceptionC(768, channels_7x7=160)
176
- inception.Mixed_6e = FIDInceptionC(768, channels_7x7=192)
177
- inception.Mixed_7b = FIDInceptionE_1(1280)
178
- inception.Mixed_7c = FIDInceptionE_2(2048)
179
-
180
- if os.path.exists(LOCAL_FID_WEIGHTS):
181
- state_dict = torch.load(LOCAL_FID_WEIGHTS, map_location=lambda storage, loc: storage)
182
- else:
183
- state_dict = load_url(FID_WEIGHTS_URL, progress=True)
184
-
185
- inception.load_state_dict(state_dict)
186
- return inception
187
-
188
-
189
- class FIDInceptionA(models.inception.InceptionA):
190
- """InceptionA block patched for FID computation"""
191
-
192
- def __init__(self, in_channels, pool_features):
193
- super(FIDInceptionA, self).__init__(in_channels, pool_features)
194
-
195
- def forward(self, x):
196
- branch1x1 = self.branch1x1(x)
197
-
198
- branch5x5 = self.branch5x5_1(x)
199
- branch5x5 = self.branch5x5_2(branch5x5)
200
-
201
- branch3x3dbl = self.branch3x3dbl_1(x)
202
- branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl)
203
- branch3x3dbl = self.branch3x3dbl_3(branch3x3dbl)
204
-
205
- # Patch: Tensorflow's average pool does not use the padded zero's in
206
- # its average calculation
207
- branch_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1, count_include_pad=False)
208
- branch_pool = self.branch_pool(branch_pool)
209
-
210
- outputs = [branch1x1, branch5x5, branch3x3dbl, branch_pool]
211
- return torch.cat(outputs, 1)
212
-
213
-
214
- class FIDInceptionC(models.inception.InceptionC):
215
- """InceptionC block patched for FID computation"""
216
-
217
- def __init__(self, in_channels, channels_7x7):
218
- super(FIDInceptionC, self).__init__(in_channels, channels_7x7)
219
-
220
- def forward(self, x):
221
- branch1x1 = self.branch1x1(x)
222
-
223
- branch7x7 = self.branch7x7_1(x)
224
- branch7x7 = self.branch7x7_2(branch7x7)
225
- branch7x7 = self.branch7x7_3(branch7x7)
226
-
227
- branch7x7dbl = self.branch7x7dbl_1(x)
228
- branch7x7dbl = self.branch7x7dbl_2(branch7x7dbl)
229
- branch7x7dbl = self.branch7x7dbl_3(branch7x7dbl)
230
- branch7x7dbl = self.branch7x7dbl_4(branch7x7dbl)
231
- branch7x7dbl = self.branch7x7dbl_5(branch7x7dbl)
232
-
233
- # Patch: Tensorflow's average pool does not use the padded zero's in
234
- # its average calculation
235
- branch_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1, count_include_pad=False)
236
- branch_pool = self.branch_pool(branch_pool)
237
-
238
- outputs = [branch1x1, branch7x7, branch7x7dbl, branch_pool]
239
- return torch.cat(outputs, 1)
240
-
241
-
242
- class FIDInceptionE_1(models.inception.InceptionE):
243
- """First InceptionE block patched for FID computation"""
244
-
245
- def __init__(self, in_channels):
246
- super(FIDInceptionE_1, self).__init__(in_channels)
247
-
248
- def forward(self, x):
249
- branch1x1 = self.branch1x1(x)
250
-
251
- branch3x3 = self.branch3x3_1(x)
252
- branch3x3 = [
253
- self.branch3x3_2a(branch3x3),
254
- self.branch3x3_2b(branch3x3),
255
- ]
256
- branch3x3 = torch.cat(branch3x3, 1)
257
-
258
- branch3x3dbl = self.branch3x3dbl_1(x)
259
- branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl)
260
- branch3x3dbl = [
261
- self.branch3x3dbl_3a(branch3x3dbl),
262
- self.branch3x3dbl_3b(branch3x3dbl),
263
- ]
264
- branch3x3dbl = torch.cat(branch3x3dbl, 1)
265
-
266
- # Patch: Tensorflow's average pool does not use the padded zero's in
267
- # its average calculation
268
- branch_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1, count_include_pad=False)
269
- branch_pool = self.branch_pool(branch_pool)
270
-
271
- outputs = [branch1x1, branch3x3, branch3x3dbl, branch_pool]
272
- return torch.cat(outputs, 1)
273
-
274
-
275
- class FIDInceptionE_2(models.inception.InceptionE):
276
- """Second InceptionE block patched for FID computation"""
277
-
278
- def __init__(self, in_channels):
279
- super(FIDInceptionE_2, self).__init__(in_channels)
280
-
281
- def forward(self, x):
282
- branch1x1 = self.branch1x1(x)
283
-
284
- branch3x3 = self.branch3x3_1(x)
285
- branch3x3 = [
286
- self.branch3x3_2a(branch3x3),
287
- self.branch3x3_2b(branch3x3),
288
- ]
289
- branch3x3 = torch.cat(branch3x3, 1)
290
-
291
- branch3x3dbl = self.branch3x3dbl_1(x)
292
- branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl)
293
- branch3x3dbl = [
294
- self.branch3x3dbl_3a(branch3x3dbl),
295
- self.branch3x3dbl_3b(branch3x3dbl),
296
- ]
297
- branch3x3dbl = torch.cat(branch3x3dbl, 1)
298
-
299
- # Patch: The FID Inception model uses max pooling instead of average
300
- # pooling. This is likely an error in this specific Inception
301
- # implementation, as other Inception models use average pooling here
302
- # (which matches the description in the paper).
303
- branch_pool = F.max_pool2d(x, kernel_size=3, stride=1, padding=1)
304
- branch_pool = self.branch_pool(branch_pool)
305
-
306
- outputs = [branch1x1, branch3x3, branch3x3dbl, branch_pool]
307
- return torch.cat(outputs, 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/rcan_arch.py DELETED
@@ -1,135 +0,0 @@
1
- import torch
2
- from torch import nn as nn
3
-
4
- from basicsr.utils.registry import ARCH_REGISTRY
5
- from .arch_util import Upsample, make_layer
6
-
7
-
8
- class ChannelAttention(nn.Module):
9
- """Channel attention used in RCAN.
10
-
11
- Args:
12
- num_feat (int): Channel number of intermediate features.
13
- squeeze_factor (int): Channel squeeze factor. Default: 16.
14
- """
15
-
16
- def __init__(self, num_feat, squeeze_factor=16):
17
- super(ChannelAttention, self).__init__()
18
- self.attention = nn.Sequential(
19
- nn.AdaptiveAvgPool2d(1), nn.Conv2d(num_feat, num_feat // squeeze_factor, 1, padding=0),
20
- nn.ReLU(inplace=True), nn.Conv2d(num_feat // squeeze_factor, num_feat, 1, padding=0), nn.Sigmoid())
21
-
22
- def forward(self, x):
23
- y = self.attention(x)
24
- return x * y
25
-
26
-
27
- class RCAB(nn.Module):
28
- """Residual Channel Attention Block (RCAB) used in RCAN.
29
-
30
- Args:
31
- num_feat (int): Channel number of intermediate features.
32
- squeeze_factor (int): Channel squeeze factor. Default: 16.
33
- res_scale (float): Scale the residual. Default: 1.
34
- """
35
-
36
- def __init__(self, num_feat, squeeze_factor=16, res_scale=1):
37
- super(RCAB, self).__init__()
38
- self.res_scale = res_scale
39
-
40
- self.rcab = nn.Sequential(
41
- nn.Conv2d(num_feat, num_feat, 3, 1, 1), nn.ReLU(True), nn.Conv2d(num_feat, num_feat, 3, 1, 1),
42
- ChannelAttention(num_feat, squeeze_factor))
43
-
44
- def forward(self, x):
45
- res = self.rcab(x) * self.res_scale
46
- return res + x
47
-
48
-
49
- class ResidualGroup(nn.Module):
50
- """Residual Group of RCAB.
51
-
52
- Args:
53
- num_feat (int): Channel number of intermediate features.
54
- num_block (int): Block number in the body network.
55
- squeeze_factor (int): Channel squeeze factor. Default: 16.
56
- res_scale (float): Scale the residual. Default: 1.
57
- """
58
-
59
- def __init__(self, num_feat, num_block, squeeze_factor=16, res_scale=1):
60
- super(ResidualGroup, self).__init__()
61
-
62
- self.residual_group = make_layer(
63
- RCAB, num_block, num_feat=num_feat, squeeze_factor=squeeze_factor, res_scale=res_scale)
64
- self.conv = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
65
-
66
- def forward(self, x):
67
- res = self.conv(self.residual_group(x))
68
- return res + x
69
-
70
-
71
- @ARCH_REGISTRY.register()
72
- class RCAN(nn.Module):
73
- """Residual Channel Attention Networks.
74
-
75
- ``Paper: Image Super-Resolution Using Very Deep Residual Channel Attention Networks``
76
-
77
- Reference: https://github.com/yulunzhang/RCAN
78
-
79
- Args:
80
- num_in_ch (int): Channel number of inputs.
81
- num_out_ch (int): Channel number of outputs.
82
- num_feat (int): Channel number of intermediate features.
83
- Default: 64.
84
- num_group (int): Number of ResidualGroup. Default: 10.
85
- num_block (int): Number of RCAB in ResidualGroup. Default: 16.
86
- squeeze_factor (int): Channel squeeze factor. Default: 16.
87
- upscale (int): Upsampling factor. Support 2^n and 3.
88
- Default: 4.
89
- res_scale (float): Used to scale the residual in residual block.
90
- Default: 1.
91
- img_range (float): Image range. Default: 255.
92
- rgb_mean (tuple[float]): Image mean in RGB orders.
93
- Default: (0.4488, 0.4371, 0.4040), calculated from DIV2K dataset.
94
- """
95
-
96
- def __init__(self,
97
- num_in_ch,
98
- num_out_ch,
99
- num_feat=64,
100
- num_group=10,
101
- num_block=16,
102
- squeeze_factor=16,
103
- upscale=4,
104
- res_scale=1,
105
- img_range=255.,
106
- rgb_mean=(0.4488, 0.4371, 0.4040)):
107
- super(RCAN, self).__init__()
108
-
109
- self.img_range = img_range
110
- self.mean = torch.Tensor(rgb_mean).view(1, 3, 1, 1)
111
-
112
- self.conv_first = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1)
113
- self.body = make_layer(
114
- ResidualGroup,
115
- num_group,
116
- num_feat=num_feat,
117
- num_block=num_block,
118
- squeeze_factor=squeeze_factor,
119
- res_scale=res_scale)
120
- self.conv_after_body = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
121
- self.upsample = Upsample(upscale, num_feat)
122
- self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
123
-
124
- def forward(self, x):
125
- self.mean = self.mean.type_as(x)
126
-
127
- x = (x - self.mean) * self.img_range
128
- x = self.conv_first(x)
129
- res = self.conv_after_body(self.body(x))
130
- res += x
131
-
132
- x = self.conv_last(self.upsample(res))
133
- x = x / self.img_range + self.mean
134
-
135
- return x
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/ridnet_arch.py DELETED
@@ -1,180 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
-
4
- from basicsr.utils.registry import ARCH_REGISTRY
5
- from .arch_util import ResidualBlockNoBN, make_layer
6
-
7
-
8
- class MeanShift(nn.Conv2d):
9
- """ Data normalization with mean and std.
10
-
11
- Args:
12
- rgb_range (int): Maximum value of RGB.
13
- rgb_mean (list[float]): Mean for RGB channels.
14
- rgb_std (list[float]): Std for RGB channels.
15
- sign (int): For subtraction, sign is -1, for addition, sign is 1.
16
- Default: -1.
17
- requires_grad (bool): Whether to update the self.weight and self.bias.
18
- Default: True.
19
- """
20
-
21
- def __init__(self, rgb_range, rgb_mean, rgb_std, sign=-1, requires_grad=True):
22
- super(MeanShift, self).__init__(3, 3, kernel_size=1)
23
- std = torch.Tensor(rgb_std)
24
- self.weight.data = torch.eye(3).view(3, 3, 1, 1)
25
- self.weight.data.div_(std.view(3, 1, 1, 1))
26
- self.bias.data = sign * rgb_range * torch.Tensor(rgb_mean)
27
- self.bias.data.div_(std)
28
- self.requires_grad = requires_grad
29
-
30
-
31
- class EResidualBlockNoBN(nn.Module):
32
- """Enhanced Residual block without BN.
33
-
34
- There are three convolution layers in residual branch.
35
- """
36
-
37
- def __init__(self, in_channels, out_channels):
38
- super(EResidualBlockNoBN, self).__init__()
39
-
40
- self.body = nn.Sequential(
41
- nn.Conv2d(in_channels, out_channels, 3, 1, 1),
42
- nn.ReLU(inplace=True),
43
- nn.Conv2d(out_channels, out_channels, 3, 1, 1),
44
- nn.ReLU(inplace=True),
45
- nn.Conv2d(out_channels, out_channels, 1, 1, 0),
46
- )
47
- self.relu = nn.ReLU(inplace=True)
48
-
49
- def forward(self, x):
50
- out = self.body(x)
51
- out = self.relu(out + x)
52
- return out
53
-
54
-
55
- class MergeRun(nn.Module):
56
- """ Merge-and-run unit.
57
-
58
- This unit contains two branches with different dilated convolutions,
59
- followed by a convolution to process the concatenated features.
60
-
61
- Paper: Real Image Denoising with Feature Attention
62
- Ref git repo: https://github.com/saeed-anwar/RIDNet
63
- """
64
-
65
- def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1):
66
- super(MergeRun, self).__init__()
67
-
68
- self.dilation1 = nn.Sequential(
69
- nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding), nn.ReLU(inplace=True),
70
- nn.Conv2d(out_channels, out_channels, kernel_size, stride, 2, 2), nn.ReLU(inplace=True))
71
- self.dilation2 = nn.Sequential(
72
- nn.Conv2d(in_channels, out_channels, kernel_size, stride, 3, 3), nn.ReLU(inplace=True),
73
- nn.Conv2d(out_channels, out_channels, kernel_size, stride, 4, 4), nn.ReLU(inplace=True))
74
-
75
- self.aggregation = nn.Sequential(
76
- nn.Conv2d(out_channels * 2, out_channels, kernel_size, stride, padding), nn.ReLU(inplace=True))
77
-
78
- def forward(self, x):
79
- dilation1 = self.dilation1(x)
80
- dilation2 = self.dilation2(x)
81
- out = torch.cat([dilation1, dilation2], dim=1)
82
- out = self.aggregation(out)
83
- out = out + x
84
- return out
85
-
86
-
87
- class ChannelAttention(nn.Module):
88
- """Channel attention.
89
-
90
- Args:
91
- num_feat (int): Channel number of intermediate features.
92
- squeeze_factor (int): Channel squeeze factor. Default:
93
- """
94
-
95
- def __init__(self, mid_channels, squeeze_factor=16):
96
- super(ChannelAttention, self).__init__()
97
- self.attention = nn.Sequential(
98
- nn.AdaptiveAvgPool2d(1), nn.Conv2d(mid_channels, mid_channels // squeeze_factor, 1, padding=0),
99
- nn.ReLU(inplace=True), nn.Conv2d(mid_channels // squeeze_factor, mid_channels, 1, padding=0), nn.Sigmoid())
100
-
101
- def forward(self, x):
102
- y = self.attention(x)
103
- return x * y
104
-
105
-
106
- class EAM(nn.Module):
107
- """Enhancement attention modules (EAM) in RIDNet.
108
-
109
- This module contains a merge-and-run unit, a residual block,
110
- an enhanced residual block and a feature attention unit.
111
-
112
- Attributes:
113
- merge: The merge-and-run unit.
114
- block1: The residual block.
115
- block2: The enhanced residual block.
116
- ca: The feature/channel attention unit.
117
- """
118
-
119
- def __init__(self, in_channels, mid_channels, out_channels):
120
- super(EAM, self).__init__()
121
-
122
- self.merge = MergeRun(in_channels, mid_channels)
123
- self.block1 = ResidualBlockNoBN(mid_channels)
124
- self.block2 = EResidualBlockNoBN(mid_channels, out_channels)
125
- self.ca = ChannelAttention(out_channels)
126
- # The residual block in the paper contains a relu after addition.
127
- self.relu = nn.ReLU(inplace=True)
128
-
129
- def forward(self, x):
130
- out = self.merge(x)
131
- out = self.relu(self.block1(out))
132
- out = self.block2(out)
133
- out = self.ca(out)
134
- return out
135
-
136
-
137
- @ARCH_REGISTRY.register()
138
- class RIDNet(nn.Module):
139
- """RIDNet: Real Image Denoising with Feature Attention.
140
-
141
- Ref git repo: https://github.com/saeed-anwar/RIDNet
142
-
143
- Args:
144
- in_channels (int): Channel number of inputs.
145
- mid_channels (int): Channel number of EAM modules.
146
- Default: 64.
147
- out_channels (int): Channel number of outputs.
148
- num_block (int): Number of EAM. Default: 4.
149
- img_range (float): Image range. Default: 255.
150
- rgb_mean (tuple[float]): Image mean in RGB orders.
151
- Default: (0.4488, 0.4371, 0.4040), calculated from DIV2K dataset.
152
- """
153
-
154
- def __init__(self,
155
- in_channels,
156
- mid_channels,
157
- out_channels,
158
- num_block=4,
159
- img_range=255.,
160
- rgb_mean=(0.4488, 0.4371, 0.4040),
161
- rgb_std=(1.0, 1.0, 1.0)):
162
- super(RIDNet, self).__init__()
163
-
164
- self.sub_mean = MeanShift(img_range, rgb_mean, rgb_std)
165
- self.add_mean = MeanShift(img_range, rgb_mean, rgb_std, 1)
166
-
167
- self.head = nn.Conv2d(in_channels, mid_channels, 3, 1, 1)
168
- self.body = make_layer(
169
- EAM, num_block, in_channels=mid_channels, mid_channels=mid_channels, out_channels=mid_channels)
170
- self.tail = nn.Conv2d(mid_channels, out_channels, 3, 1, 1)
171
-
172
- self.relu = nn.ReLU(inplace=True)
173
-
174
- def forward(self, x):
175
- res = self.sub_mean(x)
176
- res = self.tail(self.body(self.relu(self.head(res))))
177
- res = self.add_mean(res)
178
-
179
- out = x + res
180
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/rrdbnet_arch.py DELETED
@@ -1,119 +0,0 @@
1
- import torch
2
- from torch import nn as nn
3
- from torch.nn import functional as F
4
-
5
- from basicsr.utils.registry import ARCH_REGISTRY
6
- from .arch_util import default_init_weights, make_layer, pixel_unshuffle
7
-
8
-
9
- class ResidualDenseBlock(nn.Module):
10
- """Residual Dense Block.
11
-
12
- Used in RRDB block in ESRGAN.
13
-
14
- Args:
15
- num_feat (int): Channel number of intermediate features.
16
- num_grow_ch (int): Channels for each growth.
17
- """
18
-
19
- def __init__(self, num_feat=64, num_grow_ch=32):
20
- super(ResidualDenseBlock, self).__init__()
21
- self.conv1 = nn.Conv2d(num_feat, num_grow_ch, 3, 1, 1)
22
- self.conv2 = nn.Conv2d(num_feat + num_grow_ch, num_grow_ch, 3, 1, 1)
23
- self.conv3 = nn.Conv2d(num_feat + 2 * num_grow_ch, num_grow_ch, 3, 1, 1)
24
- self.conv4 = nn.Conv2d(num_feat + 3 * num_grow_ch, num_grow_ch, 3, 1, 1)
25
- self.conv5 = nn.Conv2d(num_feat + 4 * num_grow_ch, num_feat, 3, 1, 1)
26
-
27
- self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True)
28
-
29
- # initialization
30
- default_init_weights([self.conv1, self.conv2, self.conv3, self.conv4, self.conv5], 0.1)
31
-
32
- def forward(self, x):
33
- x1 = self.lrelu(self.conv1(x))
34
- x2 = self.lrelu(self.conv2(torch.cat((x, x1), 1)))
35
- x3 = self.lrelu(self.conv3(torch.cat((x, x1, x2), 1)))
36
- x4 = self.lrelu(self.conv4(torch.cat((x, x1, x2, x3), 1)))
37
- x5 = self.conv5(torch.cat((x, x1, x2, x3, x4), 1))
38
- # Empirically, we use 0.2 to scale the residual for better performance
39
- return x5 * 0.2 + x
40
-
41
-
42
- class RRDB(nn.Module):
43
- """Residual in Residual Dense Block.
44
-
45
- Used in RRDB-Net in ESRGAN.
46
-
47
- Args:
48
- num_feat (int): Channel number of intermediate features.
49
- num_grow_ch (int): Channels for each growth.
50
- """
51
-
52
- def __init__(self, num_feat, num_grow_ch=32):
53
- super(RRDB, self).__init__()
54
- self.rdb1 = ResidualDenseBlock(num_feat, num_grow_ch)
55
- self.rdb2 = ResidualDenseBlock(num_feat, num_grow_ch)
56
- self.rdb3 = ResidualDenseBlock(num_feat, num_grow_ch)
57
-
58
- def forward(self, x):
59
- out = self.rdb1(x)
60
- out = self.rdb2(out)
61
- out = self.rdb3(out)
62
- # Empirically, we use 0.2 to scale the residual for better performance
63
- return out * 0.2 + x
64
-
65
-
66
- @ARCH_REGISTRY.register()
67
- class RRDBNet(nn.Module):
68
- """Networks consisting of Residual in Residual Dense Block, which is used
69
- in ESRGAN.
70
-
71
- ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks.
72
-
73
- We extend ESRGAN for scale x2 and scale x1.
74
- Note: This is one option for scale 1, scale 2 in RRDBNet.
75
- We first employ the pixel-unshuffle (an inverse operation of pixelshuffle to reduce the spatial size
76
- and enlarge the channel size before feeding inputs into the main ESRGAN architecture.
77
-
78
- Args:
79
- num_in_ch (int): Channel number of inputs.
80
- num_out_ch (int): Channel number of outputs.
81
- num_feat (int): Channel number of intermediate features.
82
- Default: 64
83
- num_block (int): Block number in the trunk network. Defaults: 23
84
- num_grow_ch (int): Channels for each growth. Default: 32.
85
- """
86
-
87
- def __init__(self, num_in_ch, num_out_ch, scale=4, num_feat=64, num_block=23, num_grow_ch=32):
88
- super(RRDBNet, self).__init__()
89
- self.scale = scale
90
- if scale == 2:
91
- num_in_ch = num_in_ch * 4
92
- elif scale == 1:
93
- num_in_ch = num_in_ch * 16
94
- self.conv_first = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1)
95
- self.body = make_layer(RRDB, num_block, num_feat=num_feat, num_grow_ch=num_grow_ch)
96
- self.conv_body = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
97
- # upsample
98
- self.conv_up1 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
99
- self.conv_up2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
100
- self.conv_hr = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
101
- self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
102
-
103
- self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True)
104
-
105
- def forward(self, x):
106
- if self.scale == 2:
107
- feat = pixel_unshuffle(x, scale=2)
108
- elif self.scale == 1:
109
- feat = pixel_unshuffle(x, scale=4)
110
- else:
111
- feat = x
112
- feat = self.conv_first(feat)
113
- body_feat = self.conv_body(self.body(feat))
114
- feat = feat + body_feat
115
- # upsample
116
- feat = self.lrelu(self.conv_up1(F.interpolate(feat, scale_factor=2, mode='nearest')))
117
- feat = self.lrelu(self.conv_up2(F.interpolate(feat, scale_factor=2, mode='nearest')))
118
- out = self.conv_last(self.lrelu(self.conv_hr(feat)))
119
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/spynet_arch.py DELETED
@@ -1,96 +0,0 @@
1
- import math
2
- import torch
3
- from torch import nn as nn
4
- from torch.nn import functional as F
5
-
6
- from basicsr.utils.registry import ARCH_REGISTRY
7
- from .arch_util import flow_warp
8
-
9
-
10
- class BasicModule(nn.Module):
11
- """Basic Module for SpyNet.
12
- """
13
-
14
- def __init__(self):
15
- super(BasicModule, self).__init__()
16
-
17
- self.basic_module = nn.Sequential(
18
- nn.Conv2d(in_channels=8, out_channels=32, kernel_size=7, stride=1, padding=3), nn.ReLU(inplace=False),
19
- nn.Conv2d(in_channels=32, out_channels=64, kernel_size=7, stride=1, padding=3), nn.ReLU(inplace=False),
20
- nn.Conv2d(in_channels=64, out_channels=32, kernel_size=7, stride=1, padding=3), nn.ReLU(inplace=False),
21
- nn.Conv2d(in_channels=32, out_channels=16, kernel_size=7, stride=1, padding=3), nn.ReLU(inplace=False),
22
- nn.Conv2d(in_channels=16, out_channels=2, kernel_size=7, stride=1, padding=3))
23
-
24
- def forward(self, tensor_input):
25
- return self.basic_module(tensor_input)
26
-
27
-
28
- @ARCH_REGISTRY.register()
29
- class SpyNet(nn.Module):
30
- """SpyNet architecture.
31
-
32
- Args:
33
- load_path (str): path for pretrained SpyNet. Default: None.
34
- """
35
-
36
- def __init__(self, load_path=None):
37
- super(SpyNet, self).__init__()
38
- self.basic_module = nn.ModuleList([BasicModule() for _ in range(6)])
39
- if load_path:
40
- self.load_state_dict(torch.load(load_path, map_location=lambda storage, loc: storage)['params'])
41
-
42
- self.register_buffer('mean', torch.Tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
43
- self.register_buffer('std', torch.Tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1))
44
-
45
- def preprocess(self, tensor_input):
46
- tensor_output = (tensor_input - self.mean) / self.std
47
- return tensor_output
48
-
49
- def process(self, ref, supp):
50
- flow = []
51
-
52
- ref = [self.preprocess(ref)]
53
- supp = [self.preprocess(supp)]
54
-
55
- for level in range(5):
56
- ref.insert(0, F.avg_pool2d(input=ref[0], kernel_size=2, stride=2, count_include_pad=False))
57
- supp.insert(0, F.avg_pool2d(input=supp[0], kernel_size=2, stride=2, count_include_pad=False))
58
-
59
- flow = ref[0].new_zeros(
60
- [ref[0].size(0), 2,
61
- int(math.floor(ref[0].size(2) / 2.0)),
62
- int(math.floor(ref[0].size(3) / 2.0))])
63
-
64
- for level in range(len(ref)):
65
- upsampled_flow = F.interpolate(input=flow, scale_factor=2, mode='bilinear', align_corners=True) * 2.0
66
-
67
- if upsampled_flow.size(2) != ref[level].size(2):
68
- upsampled_flow = F.pad(input=upsampled_flow, pad=[0, 0, 0, 1], mode='replicate')
69
- if upsampled_flow.size(3) != ref[level].size(3):
70
- upsampled_flow = F.pad(input=upsampled_flow, pad=[0, 1, 0, 0], mode='replicate')
71
-
72
- flow = self.basic_module[level](torch.cat([
73
- ref[level],
74
- flow_warp(
75
- supp[level], upsampled_flow.permute(0, 2, 3, 1), interp_mode='bilinear', padding_mode='border'),
76
- upsampled_flow
77
- ], 1)) + upsampled_flow
78
-
79
- return flow
80
-
81
- def forward(self, ref, supp):
82
- assert ref.size() == supp.size()
83
-
84
- h, w = ref.size(2), ref.size(3)
85
- w_floor = math.floor(math.ceil(w / 32.0) * 32.0)
86
- h_floor = math.floor(math.ceil(h / 32.0) * 32.0)
87
-
88
- ref = F.interpolate(input=ref, size=(h_floor, w_floor), mode='bilinear', align_corners=False)
89
- supp = F.interpolate(input=supp, size=(h_floor, w_floor), mode='bilinear', align_corners=False)
90
-
91
- flow = F.interpolate(input=self.process(ref, supp), size=(h, w), mode='bilinear', align_corners=False)
92
-
93
- flow[:, 0, :, :] *= float(w) / float(w_floor)
94
- flow[:, 1, :, :] *= float(h) / float(h_floor)
95
-
96
- return flow
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/srresnet_arch.py DELETED
@@ -1,65 +0,0 @@
1
- from torch import nn as nn
2
- from torch.nn import functional as F
3
-
4
- from basicsr.utils.registry import ARCH_REGISTRY
5
- from .arch_util import ResidualBlockNoBN, default_init_weights, make_layer
6
-
7
-
8
- @ARCH_REGISTRY.register()
9
- class MSRResNet(nn.Module):
10
- """Modified SRResNet.
11
-
12
- A compacted version modified from SRResNet in
13
- "Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network"
14
- It uses residual blocks without BN, similar to EDSR.
15
- Currently, it supports x2, x3 and x4 upsampling scale factor.
16
-
17
- Args:
18
- num_in_ch (int): Channel number of inputs. Default: 3.
19
- num_out_ch (int): Channel number of outputs. Default: 3.
20
- num_feat (int): Channel number of intermediate features. Default: 64.
21
- num_block (int): Block number in the body network. Default: 16.
22
- upscale (int): Upsampling factor. Support x2, x3 and x4. Default: 4.
23
- """
24
-
25
- def __init__(self, num_in_ch=3, num_out_ch=3, num_feat=64, num_block=16, upscale=4):
26
- super(MSRResNet, self).__init__()
27
- self.upscale = upscale
28
-
29
- self.conv_first = nn.Conv2d(num_in_ch, num_feat, 3, 1, 1)
30
- self.body = make_layer(ResidualBlockNoBN, num_block, num_feat=num_feat)
31
-
32
- # upsampling
33
- if self.upscale in [2, 3]:
34
- self.upconv1 = nn.Conv2d(num_feat, num_feat * self.upscale * self.upscale, 3, 1, 1)
35
- self.pixel_shuffle = nn.PixelShuffle(self.upscale)
36
- elif self.upscale == 4:
37
- self.upconv1 = nn.Conv2d(num_feat, num_feat * 4, 3, 1, 1)
38
- self.upconv2 = nn.Conv2d(num_feat, num_feat * 4, 3, 1, 1)
39
- self.pixel_shuffle = nn.PixelShuffle(2)
40
-
41
- self.conv_hr = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
42
- self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
43
-
44
- # activation function
45
- self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
46
-
47
- # initialization
48
- default_init_weights([self.conv_first, self.upconv1, self.conv_hr, self.conv_last], 0.1)
49
- if self.upscale == 4:
50
- default_init_weights(self.upconv2, 0.1)
51
-
52
- def forward(self, x):
53
- feat = self.lrelu(self.conv_first(x))
54
- out = self.body(feat)
55
-
56
- if self.upscale == 4:
57
- out = self.lrelu(self.pixel_shuffle(self.upconv1(out)))
58
- out = self.lrelu(self.pixel_shuffle(self.upconv2(out)))
59
- elif self.upscale in [2, 3]:
60
- out = self.lrelu(self.pixel_shuffle(self.upconv1(out)))
61
-
62
- out = self.conv_last(self.lrelu(self.conv_hr(out)))
63
- base = F.interpolate(x, scale_factor=self.upscale, mode='bilinear', align_corners=False)
64
- out += base
65
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/srvgg_arch.py DELETED
@@ -1,70 +0,0 @@
1
- from torch import nn as nn
2
- from torch.nn import functional as F
3
-
4
- from basicsr.utils.registry import ARCH_REGISTRY
5
-
6
-
7
- @ARCH_REGISTRY.register(suffix='basicsr')
8
- class SRVGGNetCompact(nn.Module):
9
- """A compact VGG-style network structure for super-resolution.
10
-
11
- It is a compact network structure, which performs upsampling in the last layer and no convolution is
12
- conducted on the HR feature space.
13
-
14
- Args:
15
- num_in_ch (int): Channel number of inputs. Default: 3.
16
- num_out_ch (int): Channel number of outputs. Default: 3.
17
- num_feat (int): Channel number of intermediate features. Default: 64.
18
- num_conv (int): Number of convolution layers in the body network. Default: 16.
19
- upscale (int): Upsampling factor. Default: 4.
20
- act_type (str): Activation type, options: 'relu', 'prelu', 'leakyrelu'. Default: prelu.
21
- """
22
-
23
- def __init__(self, num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=16, upscale=4, act_type='prelu'):
24
- super(SRVGGNetCompact, self).__init__()
25
- self.num_in_ch = num_in_ch
26
- self.num_out_ch = num_out_ch
27
- self.num_feat = num_feat
28
- self.num_conv = num_conv
29
- self.upscale = upscale
30
- self.act_type = act_type
31
-
32
- self.body = nn.ModuleList()
33
- # the first conv
34
- self.body.append(nn.Conv2d(num_in_ch, num_feat, 3, 1, 1))
35
- # the first activation
36
- if act_type == 'relu':
37
- activation = nn.ReLU(inplace=True)
38
- elif act_type == 'prelu':
39
- activation = nn.PReLU(num_parameters=num_feat)
40
- elif act_type == 'leakyrelu':
41
- activation = nn.LeakyReLU(negative_slope=0.1, inplace=True)
42
- self.body.append(activation)
43
-
44
- # the body structure
45
- for _ in range(num_conv):
46
- self.body.append(nn.Conv2d(num_feat, num_feat, 3, 1, 1))
47
- # activation
48
- if act_type == 'relu':
49
- activation = nn.ReLU(inplace=True)
50
- elif act_type == 'prelu':
51
- activation = nn.PReLU(num_parameters=num_feat)
52
- elif act_type == 'leakyrelu':
53
- activation = nn.LeakyReLU(negative_slope=0.1, inplace=True)
54
- self.body.append(activation)
55
-
56
- # the last conv
57
- self.body.append(nn.Conv2d(num_feat, num_out_ch * upscale * upscale, 3, 1, 1))
58
- # upsample
59
- self.upsampler = nn.PixelShuffle(upscale)
60
-
61
- def forward(self, x):
62
- out = x
63
- for i in range(0, len(self.body)):
64
- out = self.body[i](out)
65
-
66
- out = self.upsampler(out)
67
- # add the nearest upsampled image, so that the network learns the residual
68
- base = F.interpolate(x, scale_factor=self.upscale, mode='nearest')
69
- out += base
70
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/stylegan2_arch.py DELETED
@@ -1,799 +0,0 @@
1
- import math
2
- import random
3
- import torch
4
- from torch import nn
5
- from torch.nn import functional as F
6
-
7
- from basicsr.ops.fused_act import FusedLeakyReLU, fused_leaky_relu
8
- from basicsr.ops.upfirdn2d import upfirdn2d
9
- from basicsr.utils.registry import ARCH_REGISTRY
10
-
11
-
12
- class NormStyleCode(nn.Module):
13
-
14
- def forward(self, x):
15
- """Normalize the style codes.
16
-
17
- Args:
18
- x (Tensor): Style codes with shape (b, c).
19
-
20
- Returns:
21
- Tensor: Normalized tensor.
22
- """
23
- return x * torch.rsqrt(torch.mean(x**2, dim=1, keepdim=True) + 1e-8)
24
-
25
-
26
- def make_resample_kernel(k):
27
- """Make resampling kernel for UpFirDn.
28
-
29
- Args:
30
- k (list[int]): A list indicating the 1D resample kernel magnitude.
31
-
32
- Returns:
33
- Tensor: 2D resampled kernel.
34
- """
35
- k = torch.tensor(k, dtype=torch.float32)
36
- if k.ndim == 1:
37
- k = k[None, :] * k[:, None] # to 2D kernel, outer product
38
- # normalize
39
- k /= k.sum()
40
- return k
41
-
42
-
43
- class UpFirDnUpsample(nn.Module):
44
- """Upsample, FIR filter, and downsample (upsampole version).
45
-
46
- References:
47
- 1. https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.upfirdn.html # noqa: E501
48
- 2. http://www.ece.northwestern.edu/local-apps/matlabhelp/toolbox/signal/upfirdn.html # noqa: E501
49
-
50
- Args:
51
- resample_kernel (list[int]): A list indicating the 1D resample kernel
52
- magnitude.
53
- factor (int): Upsampling scale factor. Default: 2.
54
- """
55
-
56
- def __init__(self, resample_kernel, factor=2):
57
- super(UpFirDnUpsample, self).__init__()
58
- self.kernel = make_resample_kernel(resample_kernel) * (factor**2)
59
- self.factor = factor
60
-
61
- pad = self.kernel.shape[0] - factor
62
- self.pad = ((pad + 1) // 2 + factor - 1, pad // 2)
63
-
64
- def forward(self, x):
65
- out = upfirdn2d(x, self.kernel.type_as(x), up=self.factor, down=1, pad=self.pad)
66
- return out
67
-
68
- def __repr__(self):
69
- return (f'{self.__class__.__name__}(factor={self.factor})')
70
-
71
-
72
- class UpFirDnDownsample(nn.Module):
73
- """Upsample, FIR filter, and downsample (downsampole version).
74
-
75
- Args:
76
- resample_kernel (list[int]): A list indicating the 1D resample kernel
77
- magnitude.
78
- factor (int): Downsampling scale factor. Default: 2.
79
- """
80
-
81
- def __init__(self, resample_kernel, factor=2):
82
- super(UpFirDnDownsample, self).__init__()
83
- self.kernel = make_resample_kernel(resample_kernel)
84
- self.factor = factor
85
-
86
- pad = self.kernel.shape[0] - factor
87
- self.pad = ((pad + 1) // 2, pad // 2)
88
-
89
- def forward(self, x):
90
- out = upfirdn2d(x, self.kernel.type_as(x), up=1, down=self.factor, pad=self.pad)
91
- return out
92
-
93
- def __repr__(self):
94
- return (f'{self.__class__.__name__}(factor={self.factor})')
95
-
96
-
97
- class UpFirDnSmooth(nn.Module):
98
- """Upsample, FIR filter, and downsample (smooth version).
99
-
100
- Args:
101
- resample_kernel (list[int]): A list indicating the 1D resample kernel
102
- magnitude.
103
- upsample_factor (int): Upsampling scale factor. Default: 1.
104
- downsample_factor (int): Downsampling scale factor. Default: 1.
105
- kernel_size (int): Kernel size: Default: 1.
106
- """
107
-
108
- def __init__(self, resample_kernel, upsample_factor=1, downsample_factor=1, kernel_size=1):
109
- super(UpFirDnSmooth, self).__init__()
110
- self.upsample_factor = upsample_factor
111
- self.downsample_factor = downsample_factor
112
- self.kernel = make_resample_kernel(resample_kernel)
113
- if upsample_factor > 1:
114
- self.kernel = self.kernel * (upsample_factor**2)
115
-
116
- if upsample_factor > 1:
117
- pad = (self.kernel.shape[0] - upsample_factor) - (kernel_size - 1)
118
- self.pad = ((pad + 1) // 2 + upsample_factor - 1, pad // 2 + 1)
119
- elif downsample_factor > 1:
120
- pad = (self.kernel.shape[0] - downsample_factor) + (kernel_size - 1)
121
- self.pad = ((pad + 1) // 2, pad // 2)
122
- else:
123
- raise NotImplementedError
124
-
125
- def forward(self, x):
126
- out = upfirdn2d(x, self.kernel.type_as(x), up=1, down=1, pad=self.pad)
127
- return out
128
-
129
- def __repr__(self):
130
- return (f'{self.__class__.__name__}(upsample_factor={self.upsample_factor}'
131
- f', downsample_factor={self.downsample_factor})')
132
-
133
-
134
- class EqualLinear(nn.Module):
135
- """Equalized Linear as StyleGAN2.
136
-
137
- Args:
138
- in_channels (int): Size of each sample.
139
- out_channels (int): Size of each output sample.
140
- bias (bool): If set to ``False``, the layer will not learn an additive
141
- bias. Default: ``True``.
142
- bias_init_val (float): Bias initialized value. Default: 0.
143
- lr_mul (float): Learning rate multiplier. Default: 1.
144
- activation (None | str): The activation after ``linear`` operation.
145
- Supported: 'fused_lrelu', None. Default: None.
146
- """
147
-
148
- def __init__(self, in_channels, out_channels, bias=True, bias_init_val=0, lr_mul=1, activation=None):
149
- super(EqualLinear, self).__init__()
150
- self.in_channels = in_channels
151
- self.out_channels = out_channels
152
- self.lr_mul = lr_mul
153
- self.activation = activation
154
- if self.activation not in ['fused_lrelu', None]:
155
- raise ValueError(f'Wrong activation value in EqualLinear: {activation}'
156
- "Supported ones are: ['fused_lrelu', None].")
157
- self.scale = (1 / math.sqrt(in_channels)) * lr_mul
158
-
159
- self.weight = nn.Parameter(torch.randn(out_channels, in_channels).div_(lr_mul))
160
- if bias:
161
- self.bias = nn.Parameter(torch.zeros(out_channels).fill_(bias_init_val))
162
- else:
163
- self.register_parameter('bias', None)
164
-
165
- def forward(self, x):
166
- if self.bias is None:
167
- bias = None
168
- else:
169
- bias = self.bias * self.lr_mul
170
- if self.activation == 'fused_lrelu':
171
- out = F.linear(x, self.weight * self.scale)
172
- out = fused_leaky_relu(out, bias)
173
- else:
174
- out = F.linear(x, self.weight * self.scale, bias=bias)
175
- return out
176
-
177
- def __repr__(self):
178
- return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
179
- f'out_channels={self.out_channels}, bias={self.bias is not None})')
180
-
181
-
182
- class ModulatedConv2d(nn.Module):
183
- """Modulated Conv2d used in StyleGAN2.
184
-
185
- There is no bias in ModulatedConv2d.
186
-
187
- Args:
188
- in_channels (int): Channel number of the input.
189
- out_channels (int): Channel number of the output.
190
- kernel_size (int): Size of the convolving kernel.
191
- num_style_feat (int): Channel number of style features.
192
- demodulate (bool): Whether to demodulate in the conv layer.
193
- Default: True.
194
- sample_mode (str | None): Indicating 'upsample', 'downsample' or None.
195
- Default: None.
196
- resample_kernel (list[int]): A list indicating the 1D resample kernel
197
- magnitude. Default: (1, 3, 3, 1).
198
- eps (float): A value added to the denominator for numerical stability.
199
- Default: 1e-8.
200
- """
201
-
202
- def __init__(self,
203
- in_channels,
204
- out_channels,
205
- kernel_size,
206
- num_style_feat,
207
- demodulate=True,
208
- sample_mode=None,
209
- resample_kernel=(1, 3, 3, 1),
210
- eps=1e-8):
211
- super(ModulatedConv2d, self).__init__()
212
- self.in_channels = in_channels
213
- self.out_channels = out_channels
214
- self.kernel_size = kernel_size
215
- self.demodulate = demodulate
216
- self.sample_mode = sample_mode
217
- self.eps = eps
218
-
219
- if self.sample_mode == 'upsample':
220
- self.smooth = UpFirDnSmooth(
221
- resample_kernel, upsample_factor=2, downsample_factor=1, kernel_size=kernel_size)
222
- elif self.sample_mode == 'downsample':
223
- self.smooth = UpFirDnSmooth(
224
- resample_kernel, upsample_factor=1, downsample_factor=2, kernel_size=kernel_size)
225
- elif self.sample_mode is None:
226
- pass
227
- else:
228
- raise ValueError(f'Wrong sample mode {self.sample_mode}, '
229
- "supported ones are ['upsample', 'downsample', None].")
230
-
231
- self.scale = 1 / math.sqrt(in_channels * kernel_size**2)
232
- # modulation inside each modulated conv
233
- self.modulation = EqualLinear(
234
- num_style_feat, in_channels, bias=True, bias_init_val=1, lr_mul=1, activation=None)
235
-
236
- self.weight = nn.Parameter(torch.randn(1, out_channels, in_channels, kernel_size, kernel_size))
237
- self.padding = kernel_size // 2
238
-
239
- def forward(self, x, style):
240
- """Forward function.
241
-
242
- Args:
243
- x (Tensor): Tensor with shape (b, c, h, w).
244
- style (Tensor): Tensor with shape (b, num_style_feat).
245
-
246
- Returns:
247
- Tensor: Modulated tensor after convolution.
248
- """
249
- b, c, h, w = x.shape # c = c_in
250
- # weight modulation
251
- style = self.modulation(style).view(b, 1, c, 1, 1)
252
- # self.weight: (1, c_out, c_in, k, k); style: (b, 1, c, 1, 1)
253
- weight = self.scale * self.weight * style # (b, c_out, c_in, k, k)
254
-
255
- if self.demodulate:
256
- demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + self.eps)
257
- weight = weight * demod.view(b, self.out_channels, 1, 1, 1)
258
-
259
- weight = weight.view(b * self.out_channels, c, self.kernel_size, self.kernel_size)
260
-
261
- if self.sample_mode == 'upsample':
262
- x = x.view(1, b * c, h, w)
263
- weight = weight.view(b, self.out_channels, c, self.kernel_size, self.kernel_size)
264
- weight = weight.transpose(1, 2).reshape(b * c, self.out_channels, self.kernel_size, self.kernel_size)
265
- out = F.conv_transpose2d(x, weight, padding=0, stride=2, groups=b)
266
- out = out.view(b, self.out_channels, *out.shape[2:4])
267
- out = self.smooth(out)
268
- elif self.sample_mode == 'downsample':
269
- x = self.smooth(x)
270
- x = x.view(1, b * c, *x.shape[2:4])
271
- out = F.conv2d(x, weight, padding=0, stride=2, groups=b)
272
- out = out.view(b, self.out_channels, *out.shape[2:4])
273
- else:
274
- x = x.view(1, b * c, h, w)
275
- # weight: (b*c_out, c_in, k, k), groups=b
276
- out = F.conv2d(x, weight, padding=self.padding, groups=b)
277
- out = out.view(b, self.out_channels, *out.shape[2:4])
278
-
279
- return out
280
-
281
- def __repr__(self):
282
- return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
283
- f'out_channels={self.out_channels}, '
284
- f'kernel_size={self.kernel_size}, '
285
- f'demodulate={self.demodulate}, sample_mode={self.sample_mode})')
286
-
287
-
288
- class StyleConv(nn.Module):
289
- """Style conv.
290
-
291
- Args:
292
- in_channels (int): Channel number of the input.
293
- out_channels (int): Channel number of the output.
294
- kernel_size (int): Size of the convolving kernel.
295
- num_style_feat (int): Channel number of style features.
296
- demodulate (bool): Whether demodulate in the conv layer. Default: True.
297
- sample_mode (str | None): Indicating 'upsample', 'downsample' or None.
298
- Default: None.
299
- resample_kernel (list[int]): A list indicating the 1D resample kernel
300
- magnitude. Default: (1, 3, 3, 1).
301
- """
302
-
303
- def __init__(self,
304
- in_channels,
305
- out_channels,
306
- kernel_size,
307
- num_style_feat,
308
- demodulate=True,
309
- sample_mode=None,
310
- resample_kernel=(1, 3, 3, 1)):
311
- super(StyleConv, self).__init__()
312
- self.modulated_conv = ModulatedConv2d(
313
- in_channels,
314
- out_channels,
315
- kernel_size,
316
- num_style_feat,
317
- demodulate=demodulate,
318
- sample_mode=sample_mode,
319
- resample_kernel=resample_kernel)
320
- self.weight = nn.Parameter(torch.zeros(1)) # for noise injection
321
- self.activate = FusedLeakyReLU(out_channels)
322
-
323
- def forward(self, x, style, noise=None):
324
- # modulate
325
- out = self.modulated_conv(x, style)
326
- # noise injection
327
- if noise is None:
328
- b, _, h, w = out.shape
329
- noise = out.new_empty(b, 1, h, w).normal_()
330
- out = out + self.weight * noise
331
- # activation (with bias)
332
- out = self.activate(out)
333
- return out
334
-
335
-
336
- class ToRGB(nn.Module):
337
- """To RGB from features.
338
-
339
- Args:
340
- in_channels (int): Channel number of input.
341
- num_style_feat (int): Channel number of style features.
342
- upsample (bool): Whether to upsample. Default: True.
343
- resample_kernel (list[int]): A list indicating the 1D resample kernel
344
- magnitude. Default: (1, 3, 3, 1).
345
- """
346
-
347
- def __init__(self, in_channels, num_style_feat, upsample=True, resample_kernel=(1, 3, 3, 1)):
348
- super(ToRGB, self).__init__()
349
- if upsample:
350
- self.upsample = UpFirDnUpsample(resample_kernel, factor=2)
351
- else:
352
- self.upsample = None
353
- self.modulated_conv = ModulatedConv2d(
354
- in_channels, 3, kernel_size=1, num_style_feat=num_style_feat, demodulate=False, sample_mode=None)
355
- self.bias = nn.Parameter(torch.zeros(1, 3, 1, 1))
356
-
357
- def forward(self, x, style, skip=None):
358
- """Forward function.
359
-
360
- Args:
361
- x (Tensor): Feature tensor with shape (b, c, h, w).
362
- style (Tensor): Tensor with shape (b, num_style_feat).
363
- skip (Tensor): Base/skip tensor. Default: None.
364
-
365
- Returns:
366
- Tensor: RGB images.
367
- """
368
- out = self.modulated_conv(x, style)
369
- out = out + self.bias
370
- if skip is not None:
371
- if self.upsample:
372
- skip = self.upsample(skip)
373
- out = out + skip
374
- return out
375
-
376
-
377
- class ConstantInput(nn.Module):
378
- """Constant input.
379
-
380
- Args:
381
- num_channel (int): Channel number of constant input.
382
- size (int): Spatial size of constant input.
383
- """
384
-
385
- def __init__(self, num_channel, size):
386
- super(ConstantInput, self).__init__()
387
- self.weight = nn.Parameter(torch.randn(1, num_channel, size, size))
388
-
389
- def forward(self, batch):
390
- out = self.weight.repeat(batch, 1, 1, 1)
391
- return out
392
-
393
-
394
- @ARCH_REGISTRY.register()
395
- class StyleGAN2Generator(nn.Module):
396
- """StyleGAN2 Generator.
397
-
398
- Args:
399
- out_size (int): The spatial size of outputs.
400
- num_style_feat (int): Channel number of style features. Default: 512.
401
- num_mlp (int): Layer number of MLP style layers. Default: 8.
402
- channel_multiplier (int): Channel multiplier for large networks of
403
- StyleGAN2. Default: 2.
404
- resample_kernel (list[int]): A list indicating the 1D resample kernel
405
- magnitude. A cross production will be applied to extent 1D resample
406
- kernel to 2D resample kernel. Default: (1, 3, 3, 1).
407
- lr_mlp (float): Learning rate multiplier for mlp layers. Default: 0.01.
408
- narrow (float): Narrow ratio for channels. Default: 1.0.
409
- """
410
-
411
- def __init__(self,
412
- out_size,
413
- num_style_feat=512,
414
- num_mlp=8,
415
- channel_multiplier=2,
416
- resample_kernel=(1, 3, 3, 1),
417
- lr_mlp=0.01,
418
- narrow=1):
419
- super(StyleGAN2Generator, self).__init__()
420
- # Style MLP layers
421
- self.num_style_feat = num_style_feat
422
- style_mlp_layers = [NormStyleCode()]
423
- for i in range(num_mlp):
424
- style_mlp_layers.append(
425
- EqualLinear(
426
- num_style_feat, num_style_feat, bias=True, bias_init_val=0, lr_mul=lr_mlp,
427
- activation='fused_lrelu'))
428
- self.style_mlp = nn.Sequential(*style_mlp_layers)
429
-
430
- channels = {
431
- '4': int(512 * narrow),
432
- '8': int(512 * narrow),
433
- '16': int(512 * narrow),
434
- '32': int(512 * narrow),
435
- '64': int(256 * channel_multiplier * narrow),
436
- '128': int(128 * channel_multiplier * narrow),
437
- '256': int(64 * channel_multiplier * narrow),
438
- '512': int(32 * channel_multiplier * narrow),
439
- '1024': int(16 * channel_multiplier * narrow)
440
- }
441
- self.channels = channels
442
-
443
- self.constant_input = ConstantInput(channels['4'], size=4)
444
- self.style_conv1 = StyleConv(
445
- channels['4'],
446
- channels['4'],
447
- kernel_size=3,
448
- num_style_feat=num_style_feat,
449
- demodulate=True,
450
- sample_mode=None,
451
- resample_kernel=resample_kernel)
452
- self.to_rgb1 = ToRGB(channels['4'], num_style_feat, upsample=False, resample_kernel=resample_kernel)
453
-
454
- self.log_size = int(math.log(out_size, 2))
455
- self.num_layers = (self.log_size - 2) * 2 + 1
456
- self.num_latent = self.log_size * 2 - 2
457
-
458
- self.style_convs = nn.ModuleList()
459
- self.to_rgbs = nn.ModuleList()
460
- self.noises = nn.Module()
461
-
462
- in_channels = channels['4']
463
- # noise
464
- for layer_idx in range(self.num_layers):
465
- resolution = 2**((layer_idx + 5) // 2)
466
- shape = [1, 1, resolution, resolution]
467
- self.noises.register_buffer(f'noise{layer_idx}', torch.randn(*shape))
468
- # style convs and to_rgbs
469
- for i in range(3, self.log_size + 1):
470
- out_channels = channels[f'{2**i}']
471
- self.style_convs.append(
472
- StyleConv(
473
- in_channels,
474
- out_channels,
475
- kernel_size=3,
476
- num_style_feat=num_style_feat,
477
- demodulate=True,
478
- sample_mode='upsample',
479
- resample_kernel=resample_kernel,
480
- ))
481
- self.style_convs.append(
482
- StyleConv(
483
- out_channels,
484
- out_channels,
485
- kernel_size=3,
486
- num_style_feat=num_style_feat,
487
- demodulate=True,
488
- sample_mode=None,
489
- resample_kernel=resample_kernel))
490
- self.to_rgbs.append(ToRGB(out_channels, num_style_feat, upsample=True, resample_kernel=resample_kernel))
491
- in_channels = out_channels
492
-
493
- def make_noise(self):
494
- """Make noise for noise injection."""
495
- device = self.constant_input.weight.device
496
- noises = [torch.randn(1, 1, 4, 4, device=device)]
497
-
498
- for i in range(3, self.log_size + 1):
499
- for _ in range(2):
500
- noises.append(torch.randn(1, 1, 2**i, 2**i, device=device))
501
-
502
- return noises
503
-
504
- def get_latent(self, x):
505
- return self.style_mlp(x)
506
-
507
- def mean_latent(self, num_latent):
508
- latent_in = torch.randn(num_latent, self.num_style_feat, device=self.constant_input.weight.device)
509
- latent = self.style_mlp(latent_in).mean(0, keepdim=True)
510
- return latent
511
-
512
- def forward(self,
513
- styles,
514
- input_is_latent=False,
515
- noise=None,
516
- randomize_noise=True,
517
- truncation=1,
518
- truncation_latent=None,
519
- inject_index=None,
520
- return_latents=False):
521
- """Forward function for StyleGAN2Generator.
522
-
523
- Args:
524
- styles (list[Tensor]): Sample codes of styles.
525
- input_is_latent (bool): Whether input is latent style.
526
- Default: False.
527
- noise (Tensor | None): Input noise or None. Default: None.
528
- randomize_noise (bool): Randomize noise, used when 'noise' is
529
- False. Default: True.
530
- truncation (float): TODO. Default: 1.
531
- truncation_latent (Tensor | None): TODO. Default: None.
532
- inject_index (int | None): The injection index for mixing noise.
533
- Default: None.
534
- return_latents (bool): Whether to return style latents.
535
- Default: False.
536
- """
537
- # style codes -> latents with Style MLP layer
538
- if not input_is_latent:
539
- styles = [self.style_mlp(s) for s in styles]
540
- # noises
541
- if noise is None:
542
- if randomize_noise:
543
- noise = [None] * self.num_layers # for each style conv layer
544
- else: # use the stored noise
545
- noise = [getattr(self.noises, f'noise{i}') for i in range(self.num_layers)]
546
- # style truncation
547
- if truncation < 1:
548
- style_truncation = []
549
- for style in styles:
550
- style_truncation.append(truncation_latent + truncation * (style - truncation_latent))
551
- styles = style_truncation
552
- # get style latent with injection
553
- if len(styles) == 1:
554
- inject_index = self.num_latent
555
-
556
- if styles[0].ndim < 3:
557
- # repeat latent code for all the layers
558
- latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
559
- else: # used for encoder with different latent code for each layer
560
- latent = styles[0]
561
- elif len(styles) == 2: # mixing noises
562
- if inject_index is None:
563
- inject_index = random.randint(1, self.num_latent - 1)
564
- latent1 = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
565
- latent2 = styles[1].unsqueeze(1).repeat(1, self.num_latent - inject_index, 1)
566
- latent = torch.cat([latent1, latent2], 1)
567
-
568
- # main generation
569
- out = self.constant_input(latent.shape[0])
570
- out = self.style_conv1(out, latent[:, 0], noise=noise[0])
571
- skip = self.to_rgb1(out, latent[:, 1])
572
-
573
- i = 1
574
- for conv1, conv2, noise1, noise2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], noise[1::2],
575
- noise[2::2], self.to_rgbs):
576
- out = conv1(out, latent[:, i], noise=noise1)
577
- out = conv2(out, latent[:, i + 1], noise=noise2)
578
- skip = to_rgb(out, latent[:, i + 2], skip)
579
- i += 2
580
-
581
- image = skip
582
-
583
- if return_latents:
584
- return image, latent
585
- else:
586
- return image, None
587
-
588
-
589
- class ScaledLeakyReLU(nn.Module):
590
- """Scaled LeakyReLU.
591
-
592
- Args:
593
- negative_slope (float): Negative slope. Default: 0.2.
594
- """
595
-
596
- def __init__(self, negative_slope=0.2):
597
- super(ScaledLeakyReLU, self).__init__()
598
- self.negative_slope = negative_slope
599
-
600
- def forward(self, x):
601
- out = F.leaky_relu(x, negative_slope=self.negative_slope)
602
- return out * math.sqrt(2)
603
-
604
-
605
- class EqualConv2d(nn.Module):
606
- """Equalized Linear as StyleGAN2.
607
-
608
- Args:
609
- in_channels (int): Channel number of the input.
610
- out_channels (int): Channel number of the output.
611
- kernel_size (int): Size of the convolving kernel.
612
- stride (int): Stride of the convolution. Default: 1
613
- padding (int): Zero-padding added to both sides of the input.
614
- Default: 0.
615
- bias (bool): If ``True``, adds a learnable bias to the output.
616
- Default: ``True``.
617
- bias_init_val (float): Bias initialized value. Default: 0.
618
- """
619
-
620
- def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, bias=True, bias_init_val=0):
621
- super(EqualConv2d, self).__init__()
622
- self.in_channels = in_channels
623
- self.out_channels = out_channels
624
- self.kernel_size = kernel_size
625
- self.stride = stride
626
- self.padding = padding
627
- self.scale = 1 / math.sqrt(in_channels * kernel_size**2)
628
-
629
- self.weight = nn.Parameter(torch.randn(out_channels, in_channels, kernel_size, kernel_size))
630
- if bias:
631
- self.bias = nn.Parameter(torch.zeros(out_channels).fill_(bias_init_val))
632
- else:
633
- self.register_parameter('bias', None)
634
-
635
- def forward(self, x):
636
- out = F.conv2d(
637
- x,
638
- self.weight * self.scale,
639
- bias=self.bias,
640
- stride=self.stride,
641
- padding=self.padding,
642
- )
643
-
644
- return out
645
-
646
- def __repr__(self):
647
- return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
648
- f'out_channels={self.out_channels}, '
649
- f'kernel_size={self.kernel_size},'
650
- f' stride={self.stride}, padding={self.padding}, '
651
- f'bias={self.bias is not None})')
652
-
653
-
654
- class ConvLayer(nn.Sequential):
655
- """Conv Layer used in StyleGAN2 Discriminator.
656
-
657
- Args:
658
- in_channels (int): Channel number of the input.
659
- out_channels (int): Channel number of the output.
660
- kernel_size (int): Kernel size.
661
- downsample (bool): Whether downsample by a factor of 2.
662
- Default: False.
663
- resample_kernel (list[int]): A list indicating the 1D resample
664
- kernel magnitude. A cross production will be applied to
665
- extent 1D resample kernel to 2D resample kernel.
666
- Default: (1, 3, 3, 1).
667
- bias (bool): Whether with bias. Default: True.
668
- activate (bool): Whether use activateion. Default: True.
669
- """
670
-
671
- def __init__(self,
672
- in_channels,
673
- out_channels,
674
- kernel_size,
675
- downsample=False,
676
- resample_kernel=(1, 3, 3, 1),
677
- bias=True,
678
- activate=True):
679
- layers = []
680
- # downsample
681
- if downsample:
682
- layers.append(
683
- UpFirDnSmooth(resample_kernel, upsample_factor=1, downsample_factor=2, kernel_size=kernel_size))
684
- stride = 2
685
- self.padding = 0
686
- else:
687
- stride = 1
688
- self.padding = kernel_size // 2
689
- # conv
690
- layers.append(
691
- EqualConv2d(
692
- in_channels, out_channels, kernel_size, stride=stride, padding=self.padding, bias=bias
693
- and not activate))
694
- # activation
695
- if activate:
696
- if bias:
697
- layers.append(FusedLeakyReLU(out_channels))
698
- else:
699
- layers.append(ScaledLeakyReLU(0.2))
700
-
701
- super(ConvLayer, self).__init__(*layers)
702
-
703
-
704
- class ResBlock(nn.Module):
705
- """Residual block used in StyleGAN2 Discriminator.
706
-
707
- Args:
708
- in_channels (int): Channel number of the input.
709
- out_channels (int): Channel number of the output.
710
- resample_kernel (list[int]): A list indicating the 1D resample
711
- kernel magnitude. A cross production will be applied to
712
- extent 1D resample kernel to 2D resample kernel.
713
- Default: (1, 3, 3, 1).
714
- """
715
-
716
- def __init__(self, in_channels, out_channels, resample_kernel=(1, 3, 3, 1)):
717
- super(ResBlock, self).__init__()
718
-
719
- self.conv1 = ConvLayer(in_channels, in_channels, 3, bias=True, activate=True)
720
- self.conv2 = ConvLayer(
721
- in_channels, out_channels, 3, downsample=True, resample_kernel=resample_kernel, bias=True, activate=True)
722
- self.skip = ConvLayer(
723
- in_channels, out_channels, 1, downsample=True, resample_kernel=resample_kernel, bias=False, activate=False)
724
-
725
- def forward(self, x):
726
- out = self.conv1(x)
727
- out = self.conv2(out)
728
- skip = self.skip(x)
729
- out = (out + skip) / math.sqrt(2)
730
- return out
731
-
732
-
733
- @ARCH_REGISTRY.register()
734
- class StyleGAN2Discriminator(nn.Module):
735
- """StyleGAN2 Discriminator.
736
-
737
- Args:
738
- out_size (int): The spatial size of outputs.
739
- channel_multiplier (int): Channel multiplier for large networks of
740
- StyleGAN2. Default: 2.
741
- resample_kernel (list[int]): A list indicating the 1D resample kernel
742
- magnitude. A cross production will be applied to extent 1D resample
743
- kernel to 2D resample kernel. Default: (1, 3, 3, 1).
744
- stddev_group (int): For group stddev statistics. Default: 4.
745
- narrow (float): Narrow ratio for channels. Default: 1.0.
746
- """
747
-
748
- def __init__(self, out_size, channel_multiplier=2, resample_kernel=(1, 3, 3, 1), stddev_group=4, narrow=1):
749
- super(StyleGAN2Discriminator, self).__init__()
750
-
751
- channels = {
752
- '4': int(512 * narrow),
753
- '8': int(512 * narrow),
754
- '16': int(512 * narrow),
755
- '32': int(512 * narrow),
756
- '64': int(256 * channel_multiplier * narrow),
757
- '128': int(128 * channel_multiplier * narrow),
758
- '256': int(64 * channel_multiplier * narrow),
759
- '512': int(32 * channel_multiplier * narrow),
760
- '1024': int(16 * channel_multiplier * narrow)
761
- }
762
-
763
- log_size = int(math.log(out_size, 2))
764
-
765
- conv_body = [ConvLayer(3, channels[f'{out_size}'], 1, bias=True, activate=True)]
766
-
767
- in_channels = channels[f'{out_size}']
768
- for i in range(log_size, 2, -1):
769
- out_channels = channels[f'{2**(i - 1)}']
770
- conv_body.append(ResBlock(in_channels, out_channels, resample_kernel))
771
- in_channels = out_channels
772
- self.conv_body = nn.Sequential(*conv_body)
773
-
774
- self.final_conv = ConvLayer(in_channels + 1, channels['4'], 3, bias=True, activate=True)
775
- self.final_linear = nn.Sequential(
776
- EqualLinear(
777
- channels['4'] * 4 * 4, channels['4'], bias=True, bias_init_val=0, lr_mul=1, activation='fused_lrelu'),
778
- EqualLinear(channels['4'], 1, bias=True, bias_init_val=0, lr_mul=1, activation=None),
779
- )
780
- self.stddev_group = stddev_group
781
- self.stddev_feat = 1
782
-
783
- def forward(self, x):
784
- out = self.conv_body(x)
785
-
786
- b, c, h, w = out.shape
787
- # concatenate a group stddev statistics to out
788
- group = min(b, self.stddev_group) # Minibatch must be divisible by (or smaller than) group_size
789
- stddev = out.view(group, -1, self.stddev_feat, c // self.stddev_feat, h, w)
790
- stddev = torch.sqrt(stddev.var(0, unbiased=False) + 1e-8)
791
- stddev = stddev.mean([2, 3, 4], keepdims=True).squeeze(2)
792
- stddev = stddev.repeat(group, 1, h, w)
793
- out = torch.cat([out, stddev], 1)
794
-
795
- out = self.final_conv(out)
796
- out = out.view(b, -1)
797
- out = self.final_linear(out)
798
-
799
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/stylegan2_bilinear_arch.py DELETED
@@ -1,614 +0,0 @@
1
- import math
2
- import random
3
- import torch
4
- from torch import nn
5
- from torch.nn import functional as F
6
-
7
- from basicsr.ops.fused_act import FusedLeakyReLU, fused_leaky_relu
8
- from basicsr.utils.registry import ARCH_REGISTRY
9
-
10
-
11
- class NormStyleCode(nn.Module):
12
-
13
- def forward(self, x):
14
- """Normalize the style codes.
15
-
16
- Args:
17
- x (Tensor): Style codes with shape (b, c).
18
-
19
- Returns:
20
- Tensor: Normalized tensor.
21
- """
22
- return x * torch.rsqrt(torch.mean(x**2, dim=1, keepdim=True) + 1e-8)
23
-
24
-
25
- class EqualLinear(nn.Module):
26
- """Equalized Linear as StyleGAN2.
27
-
28
- Args:
29
- in_channels (int): Size of each sample.
30
- out_channels (int): Size of each output sample.
31
- bias (bool): If set to ``False``, the layer will not learn an additive
32
- bias. Default: ``True``.
33
- bias_init_val (float): Bias initialized value. Default: 0.
34
- lr_mul (float): Learning rate multiplier. Default: 1.
35
- activation (None | str): The activation after ``linear`` operation.
36
- Supported: 'fused_lrelu', None. Default: None.
37
- """
38
-
39
- def __init__(self, in_channels, out_channels, bias=True, bias_init_val=0, lr_mul=1, activation=None):
40
- super(EqualLinear, self).__init__()
41
- self.in_channels = in_channels
42
- self.out_channels = out_channels
43
- self.lr_mul = lr_mul
44
- self.activation = activation
45
- if self.activation not in ['fused_lrelu', None]:
46
- raise ValueError(f'Wrong activation value in EqualLinear: {activation}'
47
- "Supported ones are: ['fused_lrelu', None].")
48
- self.scale = (1 / math.sqrt(in_channels)) * lr_mul
49
-
50
- self.weight = nn.Parameter(torch.randn(out_channels, in_channels).div_(lr_mul))
51
- if bias:
52
- self.bias = nn.Parameter(torch.zeros(out_channels).fill_(bias_init_val))
53
- else:
54
- self.register_parameter('bias', None)
55
-
56
- def forward(self, x):
57
- if self.bias is None:
58
- bias = None
59
- else:
60
- bias = self.bias * self.lr_mul
61
- if self.activation == 'fused_lrelu':
62
- out = F.linear(x, self.weight * self.scale)
63
- out = fused_leaky_relu(out, bias)
64
- else:
65
- out = F.linear(x, self.weight * self.scale, bias=bias)
66
- return out
67
-
68
- def __repr__(self):
69
- return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
70
- f'out_channels={self.out_channels}, bias={self.bias is not None})')
71
-
72
-
73
- class ModulatedConv2d(nn.Module):
74
- """Modulated Conv2d used in StyleGAN2.
75
-
76
- There is no bias in ModulatedConv2d.
77
-
78
- Args:
79
- in_channels (int): Channel number of the input.
80
- out_channels (int): Channel number of the output.
81
- kernel_size (int): Size of the convolving kernel.
82
- num_style_feat (int): Channel number of style features.
83
- demodulate (bool): Whether to demodulate in the conv layer.
84
- Default: True.
85
- sample_mode (str | None): Indicating 'upsample', 'downsample' or None.
86
- Default: None.
87
- eps (float): A value added to the denominator for numerical stability.
88
- Default: 1e-8.
89
- """
90
-
91
- def __init__(self,
92
- in_channels,
93
- out_channels,
94
- kernel_size,
95
- num_style_feat,
96
- demodulate=True,
97
- sample_mode=None,
98
- eps=1e-8,
99
- interpolation_mode='bilinear'):
100
- super(ModulatedConv2d, self).__init__()
101
- self.in_channels = in_channels
102
- self.out_channels = out_channels
103
- self.kernel_size = kernel_size
104
- self.demodulate = demodulate
105
- self.sample_mode = sample_mode
106
- self.eps = eps
107
- self.interpolation_mode = interpolation_mode
108
- if self.interpolation_mode == 'nearest':
109
- self.align_corners = None
110
- else:
111
- self.align_corners = False
112
-
113
- self.scale = 1 / math.sqrt(in_channels * kernel_size**2)
114
- # modulation inside each modulated conv
115
- self.modulation = EqualLinear(
116
- num_style_feat, in_channels, bias=True, bias_init_val=1, lr_mul=1, activation=None)
117
-
118
- self.weight = nn.Parameter(torch.randn(1, out_channels, in_channels, kernel_size, kernel_size))
119
- self.padding = kernel_size // 2
120
-
121
- def forward(self, x, style):
122
- """Forward function.
123
-
124
- Args:
125
- x (Tensor): Tensor with shape (b, c, h, w).
126
- style (Tensor): Tensor with shape (b, num_style_feat).
127
-
128
- Returns:
129
- Tensor: Modulated tensor after convolution.
130
- """
131
- b, c, h, w = x.shape # c = c_in
132
- # weight modulation
133
- style = self.modulation(style).view(b, 1, c, 1, 1)
134
- # self.weight: (1, c_out, c_in, k, k); style: (b, 1, c, 1, 1)
135
- weight = self.scale * self.weight * style # (b, c_out, c_in, k, k)
136
-
137
- if self.demodulate:
138
- demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + self.eps)
139
- weight = weight * demod.view(b, self.out_channels, 1, 1, 1)
140
-
141
- weight = weight.view(b * self.out_channels, c, self.kernel_size, self.kernel_size)
142
-
143
- if self.sample_mode == 'upsample':
144
- x = F.interpolate(x, scale_factor=2, mode=self.interpolation_mode, align_corners=self.align_corners)
145
- elif self.sample_mode == 'downsample':
146
- x = F.interpolate(x, scale_factor=0.5, mode=self.interpolation_mode, align_corners=self.align_corners)
147
-
148
- b, c, h, w = x.shape
149
- x = x.view(1, b * c, h, w)
150
- # weight: (b*c_out, c_in, k, k), groups=b
151
- out = F.conv2d(x, weight, padding=self.padding, groups=b)
152
- out = out.view(b, self.out_channels, *out.shape[2:4])
153
-
154
- return out
155
-
156
- def __repr__(self):
157
- return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
158
- f'out_channels={self.out_channels}, '
159
- f'kernel_size={self.kernel_size}, '
160
- f'demodulate={self.demodulate}, sample_mode={self.sample_mode})')
161
-
162
-
163
- class StyleConv(nn.Module):
164
- """Style conv.
165
-
166
- Args:
167
- in_channels (int): Channel number of the input.
168
- out_channels (int): Channel number of the output.
169
- kernel_size (int): Size of the convolving kernel.
170
- num_style_feat (int): Channel number of style features.
171
- demodulate (bool): Whether demodulate in the conv layer. Default: True.
172
- sample_mode (str | None): Indicating 'upsample', 'downsample' or None.
173
- Default: None.
174
- """
175
-
176
- def __init__(self,
177
- in_channels,
178
- out_channels,
179
- kernel_size,
180
- num_style_feat,
181
- demodulate=True,
182
- sample_mode=None,
183
- interpolation_mode='bilinear'):
184
- super(StyleConv, self).__init__()
185
- self.modulated_conv = ModulatedConv2d(
186
- in_channels,
187
- out_channels,
188
- kernel_size,
189
- num_style_feat,
190
- demodulate=demodulate,
191
- sample_mode=sample_mode,
192
- interpolation_mode=interpolation_mode)
193
- self.weight = nn.Parameter(torch.zeros(1)) # for noise injection
194
- self.activate = FusedLeakyReLU(out_channels)
195
-
196
- def forward(self, x, style, noise=None):
197
- # modulate
198
- out = self.modulated_conv(x, style)
199
- # noise injection
200
- if noise is None:
201
- b, _, h, w = out.shape
202
- noise = out.new_empty(b, 1, h, w).normal_()
203
- out = out + self.weight * noise
204
- # activation (with bias)
205
- out = self.activate(out)
206
- return out
207
-
208
-
209
- class ToRGB(nn.Module):
210
- """To RGB from features.
211
-
212
- Args:
213
- in_channels (int): Channel number of input.
214
- num_style_feat (int): Channel number of style features.
215
- upsample (bool): Whether to upsample. Default: True.
216
- """
217
-
218
- def __init__(self, in_channels, num_style_feat, upsample=True, interpolation_mode='bilinear'):
219
- super(ToRGB, self).__init__()
220
- self.upsample = upsample
221
- self.interpolation_mode = interpolation_mode
222
- if self.interpolation_mode == 'nearest':
223
- self.align_corners = None
224
- else:
225
- self.align_corners = False
226
- self.modulated_conv = ModulatedConv2d(
227
- in_channels,
228
- 3,
229
- kernel_size=1,
230
- num_style_feat=num_style_feat,
231
- demodulate=False,
232
- sample_mode=None,
233
- interpolation_mode=interpolation_mode)
234
- self.bias = nn.Parameter(torch.zeros(1, 3, 1, 1))
235
-
236
- def forward(self, x, style, skip=None):
237
- """Forward function.
238
-
239
- Args:
240
- x (Tensor): Feature tensor with shape (b, c, h, w).
241
- style (Tensor): Tensor with shape (b, num_style_feat).
242
- skip (Tensor): Base/skip tensor. Default: None.
243
-
244
- Returns:
245
- Tensor: RGB images.
246
- """
247
- out = self.modulated_conv(x, style)
248
- out = out + self.bias
249
- if skip is not None:
250
- if self.upsample:
251
- skip = F.interpolate(
252
- skip, scale_factor=2, mode=self.interpolation_mode, align_corners=self.align_corners)
253
- out = out + skip
254
- return out
255
-
256
-
257
- class ConstantInput(nn.Module):
258
- """Constant input.
259
-
260
- Args:
261
- num_channel (int): Channel number of constant input.
262
- size (int): Spatial size of constant input.
263
- """
264
-
265
- def __init__(self, num_channel, size):
266
- super(ConstantInput, self).__init__()
267
- self.weight = nn.Parameter(torch.randn(1, num_channel, size, size))
268
-
269
- def forward(self, batch):
270
- out = self.weight.repeat(batch, 1, 1, 1)
271
- return out
272
-
273
-
274
- @ARCH_REGISTRY.register(suffix='basicsr')
275
- class StyleGAN2GeneratorBilinear(nn.Module):
276
- """StyleGAN2 Generator.
277
-
278
- Args:
279
- out_size (int): The spatial size of outputs.
280
- num_style_feat (int): Channel number of style features. Default: 512.
281
- num_mlp (int): Layer number of MLP style layers. Default: 8.
282
- channel_multiplier (int): Channel multiplier for large networks of
283
- StyleGAN2. Default: 2.
284
- lr_mlp (float): Learning rate multiplier for mlp layers. Default: 0.01.
285
- narrow (float): Narrow ratio for channels. Default: 1.0.
286
- """
287
-
288
- def __init__(self,
289
- out_size,
290
- num_style_feat=512,
291
- num_mlp=8,
292
- channel_multiplier=2,
293
- lr_mlp=0.01,
294
- narrow=1,
295
- interpolation_mode='bilinear'):
296
- super(StyleGAN2GeneratorBilinear, self).__init__()
297
- # Style MLP layers
298
- self.num_style_feat = num_style_feat
299
- style_mlp_layers = [NormStyleCode()]
300
- for i in range(num_mlp):
301
- style_mlp_layers.append(
302
- EqualLinear(
303
- num_style_feat, num_style_feat, bias=True, bias_init_val=0, lr_mul=lr_mlp,
304
- activation='fused_lrelu'))
305
- self.style_mlp = nn.Sequential(*style_mlp_layers)
306
-
307
- channels = {
308
- '4': int(512 * narrow),
309
- '8': int(512 * narrow),
310
- '16': int(512 * narrow),
311
- '32': int(512 * narrow),
312
- '64': int(256 * channel_multiplier * narrow),
313
- '128': int(128 * channel_multiplier * narrow),
314
- '256': int(64 * channel_multiplier * narrow),
315
- '512': int(32 * channel_multiplier * narrow),
316
- '1024': int(16 * channel_multiplier * narrow)
317
- }
318
- self.channels = channels
319
-
320
- self.constant_input = ConstantInput(channels['4'], size=4)
321
- self.style_conv1 = StyleConv(
322
- channels['4'],
323
- channels['4'],
324
- kernel_size=3,
325
- num_style_feat=num_style_feat,
326
- demodulate=True,
327
- sample_mode=None,
328
- interpolation_mode=interpolation_mode)
329
- self.to_rgb1 = ToRGB(channels['4'], num_style_feat, upsample=False, interpolation_mode=interpolation_mode)
330
-
331
- self.log_size = int(math.log(out_size, 2))
332
- self.num_layers = (self.log_size - 2) * 2 + 1
333
- self.num_latent = self.log_size * 2 - 2
334
-
335
- self.style_convs = nn.ModuleList()
336
- self.to_rgbs = nn.ModuleList()
337
- self.noises = nn.Module()
338
-
339
- in_channels = channels['4']
340
- # noise
341
- for layer_idx in range(self.num_layers):
342
- resolution = 2**((layer_idx + 5) // 2)
343
- shape = [1, 1, resolution, resolution]
344
- self.noises.register_buffer(f'noise{layer_idx}', torch.randn(*shape))
345
- # style convs and to_rgbs
346
- for i in range(3, self.log_size + 1):
347
- out_channels = channels[f'{2**i}']
348
- self.style_convs.append(
349
- StyleConv(
350
- in_channels,
351
- out_channels,
352
- kernel_size=3,
353
- num_style_feat=num_style_feat,
354
- demodulate=True,
355
- sample_mode='upsample',
356
- interpolation_mode=interpolation_mode))
357
- self.style_convs.append(
358
- StyleConv(
359
- out_channels,
360
- out_channels,
361
- kernel_size=3,
362
- num_style_feat=num_style_feat,
363
- demodulate=True,
364
- sample_mode=None,
365
- interpolation_mode=interpolation_mode))
366
- self.to_rgbs.append(
367
- ToRGB(out_channels, num_style_feat, upsample=True, interpolation_mode=interpolation_mode))
368
- in_channels = out_channels
369
-
370
- def make_noise(self):
371
- """Make noise for noise injection."""
372
- device = self.constant_input.weight.device
373
- noises = [torch.randn(1, 1, 4, 4, device=device)]
374
-
375
- for i in range(3, self.log_size + 1):
376
- for _ in range(2):
377
- noises.append(torch.randn(1, 1, 2**i, 2**i, device=device))
378
-
379
- return noises
380
-
381
- def get_latent(self, x):
382
- return self.style_mlp(x)
383
-
384
- def mean_latent(self, num_latent):
385
- latent_in = torch.randn(num_latent, self.num_style_feat, device=self.constant_input.weight.device)
386
- latent = self.style_mlp(latent_in).mean(0, keepdim=True)
387
- return latent
388
-
389
- def forward(self,
390
- styles,
391
- input_is_latent=False,
392
- noise=None,
393
- randomize_noise=True,
394
- truncation=1,
395
- truncation_latent=None,
396
- inject_index=None,
397
- return_latents=False):
398
- """Forward function for StyleGAN2Generator.
399
-
400
- Args:
401
- styles (list[Tensor]): Sample codes of styles.
402
- input_is_latent (bool): Whether input is latent style.
403
- Default: False.
404
- noise (Tensor | None): Input noise or None. Default: None.
405
- randomize_noise (bool): Randomize noise, used when 'noise' is
406
- False. Default: True.
407
- truncation (float): TODO. Default: 1.
408
- truncation_latent (Tensor | None): TODO. Default: None.
409
- inject_index (int | None): The injection index for mixing noise.
410
- Default: None.
411
- return_latents (bool): Whether to return style latents.
412
- Default: False.
413
- """
414
- # style codes -> latents with Style MLP layer
415
- if not input_is_latent:
416
- styles = [self.style_mlp(s) for s in styles]
417
- # noises
418
- if noise is None:
419
- if randomize_noise:
420
- noise = [None] * self.num_layers # for each style conv layer
421
- else: # use the stored noise
422
- noise = [getattr(self.noises, f'noise{i}') for i in range(self.num_layers)]
423
- # style truncation
424
- if truncation < 1:
425
- style_truncation = []
426
- for style in styles:
427
- style_truncation.append(truncation_latent + truncation * (style - truncation_latent))
428
- styles = style_truncation
429
- # get style latent with injection
430
- if len(styles) == 1:
431
- inject_index = self.num_latent
432
-
433
- if styles[0].ndim < 3:
434
- # repeat latent code for all the layers
435
- latent = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
436
- else: # used for encoder with different latent code for each layer
437
- latent = styles[0]
438
- elif len(styles) == 2: # mixing noises
439
- if inject_index is None:
440
- inject_index = random.randint(1, self.num_latent - 1)
441
- latent1 = styles[0].unsqueeze(1).repeat(1, inject_index, 1)
442
- latent2 = styles[1].unsqueeze(1).repeat(1, self.num_latent - inject_index, 1)
443
- latent = torch.cat([latent1, latent2], 1)
444
-
445
- # main generation
446
- out = self.constant_input(latent.shape[0])
447
- out = self.style_conv1(out, latent[:, 0], noise=noise[0])
448
- skip = self.to_rgb1(out, latent[:, 1])
449
-
450
- i = 1
451
- for conv1, conv2, noise1, noise2, to_rgb in zip(self.style_convs[::2], self.style_convs[1::2], noise[1::2],
452
- noise[2::2], self.to_rgbs):
453
- out = conv1(out, latent[:, i], noise=noise1)
454
- out = conv2(out, latent[:, i + 1], noise=noise2)
455
- skip = to_rgb(out, latent[:, i + 2], skip)
456
- i += 2
457
-
458
- image = skip
459
-
460
- if return_latents:
461
- return image, latent
462
- else:
463
- return image, None
464
-
465
-
466
- class ScaledLeakyReLU(nn.Module):
467
- """Scaled LeakyReLU.
468
-
469
- Args:
470
- negative_slope (float): Negative slope. Default: 0.2.
471
- """
472
-
473
- def __init__(self, negative_slope=0.2):
474
- super(ScaledLeakyReLU, self).__init__()
475
- self.negative_slope = negative_slope
476
-
477
- def forward(self, x):
478
- out = F.leaky_relu(x, negative_slope=self.negative_slope)
479
- return out * math.sqrt(2)
480
-
481
-
482
- class EqualConv2d(nn.Module):
483
- """Equalized Linear as StyleGAN2.
484
-
485
- Args:
486
- in_channels (int): Channel number of the input.
487
- out_channels (int): Channel number of the output.
488
- kernel_size (int): Size of the convolving kernel.
489
- stride (int): Stride of the convolution. Default: 1
490
- padding (int): Zero-padding added to both sides of the input.
491
- Default: 0.
492
- bias (bool): If ``True``, adds a learnable bias to the output.
493
- Default: ``True``.
494
- bias_init_val (float): Bias initialized value. Default: 0.
495
- """
496
-
497
- def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, bias=True, bias_init_val=0):
498
- super(EqualConv2d, self).__init__()
499
- self.in_channels = in_channels
500
- self.out_channels = out_channels
501
- self.kernel_size = kernel_size
502
- self.stride = stride
503
- self.padding = padding
504
- self.scale = 1 / math.sqrt(in_channels * kernel_size**2)
505
-
506
- self.weight = nn.Parameter(torch.randn(out_channels, in_channels, kernel_size, kernel_size))
507
- if bias:
508
- self.bias = nn.Parameter(torch.zeros(out_channels).fill_(bias_init_val))
509
- else:
510
- self.register_parameter('bias', None)
511
-
512
- def forward(self, x):
513
- out = F.conv2d(
514
- x,
515
- self.weight * self.scale,
516
- bias=self.bias,
517
- stride=self.stride,
518
- padding=self.padding,
519
- )
520
-
521
- return out
522
-
523
- def __repr__(self):
524
- return (f'{self.__class__.__name__}(in_channels={self.in_channels}, '
525
- f'out_channels={self.out_channels}, '
526
- f'kernel_size={self.kernel_size},'
527
- f' stride={self.stride}, padding={self.padding}, '
528
- f'bias={self.bias is not None})')
529
-
530
-
531
- class ConvLayer(nn.Sequential):
532
- """Conv Layer used in StyleGAN2 Discriminator.
533
-
534
- Args:
535
- in_channels (int): Channel number of the input.
536
- out_channels (int): Channel number of the output.
537
- kernel_size (int): Kernel size.
538
- downsample (bool): Whether downsample by a factor of 2.
539
- Default: False.
540
- bias (bool): Whether with bias. Default: True.
541
- activate (bool): Whether use activateion. Default: True.
542
- """
543
-
544
- def __init__(self,
545
- in_channels,
546
- out_channels,
547
- kernel_size,
548
- downsample=False,
549
- bias=True,
550
- activate=True,
551
- interpolation_mode='bilinear'):
552
- layers = []
553
- self.interpolation_mode = interpolation_mode
554
- # downsample
555
- if downsample:
556
- if self.interpolation_mode == 'nearest':
557
- self.align_corners = None
558
- else:
559
- self.align_corners = False
560
-
561
- layers.append(
562
- torch.nn.Upsample(scale_factor=0.5, mode=interpolation_mode, align_corners=self.align_corners))
563
- stride = 1
564
- self.padding = kernel_size // 2
565
- # conv
566
- layers.append(
567
- EqualConv2d(
568
- in_channels, out_channels, kernel_size, stride=stride, padding=self.padding, bias=bias
569
- and not activate))
570
- # activation
571
- if activate:
572
- if bias:
573
- layers.append(FusedLeakyReLU(out_channels))
574
- else:
575
- layers.append(ScaledLeakyReLU(0.2))
576
-
577
- super(ConvLayer, self).__init__(*layers)
578
-
579
-
580
- class ResBlock(nn.Module):
581
- """Residual block used in StyleGAN2 Discriminator.
582
-
583
- Args:
584
- in_channels (int): Channel number of the input.
585
- out_channels (int): Channel number of the output.
586
- """
587
-
588
- def __init__(self, in_channels, out_channels, interpolation_mode='bilinear'):
589
- super(ResBlock, self).__init__()
590
-
591
- self.conv1 = ConvLayer(in_channels, in_channels, 3, bias=True, activate=True)
592
- self.conv2 = ConvLayer(
593
- in_channels,
594
- out_channels,
595
- 3,
596
- downsample=True,
597
- interpolation_mode=interpolation_mode,
598
- bias=True,
599
- activate=True)
600
- self.skip = ConvLayer(
601
- in_channels,
602
- out_channels,
603
- 1,
604
- downsample=True,
605
- interpolation_mode=interpolation_mode,
606
- bias=False,
607
- activate=False)
608
-
609
- def forward(self, x):
610
- out = self.conv1(x)
611
- out = self.conv2(out)
612
- skip = self.skip(x)
613
- out = (out + skip) / math.sqrt(2)
614
- return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/swinir_arch.py DELETED
@@ -1,956 +0,0 @@
1
- # Modified from https://github.com/JingyunLiang/SwinIR
2
- # SwinIR: Image Restoration Using Swin Transformer, https://arxiv.org/abs/2108.10257
3
- # Originally Written by Ze Liu, Modified by Jingyun Liang.
4
-
5
- import math
6
- import torch
7
- import torch.nn as nn
8
- import torch.utils.checkpoint as checkpoint
9
-
10
- from basicsr.utils.registry import ARCH_REGISTRY
11
- from .arch_util import to_2tuple, trunc_normal_
12
-
13
-
14
- def drop_path(x, drop_prob: float = 0., training: bool = False):
15
- """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
16
-
17
- From: https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/layers/drop.py
18
- """
19
- if drop_prob == 0. or not training:
20
- return x
21
- keep_prob = 1 - drop_prob
22
- shape = (x.shape[0], ) + (1, ) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
23
- random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device)
24
- random_tensor.floor_() # binarize
25
- output = x.div(keep_prob) * random_tensor
26
- return output
27
-
28
-
29
- class DropPath(nn.Module):
30
- """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
31
-
32
- From: https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/layers/drop.py
33
- """
34
-
35
- def __init__(self, drop_prob=None):
36
- super(DropPath, self).__init__()
37
- self.drop_prob = drop_prob
38
-
39
- def forward(self, x):
40
- return drop_path(x, self.drop_prob, self.training)
41
-
42
-
43
- class Mlp(nn.Module):
44
-
45
- def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):
46
- super().__init__()
47
- out_features = out_features or in_features
48
- hidden_features = hidden_features or in_features
49
- self.fc1 = nn.Linear(in_features, hidden_features)
50
- self.act = act_layer()
51
- self.fc2 = nn.Linear(hidden_features, out_features)
52
- self.drop = nn.Dropout(drop)
53
-
54
- def forward(self, x):
55
- x = self.fc1(x)
56
- x = self.act(x)
57
- x = self.drop(x)
58
- x = self.fc2(x)
59
- x = self.drop(x)
60
- return x
61
-
62
-
63
- def window_partition(x, window_size):
64
- """
65
- Args:
66
- x: (b, h, w, c)
67
- window_size (int): window size
68
-
69
- Returns:
70
- windows: (num_windows*b, window_size, window_size, c)
71
- """
72
- b, h, w, c = x.shape
73
- x = x.view(b, h // window_size, window_size, w // window_size, window_size, c)
74
- windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, c)
75
- return windows
76
-
77
-
78
- def window_reverse(windows, window_size, h, w):
79
- """
80
- Args:
81
- windows: (num_windows*b, window_size, window_size, c)
82
- window_size (int): Window size
83
- h (int): Height of image
84
- w (int): Width of image
85
-
86
- Returns:
87
- x: (b, h, w, c)
88
- """
89
- b = int(windows.shape[0] / (h * w / window_size / window_size))
90
- x = windows.view(b, h // window_size, w // window_size, window_size, window_size, -1)
91
- x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(b, h, w, -1)
92
- return x
93
-
94
-
95
- class WindowAttention(nn.Module):
96
- r""" Window based multi-head self attention (W-MSA) module with relative position bias.
97
- It supports both of shifted and non-shifted window.
98
-
99
- Args:
100
- dim (int): Number of input channels.
101
- window_size (tuple[int]): The height and width of the window.
102
- num_heads (int): Number of attention heads.
103
- qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
104
- qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set
105
- attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0
106
- proj_drop (float, optional): Dropout ratio of output. Default: 0.0
107
- """
108
-
109
- def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0.):
110
-
111
- super().__init__()
112
- self.dim = dim
113
- self.window_size = window_size # Wh, Ww
114
- self.num_heads = num_heads
115
- head_dim = dim // num_heads
116
- self.scale = qk_scale or head_dim**-0.5
117
-
118
- # define a parameter table of relative position bias
119
- self.relative_position_bias_table = nn.Parameter(
120
- torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads)) # 2*Wh-1 * 2*Ww-1, nH
121
-
122
- # get pair-wise relative position index for each token inside the window
123
- coords_h = torch.arange(self.window_size[0])
124
- coords_w = torch.arange(self.window_size[1])
125
- coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww
126
- coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww
127
- relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww
128
- relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2
129
- relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0
130
- relative_coords[:, :, 1] += self.window_size[1] - 1
131
- relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1
132
- relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww
133
- self.register_buffer('relative_position_index', relative_position_index)
134
-
135
- self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
136
- self.attn_drop = nn.Dropout(attn_drop)
137
- self.proj = nn.Linear(dim, dim)
138
-
139
- self.proj_drop = nn.Dropout(proj_drop)
140
-
141
- trunc_normal_(self.relative_position_bias_table, std=.02)
142
- self.softmax = nn.Softmax(dim=-1)
143
-
144
- def forward(self, x, mask=None):
145
- """
146
- Args:
147
- x: input features with shape of (num_windows*b, n, c)
148
- mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None
149
- """
150
- b_, n, c = x.shape
151
- qkv = self.qkv(x).reshape(b_, n, 3, self.num_heads, c // self.num_heads).permute(2, 0, 3, 1, 4)
152
- q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
153
-
154
- q = q * self.scale
155
- attn = (q @ k.transpose(-2, -1))
156
-
157
- relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view(
158
- self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH
159
- relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww
160
- attn = attn + relative_position_bias.unsqueeze(0)
161
-
162
- if mask is not None:
163
- nw = mask.shape[0]
164
- attn = attn.view(b_ // nw, nw, self.num_heads, n, n) + mask.unsqueeze(1).unsqueeze(0)
165
- attn = attn.view(-1, self.num_heads, n, n)
166
- attn = self.softmax(attn)
167
- else:
168
- attn = self.softmax(attn)
169
-
170
- attn = self.attn_drop(attn)
171
-
172
- x = (attn @ v).transpose(1, 2).reshape(b_, n, c)
173
- x = self.proj(x)
174
- x = self.proj_drop(x)
175
- return x
176
-
177
- def extra_repr(self) -> str:
178
- return f'dim={self.dim}, window_size={self.window_size}, num_heads={self.num_heads}'
179
-
180
- def flops(self, n):
181
- # calculate flops for 1 window with token length of n
182
- flops = 0
183
- # qkv = self.qkv(x)
184
- flops += n * self.dim * 3 * self.dim
185
- # attn = (q @ k.transpose(-2, -1))
186
- flops += self.num_heads * n * (self.dim // self.num_heads) * n
187
- # x = (attn @ v)
188
- flops += self.num_heads * n * n * (self.dim // self.num_heads)
189
- # x = self.proj(x)
190
- flops += n * self.dim * self.dim
191
- return flops
192
-
193
-
194
- class SwinTransformerBlock(nn.Module):
195
- r""" Swin Transformer Block.
196
-
197
- Args:
198
- dim (int): Number of input channels.
199
- input_resolution (tuple[int]): Input resolution.
200
- num_heads (int): Number of attention heads.
201
- window_size (int): Window size.
202
- shift_size (int): Shift size for SW-MSA.
203
- mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
204
- qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
205
- qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
206
- drop (float, optional): Dropout rate. Default: 0.0
207
- attn_drop (float, optional): Attention dropout rate. Default: 0.0
208
- drop_path (float, optional): Stochastic depth rate. Default: 0.0
209
- act_layer (nn.Module, optional): Activation layer. Default: nn.GELU
210
- norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
211
- """
212
-
213
- def __init__(self,
214
- dim,
215
- input_resolution,
216
- num_heads,
217
- window_size=7,
218
- shift_size=0,
219
- mlp_ratio=4.,
220
- qkv_bias=True,
221
- qk_scale=None,
222
- drop=0.,
223
- attn_drop=0.,
224
- drop_path=0.,
225
- act_layer=nn.GELU,
226
- norm_layer=nn.LayerNorm):
227
- super().__init__()
228
- self.dim = dim
229
- self.input_resolution = input_resolution
230
- self.num_heads = num_heads
231
- self.window_size = window_size
232
- self.shift_size = shift_size
233
- self.mlp_ratio = mlp_ratio
234
- if min(self.input_resolution) <= self.window_size:
235
- # if window size is larger than input resolution, we don't partition windows
236
- self.shift_size = 0
237
- self.window_size = min(self.input_resolution)
238
- assert 0 <= self.shift_size < self.window_size, 'shift_size must in 0-window_size'
239
-
240
- self.norm1 = norm_layer(dim)
241
- self.attn = WindowAttention(
242
- dim,
243
- window_size=to_2tuple(self.window_size),
244
- num_heads=num_heads,
245
- qkv_bias=qkv_bias,
246
- qk_scale=qk_scale,
247
- attn_drop=attn_drop,
248
- proj_drop=drop)
249
-
250
- self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
251
- self.norm2 = norm_layer(dim)
252
- mlp_hidden_dim = int(dim * mlp_ratio)
253
- self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
254
-
255
- if self.shift_size > 0:
256
- attn_mask = self.calculate_mask(self.input_resolution)
257
- else:
258
- attn_mask = None
259
-
260
- self.register_buffer('attn_mask', attn_mask)
261
-
262
- def calculate_mask(self, x_size):
263
- # calculate attention mask for SW-MSA
264
- h, w = x_size
265
- img_mask = torch.zeros((1, h, w, 1)) # 1 h w 1
266
- h_slices = (slice(0, -self.window_size), slice(-self.window_size,
267
- -self.shift_size), slice(-self.shift_size, None))
268
- w_slices = (slice(0, -self.window_size), slice(-self.window_size,
269
- -self.shift_size), slice(-self.shift_size, None))
270
- cnt = 0
271
- for h in h_slices:
272
- for w in w_slices:
273
- img_mask[:, h, w, :] = cnt
274
- cnt += 1
275
-
276
- mask_windows = window_partition(img_mask, self.window_size) # nw, window_size, window_size, 1
277
- mask_windows = mask_windows.view(-1, self.window_size * self.window_size)
278
- attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)
279
- attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill(attn_mask == 0, float(0.0))
280
-
281
- return attn_mask
282
-
283
- def forward(self, x, x_size):
284
- h, w = x_size
285
- b, _, c = x.shape
286
- # assert seq_len == h * w, "input feature has wrong size"
287
-
288
- shortcut = x
289
- x = self.norm1(x)
290
- x = x.view(b, h, w, c)
291
-
292
- # cyclic shift
293
- if self.shift_size > 0:
294
- shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2))
295
- else:
296
- shifted_x = x
297
-
298
- # partition windows
299
- x_windows = window_partition(shifted_x, self.window_size) # nw*b, window_size, window_size, c
300
- x_windows = x_windows.view(-1, self.window_size * self.window_size, c) # nw*b, window_size*window_size, c
301
-
302
- # W-MSA/SW-MSA (to be compatible for testing on images whose shapes are the multiple of window size
303
- if self.input_resolution == x_size:
304
- attn_windows = self.attn(x_windows, mask=self.attn_mask) # nw*b, window_size*window_size, c
305
- else:
306
- attn_windows = self.attn(x_windows, mask=self.calculate_mask(x_size).to(x.device))
307
-
308
- # merge windows
309
- attn_windows = attn_windows.view(-1, self.window_size, self.window_size, c)
310
- shifted_x = window_reverse(attn_windows, self.window_size, h, w) # b h' w' c
311
-
312
- # reverse cyclic shift
313
- if self.shift_size > 0:
314
- x = torch.roll(shifted_x, shifts=(self.shift_size, self.shift_size), dims=(1, 2))
315
- else:
316
- x = shifted_x
317
- x = x.view(b, h * w, c)
318
-
319
- # FFN
320
- x = shortcut + self.drop_path(x)
321
- x = x + self.drop_path(self.mlp(self.norm2(x)))
322
-
323
- return x
324
-
325
- def extra_repr(self) -> str:
326
- return (f'dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, '
327
- f'window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}')
328
-
329
- def flops(self):
330
- flops = 0
331
- h, w = self.input_resolution
332
- # norm1
333
- flops += self.dim * h * w
334
- # W-MSA/SW-MSA
335
- nw = h * w / self.window_size / self.window_size
336
- flops += nw * self.attn.flops(self.window_size * self.window_size)
337
- # mlp
338
- flops += 2 * h * w * self.dim * self.dim * self.mlp_ratio
339
- # norm2
340
- flops += self.dim * h * w
341
- return flops
342
-
343
-
344
- class PatchMerging(nn.Module):
345
- r""" Patch Merging Layer.
346
-
347
- Args:
348
- input_resolution (tuple[int]): Resolution of input feature.
349
- dim (int): Number of input channels.
350
- norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
351
- """
352
-
353
- def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm):
354
- super().__init__()
355
- self.input_resolution = input_resolution
356
- self.dim = dim
357
- self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)
358
- self.norm = norm_layer(4 * dim)
359
-
360
- def forward(self, x):
361
- """
362
- x: b, h*w, c
363
- """
364
- h, w = self.input_resolution
365
- b, seq_len, c = x.shape
366
- assert seq_len == h * w, 'input feature has wrong size'
367
- assert h % 2 == 0 and w % 2 == 0, f'x size ({h}*{w}) are not even.'
368
-
369
- x = x.view(b, h, w, c)
370
-
371
- x0 = x[:, 0::2, 0::2, :] # b h/2 w/2 c
372
- x1 = x[:, 1::2, 0::2, :] # b h/2 w/2 c
373
- x2 = x[:, 0::2, 1::2, :] # b h/2 w/2 c
374
- x3 = x[:, 1::2, 1::2, :] # b h/2 w/2 c
375
- x = torch.cat([x0, x1, x2, x3], -1) # b h/2 w/2 4*c
376
- x = x.view(b, -1, 4 * c) # b h/2*w/2 4*c
377
-
378
- x = self.norm(x)
379
- x = self.reduction(x)
380
-
381
- return x
382
-
383
- def extra_repr(self) -> str:
384
- return f'input_resolution={self.input_resolution}, dim={self.dim}'
385
-
386
- def flops(self):
387
- h, w = self.input_resolution
388
- flops = h * w * self.dim
389
- flops += (h // 2) * (w // 2) * 4 * self.dim * 2 * self.dim
390
- return flops
391
-
392
-
393
- class BasicLayer(nn.Module):
394
- """ A basic Swin Transformer layer for one stage.
395
-
396
- Args:
397
- dim (int): Number of input channels.
398
- input_resolution (tuple[int]): Input resolution.
399
- depth (int): Number of blocks.
400
- num_heads (int): Number of attention heads.
401
- window_size (int): Local window size.
402
- mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
403
- qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
404
- qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
405
- drop (float, optional): Dropout rate. Default: 0.0
406
- attn_drop (float, optional): Attention dropout rate. Default: 0.0
407
- drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0
408
- norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
409
- downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None
410
- use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False.
411
- """
412
-
413
- def __init__(self,
414
- dim,
415
- input_resolution,
416
- depth,
417
- num_heads,
418
- window_size,
419
- mlp_ratio=4.,
420
- qkv_bias=True,
421
- qk_scale=None,
422
- drop=0.,
423
- attn_drop=0.,
424
- drop_path=0.,
425
- norm_layer=nn.LayerNorm,
426
- downsample=None,
427
- use_checkpoint=False):
428
-
429
- super().__init__()
430
- self.dim = dim
431
- self.input_resolution = input_resolution
432
- self.depth = depth
433
- self.use_checkpoint = use_checkpoint
434
-
435
- # build blocks
436
- self.blocks = nn.ModuleList([
437
- SwinTransformerBlock(
438
- dim=dim,
439
- input_resolution=input_resolution,
440
- num_heads=num_heads,
441
- window_size=window_size,
442
- shift_size=0 if (i % 2 == 0) else window_size // 2,
443
- mlp_ratio=mlp_ratio,
444
- qkv_bias=qkv_bias,
445
- qk_scale=qk_scale,
446
- drop=drop,
447
- attn_drop=attn_drop,
448
- drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path,
449
- norm_layer=norm_layer) for i in range(depth)
450
- ])
451
-
452
- # patch merging layer
453
- if downsample is not None:
454
- self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer)
455
- else:
456
- self.downsample = None
457
-
458
- def forward(self, x, x_size):
459
- for blk in self.blocks:
460
- if self.use_checkpoint:
461
- x = checkpoint.checkpoint(blk, x)
462
- else:
463
- x = blk(x, x_size)
464
- if self.downsample is not None:
465
- x = self.downsample(x)
466
- return x
467
-
468
- def extra_repr(self) -> str:
469
- return f'dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}'
470
-
471
- def flops(self):
472
- flops = 0
473
- for blk in self.blocks:
474
- flops += blk.flops()
475
- if self.downsample is not None:
476
- flops += self.downsample.flops()
477
- return flops
478
-
479
-
480
- class RSTB(nn.Module):
481
- """Residual Swin Transformer Block (RSTB).
482
-
483
- Args:
484
- dim (int): Number of input channels.
485
- input_resolution (tuple[int]): Input resolution.
486
- depth (int): Number of blocks.
487
- num_heads (int): Number of attention heads.
488
- window_size (int): Local window size.
489
- mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
490
- qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
491
- qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
492
- drop (float, optional): Dropout rate. Default: 0.0
493
- attn_drop (float, optional): Attention dropout rate. Default: 0.0
494
- drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0
495
- norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
496
- downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None
497
- use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False.
498
- img_size: Input image size.
499
- patch_size: Patch size.
500
- resi_connection: The convolutional block before residual connection.
501
- """
502
-
503
- def __init__(self,
504
- dim,
505
- input_resolution,
506
- depth,
507
- num_heads,
508
- window_size,
509
- mlp_ratio=4.,
510
- qkv_bias=True,
511
- qk_scale=None,
512
- drop=0.,
513
- attn_drop=0.,
514
- drop_path=0.,
515
- norm_layer=nn.LayerNorm,
516
- downsample=None,
517
- use_checkpoint=False,
518
- img_size=224,
519
- patch_size=4,
520
- resi_connection='1conv'):
521
- super(RSTB, self).__init__()
522
-
523
- self.dim = dim
524
- self.input_resolution = input_resolution
525
-
526
- self.residual_group = BasicLayer(
527
- dim=dim,
528
- input_resolution=input_resolution,
529
- depth=depth,
530
- num_heads=num_heads,
531
- window_size=window_size,
532
- mlp_ratio=mlp_ratio,
533
- qkv_bias=qkv_bias,
534
- qk_scale=qk_scale,
535
- drop=drop,
536
- attn_drop=attn_drop,
537
- drop_path=drop_path,
538
- norm_layer=norm_layer,
539
- downsample=downsample,
540
- use_checkpoint=use_checkpoint)
541
-
542
- if resi_connection == '1conv':
543
- self.conv = nn.Conv2d(dim, dim, 3, 1, 1)
544
- elif resi_connection == '3conv':
545
- # to save parameters and memory
546
- self.conv = nn.Sequential(
547
- nn.Conv2d(dim, dim // 4, 3, 1, 1), nn.LeakyReLU(negative_slope=0.2, inplace=True),
548
- nn.Conv2d(dim // 4, dim // 4, 1, 1, 0), nn.LeakyReLU(negative_slope=0.2, inplace=True),
549
- nn.Conv2d(dim // 4, dim, 3, 1, 1))
550
-
551
- self.patch_embed = PatchEmbed(
552
- img_size=img_size, patch_size=patch_size, in_chans=0, embed_dim=dim, norm_layer=None)
553
-
554
- self.patch_unembed = PatchUnEmbed(
555
- img_size=img_size, patch_size=patch_size, in_chans=0, embed_dim=dim, norm_layer=None)
556
-
557
- def forward(self, x, x_size):
558
- return self.patch_embed(self.conv(self.patch_unembed(self.residual_group(x, x_size), x_size))) + x
559
-
560
- def flops(self):
561
- flops = 0
562
- flops += self.residual_group.flops()
563
- h, w = self.input_resolution
564
- flops += h * w * self.dim * self.dim * 9
565
- flops += self.patch_embed.flops()
566
- flops += self.patch_unembed.flops()
567
-
568
- return flops
569
-
570
-
571
- class PatchEmbed(nn.Module):
572
- r""" Image to Patch Embedding
573
-
574
- Args:
575
- img_size (int): Image size. Default: 224.
576
- patch_size (int): Patch token size. Default: 4.
577
- in_chans (int): Number of input image channels. Default: 3.
578
- embed_dim (int): Number of linear projection output channels. Default: 96.
579
- norm_layer (nn.Module, optional): Normalization layer. Default: None
580
- """
581
-
582
- def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None):
583
- super().__init__()
584
- img_size = to_2tuple(img_size)
585
- patch_size = to_2tuple(patch_size)
586
- patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]]
587
- self.img_size = img_size
588
- self.patch_size = patch_size
589
- self.patches_resolution = patches_resolution
590
- self.num_patches = patches_resolution[0] * patches_resolution[1]
591
-
592
- self.in_chans = in_chans
593
- self.embed_dim = embed_dim
594
-
595
- if norm_layer is not None:
596
- self.norm = norm_layer(embed_dim)
597
- else:
598
- self.norm = None
599
-
600
- def forward(self, x):
601
- x = x.flatten(2).transpose(1, 2) # b Ph*Pw c
602
- if self.norm is not None:
603
- x = self.norm(x)
604
- return x
605
-
606
- def flops(self):
607
- flops = 0
608
- h, w = self.img_size
609
- if self.norm is not None:
610
- flops += h * w * self.embed_dim
611
- return flops
612
-
613
-
614
- class PatchUnEmbed(nn.Module):
615
- r""" Image to Patch Unembedding
616
-
617
- Args:
618
- img_size (int): Image size. Default: 224.
619
- patch_size (int): Patch token size. Default: 4.
620
- in_chans (int): Number of input image channels. Default: 3.
621
- embed_dim (int): Number of linear projection output channels. Default: 96.
622
- norm_layer (nn.Module, optional): Normalization layer. Default: None
623
- """
624
-
625
- def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None):
626
- super().__init__()
627
- img_size = to_2tuple(img_size)
628
- patch_size = to_2tuple(patch_size)
629
- patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]]
630
- self.img_size = img_size
631
- self.patch_size = patch_size
632
- self.patches_resolution = patches_resolution
633
- self.num_patches = patches_resolution[0] * patches_resolution[1]
634
-
635
- self.in_chans = in_chans
636
- self.embed_dim = embed_dim
637
-
638
- def forward(self, x, x_size):
639
- x = x.transpose(1, 2).view(x.shape[0], self.embed_dim, x_size[0], x_size[1]) # b Ph*Pw c
640
- return x
641
-
642
- def flops(self):
643
- flops = 0
644
- return flops
645
-
646
-
647
- class Upsample(nn.Sequential):
648
- """Upsample module.
649
-
650
- Args:
651
- scale (int): Scale factor. Supported scales: 2^n and 3.
652
- num_feat (int): Channel number of intermediate features.
653
- """
654
-
655
- def __init__(self, scale, num_feat):
656
- m = []
657
- if (scale & (scale - 1)) == 0: # scale = 2^n
658
- for _ in range(int(math.log(scale, 2))):
659
- m.append(nn.Conv2d(num_feat, 4 * num_feat, 3, 1, 1))
660
- m.append(nn.PixelShuffle(2))
661
- elif scale == 3:
662
- m.append(nn.Conv2d(num_feat, 9 * num_feat, 3, 1, 1))
663
- m.append(nn.PixelShuffle(3))
664
- else:
665
- raise ValueError(f'scale {scale} is not supported. Supported scales: 2^n and 3.')
666
- super(Upsample, self).__init__(*m)
667
-
668
-
669
- class UpsampleOneStep(nn.Sequential):
670
- """UpsampleOneStep module (the difference with Upsample is that it always only has 1conv + 1pixelshuffle)
671
- Used in lightweight SR to save parameters.
672
-
673
- Args:
674
- scale (int): Scale factor. Supported scales: 2^n and 3.
675
- num_feat (int): Channel number of intermediate features.
676
-
677
- """
678
-
679
- def __init__(self, scale, num_feat, num_out_ch, input_resolution=None):
680
- self.num_feat = num_feat
681
- self.input_resolution = input_resolution
682
- m = []
683
- m.append(nn.Conv2d(num_feat, (scale**2) * num_out_ch, 3, 1, 1))
684
- m.append(nn.PixelShuffle(scale))
685
- super(UpsampleOneStep, self).__init__(*m)
686
-
687
- def flops(self):
688
- h, w = self.input_resolution
689
- flops = h * w * self.num_feat * 3 * 9
690
- return flops
691
-
692
-
693
- @ARCH_REGISTRY.register()
694
- class SwinIR(nn.Module):
695
- r""" SwinIR
696
- A PyTorch impl of : `SwinIR: Image Restoration Using Swin Transformer`, based on Swin Transformer.
697
-
698
- Args:
699
- img_size (int | tuple(int)): Input image size. Default 64
700
- patch_size (int | tuple(int)): Patch size. Default: 1
701
- in_chans (int): Number of input image channels. Default: 3
702
- embed_dim (int): Patch embedding dimension. Default: 96
703
- depths (tuple(int)): Depth of each Swin Transformer layer.
704
- num_heads (tuple(int)): Number of attention heads in different layers.
705
- window_size (int): Window size. Default: 7
706
- mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4
707
- qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True
708
- qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. Default: None
709
- drop_rate (float): Dropout rate. Default: 0
710
- attn_drop_rate (float): Attention dropout rate. Default: 0
711
- drop_path_rate (float): Stochastic depth rate. Default: 0.1
712
- norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm.
713
- ape (bool): If True, add absolute position embedding to the patch embedding. Default: False
714
- patch_norm (bool): If True, add normalization after patch embedding. Default: True
715
- use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False
716
- upscale: Upscale factor. 2/3/4/8 for image SR, 1 for denoising and compress artifact reduction
717
- img_range: Image range. 1. or 255.
718
- upsampler: The reconstruction reconstruction module. 'pixelshuffle'/'pixelshuffledirect'/'nearest+conv'/None
719
- resi_connection: The convolutional block before residual connection. '1conv'/'3conv'
720
- """
721
-
722
- def __init__(self,
723
- img_size=64,
724
- patch_size=1,
725
- in_chans=3,
726
- embed_dim=96,
727
- depths=(6, 6, 6, 6),
728
- num_heads=(6, 6, 6, 6),
729
- window_size=7,
730
- mlp_ratio=4.,
731
- qkv_bias=True,
732
- qk_scale=None,
733
- drop_rate=0.,
734
- attn_drop_rate=0.,
735
- drop_path_rate=0.1,
736
- norm_layer=nn.LayerNorm,
737
- ape=False,
738
- patch_norm=True,
739
- use_checkpoint=False,
740
- upscale=2,
741
- img_range=1.,
742
- upsampler='',
743
- resi_connection='1conv',
744
- **kwargs):
745
- super(SwinIR, self).__init__()
746
- num_in_ch = in_chans
747
- num_out_ch = in_chans
748
- num_feat = 64
749
- self.img_range = img_range
750
- if in_chans == 3:
751
- rgb_mean = (0.4488, 0.4371, 0.4040)
752
- self.mean = torch.Tensor(rgb_mean).view(1, 3, 1, 1)
753
- else:
754
- self.mean = torch.zeros(1, 1, 1, 1)
755
- self.upscale = upscale
756
- self.upsampler = upsampler
757
-
758
- # ------------------------- 1, shallow feature extraction ------------------------- #
759
- self.conv_first = nn.Conv2d(num_in_ch, embed_dim, 3, 1, 1)
760
-
761
- # ------------------------- 2, deep feature extraction ------------------------- #
762
- self.num_layers = len(depths)
763
- self.embed_dim = embed_dim
764
- self.ape = ape
765
- self.patch_norm = patch_norm
766
- self.num_features = embed_dim
767
- self.mlp_ratio = mlp_ratio
768
-
769
- # split image into non-overlapping patches
770
- self.patch_embed = PatchEmbed(
771
- img_size=img_size,
772
- patch_size=patch_size,
773
- in_chans=embed_dim,
774
- embed_dim=embed_dim,
775
- norm_layer=norm_layer if self.patch_norm else None)
776
- num_patches = self.patch_embed.num_patches
777
- patches_resolution = self.patch_embed.patches_resolution
778
- self.patches_resolution = patches_resolution
779
-
780
- # merge non-overlapping patches into image
781
- self.patch_unembed = PatchUnEmbed(
782
- img_size=img_size,
783
- patch_size=patch_size,
784
- in_chans=embed_dim,
785
- embed_dim=embed_dim,
786
- norm_layer=norm_layer if self.patch_norm else None)
787
-
788
- # absolute position embedding
789
- if self.ape:
790
- self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim))
791
- trunc_normal_(self.absolute_pos_embed, std=.02)
792
-
793
- self.pos_drop = nn.Dropout(p=drop_rate)
794
-
795
- # stochastic depth
796
- dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule
797
-
798
- # build Residual Swin Transformer blocks (RSTB)
799
- self.layers = nn.ModuleList()
800
- for i_layer in range(self.num_layers):
801
- layer = RSTB(
802
- dim=embed_dim,
803
- input_resolution=(patches_resolution[0], patches_resolution[1]),
804
- depth=depths[i_layer],
805
- num_heads=num_heads[i_layer],
806
- window_size=window_size,
807
- mlp_ratio=self.mlp_ratio,
808
- qkv_bias=qkv_bias,
809
- qk_scale=qk_scale,
810
- drop=drop_rate,
811
- attn_drop=attn_drop_rate,
812
- drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], # no impact on SR results
813
- norm_layer=norm_layer,
814
- downsample=None,
815
- use_checkpoint=use_checkpoint,
816
- img_size=img_size,
817
- patch_size=patch_size,
818
- resi_connection=resi_connection)
819
- self.layers.append(layer)
820
- self.norm = norm_layer(self.num_features)
821
-
822
- # build the last conv layer in deep feature extraction
823
- if resi_connection == '1conv':
824
- self.conv_after_body = nn.Conv2d(embed_dim, embed_dim, 3, 1, 1)
825
- elif resi_connection == '3conv':
826
- # to save parameters and memory
827
- self.conv_after_body = nn.Sequential(
828
- nn.Conv2d(embed_dim, embed_dim // 4, 3, 1, 1), nn.LeakyReLU(negative_slope=0.2, inplace=True),
829
- nn.Conv2d(embed_dim // 4, embed_dim // 4, 1, 1, 0), nn.LeakyReLU(negative_slope=0.2, inplace=True),
830
- nn.Conv2d(embed_dim // 4, embed_dim, 3, 1, 1))
831
-
832
- # ------------------------- 3, high quality image reconstruction ------------------------- #
833
- if self.upsampler == 'pixelshuffle':
834
- # for classical SR
835
- self.conv_before_upsample = nn.Sequential(
836
- nn.Conv2d(embed_dim, num_feat, 3, 1, 1), nn.LeakyReLU(inplace=True))
837
- self.upsample = Upsample(upscale, num_feat)
838
- self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
839
- elif self.upsampler == 'pixelshuffledirect':
840
- # for lightweight SR (to save parameters)
841
- self.upsample = UpsampleOneStep(upscale, embed_dim, num_out_ch,
842
- (patches_resolution[0], patches_resolution[1]))
843
- elif self.upsampler == 'nearest+conv':
844
- # for real-world SR (less artifacts)
845
- assert self.upscale == 4, 'only support x4 now.'
846
- self.conv_before_upsample = nn.Sequential(
847
- nn.Conv2d(embed_dim, num_feat, 3, 1, 1), nn.LeakyReLU(inplace=True))
848
- self.conv_up1 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
849
- self.conv_up2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
850
- self.conv_hr = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
851
- self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
852
- self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True)
853
- else:
854
- # for image denoising and JPEG compression artifact reduction
855
- self.conv_last = nn.Conv2d(embed_dim, num_out_ch, 3, 1, 1)
856
-
857
- self.apply(self._init_weights)
858
-
859
- def _init_weights(self, m):
860
- if isinstance(m, nn.Linear):
861
- trunc_normal_(m.weight, std=.02)
862
- if isinstance(m, nn.Linear) and m.bias is not None:
863
- nn.init.constant_(m.bias, 0)
864
- elif isinstance(m, nn.LayerNorm):
865
- nn.init.constant_(m.bias, 0)
866
- nn.init.constant_(m.weight, 1.0)
867
-
868
- @torch.jit.ignore
869
- def no_weight_decay(self):
870
- return {'absolute_pos_embed'}
871
-
872
- @torch.jit.ignore
873
- def no_weight_decay_keywords(self):
874
- return {'relative_position_bias_table'}
875
-
876
- def forward_features(self, x):
877
- x_size = (x.shape[2], x.shape[3])
878
- x = self.patch_embed(x)
879
- if self.ape:
880
- x = x + self.absolute_pos_embed
881
- x = self.pos_drop(x)
882
-
883
- for layer in self.layers:
884
- x = layer(x, x_size)
885
-
886
- x = self.norm(x) # b seq_len c
887
- x = self.patch_unembed(x, x_size)
888
-
889
- return x
890
-
891
- def forward(self, x):
892
- self.mean = self.mean.type_as(x)
893
- x = (x - self.mean) * self.img_range
894
-
895
- if self.upsampler == 'pixelshuffle':
896
- # for classical SR
897
- x = self.conv_first(x)
898
- x = self.conv_after_body(self.forward_features(x)) + x
899
- x = self.conv_before_upsample(x)
900
- x = self.conv_last(self.upsample(x))
901
- elif self.upsampler == 'pixelshuffledirect':
902
- # for lightweight SR
903
- x = self.conv_first(x)
904
- x = self.conv_after_body(self.forward_features(x)) + x
905
- x = self.upsample(x)
906
- elif self.upsampler == 'nearest+conv':
907
- # for real-world SR
908
- x = self.conv_first(x)
909
- x = self.conv_after_body(self.forward_features(x)) + x
910
- x = self.conv_before_upsample(x)
911
- x = self.lrelu(self.conv_up1(torch.nn.functional.interpolate(x, scale_factor=2, mode='nearest')))
912
- x = self.lrelu(self.conv_up2(torch.nn.functional.interpolate(x, scale_factor=2, mode='nearest')))
913
- x = self.conv_last(self.lrelu(self.conv_hr(x)))
914
- else:
915
- # for image denoising and JPEG compression artifact reduction
916
- x_first = self.conv_first(x)
917
- res = self.conv_after_body(self.forward_features(x_first)) + x_first
918
- x = x + self.conv_last(res)
919
-
920
- x = x / self.img_range + self.mean
921
-
922
- return x
923
-
924
- def flops(self):
925
- flops = 0
926
- h, w = self.patches_resolution
927
- flops += h * w * 3 * self.embed_dim * 9
928
- flops += self.patch_embed.flops()
929
- for layer in self.layers:
930
- flops += layer.flops()
931
- flops += h * w * 3 * self.embed_dim * self.embed_dim
932
- flops += self.upsample.flops()
933
- return flops
934
-
935
-
936
- if __name__ == '__main__':
937
- upscale = 4
938
- window_size = 8
939
- height = (1024 // upscale // window_size + 1) * window_size
940
- width = (720 // upscale // window_size + 1) * window_size
941
- model = SwinIR(
942
- upscale=2,
943
- img_size=(height, width),
944
- window_size=window_size,
945
- img_range=1.,
946
- depths=[6, 6, 6, 6],
947
- embed_dim=60,
948
- num_heads=[6, 6, 6, 6],
949
- mlp_ratio=2,
950
- upsampler='pixelshuffledirect')
951
- print(model)
952
- print(height, width, model.flops() / 1e9)
953
-
954
- x = torch.randn((1, 3, height, width))
955
- x = model(x)
956
- print(x.shape)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/tof_arch.py DELETED
@@ -1,172 +0,0 @@
1
- import torch
2
- from torch import nn as nn
3
- from torch.nn import functional as F
4
-
5
- from basicsr.utils.registry import ARCH_REGISTRY
6
- from .arch_util import flow_warp
7
-
8
-
9
- class BasicModule(nn.Module):
10
- """Basic module of SPyNet.
11
-
12
- Note that unlike the architecture in spynet_arch.py, the basic module
13
- here contains batch normalization.
14
- """
15
-
16
- def __init__(self):
17
- super(BasicModule, self).__init__()
18
- self.basic_module = nn.Sequential(
19
- nn.Conv2d(in_channels=8, out_channels=32, kernel_size=7, stride=1, padding=3, bias=False),
20
- nn.BatchNorm2d(32), nn.ReLU(inplace=True),
21
- nn.Conv2d(in_channels=32, out_channels=64, kernel_size=7, stride=1, padding=3, bias=False),
22
- nn.BatchNorm2d(64), nn.ReLU(inplace=True),
23
- nn.Conv2d(in_channels=64, out_channels=32, kernel_size=7, stride=1, padding=3, bias=False),
24
- nn.BatchNorm2d(32), nn.ReLU(inplace=True),
25
- nn.Conv2d(in_channels=32, out_channels=16, kernel_size=7, stride=1, padding=3, bias=False),
26
- nn.BatchNorm2d(16), nn.ReLU(inplace=True),
27
- nn.Conv2d(in_channels=16, out_channels=2, kernel_size=7, stride=1, padding=3))
28
-
29
- def forward(self, tensor_input):
30
- """
31
- Args:
32
- tensor_input (Tensor): Input tensor with shape (b, 8, h, w).
33
- 8 channels contain:
34
- [reference image (3), neighbor image (3), initial flow (2)].
35
-
36
- Returns:
37
- Tensor: Estimated flow with shape (b, 2, h, w)
38
- """
39
- return self.basic_module(tensor_input)
40
-
41
-
42
- class SPyNetTOF(nn.Module):
43
- """SPyNet architecture for TOF.
44
-
45
- Note that this implementation is specifically for TOFlow. Please use :file:`spynet_arch.py` for general use.
46
- They differ in the following aspects:
47
-
48
- 1. The basic modules here contain BatchNorm.
49
- 2. Normalization and denormalization are not done here, as they are done in TOFlow.
50
-
51
- ``Paper: Optical Flow Estimation using a Spatial Pyramid Network``
52
-
53
- Reference: https://github.com/Coldog2333/pytoflow
54
-
55
- Args:
56
- load_path (str): Path for pretrained SPyNet. Default: None.
57
- """
58
-
59
- def __init__(self, load_path=None):
60
- super(SPyNetTOF, self).__init__()
61
-
62
- self.basic_module = nn.ModuleList([BasicModule() for _ in range(4)])
63
- if load_path:
64
- self.load_state_dict(torch.load(load_path, map_location=lambda storage, loc: storage)['params'])
65
-
66
- def forward(self, ref, supp):
67
- """
68
- Args:
69
- ref (Tensor): Reference image with shape of (b, 3, h, w).
70
- supp: The supporting image to be warped: (b, 3, h, w).
71
-
72
- Returns:
73
- Tensor: Estimated optical flow: (b, 2, h, w).
74
- """
75
- num_batches, _, h, w = ref.size()
76
- ref = [ref]
77
- supp = [supp]
78
-
79
- # generate downsampled frames
80
- for _ in range(3):
81
- ref.insert(0, F.avg_pool2d(input=ref[0], kernel_size=2, stride=2, count_include_pad=False))
82
- supp.insert(0, F.avg_pool2d(input=supp[0], kernel_size=2, stride=2, count_include_pad=False))
83
-
84
- # flow computation
85
- flow = ref[0].new_zeros(num_batches, 2, h // 16, w // 16)
86
- for i in range(4):
87
- flow_up = F.interpolate(input=flow, scale_factor=2, mode='bilinear', align_corners=True) * 2.0
88
- flow = flow_up + self.basic_module[i](
89
- torch.cat([ref[i], flow_warp(supp[i], flow_up.permute(0, 2, 3, 1)), flow_up], 1))
90
- return flow
91
-
92
-
93
- @ARCH_REGISTRY.register()
94
- class TOFlow(nn.Module):
95
- """PyTorch implementation of TOFlow.
96
-
97
- In TOFlow, the LR frames are pre-upsampled and have the same size with the GT frames.
98
-
99
- ``Paper: Video Enhancement with Task-Oriented Flow``
100
-
101
- Reference: https://github.com/anchen1011/toflow
102
-
103
- Reference: https://github.com/Coldog2333/pytoflow
104
-
105
- Args:
106
- adapt_official_weights (bool): Whether to adapt the weights translated
107
- from the official implementation. Set to false if you want to
108
- train from scratch. Default: False
109
- """
110
-
111
- def __init__(self, adapt_official_weights=False):
112
- super(TOFlow, self).__init__()
113
- self.adapt_official_weights = adapt_official_weights
114
- self.ref_idx = 0 if adapt_official_weights else 3
115
-
116
- self.register_buffer('mean', torch.Tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
117
- self.register_buffer('std', torch.Tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1))
118
-
119
- # flow estimation module
120
- self.spynet = SPyNetTOF()
121
-
122
- # reconstruction module
123
- self.conv_1 = nn.Conv2d(3 * 7, 64, 9, 1, 4)
124
- self.conv_2 = nn.Conv2d(64, 64, 9, 1, 4)
125
- self.conv_3 = nn.Conv2d(64, 64, 1)
126
- self.conv_4 = nn.Conv2d(64, 3, 1)
127
-
128
- # activation function
129
- self.relu = nn.ReLU(inplace=True)
130
-
131
- def normalize(self, img):
132
- return (img - self.mean) / self.std
133
-
134
- def denormalize(self, img):
135
- return img * self.std + self.mean
136
-
137
- def forward(self, lrs):
138
- """
139
- Args:
140
- lrs: Input lr frames: (b, 7, 3, h, w).
141
-
142
- Returns:
143
- Tensor: SR frame: (b, 3, h, w).
144
- """
145
- # In the official implementation, the 0-th frame is the reference frame
146
- if self.adapt_official_weights:
147
- lrs = lrs[:, [3, 0, 1, 2, 4, 5, 6], :, :, :]
148
-
149
- num_batches, num_lrs, _, h, w = lrs.size()
150
-
151
- lrs = self.normalize(lrs.view(-1, 3, h, w))
152
- lrs = lrs.view(num_batches, num_lrs, 3, h, w)
153
-
154
- lr_ref = lrs[:, self.ref_idx, :, :, :]
155
- lr_aligned = []
156
- for i in range(7): # 7 frames
157
- if i == self.ref_idx:
158
- lr_aligned.append(lr_ref)
159
- else:
160
- lr_supp = lrs[:, i, :, :, :]
161
- flow = self.spynet(lr_ref, lr_supp)
162
- lr_aligned.append(flow_warp(lr_supp, flow.permute(0, 2, 3, 1)))
163
-
164
- # reconstruction
165
- hr = torch.stack(lr_aligned, dim=1)
166
- hr = hr.view(num_batches, -1, h, w)
167
- hr = self.relu(self.conv_1(hr))
168
- hr = self.relu(self.conv_2(hr))
169
- hr = self.relu(self.conv_3(hr))
170
- hr = self.conv_4(hr) + lr_ref
171
-
172
- return self.denormalize(hr)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/archs/vgg_arch.py DELETED
@@ -1,161 +0,0 @@
1
- import os
2
- import torch
3
- from collections import OrderedDict
4
- from torch import nn as nn
5
- from torchvision.models import vgg as vgg
6
-
7
- from basicsr.utils.registry import ARCH_REGISTRY
8
-
9
- VGG_PRETRAIN_PATH = 'experiments/pretrained_models/vgg19-dcbb9e9d.pth'
10
- NAMES = {
11
- 'vgg11': [
12
- 'conv1_1', 'relu1_1', 'pool1', 'conv2_1', 'relu2_1', 'pool2', 'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2',
13
- 'pool3', 'conv4_1', 'relu4_1', 'conv4_2', 'relu4_2', 'pool4', 'conv5_1', 'relu5_1', 'conv5_2', 'relu5_2',
14
- 'pool5'
15
- ],
16
- 'vgg13': [
17
- 'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1', 'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',
18
- 'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'pool3', 'conv4_1', 'relu4_1', 'conv4_2', 'relu4_2', 'pool4',
19
- 'conv5_1', 'relu5_1', 'conv5_2', 'relu5_2', 'pool5'
20
- ],
21
- 'vgg16': [
22
- 'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1', 'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',
23
- 'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'conv3_3', 'relu3_3', 'pool3', 'conv4_1', 'relu4_1', 'conv4_2',
24
- 'relu4_2', 'conv4_3', 'relu4_3', 'pool4', 'conv5_1', 'relu5_1', 'conv5_2', 'relu5_2', 'conv5_3', 'relu5_3',
25
- 'pool5'
26
- ],
27
- 'vgg19': [
28
- 'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1', 'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',
29
- 'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'conv3_3', 'relu3_3', 'conv3_4', 'relu3_4', 'pool3', 'conv4_1',
30
- 'relu4_1', 'conv4_2', 'relu4_2', 'conv4_3', 'relu4_3', 'conv4_4', 'relu4_4', 'pool4', 'conv5_1', 'relu5_1',
31
- 'conv5_2', 'relu5_2', 'conv5_3', 'relu5_3', 'conv5_4', 'relu5_4', 'pool5'
32
- ]
33
- }
34
-
35
-
36
- def insert_bn(names):
37
- """Insert bn layer after each conv.
38
-
39
- Args:
40
- names (list): The list of layer names.
41
-
42
- Returns:
43
- list: The list of layer names with bn layers.
44
- """
45
- names_bn = []
46
- for name in names:
47
- names_bn.append(name)
48
- if 'conv' in name:
49
- position = name.replace('conv', '')
50
- names_bn.append('bn' + position)
51
- return names_bn
52
-
53
-
54
- @ARCH_REGISTRY.register()
55
- class VGGFeatureExtractor(nn.Module):
56
- """VGG network for feature extraction.
57
-
58
- In this implementation, we allow users to choose whether use normalization
59
- in the input feature and the type of vgg network. Note that the pretrained
60
- path must fit the vgg type.
61
-
62
- Args:
63
- layer_name_list (list[str]): Forward function returns the corresponding
64
- features according to the layer_name_list.
65
- Example: {'relu1_1', 'relu2_1', 'relu3_1'}.
66
- vgg_type (str): Set the type of vgg network. Default: 'vgg19'.
67
- use_input_norm (bool): If True, normalize the input image. Importantly,
68
- the input feature must in the range [0, 1]. Default: True.
69
- range_norm (bool): If True, norm images with range [-1, 1] to [0, 1].
70
- Default: False.
71
- requires_grad (bool): If true, the parameters of VGG network will be
72
- optimized. Default: False.
73
- remove_pooling (bool): If true, the max pooling operations in VGG net
74
- will be removed. Default: False.
75
- pooling_stride (int): The stride of max pooling operation. Default: 2.
76
- """
77
-
78
- def __init__(self,
79
- layer_name_list,
80
- vgg_type='vgg19',
81
- use_input_norm=True,
82
- range_norm=False,
83
- requires_grad=False,
84
- remove_pooling=False,
85
- pooling_stride=2):
86
- super(VGGFeatureExtractor, self).__init__()
87
-
88
- self.layer_name_list = layer_name_list
89
- self.use_input_norm = use_input_norm
90
- self.range_norm = range_norm
91
-
92
- self.names = NAMES[vgg_type.replace('_bn', '')]
93
- if 'bn' in vgg_type:
94
- self.names = insert_bn(self.names)
95
-
96
- # only borrow layers that will be used to avoid unused params
97
- max_idx = 0
98
- for v in layer_name_list:
99
- idx = self.names.index(v)
100
- if idx > max_idx:
101
- max_idx = idx
102
-
103
- if os.path.exists(VGG_PRETRAIN_PATH):
104
- vgg_net = getattr(vgg, vgg_type)(pretrained=False)
105
- state_dict = torch.load(VGG_PRETRAIN_PATH, map_location=lambda storage, loc: storage)
106
- vgg_net.load_state_dict(state_dict)
107
- else:
108
- vgg_net = getattr(vgg, vgg_type)(pretrained=True)
109
-
110
- features = vgg_net.features[:max_idx + 1]
111
-
112
- modified_net = OrderedDict()
113
- for k, v in zip(self.names, features):
114
- if 'pool' in k:
115
- # if remove_pooling is true, pooling operation will be removed
116
- if remove_pooling:
117
- continue
118
- else:
119
- # in some cases, we may want to change the default stride
120
- modified_net[k] = nn.MaxPool2d(kernel_size=2, stride=pooling_stride)
121
- else:
122
- modified_net[k] = v
123
-
124
- self.vgg_net = nn.Sequential(modified_net)
125
-
126
- if not requires_grad:
127
- self.vgg_net.eval()
128
- for param in self.parameters():
129
- param.requires_grad = False
130
- else:
131
- self.vgg_net.train()
132
- for param in self.parameters():
133
- param.requires_grad = True
134
-
135
- if self.use_input_norm:
136
- # the mean is for image with range [0, 1]
137
- self.register_buffer('mean', torch.Tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
138
- # the std is for image with range [0, 1]
139
- self.register_buffer('std', torch.Tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1))
140
-
141
- def forward(self, x):
142
- """Forward function.
143
-
144
- Args:
145
- x (Tensor): Input tensor with shape (n, c, h, w).
146
-
147
- Returns:
148
- Tensor: Forward results.
149
- """
150
- if self.range_norm:
151
- x = (x + 1) / 2
152
- if self.use_input_norm:
153
- x = (x - self.mean) / self.std
154
-
155
- output = {}
156
- for key, layer in self.vgg_net._modules.items():
157
- x = layer(x)
158
- if key in self.layer_name_list:
159
- output[key] = x.clone()
160
-
161
- return output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/__init__.py DELETED
@@ -1,101 +0,0 @@
1
- import importlib
2
- import numpy as np
3
- import random
4
- import torch
5
- import torch.utils.data
6
- from copy import deepcopy
7
- from functools import partial
8
- from os import path as osp
9
-
10
- from basicsr.data.prefetch_dataloader import PrefetchDataLoader
11
- from basicsr.utils import get_root_logger, scandir
12
- from basicsr.utils.dist_util import get_dist_info
13
- from basicsr.utils.registry import DATASET_REGISTRY
14
-
15
- __all__ = ['build_dataset', 'build_dataloader']
16
-
17
- # automatically scan and import dataset modules for registry
18
- # scan all the files under the data folder with '_dataset' in file names
19
- data_folder = osp.dirname(osp.abspath(__file__))
20
- dataset_filenames = [osp.splitext(osp.basename(v))[0] for v in scandir(data_folder) if v.endswith('_dataset.py')]
21
- # import all the dataset modules
22
- _dataset_modules = [importlib.import_module(f'basicsr.data.{file_name}') for file_name in dataset_filenames]
23
-
24
-
25
- def build_dataset(dataset_opt):
26
- """Build dataset from options.
27
-
28
- Args:
29
- dataset_opt (dict): Configuration for dataset. It must contain:
30
- name (str): Dataset name.
31
- type (str): Dataset type.
32
- """
33
- dataset_opt = deepcopy(dataset_opt)
34
- dataset = DATASET_REGISTRY.get(dataset_opt['type'])(dataset_opt)
35
- logger = get_root_logger()
36
- logger.info(f'Dataset [{dataset.__class__.__name__}] - {dataset_opt["name"]} is built.')
37
- return dataset
38
-
39
-
40
- def build_dataloader(dataset, dataset_opt, num_gpu=1, dist=False, sampler=None, seed=None):
41
- """Build dataloader.
42
-
43
- Args:
44
- dataset (torch.utils.data.Dataset): Dataset.
45
- dataset_opt (dict): Dataset options. It contains the following keys:
46
- phase (str): 'train' or 'val'.
47
- num_worker_per_gpu (int): Number of workers for each GPU.
48
- batch_size_per_gpu (int): Training batch size for each GPU.
49
- num_gpu (int): Number of GPUs. Used only in the train phase.
50
- Default: 1.
51
- dist (bool): Whether in distributed training. Used only in the train
52
- phase. Default: False.
53
- sampler (torch.utils.data.sampler): Data sampler. Default: None.
54
- seed (int | None): Seed. Default: None
55
- """
56
- phase = dataset_opt['phase']
57
- rank, _ = get_dist_info()
58
- if phase == 'train':
59
- if dist: # distributed training
60
- batch_size = dataset_opt['batch_size_per_gpu']
61
- num_workers = dataset_opt['num_worker_per_gpu']
62
- else: # non-distributed training
63
- multiplier = 1 if num_gpu == 0 else num_gpu
64
- batch_size = dataset_opt['batch_size_per_gpu'] * multiplier
65
- num_workers = dataset_opt['num_worker_per_gpu'] * multiplier
66
- dataloader_args = dict(
67
- dataset=dataset,
68
- batch_size=batch_size,
69
- shuffle=False,
70
- num_workers=num_workers,
71
- sampler=sampler,
72
- drop_last=True)
73
- if sampler is None:
74
- dataloader_args['shuffle'] = True
75
- dataloader_args['worker_init_fn'] = partial(
76
- worker_init_fn, num_workers=num_workers, rank=rank, seed=seed) if seed is not None else None
77
- elif phase in ['val', 'test']: # validation
78
- dataloader_args = dict(dataset=dataset, batch_size=1, shuffle=False, num_workers=0)
79
- else:
80
- raise ValueError(f"Wrong dataset phase: {phase}. Supported ones are 'train', 'val' and 'test'.")
81
-
82
- dataloader_args['pin_memory'] = dataset_opt.get('pin_memory', False)
83
- dataloader_args['persistent_workers'] = dataset_opt.get('persistent_workers', False)
84
-
85
- prefetch_mode = dataset_opt.get('prefetch_mode')
86
- if prefetch_mode == 'cpu': # CPUPrefetcher
87
- num_prefetch_queue = dataset_opt.get('num_prefetch_queue', 1)
88
- logger = get_root_logger()
89
- logger.info(f'Use {prefetch_mode} prefetch dataloader: num_prefetch_queue = {num_prefetch_queue}')
90
- return PrefetchDataLoader(num_prefetch_queue=num_prefetch_queue, **dataloader_args)
91
- else:
92
- # prefetch_mode=None: Normal dataloader
93
- # prefetch_mode='cuda': dataloader for CUDAPrefetcher
94
- return torch.utils.data.DataLoader(**dataloader_args)
95
-
96
-
97
- def worker_init_fn(worker_id, num_workers, rank, seed):
98
- # Set the worker seed to num_workers * rank + worker_id + seed
99
- worker_seed = num_workers * rank + worker_id + seed
100
- np.random.seed(worker_seed)
101
- random.seed(worker_seed)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/data_sampler.py DELETED
@@ -1,48 +0,0 @@
1
- import math
2
- import torch
3
- from torch.utils.data.sampler import Sampler
4
-
5
-
6
- class EnlargedSampler(Sampler):
7
- """Sampler that restricts data loading to a subset of the dataset.
8
-
9
- Modified from torch.utils.data.distributed.DistributedSampler
10
- Support enlarging the dataset for iteration-based training, for saving
11
- time when restart the dataloader after each epoch
12
-
13
- Args:
14
- dataset (torch.utils.data.Dataset): Dataset used for sampling.
15
- num_replicas (int | None): Number of processes participating in
16
- the training. It is usually the world_size.
17
- rank (int | None): Rank of the current process within num_replicas.
18
- ratio (int): Enlarging ratio. Default: 1.
19
- """
20
-
21
- def __init__(self, dataset, num_replicas, rank, ratio=1):
22
- self.dataset = dataset
23
- self.num_replicas = num_replicas
24
- self.rank = rank
25
- self.epoch = 0
26
- self.num_samples = math.ceil(len(self.dataset) * ratio / self.num_replicas)
27
- self.total_size = self.num_samples * self.num_replicas
28
-
29
- def __iter__(self):
30
- # deterministically shuffle based on epoch
31
- g = torch.Generator()
32
- g.manual_seed(self.epoch)
33
- indices = torch.randperm(self.total_size, generator=g).tolist()
34
-
35
- dataset_size = len(self.dataset)
36
- indices = [v % dataset_size for v in indices]
37
-
38
- # subsample
39
- indices = indices[self.rank:self.total_size:self.num_replicas]
40
- assert len(indices) == self.num_samples
41
-
42
- return iter(indices)
43
-
44
- def __len__(self):
45
- return self.num_samples
46
-
47
- def set_epoch(self, epoch):
48
- self.epoch = epoch
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/data_util.py DELETED
@@ -1,315 +0,0 @@
1
- import cv2
2
- import numpy as np
3
- import torch
4
- from os import path as osp
5
- from torch.nn import functional as F
6
-
7
- from basicsr.data.transforms import mod_crop
8
- from basicsr.utils import img2tensor, scandir
9
-
10
-
11
- def read_img_seq(path, require_mod_crop=False, scale=1, return_imgname=False):
12
- """Read a sequence of images from a given folder path.
13
-
14
- Args:
15
- path (list[str] | str): List of image paths or image folder path.
16
- require_mod_crop (bool): Require mod crop for each image.
17
- Default: False.
18
- scale (int): Scale factor for mod_crop. Default: 1.
19
- return_imgname(bool): Whether return image names. Default False.
20
-
21
- Returns:
22
- Tensor: size (t, c, h, w), RGB, [0, 1].
23
- list[str]: Returned image name list.
24
- """
25
- if isinstance(path, list):
26
- img_paths = path
27
- else:
28
- img_paths = sorted(list(scandir(path, full_path=True)))
29
- imgs = [cv2.imread(v).astype(np.float32) / 255. for v in img_paths]
30
-
31
- if require_mod_crop:
32
- imgs = [mod_crop(img, scale) for img in imgs]
33
- imgs = img2tensor(imgs, bgr2rgb=True, float32=True)
34
- imgs = torch.stack(imgs, dim=0)
35
-
36
- if return_imgname:
37
- imgnames = [osp.splitext(osp.basename(path))[0] for path in img_paths]
38
- return imgs, imgnames
39
- else:
40
- return imgs
41
-
42
-
43
- def generate_frame_indices(crt_idx, max_frame_num, num_frames, padding='reflection'):
44
- """Generate an index list for reading `num_frames` frames from a sequence
45
- of images.
46
-
47
- Args:
48
- crt_idx (int): Current center index.
49
- max_frame_num (int): Max number of the sequence of images (from 1).
50
- num_frames (int): Reading num_frames frames.
51
- padding (str): Padding mode, one of
52
- 'replicate' | 'reflection' | 'reflection_circle' | 'circle'
53
- Examples: current_idx = 0, num_frames = 5
54
- The generated frame indices under different padding mode:
55
- replicate: [0, 0, 0, 1, 2]
56
- reflection: [2, 1, 0, 1, 2]
57
- reflection_circle: [4, 3, 0, 1, 2]
58
- circle: [3, 4, 0, 1, 2]
59
-
60
- Returns:
61
- list[int]: A list of indices.
62
- """
63
- assert num_frames % 2 == 1, 'num_frames should be an odd number.'
64
- assert padding in ('replicate', 'reflection', 'reflection_circle', 'circle'), f'Wrong padding mode: {padding}.'
65
-
66
- max_frame_num = max_frame_num - 1 # start from 0
67
- num_pad = num_frames // 2
68
-
69
- indices = []
70
- for i in range(crt_idx - num_pad, crt_idx + num_pad + 1):
71
- if i < 0:
72
- if padding == 'replicate':
73
- pad_idx = 0
74
- elif padding == 'reflection':
75
- pad_idx = -i
76
- elif padding == 'reflection_circle':
77
- pad_idx = crt_idx + num_pad - i
78
- else:
79
- pad_idx = num_frames + i
80
- elif i > max_frame_num:
81
- if padding == 'replicate':
82
- pad_idx = max_frame_num
83
- elif padding == 'reflection':
84
- pad_idx = max_frame_num * 2 - i
85
- elif padding == 'reflection_circle':
86
- pad_idx = (crt_idx - num_pad) - (i - max_frame_num)
87
- else:
88
- pad_idx = i - num_frames
89
- else:
90
- pad_idx = i
91
- indices.append(pad_idx)
92
- return indices
93
-
94
-
95
- def paired_paths_from_lmdb(folders, keys):
96
- """Generate paired paths from lmdb files.
97
-
98
- Contents of lmdb. Taking the `lq.lmdb` for example, the file structure is:
99
-
100
- ::
101
-
102
- lq.lmdb
103
- ├── data.mdb
104
- ├── lock.mdb
105
- ├── meta_info.txt
106
-
107
- The data.mdb and lock.mdb are standard lmdb files and you can refer to
108
- https://lmdb.readthedocs.io/en/release/ for more details.
109
-
110
- The meta_info.txt is a specified txt file to record the meta information
111
- of our datasets. It will be automatically created when preparing
112
- datasets by our provided dataset tools.
113
- Each line in the txt file records
114
- 1)image name (with extension),
115
- 2)image shape,
116
- 3)compression level, separated by a white space.
117
- Example: `baboon.png (120,125,3) 1`
118
-
119
- We use the image name without extension as the lmdb key.
120
- Note that we use the same key for the corresponding lq and gt images.
121
-
122
- Args:
123
- folders (list[str]): A list of folder path. The order of list should
124
- be [input_folder, gt_folder].
125
- keys (list[str]): A list of keys identifying folders. The order should
126
- be in consistent with folders, e.g., ['lq', 'gt'].
127
- Note that this key is different from lmdb keys.
128
-
129
- Returns:
130
- list[str]: Returned path list.
131
- """
132
- assert len(folders) == 2, ('The len of folders should be 2 with [input_folder, gt_folder]. '
133
- f'But got {len(folders)}')
134
- assert len(keys) == 2, f'The len of keys should be 2 with [input_key, gt_key]. But got {len(keys)}'
135
- input_folder, gt_folder = folders
136
- input_key, gt_key = keys
137
-
138
- if not (input_folder.endswith('.lmdb') and gt_folder.endswith('.lmdb')):
139
- raise ValueError(f'{input_key} folder and {gt_key} folder should both in lmdb '
140
- f'formats. But received {input_key}: {input_folder}; '
141
- f'{gt_key}: {gt_folder}')
142
- # ensure that the two meta_info files are the same
143
- with open(osp.join(input_folder, 'meta_info.txt')) as fin:
144
- input_lmdb_keys = [line.split('.')[0] for line in fin]
145
- with open(osp.join(gt_folder, 'meta_info.txt')) as fin:
146
- gt_lmdb_keys = [line.split('.')[0] for line in fin]
147
- if set(input_lmdb_keys) != set(gt_lmdb_keys):
148
- raise ValueError(f'Keys in {input_key}_folder and {gt_key}_folder are different.')
149
- else:
150
- paths = []
151
- for lmdb_key in sorted(input_lmdb_keys):
152
- paths.append(dict([(f'{input_key}_path', lmdb_key), (f'{gt_key}_path', lmdb_key)]))
153
- return paths
154
-
155
-
156
- def paired_paths_from_meta_info_file(folders, keys, meta_info_file, filename_tmpl):
157
- """Generate paired paths from an meta information file.
158
-
159
- Each line in the meta information file contains the image names and
160
- image shape (usually for gt), separated by a white space.
161
-
162
- Example of an meta information file:
163
- ```
164
- 0001_s001.png (480,480,3)
165
- 0001_s002.png (480,480,3)
166
- ```
167
-
168
- Args:
169
- folders (list[str]): A list of folder path. The order of list should
170
- be [input_folder, gt_folder].
171
- keys (list[str]): A list of keys identifying folders. The order should
172
- be in consistent with folders, e.g., ['lq', 'gt'].
173
- meta_info_file (str): Path to the meta information file.
174
- filename_tmpl (str): Template for each filename. Note that the
175
- template excludes the file extension. Usually the filename_tmpl is
176
- for files in the input folder.
177
-
178
- Returns:
179
- list[str]: Returned path list.
180
- """
181
- assert len(folders) == 2, ('The len of folders should be 2 with [input_folder, gt_folder]. '
182
- f'But got {len(folders)}')
183
- assert len(keys) == 2, f'The len of keys should be 2 with [input_key, gt_key]. But got {len(keys)}'
184
- input_folder, gt_folder = folders
185
- input_key, gt_key = keys
186
-
187
- with open(meta_info_file, 'r') as fin:
188
- gt_names = [line.strip().split(' ')[0] for line in fin]
189
-
190
- paths = []
191
- for gt_name in gt_names:
192
- basename, ext = osp.splitext(osp.basename(gt_name))
193
- input_name = f'{filename_tmpl.format(basename)}{ext}'
194
- input_path = osp.join(input_folder, input_name)
195
- gt_path = osp.join(gt_folder, gt_name)
196
- paths.append(dict([(f'{input_key}_path', input_path), (f'{gt_key}_path', gt_path)]))
197
- return paths
198
-
199
-
200
- def paired_paths_from_folder(folders, keys, filename_tmpl):
201
- """Generate paired paths from folders.
202
-
203
- Args:
204
- folders (list[str]): A list of folder path. The order of list should
205
- be [input_folder, gt_folder].
206
- keys (list[str]): A list of keys identifying folders. The order should
207
- be in consistent with folders, e.g., ['lq', 'gt'].
208
- filename_tmpl (str): Template for each filename. Note that the
209
- template excludes the file extension. Usually the filename_tmpl is
210
- for files in the input folder.
211
-
212
- Returns:
213
- list[str]: Returned path list.
214
- """
215
- assert len(folders) == 2, ('The len of folders should be 2 with [input_folder, gt_folder]. '
216
- f'But got {len(folders)}')
217
- assert len(keys) == 2, f'The len of keys should be 2 with [input_key, gt_key]. But got {len(keys)}'
218
- input_folder, gt_folder = folders
219
- input_key, gt_key = keys
220
-
221
- input_paths = list(scandir(input_folder))
222
- gt_paths = list(scandir(gt_folder))
223
- assert len(input_paths) == len(gt_paths), (f'{input_key} and {gt_key} datasets have different number of images: '
224
- f'{len(input_paths)}, {len(gt_paths)}.')
225
- paths = []
226
- for gt_path in gt_paths:
227
- basename, ext = osp.splitext(osp.basename(gt_path))
228
- input_name = f'{filename_tmpl.format(basename)}{ext}'
229
- input_path = osp.join(input_folder, input_name)
230
- assert input_name in input_paths, f'{input_name} is not in {input_key}_paths.'
231
- gt_path = osp.join(gt_folder, gt_path)
232
- paths.append(dict([(f'{input_key}_path', input_path), (f'{gt_key}_path', gt_path)]))
233
- return paths
234
-
235
-
236
- def paths_from_folder(folder):
237
- """Generate paths from folder.
238
-
239
- Args:
240
- folder (str): Folder path.
241
-
242
- Returns:
243
- list[str]: Returned path list.
244
- """
245
-
246
- paths = list(scandir(folder))
247
- paths = [osp.join(folder, path) for path in paths]
248
- return paths
249
-
250
-
251
- def paths_from_lmdb(folder):
252
- """Generate paths from lmdb.
253
-
254
- Args:
255
- folder (str): Folder path.
256
-
257
- Returns:
258
- list[str]: Returned path list.
259
- """
260
- if not folder.endswith('.lmdb'):
261
- raise ValueError(f'Folder {folder}folder should in lmdb format.')
262
- with open(osp.join(folder, 'meta_info.txt')) as fin:
263
- paths = [line.split('.')[0] for line in fin]
264
- return paths
265
-
266
-
267
- def generate_gaussian_kernel(kernel_size=13, sigma=1.6):
268
- """Generate Gaussian kernel used in `duf_downsample`.
269
-
270
- Args:
271
- kernel_size (int): Kernel size. Default: 13.
272
- sigma (float): Sigma of the Gaussian kernel. Default: 1.6.
273
-
274
- Returns:
275
- np.array: The Gaussian kernel.
276
- """
277
- from scipy.ndimage import filters as filters
278
- kernel = np.zeros((kernel_size, kernel_size))
279
- # set element at the middle to one, a dirac delta
280
- kernel[kernel_size // 2, kernel_size // 2] = 1
281
- # gaussian-smooth the dirac, resulting in a gaussian filter
282
- return filters.gaussian_filter(kernel, sigma)
283
-
284
-
285
- def duf_downsample(x, kernel_size=13, scale=4):
286
- """Downsamping with Gaussian kernel used in the DUF official code.
287
-
288
- Args:
289
- x (Tensor): Frames to be downsampled, with shape (b, t, c, h, w).
290
- kernel_size (int): Kernel size. Default: 13.
291
- scale (int): Downsampling factor. Supported scale: (2, 3, 4).
292
- Default: 4.
293
-
294
- Returns:
295
- Tensor: DUF downsampled frames.
296
- """
297
- assert scale in (2, 3, 4), f'Only support scale (2, 3, 4), but got {scale}.'
298
-
299
- squeeze_flag = False
300
- if x.ndim == 4:
301
- squeeze_flag = True
302
- x = x.unsqueeze(0)
303
- b, t, c, h, w = x.size()
304
- x = x.view(-1, 1, h, w)
305
- pad_w, pad_h = kernel_size // 2 + scale * 2, kernel_size // 2 + scale * 2
306
- x = F.pad(x, (pad_w, pad_w, pad_h, pad_h), 'reflect')
307
-
308
- gaussian_filter = generate_gaussian_kernel(kernel_size, 0.4 * scale)
309
- gaussian_filter = torch.from_numpy(gaussian_filter).type_as(x).unsqueeze(0).unsqueeze(0)
310
- x = F.conv2d(x, gaussian_filter, stride=scale)
311
- x = x[:, :, 2:-2, 2:-2]
312
- x = x.view(b, t, c, x.size(2), x.size(3))
313
- if squeeze_flag:
314
- x = x.squeeze(0)
315
- return x
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/degradations.py DELETED
@@ -1,764 +0,0 @@
1
- import cv2
2
- import math
3
- import numpy as np
4
- import random
5
- import torch
6
- from scipy import special
7
- from scipy.stats import multivariate_normal
8
- from torchvision.transforms._functional_tensor import rgb_to_grayscale
9
-
10
- # -------------------------------------------------------------------- #
11
- # --------------------------- blur kernels --------------------------- #
12
- # -------------------------------------------------------------------- #
13
-
14
-
15
- # --------------------------- util functions --------------------------- #
16
- def sigma_matrix2(sig_x, sig_y, theta):
17
- """Calculate the rotated sigma matrix (two dimensional matrix).
18
-
19
- Args:
20
- sig_x (float):
21
- sig_y (float):
22
- theta (float): Radian measurement.
23
-
24
- Returns:
25
- ndarray: Rotated sigma matrix.
26
- """
27
- d_matrix = np.array([[sig_x**2, 0], [0, sig_y**2]])
28
- u_matrix = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
29
- return np.dot(u_matrix, np.dot(d_matrix, u_matrix.T))
30
-
31
-
32
- def mesh_grid(kernel_size):
33
- """Generate the mesh grid, centering at zero.
34
-
35
- Args:
36
- kernel_size (int):
37
-
38
- Returns:
39
- xy (ndarray): with the shape (kernel_size, kernel_size, 2)
40
- xx (ndarray): with the shape (kernel_size, kernel_size)
41
- yy (ndarray): with the shape (kernel_size, kernel_size)
42
- """
43
- ax = np.arange(-kernel_size // 2 + 1., kernel_size // 2 + 1.)
44
- xx, yy = np.meshgrid(ax, ax)
45
- xy = np.hstack((xx.reshape((kernel_size * kernel_size, 1)), yy.reshape(kernel_size * kernel_size,
46
- 1))).reshape(kernel_size, kernel_size, 2)
47
- return xy, xx, yy
48
-
49
-
50
- def pdf2(sigma_matrix, grid):
51
- """Calculate PDF of the bivariate Gaussian distribution.
52
-
53
- Args:
54
- sigma_matrix (ndarray): with the shape (2, 2)
55
- grid (ndarray): generated by :func:`mesh_grid`,
56
- with the shape (K, K, 2), K is the kernel size.
57
-
58
- Returns:
59
- kernel (ndarrray): un-normalized kernel.
60
- """
61
- inverse_sigma = np.linalg.inv(sigma_matrix)
62
- kernel = np.exp(-0.5 * np.sum(np.dot(grid, inverse_sigma) * grid, 2))
63
- return kernel
64
-
65
-
66
- def cdf2(d_matrix, grid):
67
- """Calculate the CDF of the standard bivariate Gaussian distribution.
68
- Used in skewed Gaussian distribution.
69
-
70
- Args:
71
- d_matrix (ndarrasy): skew matrix.
72
- grid (ndarray): generated by :func:`mesh_grid`,
73
- with the shape (K, K, 2), K is the kernel size.
74
-
75
- Returns:
76
- cdf (ndarray): skewed cdf.
77
- """
78
- rv = multivariate_normal([0, 0], [[1, 0], [0, 1]])
79
- grid = np.dot(grid, d_matrix)
80
- cdf = rv.cdf(grid)
81
- return cdf
82
-
83
-
84
- def bivariate_Gaussian(kernel_size, sig_x, sig_y, theta, grid=None, isotropic=True):
85
- """Generate a bivariate isotropic or anisotropic Gaussian kernel.
86
-
87
- In the isotropic mode, only `sig_x` is used. `sig_y` and `theta` is ignored.
88
-
89
- Args:
90
- kernel_size (int):
91
- sig_x (float):
92
- sig_y (float):
93
- theta (float): Radian measurement.
94
- grid (ndarray, optional): generated by :func:`mesh_grid`,
95
- with the shape (K, K, 2), K is the kernel size. Default: None
96
- isotropic (bool):
97
-
98
- Returns:
99
- kernel (ndarray): normalized kernel.
100
- """
101
- if grid is None:
102
- grid, _, _ = mesh_grid(kernel_size)
103
- if isotropic:
104
- sigma_matrix = np.array([[sig_x**2, 0], [0, sig_x**2]])
105
- else:
106
- sigma_matrix = sigma_matrix2(sig_x, sig_y, theta)
107
- kernel = pdf2(sigma_matrix, grid)
108
- kernel = kernel / np.sum(kernel)
109
- return kernel
110
-
111
-
112
- def bivariate_generalized_Gaussian(kernel_size, sig_x, sig_y, theta, beta, grid=None, isotropic=True):
113
- """Generate a bivariate generalized Gaussian kernel.
114
-
115
- ``Paper: Parameter Estimation For Multivariate Generalized Gaussian Distributions``
116
-
117
- In the isotropic mode, only `sig_x` is used. `sig_y` and `theta` is ignored.
118
-
119
- Args:
120
- kernel_size (int):
121
- sig_x (float):
122
- sig_y (float):
123
- theta (float): Radian measurement.
124
- beta (float): shape parameter, beta = 1 is the normal distribution.
125
- grid (ndarray, optional): generated by :func:`mesh_grid`,
126
- with the shape (K, K, 2), K is the kernel size. Default: None
127
-
128
- Returns:
129
- kernel (ndarray): normalized kernel.
130
- """
131
- if grid is None:
132
- grid, _, _ = mesh_grid(kernel_size)
133
- if isotropic:
134
- sigma_matrix = np.array([[sig_x**2, 0], [0, sig_x**2]])
135
- else:
136
- sigma_matrix = sigma_matrix2(sig_x, sig_y, theta)
137
- inverse_sigma = np.linalg.inv(sigma_matrix)
138
- kernel = np.exp(-0.5 * np.power(np.sum(np.dot(grid, inverse_sigma) * grid, 2), beta))
139
- kernel = kernel / np.sum(kernel)
140
- return kernel
141
-
142
-
143
- def bivariate_plateau(kernel_size, sig_x, sig_y, theta, beta, grid=None, isotropic=True):
144
- """Generate a plateau-like anisotropic kernel.
145
-
146
- 1 / (1+x^(beta))
147
-
148
- Reference: https://stats.stackexchange.com/questions/203629/is-there-a-plateau-shaped-distribution
149
-
150
- In the isotropic mode, only `sig_x` is used. `sig_y` and `theta` is ignored.
151
-
152
- Args:
153
- kernel_size (int):
154
- sig_x (float):
155
- sig_y (float):
156
- theta (float): Radian measurement.
157
- beta (float): shape parameter, beta = 1 is the normal distribution.
158
- grid (ndarray, optional): generated by :func:`mesh_grid`,
159
- with the shape (K, K, 2), K is the kernel size. Default: None
160
-
161
- Returns:
162
- kernel (ndarray): normalized kernel.
163
- """
164
- if grid is None:
165
- grid, _, _ = mesh_grid(kernel_size)
166
- if isotropic:
167
- sigma_matrix = np.array([[sig_x**2, 0], [0, sig_x**2]])
168
- else:
169
- sigma_matrix = sigma_matrix2(sig_x, sig_y, theta)
170
- inverse_sigma = np.linalg.inv(sigma_matrix)
171
- kernel = np.reciprocal(np.power(np.sum(np.dot(grid, inverse_sigma) * grid, 2), beta) + 1)
172
- kernel = kernel / np.sum(kernel)
173
- return kernel
174
-
175
-
176
- def random_bivariate_Gaussian(kernel_size,
177
- sigma_x_range,
178
- sigma_y_range,
179
- rotation_range,
180
- noise_range=None,
181
- isotropic=True):
182
- """Randomly generate bivariate isotropic or anisotropic Gaussian kernels.
183
-
184
- In the isotropic mode, only `sigma_x_range` is used. `sigma_y_range` and `rotation_range` is ignored.
185
-
186
- Args:
187
- kernel_size (int):
188
- sigma_x_range (tuple): [0.6, 5]
189
- sigma_y_range (tuple): [0.6, 5]
190
- rotation range (tuple): [-math.pi, math.pi]
191
- noise_range(tuple, optional): multiplicative kernel noise,
192
- [0.75, 1.25]. Default: None
193
-
194
- Returns:
195
- kernel (ndarray):
196
- """
197
- assert kernel_size % 2 == 1, 'Kernel size must be an odd number.'
198
- assert sigma_x_range[0] < sigma_x_range[1], 'Wrong sigma_x_range.'
199
- sigma_x = np.random.uniform(sigma_x_range[0], sigma_x_range[1])
200
- if isotropic is False:
201
- assert sigma_y_range[0] < sigma_y_range[1], 'Wrong sigma_y_range.'
202
- assert rotation_range[0] < rotation_range[1], 'Wrong rotation_range.'
203
- sigma_y = np.random.uniform(sigma_y_range[0], sigma_y_range[1])
204
- rotation = np.random.uniform(rotation_range[0], rotation_range[1])
205
- else:
206
- sigma_y = sigma_x
207
- rotation = 0
208
-
209
- kernel = bivariate_Gaussian(kernel_size, sigma_x, sigma_y, rotation, isotropic=isotropic)
210
-
211
- # add multiplicative noise
212
- if noise_range is not None:
213
- assert noise_range[0] < noise_range[1], 'Wrong noise range.'
214
- noise = np.random.uniform(noise_range[0], noise_range[1], size=kernel.shape)
215
- kernel = kernel * noise
216
- kernel = kernel / np.sum(kernel)
217
- return kernel
218
-
219
-
220
- def random_bivariate_generalized_Gaussian(kernel_size,
221
- sigma_x_range,
222
- sigma_y_range,
223
- rotation_range,
224
- beta_range,
225
- noise_range=None,
226
- isotropic=True):
227
- """Randomly generate bivariate generalized Gaussian kernels.
228
-
229
- In the isotropic mode, only `sigma_x_range` is used. `sigma_y_range` and `rotation_range` is ignored.
230
-
231
- Args:
232
- kernel_size (int):
233
- sigma_x_range (tuple): [0.6, 5]
234
- sigma_y_range (tuple): [0.6, 5]
235
- rotation range (tuple): [-math.pi, math.pi]
236
- beta_range (tuple): [0.5, 8]
237
- noise_range(tuple, optional): multiplicative kernel noise,
238
- [0.75, 1.25]. Default: None
239
-
240
- Returns:
241
- kernel (ndarray):
242
- """
243
- assert kernel_size % 2 == 1, 'Kernel size must be an odd number.'
244
- assert sigma_x_range[0] < sigma_x_range[1], 'Wrong sigma_x_range.'
245
- sigma_x = np.random.uniform(sigma_x_range[0], sigma_x_range[1])
246
- if isotropic is False:
247
- assert sigma_y_range[0] < sigma_y_range[1], 'Wrong sigma_y_range.'
248
- assert rotation_range[0] < rotation_range[1], 'Wrong rotation_range.'
249
- sigma_y = np.random.uniform(sigma_y_range[0], sigma_y_range[1])
250
- rotation = np.random.uniform(rotation_range[0], rotation_range[1])
251
- else:
252
- sigma_y = sigma_x
253
- rotation = 0
254
-
255
- # assume beta_range[0] < 1 < beta_range[1]
256
- if np.random.uniform() < 0.5:
257
- beta = np.random.uniform(beta_range[0], 1)
258
- else:
259
- beta = np.random.uniform(1, beta_range[1])
260
-
261
- kernel = bivariate_generalized_Gaussian(kernel_size, sigma_x, sigma_y, rotation, beta, isotropic=isotropic)
262
-
263
- # add multiplicative noise
264
- if noise_range is not None:
265
- assert noise_range[0] < noise_range[1], 'Wrong noise range.'
266
- noise = np.random.uniform(noise_range[0], noise_range[1], size=kernel.shape)
267
- kernel = kernel * noise
268
- kernel = kernel / np.sum(kernel)
269
- return kernel
270
-
271
-
272
- def random_bivariate_plateau(kernel_size,
273
- sigma_x_range,
274
- sigma_y_range,
275
- rotation_range,
276
- beta_range,
277
- noise_range=None,
278
- isotropic=True):
279
- """Randomly generate bivariate plateau kernels.
280
-
281
- In the isotropic mode, only `sigma_x_range` is used. `sigma_y_range` and `rotation_range` is ignored.
282
-
283
- Args:
284
- kernel_size (int):
285
- sigma_x_range (tuple): [0.6, 5]
286
- sigma_y_range (tuple): [0.6, 5]
287
- rotation range (tuple): [-math.pi/2, math.pi/2]
288
- beta_range (tuple): [1, 4]
289
- noise_range(tuple, optional): multiplicative kernel noise,
290
- [0.75, 1.25]. Default: None
291
-
292
- Returns:
293
- kernel (ndarray):
294
- """
295
- assert kernel_size % 2 == 1, 'Kernel size must be an odd number.'
296
- assert sigma_x_range[0] < sigma_x_range[1], 'Wrong sigma_x_range.'
297
- sigma_x = np.random.uniform(sigma_x_range[0], sigma_x_range[1])
298
- if isotropic is False:
299
- assert sigma_y_range[0] < sigma_y_range[1], 'Wrong sigma_y_range.'
300
- assert rotation_range[0] < rotation_range[1], 'Wrong rotation_range.'
301
- sigma_y = np.random.uniform(sigma_y_range[0], sigma_y_range[1])
302
- rotation = np.random.uniform(rotation_range[0], rotation_range[1])
303
- else:
304
- sigma_y = sigma_x
305
- rotation = 0
306
-
307
- # TODO: this may be not proper
308
- if np.random.uniform() < 0.5:
309
- beta = np.random.uniform(beta_range[0], 1)
310
- else:
311
- beta = np.random.uniform(1, beta_range[1])
312
-
313
- kernel = bivariate_plateau(kernel_size, sigma_x, sigma_y, rotation, beta, isotropic=isotropic)
314
- # add multiplicative noise
315
- if noise_range is not None:
316
- assert noise_range[0] < noise_range[1], 'Wrong noise range.'
317
- noise = np.random.uniform(noise_range[0], noise_range[1], size=kernel.shape)
318
- kernel = kernel * noise
319
- kernel = kernel / np.sum(kernel)
320
-
321
- return kernel
322
-
323
-
324
- def random_mixed_kernels(kernel_list,
325
- kernel_prob,
326
- kernel_size=21,
327
- sigma_x_range=(0.6, 5),
328
- sigma_y_range=(0.6, 5),
329
- rotation_range=(-math.pi, math.pi),
330
- betag_range=(0.5, 8),
331
- betap_range=(0.5, 8),
332
- noise_range=None):
333
- """Randomly generate mixed kernels.
334
-
335
- Args:
336
- kernel_list (tuple): a list name of kernel types,
337
- support ['iso', 'aniso', 'skew', 'generalized', 'plateau_iso',
338
- 'plateau_aniso']
339
- kernel_prob (tuple): corresponding kernel probability for each
340
- kernel type
341
- kernel_size (int):
342
- sigma_x_range (tuple): [0.6, 5]
343
- sigma_y_range (tuple): [0.6, 5]
344
- rotation range (tuple): [-math.pi, math.pi]
345
- beta_range (tuple): [0.5, 8]
346
- noise_range(tuple, optional): multiplicative kernel noise,
347
- [0.75, 1.25]. Default: None
348
-
349
- Returns:
350
- kernel (ndarray):
351
- """
352
- kernel_type = random.choices(kernel_list, kernel_prob)[0]
353
- if kernel_type == 'iso':
354
- kernel = random_bivariate_Gaussian(
355
- kernel_size, sigma_x_range, sigma_y_range, rotation_range, noise_range=noise_range, isotropic=True)
356
- elif kernel_type == 'aniso':
357
- kernel = random_bivariate_Gaussian(
358
- kernel_size, sigma_x_range, sigma_y_range, rotation_range, noise_range=noise_range, isotropic=False)
359
- elif kernel_type == 'generalized_iso':
360
- kernel = random_bivariate_generalized_Gaussian(
361
- kernel_size,
362
- sigma_x_range,
363
- sigma_y_range,
364
- rotation_range,
365
- betag_range,
366
- noise_range=noise_range,
367
- isotropic=True)
368
- elif kernel_type == 'generalized_aniso':
369
- kernel = random_bivariate_generalized_Gaussian(
370
- kernel_size,
371
- sigma_x_range,
372
- sigma_y_range,
373
- rotation_range,
374
- betag_range,
375
- noise_range=noise_range,
376
- isotropic=False)
377
- elif kernel_type == 'plateau_iso':
378
- kernel = random_bivariate_plateau(
379
- kernel_size, sigma_x_range, sigma_y_range, rotation_range, betap_range, noise_range=None, isotropic=True)
380
- elif kernel_type == 'plateau_aniso':
381
- kernel = random_bivariate_plateau(
382
- kernel_size, sigma_x_range, sigma_y_range, rotation_range, betap_range, noise_range=None, isotropic=False)
383
- return kernel
384
-
385
-
386
- np.seterr(divide='ignore', invalid='ignore')
387
-
388
-
389
- def circular_lowpass_kernel(cutoff, kernel_size, pad_to=0):
390
- """2D sinc filter
391
-
392
- Reference: https://dsp.stackexchange.com/questions/58301/2-d-circularly-symmetric-low-pass-filter
393
-
394
- Args:
395
- cutoff (float): cutoff frequency in radians (pi is max)
396
- kernel_size (int): horizontal and vertical size, must be odd.
397
- pad_to (int): pad kernel size to desired size, must be odd or zero.
398
- """
399
- assert kernel_size % 2 == 1, 'Kernel size must be an odd number.'
400
- kernel = np.fromfunction(
401
- lambda x, y: cutoff * special.j1(cutoff * np.sqrt(
402
- (x - (kernel_size - 1) / 2)**2 + (y - (kernel_size - 1) / 2)**2)) / (2 * np.pi * np.sqrt(
403
- (x - (kernel_size - 1) / 2)**2 + (y - (kernel_size - 1) / 2)**2)), [kernel_size, kernel_size])
404
- kernel[(kernel_size - 1) // 2, (kernel_size - 1) // 2] = cutoff**2 / (4 * np.pi)
405
- kernel = kernel / np.sum(kernel)
406
- if pad_to > kernel_size:
407
- pad_size = (pad_to - kernel_size) // 2
408
- kernel = np.pad(kernel, ((pad_size, pad_size), (pad_size, pad_size)))
409
- return kernel
410
-
411
-
412
- # ------------------------------------------------------------- #
413
- # --------------------------- noise --------------------------- #
414
- # ------------------------------------------------------------- #
415
-
416
- # ----------------------- Gaussian Noise ----------------------- #
417
-
418
-
419
- def generate_gaussian_noise(img, sigma=10, gray_noise=False):
420
- """Generate Gaussian noise.
421
-
422
- Args:
423
- img (Numpy array): Input image, shape (h, w, c), range [0, 1], float32.
424
- sigma (float): Noise scale (measured in range 255). Default: 10.
425
-
426
- Returns:
427
- (Numpy array): Returned noisy image, shape (h, w, c), range[0, 1],
428
- float32.
429
- """
430
- if gray_noise:
431
- noise = np.float32(np.random.randn(*(img.shape[0:2]))) * sigma / 255.
432
- noise = np.expand_dims(noise, axis=2).repeat(3, axis=2)
433
- else:
434
- noise = np.float32(np.random.randn(*(img.shape))) * sigma / 255.
435
- return noise
436
-
437
-
438
- def add_gaussian_noise(img, sigma=10, clip=True, rounds=False, gray_noise=False):
439
- """Add Gaussian noise.
440
-
441
- Args:
442
- img (Numpy array): Input image, shape (h, w, c), range [0, 1], float32.
443
- sigma (float): Noise scale (measured in range 255). Default: 10.
444
-
445
- Returns:
446
- (Numpy array): Returned noisy image, shape (h, w, c), range[0, 1],
447
- float32.
448
- """
449
- noise = generate_gaussian_noise(img, sigma, gray_noise)
450
- out = img + noise
451
- if clip and rounds:
452
- out = np.clip((out * 255.0).round(), 0, 255) / 255.
453
- elif clip:
454
- out = np.clip(out, 0, 1)
455
- elif rounds:
456
- out = (out * 255.0).round() / 255.
457
- return out
458
-
459
-
460
- def generate_gaussian_noise_pt(img, sigma=10, gray_noise=0):
461
- """Add Gaussian noise (PyTorch version).
462
-
463
- Args:
464
- img (Tensor): Shape (b, c, h, w), range[0, 1], float32.
465
- scale (float | Tensor): Noise scale. Default: 1.0.
466
-
467
- Returns:
468
- (Tensor): Returned noisy image, shape (b, c, h, w), range[0, 1],
469
- float32.
470
- """
471
- b, _, h, w = img.size()
472
- if not isinstance(sigma, (float, int)):
473
- sigma = sigma.view(img.size(0), 1, 1, 1)
474
- if isinstance(gray_noise, (float, int)):
475
- cal_gray_noise = gray_noise > 0
476
- else:
477
- gray_noise = gray_noise.view(b, 1, 1, 1)
478
- cal_gray_noise = torch.sum(gray_noise) > 0
479
-
480
- if cal_gray_noise:
481
- noise_gray = torch.randn(*img.size()[2:4], dtype=img.dtype, device=img.device) * sigma / 255.
482
- noise_gray = noise_gray.view(b, 1, h, w)
483
-
484
- # always calculate color noise
485
- noise = torch.randn(*img.size(), dtype=img.dtype, device=img.device) * sigma / 255.
486
-
487
- if cal_gray_noise:
488
- noise = noise * (1 - gray_noise) + noise_gray * gray_noise
489
- return noise
490
-
491
-
492
- def add_gaussian_noise_pt(img, sigma=10, gray_noise=0, clip=True, rounds=False):
493
- """Add Gaussian noise (PyTorch version).
494
-
495
- Args:
496
- img (Tensor): Shape (b, c, h, w), range[0, 1], float32.
497
- scale (float | Tensor): Noise scale. Default: 1.0.
498
-
499
- Returns:
500
- (Tensor): Returned noisy image, shape (b, c, h, w), range[0, 1],
501
- float32.
502
- """
503
- noise = generate_gaussian_noise_pt(img, sigma, gray_noise)
504
- out = img + noise
505
- if clip and rounds:
506
- out = torch.clamp((out * 255.0).round(), 0, 255) / 255.
507
- elif clip:
508
- out = torch.clamp(out, 0, 1)
509
- elif rounds:
510
- out = (out * 255.0).round() / 255.
511
- return out
512
-
513
-
514
- # ----------------------- Random Gaussian Noise ----------------------- #
515
- def random_generate_gaussian_noise(img, sigma_range=(0, 10), gray_prob=0):
516
- sigma = np.random.uniform(sigma_range[0], sigma_range[1])
517
- if np.random.uniform() < gray_prob:
518
- gray_noise = True
519
- else:
520
- gray_noise = False
521
- return generate_gaussian_noise(img, sigma, gray_noise)
522
-
523
-
524
- def random_add_gaussian_noise(img, sigma_range=(0, 1.0), gray_prob=0, clip=True, rounds=False):
525
- noise = random_generate_gaussian_noise(img, sigma_range, gray_prob)
526
- out = img + noise
527
- if clip and rounds:
528
- out = np.clip((out * 255.0).round(), 0, 255) / 255.
529
- elif clip:
530
- out = np.clip(out, 0, 1)
531
- elif rounds:
532
- out = (out * 255.0).round() / 255.
533
- return out
534
-
535
-
536
- def random_generate_gaussian_noise_pt(img, sigma_range=(0, 10), gray_prob=0):
537
- sigma = torch.rand(
538
- img.size(0), dtype=img.dtype, device=img.device) * (sigma_range[1] - sigma_range[0]) + sigma_range[0]
539
- gray_noise = torch.rand(img.size(0), dtype=img.dtype, device=img.device)
540
- gray_noise = (gray_noise < gray_prob).float()
541
- return generate_gaussian_noise_pt(img, sigma, gray_noise)
542
-
543
-
544
- def random_add_gaussian_noise_pt(img, sigma_range=(0, 1.0), gray_prob=0, clip=True, rounds=False):
545
- noise = random_generate_gaussian_noise_pt(img, sigma_range, gray_prob)
546
- out = img + noise
547
- if clip and rounds:
548
- out = torch.clamp((out * 255.0).round(), 0, 255) / 255.
549
- elif clip:
550
- out = torch.clamp(out, 0, 1)
551
- elif rounds:
552
- out = (out * 255.0).round() / 255.
553
- return out
554
-
555
-
556
- # ----------------------- Poisson (Shot) Noise ----------------------- #
557
-
558
-
559
- def generate_poisson_noise(img, scale=1.0, gray_noise=False):
560
- """Generate poisson noise.
561
-
562
- Reference: https://github.com/scikit-image/scikit-image/blob/main/skimage/util/noise.py#L37-L219
563
-
564
- Args:
565
- img (Numpy array): Input image, shape (h, w, c), range [0, 1], float32.
566
- scale (float): Noise scale. Default: 1.0.
567
- gray_noise (bool): Whether generate gray noise. Default: False.
568
-
569
- Returns:
570
- (Numpy array): Returned noisy image, shape (h, w, c), range[0, 1],
571
- float32.
572
- """
573
- if gray_noise:
574
- img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
575
- # round and clip image for counting vals correctly
576
- img = np.clip((img * 255.0).round(), 0, 255) / 255.
577
- vals = len(np.unique(img))
578
- vals = 2**np.ceil(np.log2(vals))
579
- out = np.float32(np.random.poisson(img * vals) / float(vals))
580
- noise = out - img
581
- if gray_noise:
582
- noise = np.repeat(noise[:, :, np.newaxis], 3, axis=2)
583
- return noise * scale
584
-
585
-
586
- def add_poisson_noise(img, scale=1.0, clip=True, rounds=False, gray_noise=False):
587
- """Add poisson noise.
588
-
589
- Args:
590
- img (Numpy array): Input image, shape (h, w, c), range [0, 1], float32.
591
- scale (float): Noise scale. Default: 1.0.
592
- gray_noise (bool): Whether generate gray noise. Default: False.
593
-
594
- Returns:
595
- (Numpy array): Returned noisy image, shape (h, w, c), range[0, 1],
596
- float32.
597
- """
598
- noise = generate_poisson_noise(img, scale, gray_noise)
599
- out = img + noise
600
- if clip and rounds:
601
- out = np.clip((out * 255.0).round(), 0, 255) / 255.
602
- elif clip:
603
- out = np.clip(out, 0, 1)
604
- elif rounds:
605
- out = (out * 255.0).round() / 255.
606
- return out
607
-
608
-
609
- def generate_poisson_noise_pt(img, scale=1.0, gray_noise=0):
610
- """Generate a batch of poisson noise (PyTorch version)
611
-
612
- Args:
613
- img (Tensor): Input image, shape (b, c, h, w), range [0, 1], float32.
614
- scale (float | Tensor): Noise scale. Number or Tensor with shape (b).
615
- Default: 1.0.
616
- gray_noise (float | Tensor): 0-1 number or Tensor with shape (b).
617
- 0 for False, 1 for True. Default: 0.
618
-
619
- Returns:
620
- (Tensor): Returned noisy image, shape (b, c, h, w), range[0, 1],
621
- float32.
622
- """
623
- b, _, h, w = img.size()
624
- if isinstance(gray_noise, (float, int)):
625
- cal_gray_noise = gray_noise > 0
626
- else:
627
- gray_noise = gray_noise.view(b, 1, 1, 1)
628
- cal_gray_noise = torch.sum(gray_noise) > 0
629
- if cal_gray_noise:
630
- img_gray = rgb_to_grayscale(img, num_output_channels=1)
631
- # round and clip image for counting vals correctly
632
- img_gray = torch.clamp((img_gray * 255.0).round(), 0, 255) / 255.
633
- # use for-loop to get the unique values for each sample
634
- vals_list = [len(torch.unique(img_gray[i, :, :, :])) for i in range(b)]
635
- vals_list = [2**np.ceil(np.log2(vals)) for vals in vals_list]
636
- vals = img_gray.new_tensor(vals_list).view(b, 1, 1, 1)
637
- out = torch.poisson(img_gray * vals) / vals
638
- noise_gray = out - img_gray
639
- noise_gray = noise_gray.expand(b, 3, h, w)
640
-
641
- # always calculate color noise
642
- # round and clip image for counting vals correctly
643
- img = torch.clamp((img * 255.0).round(), 0, 255) / 255.
644
- # use for-loop to get the unique values for each sample
645
- vals_list = [len(torch.unique(img[i, :, :, :])) for i in range(b)]
646
- vals_list = [2**np.ceil(np.log2(vals)) for vals in vals_list]
647
- vals = img.new_tensor(vals_list).view(b, 1, 1, 1)
648
- out = torch.poisson(img * vals) / vals
649
- noise = out - img
650
- if cal_gray_noise:
651
- noise = noise * (1 - gray_noise) + noise_gray * gray_noise
652
- if not isinstance(scale, (float, int)):
653
- scale = scale.view(b, 1, 1, 1)
654
- return noise * scale
655
-
656
-
657
- def add_poisson_noise_pt(img, scale=1.0, clip=True, rounds=False, gray_noise=0):
658
- """Add poisson noise to a batch of images (PyTorch version).
659
-
660
- Args:
661
- img (Tensor): Input image, shape (b, c, h, w), range [0, 1], float32.
662
- scale (float | Tensor): Noise scale. Number or Tensor with shape (b).
663
- Default: 1.0.
664
- gray_noise (float | Tensor): 0-1 number or Tensor with shape (b).
665
- 0 for False, 1 for True. Default: 0.
666
-
667
- Returns:
668
- (Tensor): Returned noisy image, shape (b, c, h, w), range[0, 1],
669
- float32.
670
- """
671
- noise = generate_poisson_noise_pt(img, scale, gray_noise)
672
- out = img + noise
673
- if clip and rounds:
674
- out = torch.clamp((out * 255.0).round(), 0, 255) / 255.
675
- elif clip:
676
- out = torch.clamp(out, 0, 1)
677
- elif rounds:
678
- out = (out * 255.0).round() / 255.
679
- return out
680
-
681
-
682
- # ----------------------- Random Poisson (Shot) Noise ----------------------- #
683
-
684
-
685
- def random_generate_poisson_noise(img, scale_range=(0, 1.0), gray_prob=0):
686
- scale = np.random.uniform(scale_range[0], scale_range[1])
687
- if np.random.uniform() < gray_prob:
688
- gray_noise = True
689
- else:
690
- gray_noise = False
691
- return generate_poisson_noise(img, scale, gray_noise)
692
-
693
-
694
- def random_add_poisson_noise(img, scale_range=(0, 1.0), gray_prob=0, clip=True, rounds=False):
695
- noise = random_generate_poisson_noise(img, scale_range, gray_prob)
696
- out = img + noise
697
- if clip and rounds:
698
- out = np.clip((out * 255.0).round(), 0, 255) / 255.
699
- elif clip:
700
- out = np.clip(out, 0, 1)
701
- elif rounds:
702
- out = (out * 255.0).round() / 255.
703
- return out
704
-
705
-
706
- def random_generate_poisson_noise_pt(img, scale_range=(0, 1.0), gray_prob=0):
707
- scale = torch.rand(
708
- img.size(0), dtype=img.dtype, device=img.device) * (scale_range[1] - scale_range[0]) + scale_range[0]
709
- gray_noise = torch.rand(img.size(0), dtype=img.dtype, device=img.device)
710
- gray_noise = (gray_noise < gray_prob).float()
711
- return generate_poisson_noise_pt(img, scale, gray_noise)
712
-
713
-
714
- def random_add_poisson_noise_pt(img, scale_range=(0, 1.0), gray_prob=0, clip=True, rounds=False):
715
- noise = random_generate_poisson_noise_pt(img, scale_range, gray_prob)
716
- out = img + noise
717
- if clip and rounds:
718
- out = torch.clamp((out * 255.0).round(), 0, 255) / 255.
719
- elif clip:
720
- out = torch.clamp(out, 0, 1)
721
- elif rounds:
722
- out = (out * 255.0).round() / 255.
723
- return out
724
-
725
-
726
- # ------------------------------------------------------------------------ #
727
- # --------------------------- JPEG compression --------------------------- #
728
- # ------------------------------------------------------------------------ #
729
-
730
-
731
- def add_jpg_compression(img, quality=90):
732
- """Add JPG compression artifacts.
733
-
734
- Args:
735
- img (Numpy array): Input image, shape (h, w, c), range [0, 1], float32.
736
- quality (float): JPG compression quality. 0 for lowest quality, 100 for
737
- best quality. Default: 90.
738
-
739
- Returns:
740
- (Numpy array): Returned image after JPG, shape (h, w, c), range[0, 1],
741
- float32.
742
- """
743
- img = np.clip(img, 0, 1)
744
- encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality]
745
- _, encimg = cv2.imencode('.jpg', img * 255., encode_param)
746
- img = np.float32(cv2.imdecode(encimg, 1)) / 255.
747
- return img
748
-
749
-
750
- def random_add_jpg_compression(img, quality_range=(90, 100)):
751
- """Randomly add JPG compression artifacts.
752
-
753
- Args:
754
- img (Numpy array): Input image, shape (h, w, c), range [0, 1], float32.
755
- quality_range (tuple[float] | list[float]): JPG compression quality
756
- range. 0 for lowest quality, 100 for best quality.
757
- Default: (90, 100).
758
-
759
- Returns:
760
- (Numpy array): Returned image after JPG, shape (h, w, c), range[0, 1],
761
- float32.
762
- """
763
- quality = np.random.uniform(quality_range[0], quality_range[1])
764
- return add_jpg_compression(img, quality)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/ffhq_dataset.py DELETED
@@ -1,80 +0,0 @@
1
- import random
2
- import time
3
- from os import path as osp
4
- from torch.utils import data as data
5
- from torchvision.transforms.functional import normalize
6
-
7
- from basicsr.data.transforms import augment
8
- from basicsr.utils import FileClient, get_root_logger, imfrombytes, img2tensor
9
- from basicsr.utils.registry import DATASET_REGISTRY
10
-
11
-
12
- @DATASET_REGISTRY.register()
13
- class FFHQDataset(data.Dataset):
14
- """FFHQ dataset for StyleGAN.
15
-
16
- Args:
17
- opt (dict): Config for train datasets. It contains the following keys:
18
- dataroot_gt (str): Data root path for gt.
19
- io_backend (dict): IO backend type and other kwarg.
20
- mean (list | tuple): Image mean.
21
- std (list | tuple): Image std.
22
- use_hflip (bool): Whether to horizontally flip.
23
-
24
- """
25
-
26
- def __init__(self, opt):
27
- super(FFHQDataset, self).__init__()
28
- self.opt = opt
29
- # file client (io backend)
30
- self.file_client = None
31
- self.io_backend_opt = opt['io_backend']
32
-
33
- self.gt_folder = opt['dataroot_gt']
34
- self.mean = opt['mean']
35
- self.std = opt['std']
36
-
37
- if self.io_backend_opt['type'] == 'lmdb':
38
- self.io_backend_opt['db_paths'] = self.gt_folder
39
- if not self.gt_folder.endswith('.lmdb'):
40
- raise ValueError("'dataroot_gt' should end with '.lmdb', but received {self.gt_folder}")
41
- with open(osp.join(self.gt_folder, 'meta_info.txt')) as fin:
42
- self.paths = [line.split('.')[0] for line in fin]
43
- else:
44
- # FFHQ has 70000 images in total
45
- self.paths = [osp.join(self.gt_folder, f'{v:08d}.png') for v in range(70000)]
46
-
47
- def __getitem__(self, index):
48
- if self.file_client is None:
49
- self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
50
-
51
- # load gt image
52
- gt_path = self.paths[index]
53
- # avoid errors caused by high latency in reading files
54
- retry = 3
55
- while retry > 0:
56
- try:
57
- img_bytes = self.file_client.get(gt_path)
58
- except Exception as e:
59
- logger = get_root_logger()
60
- logger.warning(f'File client error: {e}, remaining retry times: {retry - 1}')
61
- # change another file to read
62
- index = random.randint(0, self.__len__())
63
- gt_path = self.paths[index]
64
- time.sleep(1) # sleep 1s for occasional server congestion
65
- else:
66
- break
67
- finally:
68
- retry -= 1
69
- img_gt = imfrombytes(img_bytes, float32=True)
70
-
71
- # random horizontal flip
72
- img_gt = augment(img_gt, hflip=self.opt['use_hflip'], rotation=False)
73
- # BGR to RGB, HWC to CHW, numpy to tensor
74
- img_gt = img2tensor(img_gt, bgr2rgb=True, float32=True)
75
- # normalize
76
- normalize(img_gt, self.mean, self.std, inplace=True)
77
- return {'gt': img_gt, 'gt_path': gt_path}
78
-
79
- def __len__(self):
80
- return len(self.paths)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/imagent_dataset.py DELETED
@@ -1,460 +0,0 @@
1
- # Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- #
3
- # This work is licensed under a Creative Commons
4
- # Attribution-NonCommercial-ShareAlike 4.0 International License.
5
- # You should have received a copy of the license along with this
6
- # work. If not, see http://creativecommons.org/licenses/by-nc-sa/4.0/
7
-
8
- """Streaming images and labels from datasets created with dataset_tool.py."""
9
-
10
- import os
11
- import numpy as np
12
- import zipfile
13
- import PIL.Image
14
- import json
15
- import torch
16
- import random
17
-
18
- from basicsr.data.degradations import circular_lowpass_kernel, random_mixed_kernels
19
- from basicsr.data.transforms import augment
20
- from basicsr.utils import img2tensor
21
- from basicsr.utils.registry import DATASET_REGISTRY
22
-
23
- try:
24
- import pyspng
25
- except ImportError:
26
- pyspng = None
27
-
28
- KERNEL_OPT = {
29
- 'blur_kernel_size': 21,
30
- 'kernel_list': ['iso', 'aniso', 'generalized_iso', 'generalized_aniso', 'plateau_iso', 'plateau_aniso'],
31
- 'kernel_prob': [0.45, 0.25, 0.12, 0.03, 0.12, 0.03],
32
- 'sinc_prob': 0.1,
33
- 'blur_sigma': [0.2, 3],
34
- 'betag_range': [0.5, 4],
35
- 'betap_range': [1, 2],
36
-
37
- 'blur_kernel_size2': 21,
38
- 'kernel_list2': ['iso', 'aniso', 'generalized_iso', 'generalized_aniso', 'plateau_iso', 'plateau_aniso'],
39
- 'kernel_prob2': [0.45, 0.25, 0.12, 0.03, 0.12, 0.03],
40
- 'sinc_prob2': 0.1,
41
- 'blur_sigma2': [0.2, 1.5],
42
- 'betag_range2': [0.5, 4],
43
- 'betap_range2': [1, 2],
44
- 'final_sinc_prob': 0.8,
45
-
46
- 'use_hflip': False,
47
- 'use_rot': False
48
- }
49
-
50
- DEGRADE_OPT = {
51
- 'resize_prob': [0.2, 0.7, 0.1], # up, down, keep
52
- 'resize_range': [0.15, 1.5],
53
- 'gaussian_noise_prob': 0.5,
54
- 'noise_range': [1, 30],
55
- 'poisson_scale_range': [0.05, 3],
56
- 'gray_noise_prob': 0.4,
57
- 'jpeg_range': [30, 95],
58
-
59
- # the second degradation process
60
- 'second_blur_prob': 0.8,
61
- 'resize_prob2': [0.3, 0.4, 0.3], # up, down, keep
62
- 'resize_range2': [0.3, 1.2],
63
- 'gaussian_noise_prob2': 0.5,
64
- 'noise_range2': [1, 25],
65
- 'poisson_scale_range2': [0.05, 2.5],
66
- 'gray_noise_prob2': 0.4,
67
- 'jpeg_range2': [30, 95],
68
-
69
- 'gt_size': 512,
70
- 'no_degradation_prob': 0.01,
71
- 'use_usm': True,
72
- 'sf': 4,
73
- 'random_size': False,
74
- 'resize_lq': False
75
- }
76
-
77
- #----------------------------------------------------------------------------
78
- # Abstract base class for datasets.
79
-
80
- class Dataset(torch.utils.data.Dataset):
81
- def __init__(self,
82
- name, # Name of the dataset.
83
- raw_shape, # Shape of the raw image data (NCHW).
84
- use_labels = True, # Enable conditioning labels? False = label dimension is zero.
85
- max_size = None, # Artificially limit the size of the dataset. None = no limit. Applied before xflip.
86
- xflip = False, # Artificially double the size of the dataset via x-flips. Applied after max_size.
87
- random_seed = 0, # Random seed to use when applying max_size.
88
- cache = False, # Cache images in CPU memory?
89
- ):
90
- self._name = name
91
- self._raw_shape = list(raw_shape)
92
- self._use_labels = use_labels
93
- self._cache = cache
94
- self._cached_images = dict() # {raw_idx: np.ndarray, ...}
95
- self._raw_labels = None
96
- self._label_shape = None
97
-
98
- # Apply max_size.
99
- self._raw_idx = np.arange(self._raw_shape[0], dtype=np.int64)
100
- if (max_size is not None) and (self._raw_idx.size > max_size):
101
- np.random.RandomState(random_seed % (1 << 31)).shuffle(self._raw_idx)
102
- self._raw_idx = np.sort(self._raw_idx[:max_size])
103
-
104
- # Apply xflip.
105
- self._xflip = np.zeros(self._raw_idx.size, dtype=np.uint8)
106
- if xflip:
107
- self._raw_idx = np.tile(self._raw_idx, 2)
108
- self._xflip = np.concatenate([self._xflip, np.ones_like(self._xflip)])
109
-
110
- def _get_raw_labels(self):
111
- if self._raw_labels is None:
112
- self._raw_labels = self._load_raw_labels() if self._use_labels else None
113
- if self._raw_labels is None:
114
- self._raw_labels = np.zeros([self._raw_shape[0], 0], dtype=np.float32)
115
- assert isinstance(self._raw_labels, np.ndarray)
116
- assert self._raw_labels.shape[0] == self._raw_shape[0]
117
- assert self._raw_labels.dtype in [np.float32, np.int64]
118
- if self._raw_labels.dtype == np.int64:
119
- assert self._raw_labels.ndim == 1
120
- assert np.all(self._raw_labels >= 0)
121
- return self._raw_labels
122
-
123
- def close(self): # to be overridden by subclass
124
- pass
125
-
126
- def _load_raw_image(self, raw_idx): # to be overridden by subclass
127
- raise NotImplementedError
128
-
129
- def _load_raw_labels(self): # to be overridden by subclass
130
- raise NotImplementedError
131
-
132
- def __getstate__(self):
133
- return dict(self.__dict__, _raw_labels=None)
134
-
135
- def __del__(self):
136
- try:
137
- self.close()
138
- except:
139
- pass
140
-
141
- def __len__(self):
142
- return self._raw_idx.size
143
-
144
- def __getitem__(self, idx):
145
- raw_idx = self._raw_idx[idx]
146
- image = self._cached_images.get(raw_idx, None)
147
- if image is None:
148
- image = self._load_raw_image(raw_idx)
149
- if self._cache:
150
- self._cached_images[raw_idx] = image
151
- assert isinstance(image, np.ndarray)
152
- assert list(image.shape) == self._raw_shape[1:]
153
- if self._xflip[idx]:
154
- assert image.ndim == 3 # CHW
155
- image = image[:, :, ::-1]
156
- return image.copy(), self.get_label(idx)
157
-
158
- def get_label(self, idx):
159
- label = self._get_raw_labels()[self._raw_idx[idx]]
160
- if label.dtype == np.int64:
161
- onehot = np.zeros(self.label_shape, dtype=np.float32)
162
- onehot[label] = 1
163
- label = onehot
164
- return label.copy()
165
-
166
- def get_details(self, idx):
167
- d = dict()
168
- d['raw_idx'] = int(self._raw_idx[idx])
169
- d['xflip'] = (int(self._xflip[idx]) != 0)
170
- d['raw_label'] = self._get_raw_labels()[d['raw_idx']].copy()
171
- return d
172
-
173
- @property
174
- def name(self):
175
- return self._name
176
-
177
- @property
178
- def image_shape(self): # [CHW]
179
- return list(self._raw_shape[1:])
180
-
181
- @property
182
- def num_channels(self):
183
- assert len(self.image_shape) == 3 # CHW
184
- return self.image_shape[0]
185
-
186
- @property
187
- def resolution(self):
188
- assert len(self.image_shape) == 3 # CHW
189
- assert self.image_shape[1] == self.image_shape[2]
190
- return self.image_shape[1]
191
-
192
- @property
193
- def label_shape(self):
194
- if self._label_shape is None:
195
- raw_labels = self._get_raw_labels()
196
- if raw_labels.dtype == np.int64:
197
- self._label_shape = [int(np.max(raw_labels)) + 1]
198
- else:
199
- self._label_shape = raw_labels.shape[1:]
200
- return list(self._label_shape)
201
-
202
- @property
203
- def label_dim(self):
204
- assert len(self.label_shape) == 1
205
- return self.label_shape[0]
206
-
207
- @property
208
- def has_labels(self):
209
- return any(x != 0 for x in self.label_shape)
210
-
211
- @property
212
- def has_onehot_labels(self):
213
- return self._get_raw_labels().dtype == np.int64
214
-
215
- #----------------------------------------------------------------------------
216
- # Dataset subclass that loads images recursively from the specified directory
217
- # or ZIP file.
218
-
219
- class ImageFolderDataset(Dataset):
220
- def __init__(self,
221
- path, # Path to directory or zip.
222
- resolution = None, # Ensure specific resolution, None = anything goes.
223
- **super_kwargs, # Additional arguments for the Dataset base class.
224
- ):
225
- self._path = path
226
- self._zipfile = None
227
-
228
- if os.path.isdir(self._path):
229
- self._type = 'dir'
230
- self._all_fnames = {os.path.relpath(os.path.join(root, fname), start=self._path) for root, _dirs, files in os.walk(self._path) for fname in files}
231
- elif self._file_ext(self._path) == '.zip':
232
- self._type = 'zip'
233
- self._all_fnames = set(self._get_zipfile().namelist())
234
- else:
235
- raise IOError('Path must point to a directory or zip')
236
-
237
- PIL.Image.init()
238
- supported_ext = PIL.Image.EXTENSION.keys() | {'.npy'}
239
- self._image_fnames = sorted(fname for fname in self._all_fnames if self._file_ext(fname) in supported_ext)
240
- if len(self._image_fnames) == 0:
241
- raise IOError('No image files found in the specified path')
242
-
243
- name = os.path.splitext(os.path.basename(self._path))[0]
244
- raw_shape = [len(self._image_fnames)] + list(self._load_raw_image(0).shape)
245
- if resolution is not None and (raw_shape[2] != resolution or raw_shape[3] != resolution):
246
- raise IOError('Image files do not match the specified resolution')
247
- super().__init__(name=name, raw_shape=raw_shape, **super_kwargs)
248
-
249
- @staticmethod
250
- def _file_ext(fname):
251
- return os.path.splitext(fname)[1].lower()
252
-
253
- def _get_zipfile(self):
254
- assert self._type == 'zip'
255
- if self._zipfile is None:
256
- self._zipfile = zipfile.ZipFile(self._path)
257
- return self._zipfile
258
-
259
- def _open_file(self, fname):
260
- if self._type == 'dir':
261
- return open(os.path.join(self._path, fname), 'rb')
262
- if self._type == 'zip':
263
- return self._get_zipfile().open(fname, 'r')
264
- return None
265
-
266
- def close(self):
267
- try:
268
- if self._zipfile is not None:
269
- self._zipfile.close()
270
- finally:
271
- self._zipfile = None
272
-
273
- def __getstate__(self):
274
- return dict(super().__getstate__(), _zipfile=None)
275
-
276
- def _load_raw_image(self, raw_idx):
277
- fname = self._image_fnames[raw_idx]
278
- ext = self._file_ext(fname)
279
- with self._open_file(fname) as f:
280
- if ext == '.npy':
281
- image = np.load(f)
282
- image = image.reshape(-1, *image.shape[-2:])
283
- elif ext == '.png' and pyspng is not None:
284
- image = pyspng.load(f.read())
285
- image = image.reshape(*image.shape[:2], -1).transpose(2, 0, 1)
286
- else:
287
- image = np.array(PIL.Image.open(f))
288
- image = image.reshape(*image.shape[:2], -1).transpose(2, 0, 1)
289
- return image
290
-
291
- def _load_raw_labels(self):
292
- fname = 'dataset.json'
293
- if fname not in self._all_fnames:
294
- return None
295
- with self._open_file(fname) as f:
296
- labels = json.load(f)['labels']
297
- if labels is None:
298
- return None
299
- labels = dict(labels)
300
- labels = [labels[fname.replace('\\', '/')] for fname in self._image_fnames]
301
- labels = np.array(labels)
302
- labels = labels.astype({1: np.int64, 2: np.float32}[labels.ndim])
303
- return labels
304
-
305
- #----------------------------------------------------------------------------
306
- @DATASET_REGISTRY.register(suffix='basicsr')
307
- class IRImageFolderDataset(ImageFolderDataset):
308
- def __init__(self,
309
- opt=None, # Degradation kernel config.
310
- **super_kwargs, # Additional arguments for the Dataset base class.
311
- ):
312
- if opt is None: opt = KERNEL_OPT
313
- self.opt = opt
314
- super().__init__(**super_kwargs)
315
-
316
- # blur settings for the first degradation
317
- self.blur_kernel_size = opt['blur_kernel_size']
318
- self.kernel_list = opt['kernel_list']
319
- self.kernel_prob = opt['kernel_prob'] # a list for each kernel probability
320
- self.blur_sigma = opt['blur_sigma']
321
- self.betag_range = opt['betag_range'] # betag used in generalized Gaussian blur kernels
322
- self.betap_range = opt['betap_range'] # betap used in plateau blur kernels
323
- self.sinc_prob = opt['sinc_prob'] # the probability for sinc filters
324
-
325
- # blur settings for the second degradation
326
- self.blur_kernel_size2 = opt['blur_kernel_size2']
327
- self.kernel_list2 = opt['kernel_list2']
328
- self.kernel_prob2 = opt['kernel_prob2']
329
- self.blur_sigma2 = opt['blur_sigma2']
330
- self.betag_range2 = opt['betag_range2']
331
- self.betap_range2 = opt['betap_range2']
332
- self.sinc_prob2 = opt['sinc_prob2']
333
-
334
- # a final sinc filter
335
- self.final_sinc_prob = opt['final_sinc_prob']
336
-
337
- self.kernel_range = [2 * v + 1 for v in range(3, 11)] # kernel size ranges from 7 to 21
338
- # TODO: kernel range is now hard-coded, should be in the configure file
339
- self.pulse_tensor = torch.zeros(21, 21).float() # convolving with pulse tensor brings no blurry effect
340
- self.pulse_tensor[10, 10] = 1
341
-
342
- def _load_raw_image(self, raw_idx):
343
- fname = self._image_fnames[raw_idx]
344
- ext = self._file_ext(fname)
345
- with self._open_file(fname) as f:
346
- if ext == '.npy':
347
- image = np.load(f)
348
- image = image.reshape(-1, *image.shape[-2:])
349
- elif ext == '.png' and pyspng is not None:
350
- image = pyspng.load(f.read())
351
- image = image.reshape(*image.shape[:2], -1).transpose(2, 0, 1)
352
- else:
353
- image = np.array(PIL.Image.open(f))
354
- image = image.reshape(*image.shape[:2], -1).transpose(2, 0, 1)
355
- return image
356
-
357
- def __getitem__(self, idx):
358
- raw_idx = self._raw_idx[idx]
359
- image = self._cached_images.get(raw_idx, None)
360
- if image is None:
361
- image = self._load_raw_image(raw_idx)
362
- if self._cache:
363
- self._cached_images[raw_idx] = image
364
-
365
- assert isinstance(image, np.ndarray), type(image)
366
- assert list(image.shape) == self._raw_shape[1:], image.shape
367
-
368
- # # FIXME: flip or rotate
369
- # image = augment(image, self.opt['use_hflip'], self.opt['use_rot'])
370
-
371
- image = image.astype(np.float32) / 255.
372
-
373
- # ------------------------ Generate kernels (used in the first degradation) ------------------------ #
374
- kernel_size = random.choice(self.kernel_range)
375
- if np.random.uniform() < self.opt['sinc_prob']:
376
- # this sinc filter setting is for kernels ranging from [7, 21]
377
- if kernel_size < 13:
378
- omega_c = np.random.uniform(np.pi / 3, np.pi)
379
- else:
380
- omega_c = np.random.uniform(np.pi / 5, np.pi)
381
- kernel = circular_lowpass_kernel(omega_c, kernel_size, pad_to=False)
382
- else:
383
- kernel = random_mixed_kernels(
384
- self.kernel_list,
385
- self.kernel_prob,
386
- kernel_size,
387
- self.blur_sigma,
388
- self.blur_sigma, [-np.pi, np.pi],
389
- self.betag_range,
390
- self.betap_range,
391
- noise_range=None)
392
- # pad kernel
393
- pad_size = (21 - kernel_size) // 2
394
- kernel = np.pad(kernel, ((pad_size, pad_size), (pad_size, pad_size)))
395
-
396
- # ------------------------ Generate kernels (used in the second degradation) ------------------------ #
397
- kernel_size = random.choice(self.kernel_range)
398
- if np.random.uniform() < self.opt['sinc_prob2']:
399
- if kernel_size < 13:
400
- omega_c = np.random.uniform(np.pi / 3, np.pi)
401
- else:
402
- omega_c = np.random.uniform(np.pi / 5, np.pi)
403
- kernel2 = circular_lowpass_kernel(omega_c, kernel_size, pad_to=False)
404
- else:
405
- kernel2 = random_mixed_kernels(
406
- self.kernel_list2,
407
- self.kernel_prob2,
408
- kernel_size,
409
- self.blur_sigma2,
410
- self.blur_sigma2, [-np.pi, np.pi],
411
- self.betag_range2,
412
- self.betap_range2,
413
- noise_range=None)
414
-
415
- # pad kernel
416
- pad_size = (21 - kernel_size) // 2
417
- kernel2 = np.pad(kernel2, ((pad_size, pad_size), (pad_size, pad_size)))
418
-
419
- # ------------------------------------- the final sinc kernel ------------------------------------- #
420
- if np.random.uniform() < self.opt['final_sinc_prob']:
421
- kernel_size = random.choice(self.kernel_range)
422
- omega_c = np.random.uniform(np.pi / 3, np.pi)
423
- sinc_kernel = circular_lowpass_kernel(omega_c, kernel_size, pad_to=21)
424
- sinc_kernel = torch.FloatTensor(sinc_kernel)
425
- else:
426
- sinc_kernel = self.pulse_tensor
427
-
428
- # numpy to tensor
429
- img_gt = torch.from_numpy(image).float()
430
-
431
- kernel = torch.FloatTensor(kernel)
432
- kernel2 = torch.FloatTensor(kernel2)
433
-
434
- return_d = {'image': img_gt, 'kernel1': kernel, 'kernel2': kernel2, 'sinc_kernel': sinc_kernel}
435
- return return_d
436
-
437
- # return image.copy(), self.get_label(idx)
438
-
439
- def collate_fn(examples, with_prior_preservation=False):
440
- pixel_values = [example["img_tensor"] for example in examples]
441
- kernel1 = [example["kernel1"] for example in examples]
442
- kernel2 = [example["kernel2"] for example in examples]
443
- sinc_kernel = [example["sinc_kernel"] for example in examples]
444
- pil_image = [example["image"] for example in examples]
445
-
446
- if with_prior_preservation:
447
- raise NotImplementedError("Prior preservation not implemented.")
448
-
449
- pixel_values = torch.stack(pixel_values)
450
- pixel_values = pixel_values.to(memory_format=torch.contiguous_format).float()
451
-
452
- kernel1 = torch.stack(kernel1)
453
- kernel1 = kernel1.to(memory_format=torch.contiguous_format).float()
454
- kernel2 = torch.stack(kernel2)
455
- kernel2 = kernel2.to(memory_format=torch.contiguous_format).float()
456
- sinc_kernel = torch.stack(sinc_kernel)
457
- sinc_kernel = sinc_kernel.to(memory_format=torch.contiguous_format).float()
458
-
459
- batch = {"image": pil_image, "img_tensor": pixel_values, "kernel1": kernel1, "kernel2": kernel2, "sinc_kernel": sinc_kernel}
460
- return batch
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/meta_info/meta_info_DIV2K800sub_GT.txt DELETED
The diff for this file is too large to render. See raw diff
 
basicsr/data/meta_info/meta_info_REDS4_test_GT.txt DELETED
@@ -1,4 +0,0 @@
1
- 000 100 (720,1280,3)
2
- 011 100 (720,1280,3)
3
- 015 100 (720,1280,3)
4
- 020 100 (720,1280,3)
 
 
 
 
 
basicsr/data/meta_info/meta_info_REDS_GT.txt DELETED
@@ -1,270 +0,0 @@
1
- 000 100 (720,1280,3)
2
- 001 100 (720,1280,3)
3
- 002 100 (720,1280,3)
4
- 003 100 (720,1280,3)
5
- 004 100 (720,1280,3)
6
- 005 100 (720,1280,3)
7
- 006 100 (720,1280,3)
8
- 007 100 (720,1280,3)
9
- 008 100 (720,1280,3)
10
- 009 100 (720,1280,3)
11
- 010 100 (720,1280,3)
12
- 011 100 (720,1280,3)
13
- 012 100 (720,1280,3)
14
- 013 100 (720,1280,3)
15
- 014 100 (720,1280,3)
16
- 015 100 (720,1280,3)
17
- 016 100 (720,1280,3)
18
- 017 100 (720,1280,3)
19
- 018 100 (720,1280,3)
20
- 019 100 (720,1280,3)
21
- 020 100 (720,1280,3)
22
- 021 100 (720,1280,3)
23
- 022 100 (720,1280,3)
24
- 023 100 (720,1280,3)
25
- 024 100 (720,1280,3)
26
- 025 100 (720,1280,3)
27
- 026 100 (720,1280,3)
28
- 027 100 (720,1280,3)
29
- 028 100 (720,1280,3)
30
- 029 100 (720,1280,3)
31
- 030 100 (720,1280,3)
32
- 031 100 (720,1280,3)
33
- 032 100 (720,1280,3)
34
- 033 100 (720,1280,3)
35
- 034 100 (720,1280,3)
36
- 035 100 (720,1280,3)
37
- 036 100 (720,1280,3)
38
- 037 100 (720,1280,3)
39
- 038 100 (720,1280,3)
40
- 039 100 (720,1280,3)
41
- 040 100 (720,1280,3)
42
- 041 100 (720,1280,3)
43
- 042 100 (720,1280,3)
44
- 043 100 (720,1280,3)
45
- 044 100 (720,1280,3)
46
- 045 100 (720,1280,3)
47
- 046 100 (720,1280,3)
48
- 047 100 (720,1280,3)
49
- 048 100 (720,1280,3)
50
- 049 100 (720,1280,3)
51
- 050 100 (720,1280,3)
52
- 051 100 (720,1280,3)
53
- 052 100 (720,1280,3)
54
- 053 100 (720,1280,3)
55
- 054 100 (720,1280,3)
56
- 055 100 (720,1280,3)
57
- 056 100 (720,1280,3)
58
- 057 100 (720,1280,3)
59
- 058 100 (720,1280,3)
60
- 059 100 (720,1280,3)
61
- 060 100 (720,1280,3)
62
- 061 100 (720,1280,3)
63
- 062 100 (720,1280,3)
64
- 063 100 (720,1280,3)
65
- 064 100 (720,1280,3)
66
- 065 100 (720,1280,3)
67
- 066 100 (720,1280,3)
68
- 067 100 (720,1280,3)
69
- 068 100 (720,1280,3)
70
- 069 100 (720,1280,3)
71
- 070 100 (720,1280,3)
72
- 071 100 (720,1280,3)
73
- 072 100 (720,1280,3)
74
- 073 100 (720,1280,3)
75
- 074 100 (720,1280,3)
76
- 075 100 (720,1280,3)
77
- 076 100 (720,1280,3)
78
- 077 100 (720,1280,3)
79
- 078 100 (720,1280,3)
80
- 079 100 (720,1280,3)
81
- 080 100 (720,1280,3)
82
- 081 100 (720,1280,3)
83
- 082 100 (720,1280,3)
84
- 083 100 (720,1280,3)
85
- 084 100 (720,1280,3)
86
- 085 100 (720,1280,3)
87
- 086 100 (720,1280,3)
88
- 087 100 (720,1280,3)
89
- 088 100 (720,1280,3)
90
- 089 100 (720,1280,3)
91
- 090 100 (720,1280,3)
92
- 091 100 (720,1280,3)
93
- 092 100 (720,1280,3)
94
- 093 100 (720,1280,3)
95
- 094 100 (720,1280,3)
96
- 095 100 (720,1280,3)
97
- 096 100 (720,1280,3)
98
- 097 100 (720,1280,3)
99
- 098 100 (720,1280,3)
100
- 099 100 (720,1280,3)
101
- 100 100 (720,1280,3)
102
- 101 100 (720,1280,3)
103
- 102 100 (720,1280,3)
104
- 103 100 (720,1280,3)
105
- 104 100 (720,1280,3)
106
- 105 100 (720,1280,3)
107
- 106 100 (720,1280,3)
108
- 107 100 (720,1280,3)
109
- 108 100 (720,1280,3)
110
- 109 100 (720,1280,3)
111
- 110 100 (720,1280,3)
112
- 111 100 (720,1280,3)
113
- 112 100 (720,1280,3)
114
- 113 100 (720,1280,3)
115
- 114 100 (720,1280,3)
116
- 115 100 (720,1280,3)
117
- 116 100 (720,1280,3)
118
- 117 100 (720,1280,3)
119
- 118 100 (720,1280,3)
120
- 119 100 (720,1280,3)
121
- 120 100 (720,1280,3)
122
- 121 100 (720,1280,3)
123
- 122 100 (720,1280,3)
124
- 123 100 (720,1280,3)
125
- 124 100 (720,1280,3)
126
- 125 100 (720,1280,3)
127
- 126 100 (720,1280,3)
128
- 127 100 (720,1280,3)
129
- 128 100 (720,1280,3)
130
- 129 100 (720,1280,3)
131
- 130 100 (720,1280,3)
132
- 131 100 (720,1280,3)
133
- 132 100 (720,1280,3)
134
- 133 100 (720,1280,3)
135
- 134 100 (720,1280,3)
136
- 135 100 (720,1280,3)
137
- 136 100 (720,1280,3)
138
- 137 100 (720,1280,3)
139
- 138 100 (720,1280,3)
140
- 139 100 (720,1280,3)
141
- 140 100 (720,1280,3)
142
- 141 100 (720,1280,3)
143
- 142 100 (720,1280,3)
144
- 143 100 (720,1280,3)
145
- 144 100 (720,1280,3)
146
- 145 100 (720,1280,3)
147
- 146 100 (720,1280,3)
148
- 147 100 (720,1280,3)
149
- 148 100 (720,1280,3)
150
- 149 100 (720,1280,3)
151
- 150 100 (720,1280,3)
152
- 151 100 (720,1280,3)
153
- 152 100 (720,1280,3)
154
- 153 100 (720,1280,3)
155
- 154 100 (720,1280,3)
156
- 155 100 (720,1280,3)
157
- 156 100 (720,1280,3)
158
- 157 100 (720,1280,3)
159
- 158 100 (720,1280,3)
160
- 159 100 (720,1280,3)
161
- 160 100 (720,1280,3)
162
- 161 100 (720,1280,3)
163
- 162 100 (720,1280,3)
164
- 163 100 (720,1280,3)
165
- 164 100 (720,1280,3)
166
- 165 100 (720,1280,3)
167
- 166 100 (720,1280,3)
168
- 167 100 (720,1280,3)
169
- 168 100 (720,1280,3)
170
- 169 100 (720,1280,3)
171
- 170 100 (720,1280,3)
172
- 171 100 (720,1280,3)
173
- 172 100 (720,1280,3)
174
- 173 100 (720,1280,3)
175
- 174 100 (720,1280,3)
176
- 175 100 (720,1280,3)
177
- 176 100 (720,1280,3)
178
- 177 100 (720,1280,3)
179
- 178 100 (720,1280,3)
180
- 179 100 (720,1280,3)
181
- 180 100 (720,1280,3)
182
- 181 100 (720,1280,3)
183
- 182 100 (720,1280,3)
184
- 183 100 (720,1280,3)
185
- 184 100 (720,1280,3)
186
- 185 100 (720,1280,3)
187
- 186 100 (720,1280,3)
188
- 187 100 (720,1280,3)
189
- 188 100 (720,1280,3)
190
- 189 100 (720,1280,3)
191
- 190 100 (720,1280,3)
192
- 191 100 (720,1280,3)
193
- 192 100 (720,1280,3)
194
- 193 100 (720,1280,3)
195
- 194 100 (720,1280,3)
196
- 195 100 (720,1280,3)
197
- 196 100 (720,1280,3)
198
- 197 100 (720,1280,3)
199
- 198 100 (720,1280,3)
200
- 199 100 (720,1280,3)
201
- 200 100 (720,1280,3)
202
- 201 100 (720,1280,3)
203
- 202 100 (720,1280,3)
204
- 203 100 (720,1280,3)
205
- 204 100 (720,1280,3)
206
- 205 100 (720,1280,3)
207
- 206 100 (720,1280,3)
208
- 207 100 (720,1280,3)
209
- 208 100 (720,1280,3)
210
- 209 100 (720,1280,3)
211
- 210 100 (720,1280,3)
212
- 211 100 (720,1280,3)
213
- 212 100 (720,1280,3)
214
- 213 100 (720,1280,3)
215
- 214 100 (720,1280,3)
216
- 215 100 (720,1280,3)
217
- 216 100 (720,1280,3)
218
- 217 100 (720,1280,3)
219
- 218 100 (720,1280,3)
220
- 219 100 (720,1280,3)
221
- 220 100 (720,1280,3)
222
- 221 100 (720,1280,3)
223
- 222 100 (720,1280,3)
224
- 223 100 (720,1280,3)
225
- 224 100 (720,1280,3)
226
- 225 100 (720,1280,3)
227
- 226 100 (720,1280,3)
228
- 227 100 (720,1280,3)
229
- 228 100 (720,1280,3)
230
- 229 100 (720,1280,3)
231
- 230 100 (720,1280,3)
232
- 231 100 (720,1280,3)
233
- 232 100 (720,1280,3)
234
- 233 100 (720,1280,3)
235
- 234 100 (720,1280,3)
236
- 235 100 (720,1280,3)
237
- 236 100 (720,1280,3)
238
- 237 100 (720,1280,3)
239
- 238 100 (720,1280,3)
240
- 239 100 (720,1280,3)
241
- 240 100 (720,1280,3)
242
- 241 100 (720,1280,3)
243
- 242 100 (720,1280,3)
244
- 243 100 (720,1280,3)
245
- 244 100 (720,1280,3)
246
- 245 100 (720,1280,3)
247
- 246 100 (720,1280,3)
248
- 247 100 (720,1280,3)
249
- 248 100 (720,1280,3)
250
- 249 100 (720,1280,3)
251
- 250 100 (720,1280,3)
252
- 251 100 (720,1280,3)
253
- 252 100 (720,1280,3)
254
- 253 100 (720,1280,3)
255
- 254 100 (720,1280,3)
256
- 255 100 (720,1280,3)
257
- 256 100 (720,1280,3)
258
- 257 100 (720,1280,3)
259
- 258 100 (720,1280,3)
260
- 259 100 (720,1280,3)
261
- 260 100 (720,1280,3)
262
- 261 100 (720,1280,3)
263
- 262 100 (720,1280,3)
264
- 263 100 (720,1280,3)
265
- 264 100 (720,1280,3)
266
- 265 100 (720,1280,3)
267
- 266 100 (720,1280,3)
268
- 267 100 (720,1280,3)
269
- 268 100 (720,1280,3)
270
- 269 100 (720,1280,3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/meta_info/meta_info_REDSofficial4_test_GT.txt DELETED
@@ -1,4 +0,0 @@
1
- 240 100 (720,1280,3)
2
- 241 100 (720,1280,3)
3
- 246 100 (720,1280,3)
4
- 257 100 (720,1280,3)
 
 
 
 
 
basicsr/data/meta_info/meta_info_REDSval_official_test_GT.txt DELETED
@@ -1,30 +0,0 @@
1
- 240 100 (720,1280,3)
2
- 241 100 (720,1280,3)
3
- 242 100 (720,1280,3)
4
- 243 100 (720,1280,3)
5
- 244 100 (720,1280,3)
6
- 245 100 (720,1280,3)
7
- 246 100 (720,1280,3)
8
- 247 100 (720,1280,3)
9
- 248 100 (720,1280,3)
10
- 249 100 (720,1280,3)
11
- 250 100 (720,1280,3)
12
- 251 100 (720,1280,3)
13
- 252 100 (720,1280,3)
14
- 253 100 (720,1280,3)
15
- 254 100 (720,1280,3)
16
- 255 100 (720,1280,3)
17
- 256 100 (720,1280,3)
18
- 257 100 (720,1280,3)
19
- 258 100 (720,1280,3)
20
- 259 100 (720,1280,3)
21
- 260 100 (720,1280,3)
22
- 261 100 (720,1280,3)
23
- 262 100 (720,1280,3)
24
- 263 100 (720,1280,3)
25
- 264 100 (720,1280,3)
26
- 265 100 (720,1280,3)
27
- 266 100 (720,1280,3)
28
- 267 100 (720,1280,3)
29
- 268 100 (720,1280,3)
30
- 269 100 (720,1280,3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/meta_info/meta_info_Vimeo90K_test_GT.txt DELETED
The diff for this file is too large to render. See raw diff
 
basicsr/data/meta_info/meta_info_Vimeo90K_test_fast_GT.txt DELETED
@@ -1,1225 +0,0 @@
1
- 00001/0625 7 (256,448,3)
2
- 00001/0632 7 (256,448,3)
3
- 00001/0807 7 (256,448,3)
4
- 00001/0832 7 (256,448,3)
5
- 00001/0834 7 (256,448,3)
6
- 00001/0836 7 (256,448,3)
7
- 00002/0004 7 (256,448,3)
8
- 00002/0112 7 (256,448,3)
9
- 00002/0116 7 (256,448,3)
10
- 00002/0123 7 (256,448,3)
11
- 00002/0455 7 (256,448,3)
12
- 00002/0602 7 (256,448,3)
13
- 00002/0976 7 (256,448,3)
14
- 00002/0980 7 (256,448,3)
15
- 00002/0983 7 (256,448,3)
16
- 00002/1000 7 (256,448,3)
17
- 00003/0022 7 (256,448,3)
18
- 00003/0031 7 (256,448,3)
19
- 00003/0035 7 (256,448,3)
20
- 00003/0041 7 (256,448,3)
21
- 00003/0073 7 (256,448,3)
22
- 00003/0107 7 (256,448,3)
23
- 00003/0111 7 (256,448,3)
24
- 00003/0114 7 (256,448,3)
25
- 00003/0117 7 (256,448,3)
26
- 00003/0121 7 (256,448,3)
27
- 00003/0499 7 (256,448,3)
28
- 00003/0501 7 (256,448,3)
29
- 00003/0507 7 (256,448,3)
30
- 00003/0510 7 (256,448,3)
31
- 00003/0517 7 (256,448,3)
32
- 00003/0522 7 (256,448,3)
33
- 00003/0531 7 (256,448,3)
34
- 00003/0533 7 (256,448,3)
35
- 00003/0534 7 (256,448,3)
36
- 00003/0682 7 (256,448,3)
37
- 00003/0687 7 (256,448,3)
38
- 00003/0715 7 (256,448,3)
39
- 00003/0742 7 (256,448,3)
40
- 00003/0751 7 (256,448,3)
41
- 00003/0984 7 (256,448,3)
42
- 00004/0042 7 (256,448,3)
43
- 00004/0165 7 (256,448,3)
44
- 00004/0321 7 (256,448,3)
45
- 00004/0569 7 (256,448,3)
46
- 00004/0572 7 (256,448,3)
47
- 00004/0619 7 (256,448,3)
48
- 00004/0776 7 (256,448,3)
49
- 00004/0780 7 (256,448,3)
50
- 00004/0825 7 (256,448,3)
51
- 00004/0832 7 (256,448,3)
52
- 00004/0853 7 (256,448,3)
53
- 00004/0876 7 (256,448,3)
54
- 00004/0888 7 (256,448,3)
55
- 00005/0015 7 (256,448,3)
56
- 00005/0021 7 (256,448,3)
57
- 00005/0022 7 (256,448,3)
58
- 00005/0024 7 (256,448,3)
59
- 00005/0026 7 (256,448,3)
60
- 00005/0394 7 (256,448,3)
61
- 00005/0403 7 (256,448,3)
62
- 00005/0531 7 (256,448,3)
63
- 00005/0546 7 (256,448,3)
64
- 00005/0554 7 (256,448,3)
65
- 00005/0694 7 (256,448,3)
66
- 00005/0700 7 (256,448,3)
67
- 00005/0740 7 (256,448,3)
68
- 00005/0826 7 (256,448,3)
69
- 00005/0832 7 (256,448,3)
70
- 00005/0834 7 (256,448,3)
71
- 00005/0943 7 (256,448,3)
72
- 00006/0184 7 (256,448,3)
73
- 00006/0205 7 (256,448,3)
74
- 00006/0206 7 (256,448,3)
75
- 00006/0211 7 (256,448,3)
76
- 00006/0271 7 (256,448,3)
77
- 00006/0273 7 (256,448,3)
78
- 00006/0277 7 (256,448,3)
79
- 00006/0283 7 (256,448,3)
80
- 00006/0287 7 (256,448,3)
81
- 00006/0298 7 (256,448,3)
82
- 00006/0310 7 (256,448,3)
83
- 00006/0356 7 (256,448,3)
84
- 00006/0357 7 (256,448,3)
85
- 00006/0544 7 (256,448,3)
86
- 00006/0565 7 (256,448,3)
87
- 00006/0569 7 (256,448,3)
88
- 00006/0573 7 (256,448,3)
89
- 00006/0592 7 (256,448,3)
90
- 00006/0613 7 (256,448,3)
91
- 00006/0633 7 (256,448,3)
92
- 00006/0637 7 (256,448,3)
93
- 00006/0646 7 (256,448,3)
94
- 00006/0649 7 (256,448,3)
95
- 00006/0655 7 (256,448,3)
96
- 00006/0658 7 (256,448,3)
97
- 00006/0662 7 (256,448,3)
98
- 00006/0666 7 (256,448,3)
99
- 00006/0673 7 (256,448,3)
100
- 00007/0248 7 (256,448,3)
101
- 00007/0253 7 (256,448,3)
102
- 00007/0430 7 (256,448,3)
103
- 00007/0434 7 (256,448,3)
104
- 00007/0436 7 (256,448,3)
105
- 00007/0452 7 (256,448,3)
106
- 00007/0464 7 (256,448,3)
107
- 00007/0470 7 (256,448,3)
108
- 00007/0472 7 (256,448,3)
109
- 00007/0483 7 (256,448,3)
110
- 00007/0484 7 (256,448,3)
111
- 00007/0493 7 (256,448,3)
112
- 00007/0508 7 (256,448,3)
113
- 00007/0514 7 (256,448,3)
114
- 00007/0697 7 (256,448,3)
115
- 00007/0698 7 (256,448,3)
116
- 00007/0744 7 (256,448,3)
117
- 00007/0775 7 (256,448,3)
118
- 00007/0786 7 (256,448,3)
119
- 00007/0790 7 (256,448,3)
120
- 00007/0800 7 (256,448,3)
121
- 00007/0833 7 (256,448,3)
122
- 00007/0867 7 (256,448,3)
123
- 00007/0879 7 (256,448,3)
124
- 00007/0899 7 (256,448,3)
125
- 00008/0251 7 (256,448,3)
126
- 00008/0322 7 (256,448,3)
127
- 00008/0971 7 (256,448,3)
128
- 00008/0976 7 (256,448,3)
129
- 00009/0016 7 (256,448,3)
130
- 00009/0036 7 (256,448,3)
131
- 00009/0037 7 (256,448,3)
132
- 00009/0609 7 (256,448,3)
133
- 00009/0812 7 (256,448,3)
134
- 00009/0821 7 (256,448,3)
135
- 00009/0947 7 (256,448,3)
136
- 00009/0952 7 (256,448,3)
137
- 00009/0955 7 (256,448,3)
138
- 00009/0970 7 (256,448,3)
139
- 00010/0072 7 (256,448,3)
140
- 00010/0074 7 (256,448,3)
141
- 00010/0079 7 (256,448,3)
142
- 00010/0085 7 (256,448,3)
143
- 00010/0139 7 (256,448,3)
144
- 00010/0140 7 (256,448,3)
145
- 00010/0183 7 (256,448,3)
146
- 00010/0200 7 (256,448,3)
147
- 00010/0223 7 (256,448,3)
148
- 00010/0305 7 (256,448,3)
149
- 00010/0323 7 (256,448,3)
150
- 00010/0338 7 (256,448,3)
151
- 00010/0342 7 (256,448,3)
152
- 00010/0350 7 (256,448,3)
153
- 00010/0356 7 (256,448,3)
154
- 00010/0362 7 (256,448,3)
155
- 00010/0366 7 (256,448,3)
156
- 00010/0375 7 (256,448,3)
157
- 00010/0404 7 (256,448,3)
158
- 00010/0407 7 (256,448,3)
159
- 00010/0414 7 (256,448,3)
160
- 00010/0418 7 (256,448,3)
161
- 00010/0429 7 (256,448,3)
162
- 00010/0557 7 (256,448,3)
163
- 00010/0564 7 (256,448,3)
164
- 00010/0733 7 (256,448,3)
165
- 00010/0935 7 (256,448,3)
166
- 00010/0939 7 (256,448,3)
167
- 00010/0943 7 (256,448,3)
168
- 00011/0242 7 (256,448,3)
169
- 00011/0259 7 (256,448,3)
170
- 00011/0263 7 (256,448,3)
171
- 00011/0266 7 (256,448,3)
172
- 00011/0278 7 (256,448,3)
173
- 00011/0890 7 (256,448,3)
174
- 00011/0894 7 (256,448,3)
175
- 00011/0903 7 (256,448,3)
176
- 00011/0906 7 (256,448,3)
177
- 00011/0913 7 (256,448,3)
178
- 00012/0011 7 (256,448,3)
179
- 00012/0014 7 (256,448,3)
180
- 00012/0126 7 (256,448,3)
181
- 00012/0127 7 (256,448,3)
182
- 00012/0526 7 (256,448,3)
183
- 00012/0551 7 (256,448,3)
184
- 00012/0896 7 (256,448,3)
185
- 00012/0910 7 (256,448,3)
186
- 00012/0915 7 (256,448,3)
187
- 00013/0167 7 (256,448,3)
188
- 00013/0794 7 (256,448,3)
189
- 00013/0807 7 (256,448,3)
190
- 00013/0846 7 (256,448,3)
191
- 00013/0882 7 (256,448,3)
192
- 00013/0889 7 (256,448,3)
193
- 00013/0910 7 (256,448,3)
194
- 00013/0913 7 (256,448,3)
195
- 00013/0924 7 (256,448,3)
196
- 00013/0931 7 (256,448,3)
197
- 00013/0944 7 (256,448,3)
198
- 00013/0955 7 (256,448,3)
199
- 00013/0962 7 (256,448,3)
200
- 00013/0969 7 (256,448,3)
201
- 00014/0012 7 (256,448,3)
202
- 00014/0025 7 (256,448,3)
203
- 00014/0473 7 (256,448,3)
204
- 00014/0499 7 (256,448,3)
205
- 00014/0524 7 (256,448,3)
206
- 00014/0739 7 (256,448,3)
207
- 00014/0753 7 (256,448,3)
208
- 00014/0771 7 (256,448,3)
209
- 00014/0832 7 (256,448,3)
210
- 00014/0836 7 (256,448,3)
211
- 00014/0838 7 (256,448,3)
212
- 00014/0839 7 (256,448,3)
213
- 00014/0843 7 (256,448,3)
214
- 00014/0846 7 (256,448,3)
215
- 00014/0849 7 (256,448,3)
216
- 00014/0859 7 (256,448,3)
217
- 00014/0880 7 (256,448,3)
218
- 00014/0906 7 (256,448,3)
219
- 00015/0030 7 (256,448,3)
220
- 00015/0067 7 (256,448,3)
221
- 00015/0084 7 (256,448,3)
222
- 00015/0190 7 (256,448,3)
223
- 00015/0575 7 (256,448,3)
224
- 00015/0784 7 (256,448,3)
225
- 00015/0855 7 (256,448,3)
226
- 00015/0904 7 (256,448,3)
227
- 00015/0914 7 (256,448,3)
228
- 00015/0936 7 (256,448,3)
229
- 00015/0939 7 (256,448,3)
230
- 00015/0943 7 (256,448,3)
231
- 00015/0957 7 (256,448,3)
232
- 00016/0131 7 (256,448,3)
233
- 00016/0173 7 (256,448,3)
234
- 00016/0320 7 (256,448,3)
235
- 00016/0328 7 (256,448,3)
236
- 00016/0334 7 (256,448,3)
237
- 00016/0338 7 (256,448,3)
238
- 00016/0339 7 (256,448,3)
239
- 00016/0345 7 (256,448,3)
240
- 00016/0365 7 (256,448,3)
241
- 00016/0584 7 (256,448,3)
242
- 00016/0634 7 (256,448,3)
243
- 00017/0342 7 (256,448,3)
244
- 00017/0346 7 (256,448,3)
245
- 00017/0350 7 (256,448,3)
246
- 00017/0766 7 (256,448,3)
247
- 00017/0786 7 (256,448,3)
248
- 00017/0911 7 (256,448,3)
249
- 00017/0914 7 (256,448,3)
250
- 00018/0217 7 (256,448,3)
251
- 00018/0258 7 (256,448,3)
252
- 00018/0307 7 (256,448,3)
253
- 00018/0480 7 (256,448,3)
254
- 00018/0491 7 (256,448,3)
255
- 00018/0994 7 (256,448,3)
256
- 00018/0995 7 (256,448,3)
257
- 00018/0997 7 (256,448,3)
258
- 00018/1000 7 (256,448,3)
259
- 00019/0007 7 (256,448,3)
260
- 00019/0016 7 (256,448,3)
261
- 00019/0026 7 (256,448,3)
262
- 00019/0030 7 (256,448,3)
263
- 00019/0086 7 (256,448,3)
264
- 00019/0089 7 (256,448,3)
265
- 00019/0111 7 (256,448,3)
266
- 00019/0285 7 (256,448,3)
267
- 00019/0415 7 (256,448,3)
268
- 00019/0434 7 (256,448,3)
269
- 00019/0437 7 (256,448,3)
270
- 00019/0568 7 (256,448,3)
271
- 00019/0570 7 (256,448,3)
272
- 00019/0591 7 (256,448,3)
273
- 00019/0596 7 (256,448,3)
274
- 00019/0603 7 (256,448,3)
275
- 00019/0607 7 (256,448,3)
276
- 00019/0637 7 (256,448,3)
277
- 00019/0644 7 (256,448,3)
278
- 00019/0647 7 (256,448,3)
279
- 00019/0787 7 (256,448,3)
280
- 00019/0993 7 (256,448,3)
281
- 00019/0998 7 (256,448,3)
282
- 00021/0232 7 (256,448,3)
283
- 00021/0255 7 (256,448,3)
284
- 00021/0646 7 (256,448,3)
285
- 00021/0653 7 (256,448,3)
286
- 00021/0657 7 (256,448,3)
287
- 00021/0668 7 (256,448,3)
288
- 00021/0672 7 (256,448,3)
289
- 00021/0725 7 (256,448,3)
290
- 00021/0750 7 (256,448,3)
291
- 00021/0764 7 (256,448,3)
292
- 00021/0821 7 (256,448,3)
293
- 00022/0192 7 (256,448,3)
294
- 00022/0391 7 (256,448,3)
295
- 00022/0514 7 (256,448,3)
296
- 00022/0567 7 (256,448,3)
297
- 00022/0674 7 (256,448,3)
298
- 00022/0686 7 (256,448,3)
299
- 00022/0700 7 (256,448,3)
300
- 00023/0020 7 (256,448,3)
301
- 00023/0024 7 (256,448,3)
302
- 00023/0025 7 (256,448,3)
303
- 00023/0042 7 (256,448,3)
304
- 00023/0050 7 (256,448,3)
305
- 00023/0094 7 (256,448,3)
306
- 00023/0107 7 (256,448,3)
307
- 00023/0635 7 (256,448,3)
308
- 00023/0698 7 (256,448,3)
309
- 00023/0774 7 (256,448,3)
310
- 00023/0795 7 (256,448,3)
311
- 00023/0821 7 (256,448,3)
312
- 00023/0839 7 (256,448,3)
313
- 00023/0846 7 (256,448,3)
314
- 00023/0869 7 (256,448,3)
315
- 00023/0879 7 (256,448,3)
316
- 00023/0887 7 (256,448,3)
317
- 00023/0899 7 (256,448,3)
318
- 00023/0910 7 (256,448,3)
319
- 00023/0920 7 (256,448,3)
320
- 00023/0929 7 (256,448,3)
321
- 00023/0941 7 (256,448,3)
322
- 00023/0942 7 (256,448,3)
323
- 00023/0952 7 (256,448,3)
324
- 00024/0066 7 (256,448,3)
325
- 00024/0072 7 (256,448,3)
326
- 00024/0080 7 (256,448,3)
327
- 00024/0093 7 (256,448,3)
328
- 00024/0107 7 (256,448,3)
329
- 00024/0262 7 (256,448,3)
330
- 00024/0283 7 (256,448,3)
331
- 00024/0294 7 (256,448,3)
332
- 00024/0296 7 (256,448,3)
333
- 00024/0304 7 (256,448,3)
334
- 00024/0315 7 (256,448,3)
335
- 00024/0322 7 (256,448,3)
336
- 00024/0648 7 (256,448,3)
337
- 00024/0738 7 (256,448,3)
338
- 00024/0743 7 (256,448,3)
339
- 00025/0542 7 (256,448,3)
340
- 00025/0769 7 (256,448,3)
341
- 00025/0984 7 (256,448,3)
342
- 00025/0985 7 (256,448,3)
343
- 00025/0989 7 (256,448,3)
344
- 00025/0991 7 (256,448,3)
345
- 00026/0009 7 (256,448,3)
346
- 00026/0013 7 (256,448,3)
347
- 00026/0020 7 (256,448,3)
348
- 00026/0021 7 (256,448,3)
349
- 00026/0025 7 (256,448,3)
350
- 00026/0135 7 (256,448,3)
351
- 00026/0200 7 (256,448,3)
352
- 00026/0297 7 (256,448,3)
353
- 00026/0306 7 (256,448,3)
354
- 00026/0444 7 (256,448,3)
355
- 00026/0450 7 (256,448,3)
356
- 00026/0453 7 (256,448,3)
357
- 00026/0464 7 (256,448,3)
358
- 00026/0486 7 (256,448,3)
359
- 00026/0773 7 (256,448,3)
360
- 00026/0785 7 (256,448,3)
361
- 00026/0836 7 (256,448,3)
362
- 00026/0838 7 (256,448,3)
363
- 00026/0848 7 (256,448,3)
364
- 00026/0885 7 (256,448,3)
365
- 00026/0893 7 (256,448,3)
366
- 00026/0939 7 (256,448,3)
367
- 00026/0942 7 (256,448,3)
368
- 00027/0092 7 (256,448,3)
369
- 00027/0112 7 (256,448,3)
370
- 00027/0115 7 (256,448,3)
371
- 00027/0143 7 (256,448,3)
372
- 00027/0175 7 (256,448,3)
373
- 00027/0179 7 (256,448,3)
374
- 00027/0183 7 (256,448,3)
375
- 00027/0197 7 (256,448,3)
376
- 00027/0199 7 (256,448,3)
377
- 00027/0300 7 (256,448,3)
378
- 00028/0015 7 (256,448,3)
379
- 00028/0032 7 (256,448,3)
380
- 00028/0048 7 (256,448,3)
381
- 00028/0068 7 (256,448,3)
382
- 00028/0219 7 (256,448,3)
383
- 00028/0606 7 (256,448,3)
384
- 00028/0626 7 (256,448,3)
385
- 00028/0748 7 (256,448,3)
386
- 00028/0764 7 (256,448,3)
387
- 00028/0772 7 (256,448,3)
388
- 00028/0780 7 (256,448,3)
389
- 00028/0926 7 (256,448,3)
390
- 00028/0947 7 (256,448,3)
391
- 00028/0962 7 (256,448,3)
392
- 00029/0085 7 (256,448,3)
393
- 00029/0281 7 (256,448,3)
394
- 00029/0284 7 (256,448,3)
395
- 00029/0288 7 (256,448,3)
396
- 00029/0294 7 (256,448,3)
397
- 00029/0364 7 (256,448,3)
398
- 00029/0369 7 (256,448,3)
399
- 00029/0421 7 (256,448,3)
400
- 00029/0425 7 (256,448,3)
401
- 00029/0550 7 (256,448,3)
402
- 00030/0014 7 (256,448,3)
403
- 00030/0101 7 (256,448,3)
404
- 00030/0143 7 (256,448,3)
405
- 00030/0351 7 (256,448,3)
406
- 00030/0356 7 (256,448,3)
407
- 00030/0371 7 (256,448,3)
408
- 00030/0484 7 (256,448,3)
409
- 00030/0492 7 (256,448,3)
410
- 00030/0503 7 (256,448,3)
411
- 00030/0682 7 (256,448,3)
412
- 00030/0696 7 (256,448,3)
413
- 00030/0735 7 (256,448,3)
414
- 00030/0737 7 (256,448,3)
415
- 00030/0868 7 (256,448,3)
416
- 00031/0161 7 (256,448,3)
417
- 00031/0180 7 (256,448,3)
418
- 00031/0194 7 (256,448,3)
419
- 00031/0253 7 (256,448,3)
420
- 00031/0293 7 (256,448,3)
421
- 00031/0466 7 (256,448,3)
422
- 00031/0477 7 (256,448,3)
423
- 00031/0549 7 (256,448,3)
424
- 00031/0600 7 (256,448,3)
425
- 00031/0617 7 (256,448,3)
426
- 00031/0649 7 (256,448,3)
427
- 00032/0015 7 (256,448,3)
428
- 00032/0020 7 (256,448,3)
429
- 00032/0023 7 (256,448,3)
430
- 00032/0048 7 (256,448,3)
431
- 00032/0056 7 (256,448,3)
432
- 00032/0872 7 (256,448,3)
433
- 00033/0069 7 (256,448,3)
434
- 00033/0073 7 (256,448,3)
435
- 00033/0078 7 (256,448,3)
436
- 00033/0079 7 (256,448,3)
437
- 00033/0086 7 (256,448,3)
438
- 00033/0088 7 (256,448,3)
439
- 00033/0091 7 (256,448,3)
440
- 00033/0096 7 (256,448,3)
441
- 00033/0607 7 (256,448,3)
442
- 00033/0613 7 (256,448,3)
443
- 00033/0616 7 (256,448,3)
444
- 00033/0619 7 (256,448,3)
445
- 00033/0626 7 (256,448,3)
446
- 00033/0628 7 (256,448,3)
447
- 00033/0637 7 (256,448,3)
448
- 00033/0686 7 (256,448,3)
449
- 00033/0842 7 (256,448,3)
450
- 00034/0261 7 (256,448,3)
451
- 00034/0265 7 (256,448,3)
452
- 00034/0269 7 (256,448,3)
453
- 00034/0275 7 (256,448,3)
454
- 00034/0286 7 (256,448,3)
455
- 00034/0294 7 (256,448,3)
456
- 00034/0431 7 (256,448,3)
457
- 00034/0577 7 (256,448,3)
458
- 00034/0685 7 (256,448,3)
459
- 00034/0687 7 (256,448,3)
460
- 00034/0703 7 (256,448,3)
461
- 00034/0715 7 (256,448,3)
462
- 00034/0935 7 (256,448,3)
463
- 00034/0943 7 (256,448,3)
464
- 00034/0963 7 (256,448,3)
465
- 00034/0979 7 (256,448,3)
466
- 00034/0990 7 (256,448,3)
467
- 00035/0129 7 (256,448,3)
468
- 00035/0153 7 (256,448,3)
469
- 00035/0156 7 (256,448,3)
470
- 00035/0474 7 (256,448,3)
471
- 00035/0507 7 (256,448,3)
472
- 00035/0532 7 (256,448,3)
473
- 00035/0560 7 (256,448,3)
474
- 00035/0572 7 (256,448,3)
475
- 00035/0587 7 (256,448,3)
476
- 00035/0588 7 (256,448,3)
477
- 00035/0640 7 (256,448,3)
478
- 00035/0654 7 (256,448,3)
479
- 00035/0655 7 (256,448,3)
480
- 00035/0737 7 (256,448,3)
481
- 00035/0843 7 (256,448,3)
482
- 00035/0932 7 (256,448,3)
483
- 00035/0957 7 (256,448,3)
484
- 00036/0029 7 (256,448,3)
485
- 00036/0266 7 (256,448,3)
486
- 00036/0276 7 (256,448,3)
487
- 00036/0310 7 (256,448,3)
488
- 00036/0314 7 (256,448,3)
489
- 00036/0320 7 (256,448,3)
490
- 00036/0333 7 (256,448,3)
491
- 00036/0348 7 (256,448,3)
492
- 00036/0357 7 (256,448,3)
493
- 00036/0360 7 (256,448,3)
494
- 00036/0368 7 (256,448,3)
495
- 00036/0371 7 (256,448,3)
496
- 00036/0378 7 (256,448,3)
497
- 00036/0391 7 (256,448,3)
498
- 00036/0440 7 (256,448,3)
499
- 00036/0731 7 (256,448,3)
500
- 00036/0733 7 (256,448,3)
501
- 00036/0741 7 (256,448,3)
502
- 00036/0743 7 (256,448,3)
503
- 00036/0927 7 (256,448,3)
504
- 00036/0931 7 (256,448,3)
505
- 00036/0933 7 (256,448,3)
506
- 00036/0938 7 (256,448,3)
507
- 00036/0944 7 (256,448,3)
508
- 00036/0946 7 (256,448,3)
509
- 00036/0951 7 (256,448,3)
510
- 00036/0953 7 (256,448,3)
511
- 00036/0963 7 (256,448,3)
512
- 00036/0964 7 (256,448,3)
513
- 00036/0981 7 (256,448,3)
514
- 00036/0991 7 (256,448,3)
515
- 00037/0072 7 (256,448,3)
516
- 00037/0079 7 (256,448,3)
517
- 00037/0132 7 (256,448,3)
518
- 00037/0135 7 (256,448,3)
519
- 00037/0137 7 (256,448,3)
520
- 00037/0141 7 (256,448,3)
521
- 00037/0229 7 (256,448,3)
522
- 00037/0234 7 (256,448,3)
523
- 00037/0239 7 (256,448,3)
524
- 00037/0242 7 (256,448,3)
525
- 00037/0254 7 (256,448,3)
526
- 00037/0269 7 (256,448,3)
527
- 00037/0276 7 (256,448,3)
528
- 00037/0279 7 (256,448,3)
529
- 00037/0286 7 (256,448,3)
530
- 00037/0345 7 (256,448,3)
531
- 00037/0449 7 (256,448,3)
532
- 00037/0450 7 (256,448,3)
533
- 00037/0820 7 (256,448,3)
534
- 00037/0824 7 (256,448,3)
535
- 00037/0859 7 (256,448,3)
536
- 00037/0899 7 (256,448,3)
537
- 00037/0906 7 (256,448,3)
538
- 00038/0535 7 (256,448,3)
539
- 00038/0572 7 (256,448,3)
540
- 00038/0675 7 (256,448,3)
541
- 00038/0731 7 (256,448,3)
542
- 00038/0732 7 (256,448,3)
543
- 00038/0744 7 (256,448,3)
544
- 00038/0755 7 (256,448,3)
545
- 00039/0002 7 (256,448,3)
546
- 00039/0013 7 (256,448,3)
547
- 00039/0247 7 (256,448,3)
548
- 00039/0489 7 (256,448,3)
549
- 00039/0504 7 (256,448,3)
550
- 00039/0558 7 (256,448,3)
551
- 00039/0686 7 (256,448,3)
552
- 00039/0727 7 (256,448,3)
553
- 00039/0769 7 (256,448,3)
554
- 00040/0081 7 (256,448,3)
555
- 00040/0082 7 (256,448,3)
556
- 00040/0402 7 (256,448,3)
557
- 00040/0407 7 (256,448,3)
558
- 00040/0408 7 (256,448,3)
559
- 00040/0410 7 (256,448,3)
560
- 00040/0411 7 (256,448,3)
561
- 00040/0412 7 (256,448,3)
562
- 00040/0413 7 (256,448,3)
563
- 00040/0415 7 (256,448,3)
564
- 00040/0421 7 (256,448,3)
565
- 00040/0422 7 (256,448,3)
566
- 00040/0426 7 (256,448,3)
567
- 00040/0438 7 (256,448,3)
568
- 00040/0439 7 (256,448,3)
569
- 00040/0440 7 (256,448,3)
570
- 00040/0443 7 (256,448,3)
571
- 00040/0457 7 (256,448,3)
572
- 00040/0459 7 (256,448,3)
573
- 00040/0725 7 (256,448,3)
574
- 00040/0727 7 (256,448,3)
575
- 00040/0936 7 (256,448,3)
576
- 00040/0959 7 (256,448,3)
577
- 00040/0964 7 (256,448,3)
578
- 00040/0968 7 (256,448,3)
579
- 00040/0974 7 (256,448,3)
580
- 00040/0978 7 (256,448,3)
581
- 00040/0979 7 (256,448,3)
582
- 00040/0989 7 (256,448,3)
583
- 00040/0993 7 (256,448,3)
584
- 00040/0994 7 (256,448,3)
585
- 00040/0997 7 (256,448,3)
586
- 00041/0001 7 (256,448,3)
587
- 00041/0007 7 (256,448,3)
588
- 00041/0019 7 (256,448,3)
589
- 00041/0040 7 (256,448,3)
590
- 00041/0350 7 (256,448,3)
591
- 00041/0357 7 (256,448,3)
592
- 00041/0393 7 (256,448,3)
593
- 00041/0890 7 (256,448,3)
594
- 00041/0909 7 (256,448,3)
595
- 00041/0915 7 (256,448,3)
596
- 00041/0933 7 (256,448,3)
597
- 00042/0017 7 (256,448,3)
598
- 00042/0332 7 (256,448,3)
599
- 00042/0346 7 (256,448,3)
600
- 00042/0350 7 (256,448,3)
601
- 00042/0356 7 (256,448,3)
602
- 00042/0382 7 (256,448,3)
603
- 00042/0389 7 (256,448,3)
604
- 00042/0539 7 (256,448,3)
605
- 00042/0546 7 (256,448,3)
606
- 00042/0550 7 (256,448,3)
607
- 00042/0553 7 (256,448,3)
608
- 00042/0555 7 (256,448,3)
609
- 00042/0560 7 (256,448,3)
610
- 00042/0570 7 (256,448,3)
611
- 00043/0119 7 (256,448,3)
612
- 00043/0122 7 (256,448,3)
613
- 00043/0168 7 (256,448,3)
614
- 00043/0274 7 (256,448,3)
615
- 00043/0304 7 (256,448,3)
616
- 00043/0731 7 (256,448,3)
617
- 00043/0735 7 (256,448,3)
618
- 00043/0739 7 (256,448,3)
619
- 00043/0740 7 (256,448,3)
620
- 00044/0212 7 (256,448,3)
621
- 00044/0432 7 (256,448,3)
622
- 00044/0934 7 (256,448,3)
623
- 00044/0940 7 (256,448,3)
624
- 00044/0987 7 (256,448,3)
625
- 00045/0004 7 (256,448,3)
626
- 00045/0009 7 (256,448,3)
627
- 00045/0011 7 (256,448,3)
628
- 00045/0019 7 (256,448,3)
629
- 00045/0023 7 (256,448,3)
630
- 00045/0289 7 (256,448,3)
631
- 00045/0760 7 (256,448,3)
632
- 00045/0779 7 (256,448,3)
633
- 00045/0816 7 (256,448,3)
634
- 00045/0820 7 (256,448,3)
635
- 00046/0132 7 (256,448,3)
636
- 00046/0350 7 (256,448,3)
637
- 00046/0356 7 (256,448,3)
638
- 00046/0357 7 (256,448,3)
639
- 00046/0379 7 (256,448,3)
640
- 00046/0410 7 (256,448,3)
641
- 00046/0412 7 (256,448,3)
642
- 00046/0481 7 (256,448,3)
643
- 00046/0497 7 (256,448,3)
644
- 00046/0510 7 (256,448,3)
645
- 00046/0515 7 (256,448,3)
646
- 00046/0529 7 (256,448,3)
647
- 00046/0544 7 (256,448,3)
648
- 00046/0545 7 (256,448,3)
649
- 00046/0552 7 (256,448,3)
650
- 00046/0559 7 (256,448,3)
651
- 00046/0589 7 (256,448,3)
652
- 00046/0642 7 (256,448,3)
653
- 00046/0724 7 (256,448,3)
654
- 00046/0758 7 (256,448,3)
655
- 00046/0930 7 (256,448,3)
656
- 00046/0953 7 (256,448,3)
657
- 00047/0013 7 (256,448,3)
658
- 00047/0014 7 (256,448,3)
659
- 00047/0017 7 (256,448,3)
660
- 00047/0076 7 (256,448,3)
661
- 00047/0151 7 (256,448,3)
662
- 00047/0797 7 (256,448,3)
663
- 00048/0014 7 (256,448,3)
664
- 00048/0021 7 (256,448,3)
665
- 00048/0026 7 (256,448,3)
666
- 00048/0030 7 (256,448,3)
667
- 00048/0039 7 (256,448,3)
668
- 00048/0045 7 (256,448,3)
669
- 00048/0049 7 (256,448,3)
670
- 00048/0145 7 (256,448,3)
671
- 00048/0188 7 (256,448,3)
672
- 00048/0302 7 (256,448,3)
673
- 00048/0361 7 (256,448,3)
674
- 00048/0664 7 (256,448,3)
675
- 00048/0672 7 (256,448,3)
676
- 00048/0681 7 (256,448,3)
677
- 00048/0689 7 (256,448,3)
678
- 00048/0690 7 (256,448,3)
679
- 00048/0691 7 (256,448,3)
680
- 00048/0711 7 (256,448,3)
681
- 00049/0085 7 (256,448,3)
682
- 00049/0810 7 (256,448,3)
683
- 00049/0858 7 (256,448,3)
684
- 00049/0865 7 (256,448,3)
685
- 00049/0871 7 (256,448,3)
686
- 00049/0903 7 (256,448,3)
687
- 00049/0928 7 (256,448,3)
688
- 00050/0092 7 (256,448,3)
689
- 00050/0101 7 (256,448,3)
690
- 00050/0108 7 (256,448,3)
691
- 00050/0112 7 (256,448,3)
692
- 00050/0120 7 (256,448,3)
693
- 00050/0128 7 (256,448,3)
694
- 00050/0383 7 (256,448,3)
695
- 00050/0395 7 (256,448,3)
696
- 00050/0405 7 (256,448,3)
697
- 00050/0632 7 (256,448,3)
698
- 00050/0648 7 (256,448,3)
699
- 00050/0649 7 (256,448,3)
700
- 00050/0659 7 (256,448,3)
701
- 00050/0699 7 (256,448,3)
702
- 00050/0708 7 (256,448,3)
703
- 00050/0716 7 (256,448,3)
704
- 00050/0758 7 (256,448,3)
705
- 00050/0761 7 (256,448,3)
706
- 00051/0572 7 (256,448,3)
707
- 00052/0163 7 (256,448,3)
708
- 00052/0242 7 (256,448,3)
709
- 00052/0260 7 (256,448,3)
710
- 00052/0322 7 (256,448,3)
711
- 00052/0333 7 (256,448,3)
712
- 00052/0806 7 (256,448,3)
713
- 00052/0813 7 (256,448,3)
714
- 00052/0821 7 (256,448,3)
715
- 00052/0830 7 (256,448,3)
716
- 00052/0914 7 (256,448,3)
717
- 00052/0923 7 (256,448,3)
718
- 00052/0959 7 (256,448,3)
719
- 00053/0288 7 (256,448,3)
720
- 00053/0290 7 (256,448,3)
721
- 00053/0323 7 (256,448,3)
722
- 00053/0337 7 (256,448,3)
723
- 00053/0340 7 (256,448,3)
724
- 00053/0437 7 (256,448,3)
725
- 00053/0595 7 (256,448,3)
726
- 00053/0739 7 (256,448,3)
727
- 00053/0761 7 (256,448,3)
728
- 00054/0014 7 (256,448,3)
729
- 00054/0017 7 (256,448,3)
730
- 00054/0178 7 (256,448,3)
731
- 00054/0183 7 (256,448,3)
732
- 00054/0196 7 (256,448,3)
733
- 00054/0205 7 (256,448,3)
734
- 00054/0214 7 (256,448,3)
735
- 00054/0289 7 (256,448,3)
736
- 00054/0453 7 (256,448,3)
737
- 00054/0498 7 (256,448,3)
738
- 00054/0502 7 (256,448,3)
739
- 00054/0514 7 (256,448,3)
740
- 00054/0773 7 (256,448,3)
741
- 00055/0001 7 (256,448,3)
742
- 00055/0115 7 (256,448,3)
743
- 00055/0118 7 (256,448,3)
744
- 00055/0171 7 (256,448,3)
745
- 00055/0214 7 (256,448,3)
746
- 00055/0354 7 (256,448,3)
747
- 00055/0449 7 (256,448,3)
748
- 00055/0473 7 (256,448,3)
749
- 00055/0649 7 (256,448,3)
750
- 00055/0800 7 (256,448,3)
751
- 00055/0803 7 (256,448,3)
752
- 00055/0990 7 (256,448,3)
753
- 00056/0041 7 (256,448,3)
754
- 00056/0120 7 (256,448,3)
755
- 00056/0293 7 (256,448,3)
756
- 00056/0357 7 (256,448,3)
757
- 00056/0506 7 (256,448,3)
758
- 00056/0561 7 (256,448,3)
759
- 00056/0567 7 (256,448,3)
760
- 00056/0575 7 (256,448,3)
761
- 00057/0175 7 (256,448,3)
762
- 00057/0495 7 (256,448,3)
763
- 00057/0498 7 (256,448,3)
764
- 00057/0506 7 (256,448,3)
765
- 00057/0612 7 (256,448,3)
766
- 00057/0620 7 (256,448,3)
767
- 00057/0623 7 (256,448,3)
768
- 00057/0635 7 (256,448,3)
769
- 00057/0773 7 (256,448,3)
770
- 00057/0778 7 (256,448,3)
771
- 00057/0867 7 (256,448,3)
772
- 00057/0976 7 (256,448,3)
773
- 00057/0980 7 (256,448,3)
774
- 00057/0985 7 (256,448,3)
775
- 00057/0992 7 (256,448,3)
776
- 00058/0009 7 (256,448,3)
777
- 00058/0076 7 (256,448,3)
778
- 00058/0078 7 (256,448,3)
779
- 00058/0279 7 (256,448,3)
780
- 00058/0283 7 (256,448,3)
781
- 00058/0286 7 (256,448,3)
782
- 00058/0350 7 (256,448,3)
783
- 00058/0380 7 (256,448,3)
784
- 00061/0132 7 (256,448,3)
785
- 00061/0141 7 (256,448,3)
786
- 00061/0156 7 (256,448,3)
787
- 00061/0159 7 (256,448,3)
788
- 00061/0168 7 (256,448,3)
789
- 00061/0170 7 (256,448,3)
790
- 00061/0186 7 (256,448,3)
791
- 00061/0219 7 (256,448,3)
792
- 00061/0227 7 (256,448,3)
793
- 00061/0238 7 (256,448,3)
794
- 00061/0256 7 (256,448,3)
795
- 00061/0303 7 (256,448,3)
796
- 00061/0312 7 (256,448,3)
797
- 00061/0313 7 (256,448,3)
798
- 00061/0325 7 (256,448,3)
799
- 00061/0367 7 (256,448,3)
800
- 00061/0369 7 (256,448,3)
801
- 00061/0387 7 (256,448,3)
802
- 00061/0396 7 (256,448,3)
803
- 00061/0486 7 (256,448,3)
804
- 00061/0895 7 (256,448,3)
805
- 00061/0897 7 (256,448,3)
806
- 00062/0846 7 (256,448,3)
807
- 00063/0156 7 (256,448,3)
808
- 00063/0184 7 (256,448,3)
809
- 00063/0191 7 (256,448,3)
810
- 00063/0334 7 (256,448,3)
811
- 00063/0350 7 (256,448,3)
812
- 00063/0499 7 (256,448,3)
813
- 00063/0878 7 (256,448,3)
814
- 00064/0004 7 (256,448,3)
815
- 00064/0264 7 (256,448,3)
816
- 00064/0735 7 (256,448,3)
817
- 00064/0738 7 (256,448,3)
818
- 00065/0105 7 (256,448,3)
819
- 00065/0169 7 (256,448,3)
820
- 00065/0305 7 (256,448,3)
821
- 00065/0324 7 (256,448,3)
822
- 00065/0353 7 (256,448,3)
823
- 00065/0520 7 (256,448,3)
824
- 00065/0533 7 (256,448,3)
825
- 00065/0545 7 (256,448,3)
826
- 00065/0551 7 (256,448,3)
827
- 00065/0568 7 (256,448,3)
828
- 00065/0603 7 (256,448,3)
829
- 00065/0884 7 (256,448,3)
830
- 00065/0988 7 (256,448,3)
831
- 00066/0002 7 (256,448,3)
832
- 00066/0011 7 (256,448,3)
833
- 00066/0031 7 (256,448,3)
834
- 00066/0037 7 (256,448,3)
835
- 00066/0136 7 (256,448,3)
836
- 00066/0137 7 (256,448,3)
837
- 00066/0150 7 (256,448,3)
838
- 00066/0166 7 (256,448,3)
839
- 00066/0178 7 (256,448,3)
840
- 00066/0357 7 (256,448,3)
841
- 00066/0428 7 (256,448,3)
842
- 00066/0483 7 (256,448,3)
843
- 00066/0600 7 (256,448,3)
844
- 00066/0863 7 (256,448,3)
845
- 00066/0873 7 (256,448,3)
846
- 00066/0875 7 (256,448,3)
847
- 00066/0899 7 (256,448,3)
848
- 00067/0020 7 (256,448,3)
849
- 00067/0025 7 (256,448,3)
850
- 00067/0132 7 (256,448,3)
851
- 00067/0492 7 (256,448,3)
852
- 00067/0726 7 (256,448,3)
853
- 00067/0734 7 (256,448,3)
854
- 00067/0744 7 (256,448,3)
855
- 00067/0754 7 (256,448,3)
856
- 00067/0779 7 (256,448,3)
857
- 00068/0078 7 (256,448,3)
858
- 00068/0083 7 (256,448,3)
859
- 00068/0113 7 (256,448,3)
860
- 00068/0117 7 (256,448,3)
861
- 00068/0121 7 (256,448,3)
862
- 00068/0206 7 (256,448,3)
863
- 00068/0261 7 (256,448,3)
864
- 00068/0321 7 (256,448,3)
865
- 00068/0354 7 (256,448,3)
866
- 00068/0380 7 (256,448,3)
867
- 00068/0419 7 (256,448,3)
868
- 00068/0547 7 (256,448,3)
869
- 00068/0561 7 (256,448,3)
870
- 00068/0565 7 (256,448,3)
871
- 00068/0583 7 (256,448,3)
872
- 00068/0599 7 (256,448,3)
873
- 00068/0739 7 (256,448,3)
874
- 00068/0743 7 (256,448,3)
875
- 00068/0754 7 (256,448,3)
876
- 00068/0812 7 (256,448,3)
877
- 00069/0178 7 (256,448,3)
878
- 00070/0025 7 (256,448,3)
879
- 00070/0030 7 (256,448,3)
880
- 00070/0036 7 (256,448,3)
881
- 00070/0042 7 (256,448,3)
882
- 00070/0078 7 (256,448,3)
883
- 00070/0079 7 (256,448,3)
884
- 00070/0362 7 (256,448,3)
885
- 00071/0195 7 (256,448,3)
886
- 00071/0210 7 (256,448,3)
887
- 00071/0211 7 (256,448,3)
888
- 00071/0221 7 (256,448,3)
889
- 00071/0352 7 (256,448,3)
890
- 00071/0354 7 (256,448,3)
891
- 00071/0366 7 (256,448,3)
892
- 00071/0454 7 (256,448,3)
893
- 00071/0464 7 (256,448,3)
894
- 00071/0487 7 (256,448,3)
895
- 00071/0502 7 (256,448,3)
896
- 00071/0561 7 (256,448,3)
897
- 00071/0676 7 (256,448,3)
898
- 00071/0808 7 (256,448,3)
899
- 00071/0813 7 (256,448,3)
900
- 00071/0836 7 (256,448,3)
901
- 00072/0286 7 (256,448,3)
902
- 00072/0290 7 (256,448,3)
903
- 00072/0298 7 (256,448,3)
904
- 00072/0302 7 (256,448,3)
905
- 00072/0333 7 (256,448,3)
906
- 00072/0590 7 (256,448,3)
907
- 00072/0793 7 (256,448,3)
908
- 00072/0803 7 (256,448,3)
909
- 00072/0833 7 (256,448,3)
910
- 00073/0049 7 (256,448,3)
911
- 00073/0050 7 (256,448,3)
912
- 00073/0388 7 (256,448,3)
913
- 00073/0480 7 (256,448,3)
914
- 00073/0485 7 (256,448,3)
915
- 00073/0611 7 (256,448,3)
916
- 00073/0616 7 (256,448,3)
917
- 00073/0714 7 (256,448,3)
918
- 00073/0724 7 (256,448,3)
919
- 00073/0730 7 (256,448,3)
920
- 00074/0034 7 (256,448,3)
921
- 00074/0228 7 (256,448,3)
922
- 00074/0239 7 (256,448,3)
923
- 00074/0275 7 (256,448,3)
924
- 00074/0527 7 (256,448,3)
925
- 00074/0620 7 (256,448,3)
926
- 00074/0764 7 (256,448,3)
927
- 00074/0849 7 (256,448,3)
928
- 00074/0893 7 (256,448,3)
929
- 00075/0333 7 (256,448,3)
930
- 00075/0339 7 (256,448,3)
931
- 00075/0347 7 (256,448,3)
932
- 00075/0399 7 (256,448,3)
933
- 00075/0478 7 (256,448,3)
934
- 00075/0494 7 (256,448,3)
935
- 00075/0678 7 (256,448,3)
936
- 00075/0688 7 (256,448,3)
937
- 00075/0706 7 (256,448,3)
938
- 00075/0709 7 (256,448,3)
939
- 00075/0748 7 (256,448,3)
940
- 00075/0769 7 (256,448,3)
941
- 00075/0777 7 (256,448,3)
942
- 00075/0781 7 (256,448,3)
943
- 00076/0151 7 (256,448,3)
944
- 00076/0159 7 (256,448,3)
945
- 00076/0164 7 (256,448,3)
946
- 00076/0265 7 (256,448,3)
947
- 00076/0269 7 (256,448,3)
948
- 00076/0433 7 (256,448,3)
949
- 00076/0813 7 (256,448,3)
950
- 00076/0817 7 (256,448,3)
951
- 00076/0818 7 (256,448,3)
952
- 00076/0827 7 (256,448,3)
953
- 00076/0874 7 (256,448,3)
954
- 00076/0880 7 (256,448,3)
955
- 00076/0891 7 (256,448,3)
956
- 00076/0894 7 (256,448,3)
957
- 00076/0909 7 (256,448,3)
958
- 00076/0913 7 (256,448,3)
959
- 00076/0926 7 (256,448,3)
960
- 00076/0962 7 (256,448,3)
961
- 00076/0973 7 (256,448,3)
962
- 00076/0986 7 (256,448,3)
963
- 00077/0617 7 (256,448,3)
964
- 00077/0623 7 (256,448,3)
965
- 00077/0628 7 (256,448,3)
966
- 00077/0629 7 (256,448,3)
967
- 00077/0631 7 (256,448,3)
968
- 00077/0639 7 (256,448,3)
969
- 00077/0982 7 (256,448,3)
970
- 00077/0984 7 (256,448,3)
971
- 00077/0995 7 (256,448,3)
972
- 00077/0998 7 (256,448,3)
973
- 00078/0001 7 (256,448,3)
974
- 00078/0015 7 (256,448,3)
975
- 00078/0157 7 (256,448,3)
976
- 00078/0161 7 (256,448,3)
977
- 00078/0175 7 (256,448,3)
978
- 00078/0178 7 (256,448,3)
979
- 00078/0189 7 (256,448,3)
980
- 00078/0192 7 (256,448,3)
981
- 00078/0229 7 (256,448,3)
982
- 00078/0237 7 (256,448,3)
983
- 00078/0241 7 (256,448,3)
984
- 00078/0249 7 (256,448,3)
985
- 00078/0251 7 (256,448,3)
986
- 00078/0254 7 (256,448,3)
987
- 00078/0258 7 (256,448,3)
988
- 00078/0311 7 (256,448,3)
989
- 00078/0603 7 (256,448,3)
990
- 00078/0607 7 (256,448,3)
991
- 00078/0824 7 (256,448,3)
992
- 00079/0045 7 (256,448,3)
993
- 00079/0048 7 (256,448,3)
994
- 00079/0054 7 (256,448,3)
995
- 00080/0050 7 (256,448,3)
996
- 00080/0488 7 (256,448,3)
997
- 00080/0494 7 (256,448,3)
998
- 00080/0496 7 (256,448,3)
999
- 00080/0499 7 (256,448,3)
1000
- 00080/0502 7 (256,448,3)
1001
- 00080/0510 7 (256,448,3)
1002
- 00080/0534 7 (256,448,3)
1003
- 00080/0558 7 (256,448,3)
1004
- 00080/0571 7 (256,448,3)
1005
- 00080/0709 7 (256,448,3)
1006
- 00080/0882 7 (256,448,3)
1007
- 00081/0322 7 (256,448,3)
1008
- 00081/0428 7 (256,448,3)
1009
- 00081/0700 7 (256,448,3)
1010
- 00081/0706 7 (256,448,3)
1011
- 00081/0707 7 (256,448,3)
1012
- 00081/0937 7 (256,448,3)
1013
- 00082/0021 7 (256,448,3)
1014
- 00082/0424 7 (256,448,3)
1015
- 00082/0794 7 (256,448,3)
1016
- 00082/0807 7 (256,448,3)
1017
- 00082/0810 7 (256,448,3)
1018
- 00082/0824 7 (256,448,3)
1019
- 00083/0129 7 (256,448,3)
1020
- 00083/0131 7 (256,448,3)
1021
- 00083/0249 7 (256,448,3)
1022
- 00083/0250 7 (256,448,3)
1023
- 00083/0656 7 (256,448,3)
1024
- 00083/0812 7 (256,448,3)
1025
- 00083/0819 7 (256,448,3)
1026
- 00083/0824 7 (256,448,3)
1027
- 00083/0827 7 (256,448,3)
1028
- 00083/0841 7 (256,448,3)
1029
- 00083/0963 7 (256,448,3)
1030
- 00084/0047 7 (256,448,3)
1031
- 00084/0319 7 (256,448,3)
1032
- 00084/0334 7 (256,448,3)
1033
- 00084/0363 7 (256,448,3)
1034
- 00084/0493 7 (256,448,3)
1035
- 00084/0655 7 (256,448,3)
1036
- 00084/0752 7 (256,448,3)
1037
- 00084/0813 7 (256,448,3)
1038
- 00084/0886 7 (256,448,3)
1039
- 00084/0948 7 (256,448,3)
1040
- 00084/0976 7 (256,448,3)
1041
- 00085/0512 7 (256,448,3)
1042
- 00085/0641 7 (256,448,3)
1043
- 00085/0653 7 (256,448,3)
1044
- 00085/0655 7 (256,448,3)
1045
- 00085/0697 7 (256,448,3)
1046
- 00085/0698 7 (256,448,3)
1047
- 00085/0700 7 (256,448,3)
1048
- 00085/0703 7 (256,448,3)
1049
- 00085/0705 7 (256,448,3)
1050
- 00085/0709 7 (256,448,3)
1051
- 00085/0713 7 (256,448,3)
1052
- 00085/0739 7 (256,448,3)
1053
- 00085/0750 7 (256,448,3)
1054
- 00085/0763 7 (256,448,3)
1055
- 00085/0765 7 (256,448,3)
1056
- 00085/0769 7 (256,448,3)
1057
- 00085/0863 7 (256,448,3)
1058
- 00085/0868 7 (256,448,3)
1059
- 00085/0927 7 (256,448,3)
1060
- 00085/0936 7 (256,448,3)
1061
- 00085/0965 7 (256,448,3)
1062
- 00085/0969 7 (256,448,3)
1063
- 00085/0974 7 (256,448,3)
1064
- 00085/0981 7 (256,448,3)
1065
- 00085/0982 7 (256,448,3)
1066
- 00085/1000 7 (256,448,3)
1067
- 00086/0003 7 (256,448,3)
1068
- 00086/0009 7 (256,448,3)
1069
- 00086/0011 7 (256,448,3)
1070
- 00086/0028 7 (256,448,3)
1071
- 00086/0032 7 (256,448,3)
1072
- 00086/0034 7 (256,448,3)
1073
- 00086/0035 7 (256,448,3)
1074
- 00086/0042 7 (256,448,3)
1075
- 00086/0064 7 (256,448,3)
1076
- 00086/0066 7 (256,448,3)
1077
- 00086/0095 7 (256,448,3)
1078
- 00086/0099 7 (256,448,3)
1079
- 00086/0101 7 (256,448,3)
1080
- 00086/0104 7 (256,448,3)
1081
- 00086/0115 7 (256,448,3)
1082
- 00086/0116 7 (256,448,3)
1083
- 00086/0284 7 (256,448,3)
1084
- 00086/0291 7 (256,448,3)
1085
- 00086/0295 7 (256,448,3)
1086
- 00086/0302 7 (256,448,3)
1087
- 00086/0318 7 (256,448,3)
1088
- 00086/0666 7 (256,448,3)
1089
- 00086/0797 7 (256,448,3)
1090
- 00086/0851 7 (256,448,3)
1091
- 00086/0855 7 (256,448,3)
1092
- 00086/0874 7 (256,448,3)
1093
- 00086/0878 7 (256,448,3)
1094
- 00086/0881 7 (256,448,3)
1095
- 00086/0883 7 (256,448,3)
1096
- 00086/0896 7 (256,448,3)
1097
- 00086/0899 7 (256,448,3)
1098
- 00086/0903 7 (256,448,3)
1099
- 00086/0989 7 (256,448,3)
1100
- 00087/0008 7 (256,448,3)
1101
- 00087/0429 7 (256,448,3)
1102
- 00087/0511 7 (256,448,3)
1103
- 00088/0241 7 (256,448,3)
1104
- 00088/0319 7 (256,448,3)
1105
- 00088/0323 7 (256,448,3)
1106
- 00088/0411 7 (256,448,3)
1107
- 00088/0427 7 (256,448,3)
1108
- 00088/0452 7 (256,448,3)
1109
- 00088/0463 7 (256,448,3)
1110
- 00088/0476 7 (256,448,3)
1111
- 00088/0496 7 (256,448,3)
1112
- 00088/0559 7 (256,448,3)
1113
- 00089/0058 7 (256,448,3)
1114
- 00089/0061 7 (256,448,3)
1115
- 00089/0069 7 (256,448,3)
1116
- 00089/0077 7 (256,448,3)
1117
- 00089/0096 7 (256,448,3)
1118
- 00089/0099 7 (256,448,3)
1119
- 00089/0100 7 (256,448,3)
1120
- 00089/0211 7 (256,448,3)
1121
- 00089/0380 7 (256,448,3)
1122
- 00089/0381 7 (256,448,3)
1123
- 00089/0384 7 (256,448,3)
1124
- 00089/0390 7 (256,448,3)
1125
- 00089/0393 7 (256,448,3)
1126
- 00089/0394 7 (256,448,3)
1127
- 00089/0395 7 (256,448,3)
1128
- 00089/0406 7 (256,448,3)
1129
- 00089/0410 7 (256,448,3)
1130
- 00089/0412 7 (256,448,3)
1131
- 00089/0703 7 (256,448,3)
1132
- 00089/0729 7 (256,448,3)
1133
- 00089/0930 7 (256,448,3)
1134
- 00089/0952 7 (256,448,3)
1135
- 00090/0062 7 (256,448,3)
1136
- 00090/0101 7 (256,448,3)
1137
- 00090/0213 7 (256,448,3)
1138
- 00090/0216 7 (256,448,3)
1139
- 00090/0268 7 (256,448,3)
1140
- 00090/0406 7 (256,448,3)
1141
- 00090/0411 7 (256,448,3)
1142
- 00090/0442 7 (256,448,3)
1143
- 00090/0535 7 (256,448,3)
1144
- 00090/0542 7 (256,448,3)
1145
- 00090/0571 7 (256,448,3)
1146
- 00090/0934 7 (256,448,3)
1147
- 00090/0938 7 (256,448,3)
1148
- 00090/0947 7 (256,448,3)
1149
- 00091/0066 7 (256,448,3)
1150
- 00091/0448 7 (256,448,3)
1151
- 00091/0451 7 (256,448,3)
1152
- 00091/0454 7 (256,448,3)
1153
- 00091/0457 7 (256,448,3)
1154
- 00091/0467 7 (256,448,3)
1155
- 00091/0470 7 (256,448,3)
1156
- 00091/0477 7 (256,448,3)
1157
- 00091/0583 7 (256,448,3)
1158
- 00091/0981 7 (256,448,3)
1159
- 00091/0994 7 (256,448,3)
1160
- 00092/0112 7 (256,448,3)
1161
- 00092/0119 7 (256,448,3)
1162
- 00092/0129 7 (256,448,3)
1163
- 00092/0146 7 (256,448,3)
1164
- 00092/0149 7 (256,448,3)
1165
- 00092/0608 7 (256,448,3)
1166
- 00092/0643 7 (256,448,3)
1167
- 00092/0646 7 (256,448,3)
1168
- 00092/0766 7 (256,448,3)
1169
- 00092/0768 7 (256,448,3)
1170
- 00092/0779 7 (256,448,3)
1171
- 00093/0081 7 (256,448,3)
1172
- 00093/0085 7 (256,448,3)
1173
- 00093/0135 7 (256,448,3)
1174
- 00093/0241 7 (256,448,3)
1175
- 00093/0277 7 (256,448,3)
1176
- 00093/0283 7 (256,448,3)
1177
- 00093/0320 7 (256,448,3)
1178
- 00093/0598 7 (256,448,3)
1179
- 00094/0159 7 (256,448,3)
1180
- 00094/0253 7 (256,448,3)
1181
- 00094/0265 7 (256,448,3)
1182
- 00094/0267 7 (256,448,3)
1183
- 00094/0269 7 (256,448,3)
1184
- 00094/0281 7 (256,448,3)
1185
- 00094/0293 7 (256,448,3)
1186
- 00094/0404 7 (256,448,3)
1187
- 00094/0593 7 (256,448,3)
1188
- 00094/0612 7 (256,448,3)
1189
- 00094/0638 7 (256,448,3)
1190
- 00094/0656 7 (256,448,3)
1191
- 00094/0668 7 (256,448,3)
1192
- 00094/0786 7 (256,448,3)
1193
- 00094/0870 7 (256,448,3)
1194
- 00094/0897 7 (256,448,3)
1195
- 00094/0900 7 (256,448,3)
1196
- 00094/0944 7 (256,448,3)
1197
- 00094/0946 7 (256,448,3)
1198
- 00094/0952 7 (256,448,3)
1199
- 00094/0969 7 (256,448,3)
1200
- 00094/0973 7 (256,448,3)
1201
- 00094/0981 7 (256,448,3)
1202
- 00095/0088 7 (256,448,3)
1203
- 00095/0125 7 (256,448,3)
1204
- 00095/0130 7 (256,448,3)
1205
- 00095/0142 7 (256,448,3)
1206
- 00095/0151 7 (256,448,3)
1207
- 00095/0180 7 (256,448,3)
1208
- 00095/0192 7 (256,448,3)
1209
- 00095/0194 7 (256,448,3)
1210
- 00095/0195 7 (256,448,3)
1211
- 00095/0204 7 (256,448,3)
1212
- 00095/0245 7 (256,448,3)
1213
- 00095/0315 7 (256,448,3)
1214
- 00095/0321 7 (256,448,3)
1215
- 00095/0324 7 (256,448,3)
1216
- 00095/0327 7 (256,448,3)
1217
- 00095/0730 7 (256,448,3)
1218
- 00095/0731 7 (256,448,3)
1219
- 00095/0741 7 (256,448,3)
1220
- 00095/0948 7 (256,448,3)
1221
- 00096/0407 7 (256,448,3)
1222
- 00096/0420 7 (256,448,3)
1223
- 00096/0435 7 (256,448,3)
1224
- 00096/0682 7 (256,448,3)
1225
- 00096/0865 7 (256,448,3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/meta_info/meta_info_Vimeo90K_test_medium_GT.txt DELETED
The diff for this file is too large to render. See raw diff
 
basicsr/data/meta_info/meta_info_Vimeo90K_test_slow_GT.txt DELETED
@@ -1,1613 +0,0 @@
1
- 00001/0266 7 (256,448,3)
2
- 00001/0268 7 (256,448,3)
3
- 00001/0275 7 (256,448,3)
4
- 00001/0278 7 (256,448,3)
5
- 00001/0287 7 (256,448,3)
6
- 00001/0291 7 (256,448,3)
7
- 00001/0627 7 (256,448,3)
8
- 00001/0636 7 (256,448,3)
9
- 00001/0804 7 (256,448,3)
10
- 00001/0837 7 (256,448,3)
11
- 00001/0849 7 (256,448,3)
12
- 00001/0851 7 (256,448,3)
13
- 00001/0852 7 (256,448,3)
14
- 00001/0986 7 (256,448,3)
15
- 00001/0991 7 (256,448,3)
16
- 00002/0007 7 (256,448,3)
17
- 00002/0008 7 (256,448,3)
18
- 00002/0016 7 (256,448,3)
19
- 00002/0036 7 (256,448,3)
20
- 00002/0091 7 (256,448,3)
21
- 00002/0093 7 (256,448,3)
22
- 00002/0209 7 (256,448,3)
23
- 00002/0235 7 (256,448,3)
24
- 00002/0236 7 (256,448,3)
25
- 00002/0241 7 (256,448,3)
26
- 00002/0466 7 (256,448,3)
27
- 00002/0504 7 (256,448,3)
28
- 00002/0960 7 (256,448,3)
29
- 00002/0961 7 (256,448,3)
30
- 00002/0964 7 (256,448,3)
31
- 00003/0007 7 (256,448,3)
32
- 00003/0069 7 (256,448,3)
33
- 00003/0345 7 (256,448,3)
34
- 00003/0347 7 (256,448,3)
35
- 00003/0372 7 (256,448,3)
36
- 00003/0525 7 (256,448,3)
37
- 00003/0652 7 (256,448,3)
38
- 00003/0667 7 (256,448,3)
39
- 00003/0669 7 (256,448,3)
40
- 00003/0706 7 (256,448,3)
41
- 00003/0713 7 (256,448,3)
42
- 00003/0721 7 (256,448,3)
43
- 00003/0747 7 (256,448,3)
44
- 00003/0829 7 (256,448,3)
45
- 00003/0916 7 (256,448,3)
46
- 00003/0918 7 (256,448,3)
47
- 00003/0924 7 (256,448,3)
48
- 00003/0926 7 (256,448,3)
49
- 00003/0927 7 (256,448,3)
50
- 00004/0288 7 (256,448,3)
51
- 00004/0303 7 (256,448,3)
52
- 00004/0307 7 (256,448,3)
53
- 00004/0628 7 (256,448,3)
54
- 00004/0713 7 (256,448,3)
55
- 00004/0715 7 (256,448,3)
56
- 00004/0719 7 (256,448,3)
57
- 00004/0727 7 (256,448,3)
58
- 00004/0821 7 (256,448,3)
59
- 00005/0006 7 (256,448,3)
60
- 00005/0007 7 (256,448,3)
61
- 00005/0012 7 (256,448,3)
62
- 00005/0013 7 (256,448,3)
63
- 00005/0040 7 (256,448,3)
64
- 00005/0055 7 (256,448,3)
65
- 00005/0119 7 (256,448,3)
66
- 00005/0130 7 (256,448,3)
67
- 00005/0185 7 (256,448,3)
68
- 00005/0198 7 (256,448,3)
69
- 00005/0270 7 (256,448,3)
70
- 00005/0541 7 (256,448,3)
71
- 00005/0560 7 (256,448,3)
72
- 00005/0660 7 (256,448,3)
73
- 00005/0682 7 (256,448,3)
74
- 00005/0683 7 (256,448,3)
75
- 00005/0688 7 (256,448,3)
76
- 00005/0706 7 (256,448,3)
77
- 00005/0728 7 (256,448,3)
78
- 00005/0732 7 (256,448,3)
79
- 00005/0739 7 (256,448,3)
80
- 00005/0804 7 (256,448,3)
81
- 00005/0805 7 (256,448,3)
82
- 00005/0827 7 (256,448,3)
83
- 00005/0828 7 (256,448,3)
84
- 00005/0857 7 (256,448,3)
85
- 00005/0861 7 (256,448,3)
86
- 00005/0862 7 (256,448,3)
87
- 00005/0868 7 (256,448,3)
88
- 00005/0872 7 (256,448,3)
89
- 00005/0933 7 (256,448,3)
90
- 00005/0958 7 (256,448,3)
91
- 00005/0960 7 (256,448,3)
92
- 00006/0087 7 (256,448,3)
93
- 00006/0090 7 (256,448,3)
94
- 00006/0351 7 (256,448,3)
95
- 00006/0353 7 (256,448,3)
96
- 00006/0558 7 (256,448,3)
97
- 00006/0588 7 (256,448,3)
98
- 00006/0619 7 (256,448,3)
99
- 00006/0621 7 (256,448,3)
100
- 00006/0748 7 (256,448,3)
101
- 00006/0796 7 (256,448,3)
102
- 00006/0805 7 (256,448,3)
103
- 00006/0807 7 (256,448,3)
104
- 00007/0236 7 (256,448,3)
105
- 00007/0240 7 (256,448,3)
106
- 00007/0243 7 (256,448,3)
107
- 00007/0246 7 (256,448,3)
108
- 00007/0247 7 (256,448,3)
109
- 00007/0252 7 (256,448,3)
110
- 00007/0322 7 (256,448,3)
111
- 00007/0458 7 (256,448,3)
112
- 00007/0492 7 (256,448,3)
113
- 00007/0658 7 (256,448,3)
114
- 00007/0717 7 (256,448,3)
115
- 00007/0722 7 (256,448,3)
116
- 00007/0725 7 (256,448,3)
117
- 00007/0740 7 (256,448,3)
118
- 00007/0748 7 (256,448,3)
119
- 00007/0749 7 (256,448,3)
120
- 00007/0759 7 (256,448,3)
121
- 00007/0772 7 (256,448,3)
122
- 00007/0783 7 (256,448,3)
123
- 00007/0787 7 (256,448,3)
124
- 00007/0883 7 (256,448,3)
125
- 00008/0033 7 (256,448,3)
126
- 00008/0035 7 (256,448,3)
127
- 00008/0091 7 (256,448,3)
128
- 00008/0154 7 (256,448,3)
129
- 00008/0966 7 (256,448,3)
130
- 00008/0987 7 (256,448,3)
131
- 00009/0108 7 (256,448,3)
132
- 00009/0607 7 (256,448,3)
133
- 00009/0668 7 (256,448,3)
134
- 00009/0683 7 (256,448,3)
135
- 00009/0941 7 (256,448,3)
136
- 00009/0949 7 (256,448,3)
137
- 00009/0962 7 (256,448,3)
138
- 00009/0972 7 (256,448,3)
139
- 00009/0974 7 (256,448,3)
140
- 00010/0014 7 (256,448,3)
141
- 00010/0018 7 (256,448,3)
142
- 00010/0043 7 (256,448,3)
143
- 00010/0099 7 (256,448,3)
144
- 00010/0252 7 (256,448,3)
145
- 00010/0296 7 (256,448,3)
146
- 00010/0413 7 (256,448,3)
147
- 00010/0422 7 (256,448,3)
148
- 00010/0516 7 (256,448,3)
149
- 00010/0525 7 (256,448,3)
150
- 00010/0556 7 (256,448,3)
151
- 00010/0701 7 (256,448,3)
152
- 00010/0740 7 (256,448,3)
153
- 00010/0772 7 (256,448,3)
154
- 00010/0831 7 (256,448,3)
155
- 00010/0925 7 (256,448,3)
156
- 00011/0013 7 (256,448,3)
157
- 00011/0016 7 (256,448,3)
158
- 00011/0017 7 (256,448,3)
159
- 00011/0249 7 (256,448,3)
160
- 00011/0826 7 (256,448,3)
161
- 00011/0827 7 (256,448,3)
162
- 00011/0831 7 (256,448,3)
163
- 00011/0833 7 (256,448,3)
164
- 00011/0835 7 (256,448,3)
165
- 00011/0998 7 (256,448,3)
166
- 00012/0023 7 (256,448,3)
167
- 00012/0024 7 (256,448,3)
168
- 00012/0027 7 (256,448,3)
169
- 00012/0037 7 (256,448,3)
170
- 00012/0444 7 (256,448,3)
171
- 00012/0445 7 (256,448,3)
172
- 00012/0451 7 (256,448,3)
173
- 00012/0461 7 (256,448,3)
174
- 00012/0521 7 (256,448,3)
175
- 00012/0758 7 (256,448,3)
176
- 00012/0760 7 (256,448,3)
177
- 00012/0771 7 (256,448,3)
178
- 00012/0903 7 (256,448,3)
179
- 00012/0909 7 (256,448,3)
180
- 00013/0581 7 (256,448,3)
181
- 00013/0786 7 (256,448,3)
182
- 00013/0789 7 (256,448,3)
183
- 00013/0791 7 (256,448,3)
184
- 00013/0798 7 (256,448,3)
185
- 00013/0802 7 (256,448,3)
186
- 00013/0820 7 (256,448,3)
187
- 00013/0850 7 (256,448,3)
188
- 00013/0854 7 (256,448,3)
189
- 00013/0894 7 (256,448,3)
190
- 00013/0919 7 (256,448,3)
191
- 00013/0999 7 (256,448,3)
192
- 00014/0001 7 (256,448,3)
193
- 00014/0014 7 (256,448,3)
194
- 00014/0018 7 (256,448,3)
195
- 00014/0244 7 (256,448,3)
196
- 00014/0475 7 (256,448,3)
197
- 00014/0483 7 (256,448,3)
198
- 00014/0680 7 (256,448,3)
199
- 00014/0700 7 (256,448,3)
200
- 00014/0701 7 (256,448,3)
201
- 00014/0706 7 (256,448,3)
202
- 00014/0712 7 (256,448,3)
203
- 00014/0713 7 (256,448,3)
204
- 00014/0717 7 (256,448,3)
205
- 00014/0719 7 (256,448,3)
206
- 00014/0728 7 (256,448,3)
207
- 00014/0734 7 (256,448,3)
208
- 00014/0736 7 (256,448,3)
209
- 00014/0738 7 (256,448,3)
210
- 00014/0742 7 (256,448,3)
211
- 00014/0745 7 (256,448,3)
212
- 00014/0746 7 (256,448,3)
213
- 00014/0750 7 (256,448,3)
214
- 00014/0769 7 (256,448,3)
215
- 00014/0774 7 (256,448,3)
216
- 00014/0781 7 (256,448,3)
217
- 00014/0782 7 (256,448,3)
218
- 00014/0852 7 (256,448,3)
219
- 00014/0853 7 (256,448,3)
220
- 00014/0855 7 (256,448,3)
221
- 00014/0867 7 (256,448,3)
222
- 00014/0876 7 (256,448,3)
223
- 00014/0881 7 (256,448,3)
224
- 00014/0890 7 (256,448,3)
225
- 00014/0914 7 (256,448,3)
226
- 00015/0033 7 (256,448,3)
227
- 00015/0113 7 (256,448,3)
228
- 00015/0125 7 (256,448,3)
229
- 00015/0185 7 (256,448,3)
230
- 00015/0194 7 (256,448,3)
231
- 00015/0202 7 (256,448,3)
232
- 00015/0312 7 (256,448,3)
233
- 00015/0688 7 (256,448,3)
234
- 00015/0698 7 (256,448,3)
235
- 00015/0788 7 (256,448,3)
236
- 00015/0854 7 (256,448,3)
237
- 00015/0863 7 (256,448,3)
238
- 00015/0864 7 (256,448,3)
239
- 00015/0918 7 (256,448,3)
240
- 00015/0931 7 (256,448,3)
241
- 00016/0276 7 (256,448,3)
242
- 00016/0301 7 (256,448,3)
243
- 00016/0306 7 (256,448,3)
244
- 00016/0324 7 (256,448,3)
245
- 00016/0362 7 (256,448,3)
246
- 00016/0364 7 (256,448,3)
247
- 00016/0370 7 (256,448,3)
248
- 00016/0378 7 (256,448,3)
249
- 00016/0379 7 (256,448,3)
250
- 00016/0402 7 (256,448,3)
251
- 00016/0405 7 (256,448,3)
252
- 00016/0418 7 (256,448,3)
253
- 00016/0419 7 (256,448,3)
254
- 00016/0435 7 (256,448,3)
255
- 00016/0501 7 (256,448,3)
256
- 00016/0561 7 (256,448,3)
257
- 00016/0562 7 (256,448,3)
258
- 00016/0569 7 (256,448,3)
259
- 00016/0591 7 (256,448,3)
260
- 00016/0599 7 (256,448,3)
261
- 00016/0711 7 (256,448,3)
262
- 00016/0713 7 (256,448,3)
263
- 00016/0813 7 (256,448,3)
264
- 00016/0953 7 (256,448,3)
265
- 00016/0960 7 (256,448,3)
266
- 00016/0961 7 (256,448,3)
267
- 00017/0519 7 (256,448,3)
268
- 00017/0523 7 (256,448,3)
269
- 00017/0588 7 (256,448,3)
270
- 00017/0608 7 (256,448,3)
271
- 00017/0609 7 (256,448,3)
272
- 00017/0719 7 (256,448,3)
273
- 00017/0721 7 (256,448,3)
274
- 00017/0727 7 (256,448,3)
275
- 00017/0728 7 (256,448,3)
276
- 00017/0769 7 (256,448,3)
277
- 00017/0775 7 (256,448,3)
278
- 00017/0787 7 (256,448,3)
279
- 00017/0797 7 (256,448,3)
280
- 00018/0043 7 (256,448,3)
281
- 00018/0206 7 (256,448,3)
282
- 00018/0209 7 (256,448,3)
283
- 00018/0211 7 (256,448,3)
284
- 00018/0216 7 (256,448,3)
285
- 00018/0220 7 (256,448,3)
286
- 00018/0221 7 (256,448,3)
287
- 00018/0252 7 (256,448,3)
288
- 00018/0260 7 (256,448,3)
289
- 00018/0331 7 (256,448,3)
290
- 00018/0333 7 (256,448,3)
291
- 00018/0447 7 (256,448,3)
292
- 00018/0523 7 (256,448,3)
293
- 00019/0014 7 (256,448,3)
294
- 00019/0015 7 (256,448,3)
295
- 00019/0019 7 (256,448,3)
296
- 00019/0049 7 (256,448,3)
297
- 00019/0109 7 (256,448,3)
298
- 00019/0114 7 (256,448,3)
299
- 00019/0125 7 (256,448,3)
300
- 00019/0137 7 (256,448,3)
301
- 00019/0140 7 (256,448,3)
302
- 00019/0148 7 (256,448,3)
303
- 00019/0153 7 (256,448,3)
304
- 00019/0155 7 (256,448,3)
305
- 00019/0158 7 (256,448,3)
306
- 00019/0159 7 (256,448,3)
307
- 00019/0160 7 (256,448,3)
308
- 00019/0162 7 (256,448,3)
309
- 00019/0279 7 (256,448,3)
310
- 00019/0282 7 (256,448,3)
311
- 00019/0409 7 (256,448,3)
312
- 00019/0427 7 (256,448,3)
313
- 00019/0430 7 (256,448,3)
314
- 00019/0545 7 (256,448,3)
315
- 00019/0555 7 (256,448,3)
316
- 00019/0558 7 (256,448,3)
317
- 00019/0650 7 (256,448,3)
318
- 00019/0681 7 (256,448,3)
319
- 00019/0747 7 (256,448,3)
320
- 00019/0748 7 (256,448,3)
321
- 00019/0749 7 (256,448,3)
322
- 00019/0752 7 (256,448,3)
323
- 00019/0768 7 (256,448,3)
324
- 00019/0772 7 (256,448,3)
325
- 00019/0773 7 (256,448,3)
326
- 00019/0777 7 (256,448,3)
327
- 00019/0795 7 (256,448,3)
328
- 00019/0806 7 (256,448,3)
329
- 00019/0815 7 (256,448,3)
330
- 00019/0840 7 (256,448,3)
331
- 00019/0844 7 (256,448,3)
332
- 00019/0848 7 (256,448,3)
333
- 00019/0853 7 (256,448,3)
334
- 00019/0863 7 (256,448,3)
335
- 00019/0888 7 (256,448,3)
336
- 00019/0894 7 (256,448,3)
337
- 00019/0901 7 (256,448,3)
338
- 00019/0995 7 (256,448,3)
339
- 00021/0030 7 (256,448,3)
340
- 00021/0035 7 (256,448,3)
341
- 00021/0039 7 (256,448,3)
342
- 00021/0041 7 (256,448,3)
343
- 00021/0044 7 (256,448,3)
344
- 00021/0045 7 (256,448,3)
345
- 00021/0264 7 (256,448,3)
346
- 00021/0330 7 (256,448,3)
347
- 00021/0332 7 (256,448,3)
348
- 00021/0333 7 (256,448,3)
349
- 00021/0336 7 (256,448,3)
350
- 00021/0337 7 (256,448,3)
351
- 00021/0338 7 (256,448,3)
352
- 00021/0343 7 (256,448,3)
353
- 00021/0472 7 (256,448,3)
354
- 00021/0667 7 (256,448,3)
355
- 00021/0731 7 (256,448,3)
356
- 00021/0779 7 (256,448,3)
357
- 00021/0805 7 (256,448,3)
358
- 00021/0814 7 (256,448,3)
359
- 00021/0818 7 (256,448,3)
360
- 00021/0874 7 (256,448,3)
361
- 00022/0008 7 (256,448,3)
362
- 00022/0010 7 (256,448,3)
363
- 00022/0231 7 (256,448,3)
364
- 00022/0323 7 (256,448,3)
365
- 00022/0337 7 (256,448,3)
366
- 00022/0359 7 (256,448,3)
367
- 00022/0377 7 (256,448,3)
368
- 00022/0378 7 (256,448,3)
369
- 00022/0385 7 (256,448,3)
370
- 00022/0393 7 (256,448,3)
371
- 00022/0424 7 (256,448,3)
372
- 00022/0582 7 (256,448,3)
373
- 00022/0583 7 (256,448,3)
374
- 00022/0605 7 (256,448,3)
375
- 00022/0632 7 (256,448,3)
376
- 00022/0633 7 (256,448,3)
377
- 00022/0666 7 (256,448,3)
378
- 00022/0671 7 (256,448,3)
379
- 00022/0673 7 (256,448,3)
380
- 00022/0702 7 (256,448,3)
381
- 00022/0852 7 (256,448,3)
382
- 00022/0853 7 (256,448,3)
383
- 00022/0971 7 (256,448,3)
384
- 00023/0037 7 (256,448,3)
385
- 00023/0224 7 (256,448,3)
386
- 00023/0308 7 (256,448,3)
387
- 00023/0393 7 (256,448,3)
388
- 00023/0633 7 (256,448,3)
389
- 00023/0637 7 (256,448,3)
390
- 00023/0638 7 (256,448,3)
391
- 00023/0770 7 (256,448,3)
392
- 00023/0786 7 (256,448,3)
393
- 00023/0898 7 (256,448,3)
394
- 00024/0247 7 (256,448,3)
395
- 00024/0251 7 (256,448,3)
396
- 00024/0267 7 (256,448,3)
397
- 00024/0288 7 (256,448,3)
398
- 00024/0530 7 (256,448,3)
399
- 00024/0569 7 (256,448,3)
400
- 00024/0587 7 (256,448,3)
401
- 00024/0730 7 (256,448,3)
402
- 00024/0736 7 (256,448,3)
403
- 00024/0742 7 (256,448,3)
404
- 00024/0832 7 (256,448,3)
405
- 00024/0936 7 (256,448,3)
406
- 00025/0044 7 (256,448,3)
407
- 00025/0047 7 (256,448,3)
408
- 00025/0540 7 (256,448,3)
409
- 00025/0552 7 (256,448,3)
410
- 00025/0554 7 (256,448,3)
411
- 00025/0559 7 (256,448,3)
412
- 00025/0572 7 (256,448,3)
413
- 00025/0576 7 (256,448,3)
414
- 00025/0699 7 (256,448,3)
415
- 00025/0709 7 (256,448,3)
416
- 00025/0743 7 (256,448,3)
417
- 00025/0767 7 (256,448,3)
418
- 00025/0780 7 (256,448,3)
419
- 00025/0782 7 (256,448,3)
420
- 00025/0784 7 (256,448,3)
421
- 00025/0791 7 (256,448,3)
422
- 00025/0889 7 (256,448,3)
423
- 00025/0890 7 (256,448,3)
424
- 00025/0894 7 (256,448,3)
425
- 00025/0896 7 (256,448,3)
426
- 00025/0898 7 (256,448,3)
427
- 00025/0905 7 (256,448,3)
428
- 00025/0999 7 (256,448,3)
429
- 00026/0003 7 (256,448,3)
430
- 00026/0005 7 (256,448,3)
431
- 00026/0011 7 (256,448,3)
432
- 00026/0017 7 (256,448,3)
433
- 00026/0036 7 (256,448,3)
434
- 00026/0129 7 (256,448,3)
435
- 00026/0131 7 (256,448,3)
436
- 00026/0161 7 (256,448,3)
437
- 00026/0177 7 (256,448,3)
438
- 00026/0178 7 (256,448,3)
439
- 00026/0180 7 (256,448,3)
440
- 00026/0298 7 (256,448,3)
441
- 00026/0307 7 (256,448,3)
442
- 00026/0308 7 (256,448,3)
443
- 00026/0312 7 (256,448,3)
444
- 00026/0352 7 (256,448,3)
445
- 00026/0440 7 (256,448,3)
446
- 00026/0706 7 (256,448,3)
447
- 00026/0708 7 (256,448,3)
448
- 00026/0715 7 (256,448,3)
449
- 00026/0769 7 (256,448,3)
450
- 00026/0777 7 (256,448,3)
451
- 00026/0779 7 (256,448,3)
452
- 00026/0789 7 (256,448,3)
453
- 00026/0924 7 (256,448,3)
454
- 00026/0928 7 (256,448,3)
455
- 00026/0932 7 (256,448,3)
456
- 00026/0935 7 (256,448,3)
457
- 00027/0118 7 (256,448,3)
458
- 00027/0121 7 (256,448,3)
459
- 00027/0155 7 (256,448,3)
460
- 00027/0168 7 (256,448,3)
461
- 00027/0196 7 (256,448,3)
462
- 00027/0289 7 (256,448,3)
463
- 00027/0294 7 (256,448,3)
464
- 00027/0803 7 (256,448,3)
465
- 00028/0016 7 (256,448,3)
466
- 00028/0045 7 (256,448,3)
467
- 00028/0063 7 (256,448,3)
468
- 00028/0601 7 (256,448,3)
469
- 00028/0638 7 (256,448,3)
470
- 00028/0733 7 (256,448,3)
471
- 00028/0736 7 (256,448,3)
472
- 00028/0741 7 (256,448,3)
473
- 00028/0753 7 (256,448,3)
474
- 00028/0770 7 (256,448,3)
475
- 00028/0771 7 (256,448,3)
476
- 00028/0777 7 (256,448,3)
477
- 00028/0950 7 (256,448,3)
478
- 00028/0951 7 (256,448,3)
479
- 00029/0048 7 (256,448,3)
480
- 00029/0060 7 (256,448,3)
481
- 00029/0362 7 (256,448,3)
482
- 00029/0399 7 (256,448,3)
483
- 00029/0404 7 (256,448,3)
484
- 00029/0412 7 (256,448,3)
485
- 00029/0416 7 (256,448,3)
486
- 00029/0418 7 (256,448,3)
487
- 00029/0428 7 (256,448,3)
488
- 00030/0131 7 (256,448,3)
489
- 00030/0135 7 (256,448,3)
490
- 00030/0150 7 (256,448,3)
491
- 00030/0245 7 (256,448,3)
492
- 00030/0339 7 (256,448,3)
493
- 00030/0472 7 (256,448,3)
494
- 00030/0482 7 (256,448,3)
495
- 00030/0500 7 (256,448,3)
496
- 00030/0501 7 (256,448,3)
497
- 00030/0697 7 (256,448,3)
498
- 00030/0707 7 (256,448,3)
499
- 00030/0733 7 (256,448,3)
500
- 00030/0743 7 (256,448,3)
501
- 00030/0747 7 (256,448,3)
502
- 00030/0754 7 (256,448,3)
503
- 00030/0755 7 (256,448,3)
504
- 00030/0759 7 (256,448,3)
505
- 00030/0762 7 (256,448,3)
506
- 00030/0764 7 (256,448,3)
507
- 00030/0767 7 (256,448,3)
508
- 00030/0794 7 (256,448,3)
509
- 00030/0796 7 (256,448,3)
510
- 00030/0799 7 (256,448,3)
511
- 00030/0814 7 (256,448,3)
512
- 00030/0823 7 (256,448,3)
513
- 00030/0829 7 (256,448,3)
514
- 00030/0833 7 (256,448,3)
515
- 00030/0848 7 (256,448,3)
516
- 00030/0853 7 (256,448,3)
517
- 00030/0861 7 (256,448,3)
518
- 00031/0182 7 (256,448,3)
519
- 00031/0275 7 (256,448,3)
520
- 00031/0279 7 (256,448,3)
521
- 00031/0555 7 (256,448,3)
522
- 00031/0648 7 (256,448,3)
523
- 00031/0663 7 (256,448,3)
524
- 00031/0680 7 (256,448,3)
525
- 00031/0880 7 (256,448,3)
526
- 00031/0922 7 (256,448,3)
527
- 00031/0925 7 (256,448,3)
528
- 00031/0928 7 (256,448,3)
529
- 00032/0025 7 (256,448,3)
530
- 00032/0377 7 (256,448,3)
531
- 00032/0378 7 (256,448,3)
532
- 00032/0382 7 (256,448,3)
533
- 00032/0384 7 (256,448,3)
534
- 00032/0386 7 (256,448,3)
535
- 00032/0389 7 (256,448,3)
536
- 00032/0391 7 (256,448,3)
537
- 00032/0393 7 (256,448,3)
538
- 00032/0492 7 (256,448,3)
539
- 00032/0497 7 (256,448,3)
540
- 00032/0505 7 (256,448,3)
541
- 00032/0523 7 (256,448,3)
542
- 00032/0542 7 (256,448,3)
543
- 00032/0544 7 (256,448,3)
544
- 00032/0712 7 (256,448,3)
545
- 00032/0847 7 (256,448,3)
546
- 00032/0850 7 (256,448,3)
547
- 00032/0875 7 (256,448,3)
548
- 00033/0062 7 (256,448,3)
549
- 00033/0063 7 (256,448,3)
550
- 00033/0098 7 (256,448,3)
551
- 00033/0101 7 (256,448,3)
552
- 00033/0105 7 (256,448,3)
553
- 00033/0114 7 (256,448,3)
554
- 00033/0432 7 (256,448,3)
555
- 00033/0441 7 (256,448,3)
556
- 00033/0606 7 (256,448,3)
557
- 00033/0611 7 (256,448,3)
558
- 00033/0634 7 (256,448,3)
559
- 00033/0787 7 (256,448,3)
560
- 00033/0792 7 (256,448,3)
561
- 00033/0802 7 (256,448,3)
562
- 00033/0825 7 (256,448,3)
563
- 00033/0835 7 (256,448,3)
564
- 00034/0249 7 (256,448,3)
565
- 00034/0253 7 (256,448,3)
566
- 00034/0254 7 (256,448,3)
567
- 00034/0282 7 (256,448,3)
568
- 00034/0318 7 (256,448,3)
569
- 00034/0319 7 (256,448,3)
570
- 00034/0323 7 (256,448,3)
571
- 00034/0336 7 (256,448,3)
572
- 00034/0348 7 (256,448,3)
573
- 00034/0356 7 (256,448,3)
574
- 00034/0379 7 (256,448,3)
575
- 00034/0387 7 (256,448,3)
576
- 00034/0575 7 (256,448,3)
577
- 00034/0608 7 (256,448,3)
578
- 00034/0663 7 (256,448,3)
579
- 00034/0811 7 (256,448,3)
580
- 00034/0812 7 (256,448,3)
581
- 00034/0946 7 (256,448,3)
582
- 00034/0948 7 (256,448,3)
583
- 00034/0950 7 (256,448,3)
584
- 00035/0204 7 (256,448,3)
585
- 00035/0243 7 (256,448,3)
586
- 00035/0308 7 (256,448,3)
587
- 00035/0465 7 (256,448,3)
588
- 00035/0478 7 (256,448,3)
589
- 00035/0523 7 (256,448,3)
590
- 00035/0540 7 (256,448,3)
591
- 00035/0544 7 (256,448,3)
592
- 00035/0556 7 (256,448,3)
593
- 00035/0568 7 (256,448,3)
594
- 00035/0570 7 (256,448,3)
595
- 00035/0609 7 (256,448,3)
596
- 00035/0643 7 (256,448,3)
597
- 00035/0644 7 (256,448,3)
598
- 00035/0645 7 (256,448,3)
599
- 00035/0646 7 (256,448,3)
600
- 00035/0650 7 (256,448,3)
601
- 00035/0661 7 (256,448,3)
602
- 00035/0724 7 (256,448,3)
603
- 00035/0725 7 (256,448,3)
604
- 00035/0850 7 (256,448,3)
605
- 00035/0863 7 (256,448,3)
606
- 00035/0870 7 (256,448,3)
607
- 00035/0951 7 (256,448,3)
608
- 00036/0038 7 (256,448,3)
609
- 00036/0062 7 (256,448,3)
610
- 00036/0423 7 (256,448,3)
611
- 00036/0737 7 (256,448,3)
612
- 00036/0750 7 (256,448,3)
613
- 00036/0751 7 (256,448,3)
614
- 00036/0754 7 (256,448,3)
615
- 00036/0929 7 (256,448,3)
616
- 00037/0085 7 (256,448,3)
617
- 00037/0113 7 (256,448,3)
618
- 00037/0130 7 (256,448,3)
619
- 00037/0153 7 (256,448,3)
620
- 00037/0169 7 (256,448,3)
621
- 00037/0263 7 (256,448,3)
622
- 00037/0272 7 (256,448,3)
623
- 00037/0273 7 (256,448,3)
624
- 00037/0275 7 (256,448,3)
625
- 00037/0280 7 (256,448,3)
626
- 00037/0399 7 (256,448,3)
627
- 00037/0456 7 (256,448,3)
628
- 00037/0853 7 (256,448,3)
629
- 00037/0855 7 (256,448,3)
630
- 00037/0856 7 (256,448,3)
631
- 00037/0857 7 (256,448,3)
632
- 00037/0925 7 (256,448,3)
633
- 00037/0947 7 (256,448,3)
634
- 00038/0148 7 (256,448,3)
635
- 00038/0533 7 (256,448,3)
636
- 00038/0534 7 (256,448,3)
637
- 00038/0560 7 (256,448,3)
638
- 00038/0562 7 (256,448,3)
639
- 00038/0566 7 (256,448,3)
640
- 00038/0578 7 (256,448,3)
641
- 00038/0652 7 (256,448,3)
642
- 00038/0674 7 (256,448,3)
643
- 00038/0685 7 (256,448,3)
644
- 00038/0686 7 (256,448,3)
645
- 00038/0692 7 (256,448,3)
646
- 00038/0736 7 (256,448,3)
647
- 00039/0035 7 (256,448,3)
648
- 00039/0105 7 (256,448,3)
649
- 00039/0109 7 (256,448,3)
650
- 00039/0121 7 (256,448,3)
651
- 00039/0128 7 (256,448,3)
652
- 00039/0129 7 (256,448,3)
653
- 00039/0132 7 (256,448,3)
654
- 00039/0137 7 (256,448,3)
655
- 00039/0157 7 (256,448,3)
656
- 00039/0496 7 (256,448,3)
657
- 00039/0502 7 (256,448,3)
658
- 00039/0526 7 (256,448,3)
659
- 00039/0529 7 (256,448,3)
660
- 00039/0682 7 (256,448,3)
661
- 00039/0690 7 (256,448,3)
662
- 00039/0693 7 (256,448,3)
663
- 00039/0703 7 (256,448,3)
664
- 00039/0725 7 (256,448,3)
665
- 00039/0734 7 (256,448,3)
666
- 00040/0518 7 (256,448,3)
667
- 00040/0728 7 (256,448,3)
668
- 00040/0774 7 (256,448,3)
669
- 00040/0812 7 (256,448,3)
670
- 00040/0818 7 (256,448,3)
671
- 00040/0827 7 (256,448,3)
672
- 00040/0914 7 (256,448,3)
673
- 00040/0917 7 (256,448,3)
674
- 00040/0918 7 (256,448,3)
675
- 00040/0924 7 (256,448,3)
676
- 00040/0925 7 (256,448,3)
677
- 00041/0004 7 (256,448,3)
678
- 00041/0006 7 (256,448,3)
679
- 00041/0013 7 (256,448,3)
680
- 00041/0059 7 (256,448,3)
681
- 00041/0110 7 (256,448,3)
682
- 00041/0291 7 (256,448,3)
683
- 00041/0366 7 (256,448,3)
684
- 00041/0388 7 (256,448,3)
685
- 00041/0434 7 (256,448,3)
686
- 00041/0436 7 (256,448,3)
687
- 00041/0450 7 (256,448,3)
688
- 00041/0457 7 (256,448,3)
689
- 00041/0460 7 (256,448,3)
690
- 00041/0468 7 (256,448,3)
691
- 00041/0471 7 (256,448,3)
692
- 00041/0474 7 (256,448,3)
693
- 00041/0809 7 (256,448,3)
694
- 00041/0844 7 (256,448,3)
695
- 00041/0858 7 (256,448,3)
696
- 00041/0874 7 (256,448,3)
697
- 00041/0876 7 (256,448,3)
698
- 00042/0020 7 (256,448,3)
699
- 00042/0205 7 (256,448,3)
700
- 00042/0206 7 (256,448,3)
701
- 00042/0432 7 (256,448,3)
702
- 00042/0563 7 (256,448,3)
703
- 00042/0569 7 (256,448,3)
704
- 00042/0575 7 (256,448,3)
705
- 00042/0576 7 (256,448,3)
706
- 00042/0888 7 (256,448,3)
707
- 00042/0892 7 (256,448,3)
708
- 00042/0943 7 (256,448,3)
709
- 00042/0944 7 (256,448,3)
710
- 00043/0126 7 (256,448,3)
711
- 00043/0130 7 (256,448,3)
712
- 00043/0136 7 (256,448,3)
713
- 00043/0233 7 (256,448,3)
714
- 00043/0235 7 (256,448,3)
715
- 00043/0237 7 (256,448,3)
716
- 00043/0277 7 (256,448,3)
717
- 00043/0301 7 (256,448,3)
718
- 00043/0302 7 (256,448,3)
719
- 00043/0303 7 (256,448,3)
720
- 00043/0308 7 (256,448,3)
721
- 00043/0309 7 (256,448,3)
722
- 00043/0314 7 (256,448,3)
723
- 00043/0713 7 (256,448,3)
724
- 00043/0715 7 (256,448,3)
725
- 00043/0923 7 (256,448,3)
726
- 00044/0095 7 (256,448,3)
727
- 00044/0255 7 (256,448,3)
728
- 00044/0864 7 (256,448,3)
729
- 00044/0892 7 (256,448,3)
730
- 00044/0898 7 (256,448,3)
731
- 00044/0993 7 (256,448,3)
732
- 00044/0995 7 (256,448,3)
733
- 00044/0997 7 (256,448,3)
734
- 00045/0001 7 (256,448,3)
735
- 00045/0006 7 (256,448,3)
736
- 00045/0269 7 (256,448,3)
737
- 00045/0276 7 (256,448,3)
738
- 00045/0280 7 (256,448,3)
739
- 00045/0281 7 (256,448,3)
740
- 00045/0282 7 (256,448,3)
741
- 00045/0284 7 (256,448,3)
742
- 00045/0550 7 (256,448,3)
743
- 00045/0571 7 (256,448,3)
744
- 00045/0629 7 (256,448,3)
745
- 00045/0631 7 (256,448,3)
746
- 00045/0659 7 (256,448,3)
747
- 00045/0693 7 (256,448,3)
748
- 00045/0807 7 (256,448,3)
749
- 00045/0810 7 (256,448,3)
750
- 00045/0826 7 (256,448,3)
751
- 00045/0849 7 (256,448,3)
752
- 00045/0946 7 (256,448,3)
753
- 00045/0987 7 (256,448,3)
754
- 00045/0990 7 (256,448,3)
755
- 00046/0104 7 (256,448,3)
756
- 00046/0477 7 (256,448,3)
757
- 00046/0490 7 (256,448,3)
758
- 00046/0491 7 (256,448,3)
759
- 00046/0509 7 (256,448,3)
760
- 00046/0513 7 (256,448,3)
761
- 00046/0603 7 (256,448,3)
762
- 00046/0723 7 (256,448,3)
763
- 00046/0744 7 (256,448,3)
764
- 00046/0746 7 (256,448,3)
765
- 00046/0750 7 (256,448,3)
766
- 00046/0852 7 (256,448,3)
767
- 00046/0927 7 (256,448,3)
768
- 00046/0928 7 (256,448,3)
769
- 00046/0929 7 (256,448,3)
770
- 00046/0931 7 (256,448,3)
771
- 00046/0936 7 (256,448,3)
772
- 00046/0939 7 (256,448,3)
773
- 00046/0947 7 (256,448,3)
774
- 00046/0948 7 (256,448,3)
775
- 00046/0950 7 (256,448,3)
776
- 00046/0955 7 (256,448,3)
777
- 00046/0961 7 (256,448,3)
778
- 00047/0023 7 (256,448,3)
779
- 00047/0029 7 (256,448,3)
780
- 00047/0035 7 (256,448,3)
781
- 00047/0058 7 (256,448,3)
782
- 00047/0061 7 (256,448,3)
783
- 00047/0065 7 (256,448,3)
784
- 00047/0068 7 (256,448,3)
785
- 00047/0072 7 (256,448,3)
786
- 00047/0074 7 (256,448,3)
787
- 00047/0148 7 (256,448,3)
788
- 00047/0594 7 (256,448,3)
789
- 00047/0782 7 (256,448,3)
790
- 00047/0787 7 (256,448,3)
791
- 00047/0860 7 (256,448,3)
792
- 00047/0889 7 (256,448,3)
793
- 00047/0893 7 (256,448,3)
794
- 00047/0894 7 (256,448,3)
795
- 00047/0902 7 (256,448,3)
796
- 00047/0975 7 (256,448,3)
797
- 00047/0995 7 (256,448,3)
798
- 00048/0033 7 (256,448,3)
799
- 00048/0113 7 (256,448,3)
800
- 00048/0115 7 (256,448,3)
801
- 00048/0120 7 (256,448,3)
802
- 00048/0129 7 (256,448,3)
803
- 00048/0136 7 (256,448,3)
804
- 00048/0327 7 (256,448,3)
805
- 00048/0329 7 (256,448,3)
806
- 00048/0341 7 (256,448,3)
807
- 00048/0343 7 (256,448,3)
808
- 00048/0345 7 (256,448,3)
809
- 00048/0346 7 (256,448,3)
810
- 00048/0355 7 (256,448,3)
811
- 00048/0359 7 (256,448,3)
812
- 00048/0363 7 (256,448,3)
813
- 00048/0378 7 (256,448,3)
814
- 00048/0386 7 (256,448,3)
815
- 00048/0387 7 (256,448,3)
816
- 00048/0388 7 (256,448,3)
817
- 00048/0428 7 (256,448,3)
818
- 00048/0439 7 (256,448,3)
819
- 00048/0507 7 (256,448,3)
820
- 00048/0510 7 (256,448,3)
821
- 00048/0512 7 (256,448,3)
822
- 00048/0514 7 (256,448,3)
823
- 00048/0539 7 (256,448,3)
824
- 00048/0542 7 (256,448,3)
825
- 00048/0544 7 (256,448,3)
826
- 00048/0631 7 (256,448,3)
827
- 00048/0632 7 (256,448,3)
828
- 00048/0636 7 (256,448,3)
829
- 00048/0640 7 (256,448,3)
830
- 00048/0644 7 (256,448,3)
831
- 00048/0653 7 (256,448,3)
832
- 00048/0655 7 (256,448,3)
833
- 00048/0658 7 (256,448,3)
834
- 00048/0667 7 (256,448,3)
835
- 00048/0688 7 (256,448,3)
836
- 00048/0708 7 (256,448,3)
837
- 00049/0005 7 (256,448,3)
838
- 00049/0074 7 (256,448,3)
839
- 00049/0077 7 (256,448,3)
840
- 00049/0084 7 (256,448,3)
841
- 00049/0516 7 (256,448,3)
842
- 00049/0800 7 (256,448,3)
843
- 00049/0900 7 (256,448,3)
844
- 00050/0607 7 (256,448,3)
845
- 00050/0661 7 (256,448,3)
846
- 00050/0665 7 (256,448,3)
847
- 00050/0685 7 (256,448,3)
848
- 00050/0711 7 (256,448,3)
849
- 00051/0068 7 (256,448,3)
850
- 00051/0069 7 (256,448,3)
851
- 00051/0076 7 (256,448,3)
852
- 00051/0569 7 (256,448,3)
853
- 00051/0801 7 (256,448,3)
854
- 00051/0927 7 (256,448,3)
855
- 00051/0945 7 (256,448,3)
856
- 00051/0952 7 (256,448,3)
857
- 00051/0976 7 (256,448,3)
858
- 00051/0985 7 (256,448,3)
859
- 00052/0012 7 (256,448,3)
860
- 00052/0015 7 (256,448,3)
861
- 00052/0052 7 (256,448,3)
862
- 00052/0056 7 (256,448,3)
863
- 00052/0060 7 (256,448,3)
864
- 00052/0157 7 (256,448,3)
865
- 00052/0265 7 (256,448,3)
866
- 00052/0788 7 (256,448,3)
867
- 00052/0790 7 (256,448,3)
868
- 00052/0793 7 (256,448,3)
869
- 00052/0816 7 (256,448,3)
870
- 00052/0824 7 (256,448,3)
871
- 00052/0918 7 (256,448,3)
872
- 00052/0933 7 (256,448,3)
873
- 00052/0947 7 (256,448,3)
874
- 00053/0232 7 (256,448,3)
875
- 00053/0277 7 (256,448,3)
876
- 00053/0362 7 (256,448,3)
877
- 00053/0577 7 (256,448,3)
878
- 00053/0609 7 (256,448,3)
879
- 00053/0612 7 (256,448,3)
880
- 00053/0628 7 (256,448,3)
881
- 00053/0629 7 (256,448,3)
882
- 00053/0633 7 (256,448,3)
883
- 00053/0659 7 (256,448,3)
884
- 00053/0667 7 (256,448,3)
885
- 00053/0671 7 (256,448,3)
886
- 00053/0797 7 (256,448,3)
887
- 00053/0804 7 (256,448,3)
888
- 00053/0807 7 (256,448,3)
889
- 00053/0952 7 (256,448,3)
890
- 00053/0970 7 (256,448,3)
891
- 00053/0981 7 (256,448,3)
892
- 00053/0999 7 (256,448,3)
893
- 00054/0003 7 (256,448,3)
894
- 00054/0013 7 (256,448,3)
895
- 00054/0020 7 (256,448,3)
896
- 00054/0022 7 (256,448,3)
897
- 00054/0023 7 (256,448,3)
898
- 00054/0044 7 (256,448,3)
899
- 00054/0051 7 (256,448,3)
900
- 00054/0063 7 (256,448,3)
901
- 00054/0065 7 (256,448,3)
902
- 00054/0145 7 (256,448,3)
903
- 00054/0153 7 (256,448,3)
904
- 00054/0203 7 (256,448,3)
905
- 00054/0325 7 (256,448,3)
906
- 00054/0445 7 (256,448,3)
907
- 00054/0448 7 (256,448,3)
908
- 00054/0456 7 (256,448,3)
909
- 00054/0457 7 (256,448,3)
910
- 00054/0519 7 (256,448,3)
911
- 00054/0524 7 (256,448,3)
912
- 00054/0530 7 (256,448,3)
913
- 00054/0532 7 (256,448,3)
914
- 00054/0535 7 (256,448,3)
915
- 00054/0574 7 (256,448,3)
916
- 00054/0760 7 (256,448,3)
917
- 00054/0767 7 (256,448,3)
918
- 00054/0837 7 (256,448,3)
919
- 00055/0011 7 (256,448,3)
920
- 00055/0109 7 (256,448,3)
921
- 00055/0111 7 (256,448,3)
922
- 00055/0117 7 (256,448,3)
923
- 00055/0119 7 (256,448,3)
924
- 00055/0182 7 (256,448,3)
925
- 00055/0192 7 (256,448,3)
926
- 00055/0193 7 (256,448,3)
927
- 00055/0200 7 (256,448,3)
928
- 00055/0204 7 (256,448,3)
929
- 00055/0207 7 (256,448,3)
930
- 00055/0212 7 (256,448,3)
931
- 00055/0213 7 (256,448,3)
932
- 00055/0348 7 (256,448,3)
933
- 00055/0423 7 (256,448,3)
934
- 00055/0427 7 (256,448,3)
935
- 00055/0456 7 (256,448,3)
936
- 00055/0489 7 (256,448,3)
937
- 00055/0689 7 (256,448,3)
938
- 00055/0753 7 (256,448,3)
939
- 00055/0802 7 (256,448,3)
940
- 00055/0844 7 (256,448,3)
941
- 00055/0850 7 (256,448,3)
942
- 00055/0982 7 (256,448,3)
943
- 00055/0993 7 (256,448,3)
944
- 00056/0113 7 (256,448,3)
945
- 00056/0148 7 (256,448,3)
946
- 00056/0151 7 (256,448,3)
947
- 00056/0316 7 (256,448,3)
948
- 00056/0379 7 (256,448,3)
949
- 00056/0380 7 (256,448,3)
950
- 00056/0385 7 (256,448,3)
951
- 00056/0505 7 (256,448,3)
952
- 00056/0579 7 (256,448,3)
953
- 00057/0254 7 (256,448,3)
954
- 00057/0264 7 (256,448,3)
955
- 00057/0272 7 (256,448,3)
956
- 00057/0403 7 (256,448,3)
957
- 00057/0501 7 (256,448,3)
958
- 00057/0503 7 (256,448,3)
959
- 00057/0884 7 (256,448,3)
960
- 00058/0026 7 (256,448,3)
961
- 00058/0029 7 (256,448,3)
962
- 00058/0104 7 (256,448,3)
963
- 00058/0124 7 (256,448,3)
964
- 00058/0162 7 (256,448,3)
965
- 00058/0288 7 (256,448,3)
966
- 00058/0289 7 (256,448,3)
967
- 00058/0323 7 (256,448,3)
968
- 00058/0328 7 (256,448,3)
969
- 00058/0329 7 (256,448,3)
970
- 00058/0337 7 (256,448,3)
971
- 00058/0367 7 (256,448,3)
972
- 00058/0383 7 (256,448,3)
973
- 00058/0395 7 (256,448,3)
974
- 00060/0178 7 (256,448,3)
975
- 00060/0182 7 (256,448,3)
976
- 00061/0001 7 (256,448,3)
977
- 00061/0003 7 (256,448,3)
978
- 00061/0006 7 (256,448,3)
979
- 00061/0443 7 (256,448,3)
980
- 00061/0586 7 (256,448,3)
981
- 00061/0587 7 (256,448,3)
982
- 00061/0774 7 (256,448,3)
983
- 00061/0789 7 (256,448,3)
984
- 00061/0815 7 (256,448,3)
985
- 00061/0817 7 (256,448,3)
986
- 00061/0826 7 (256,448,3)
987
- 00061/0829 7 (256,448,3)
988
- 00061/0830 7 (256,448,3)
989
- 00061/0832 7 (256,448,3)
990
- 00061/0833 7 (256,448,3)
991
- 00061/0836 7 (256,448,3)
992
- 00061/0837 7 (256,448,3)
993
- 00061/0839 7 (256,448,3)
994
- 00061/0843 7 (256,448,3)
995
- 00061/0849 7 (256,448,3)
996
- 00061/0859 7 (256,448,3)
997
- 00061/0861 7 (256,448,3)
998
- 00061/0868 7 (256,448,3)
999
- 00061/0877 7 (256,448,3)
1000
- 00061/0889 7 (256,448,3)
1001
- 00061/0905 7 (256,448,3)
1002
- 00062/0115 7 (256,448,3)
1003
- 00062/0118 7 (256,448,3)
1004
- 00062/0125 7 (256,448,3)
1005
- 00062/0134 7 (256,448,3)
1006
- 00062/0142 7 (256,448,3)
1007
- 00062/0400 7 (256,448,3)
1008
- 00062/0457 7 (256,448,3)
1009
- 00062/0459 7 (256,448,3)
1010
- 00062/0560 7 (256,448,3)
1011
- 00062/0650 7 (256,448,3)
1012
- 00062/0655 7 (256,448,3)
1013
- 00062/0715 7 (256,448,3)
1014
- 00062/0847 7 (256,448,3)
1015
- 00062/0905 7 (256,448,3)
1016
- 00062/0981 7 (256,448,3)
1017
- 00063/0177 7 (256,448,3)
1018
- 00063/0230 7 (256,448,3)
1019
- 00063/0253 7 (256,448,3)
1020
- 00063/0257 7 (256,448,3)
1021
- 00063/0326 7 (256,448,3)
1022
- 00063/0530 7 (256,448,3)
1023
- 00063/0677 7 (256,448,3)
1024
- 00063/0759 7 (256,448,3)
1025
- 00063/0761 7 (256,448,3)
1026
- 00063/0777 7 (256,448,3)
1027
- 00063/0842 7 (256,448,3)
1028
- 00063/0900 7 (256,448,3)
1029
- 00064/0014 7 (256,448,3)
1030
- 00064/0028 7 (256,448,3)
1031
- 00064/0029 7 (256,448,3)
1032
- 00064/0030 7 (256,448,3)
1033
- 00064/0037 7 (256,448,3)
1034
- 00064/0044 7 (256,448,3)
1035
- 00064/0280 7 (256,448,3)
1036
- 00064/0285 7 (256,448,3)
1037
- 00064/0286 7 (256,448,3)
1038
- 00064/0291 7 (256,448,3)
1039
- 00064/0300 7 (256,448,3)
1040
- 00064/0303 7 (256,448,3)
1041
- 00064/0308 7 (256,448,3)
1042
- 00064/0314 7 (256,448,3)
1043
- 00064/0316 7 (256,448,3)
1044
- 00064/0317 7 (256,448,3)
1045
- 00064/0323 7 (256,448,3)
1046
- 00064/0435 7 (256,448,3)
1047
- 00064/0733 7 (256,448,3)
1048
- 00064/0848 7 (256,448,3)
1049
- 00064/0868 7 (256,448,3)
1050
- 00064/0888 7 (256,448,3)
1051
- 00064/0898 7 (256,448,3)
1052
- 00065/0116 7 (256,448,3)
1053
- 00065/0121 7 (256,448,3)
1054
- 00065/0122 7 (256,448,3)
1055
- 00065/0124 7 (256,448,3)
1056
- 00065/0125 7 (256,448,3)
1057
- 00065/0126 7 (256,448,3)
1058
- 00065/0136 7 (256,448,3)
1059
- 00065/0146 7 (256,448,3)
1060
- 00065/0147 7 (256,448,3)
1061
- 00065/0163 7 (256,448,3)
1062
- 00065/0170 7 (256,448,3)
1063
- 00065/0175 7 (256,448,3)
1064
- 00065/0176 7 (256,448,3)
1065
- 00065/0180 7 (256,448,3)
1066
- 00065/0184 7 (256,448,3)
1067
- 00065/0186 7 (256,448,3)
1068
- 00065/0332 7 (256,448,3)
1069
- 00065/0343 7 (256,448,3)
1070
- 00065/0365 7 (256,448,3)
1071
- 00065/0393 7 (256,448,3)
1072
- 00065/0394 7 (256,448,3)
1073
- 00065/0442 7 (256,448,3)
1074
- 00065/0459 7 (256,448,3)
1075
- 00065/0462 7 (256,448,3)
1076
- 00065/0476 7 (256,448,3)
1077
- 00065/0483 7 (256,448,3)
1078
- 00065/0590 7 (256,448,3)
1079
- 00065/0593 7 (256,448,3)
1080
- 00065/0595 7 (256,448,3)
1081
- 00065/0774 7 (256,448,3)
1082
- 00065/0947 7 (256,448,3)
1083
- 00065/0985 7 (256,448,3)
1084
- 00065/0986 7 (256,448,3)
1085
- 00066/0015 7 (256,448,3)
1086
- 00066/0043 7 (256,448,3)
1087
- 00066/0131 7 (256,448,3)
1088
- 00066/0157 7 (256,448,3)
1089
- 00066/0169 7 (256,448,3)
1090
- 00066/0374 7 (256,448,3)
1091
- 00066/0382 7 (256,448,3)
1092
- 00066/0481 7 (256,448,3)
1093
- 00066/0482 7 (256,448,3)
1094
- 00066/0491 7 (256,448,3)
1095
- 00066/0493 7 (256,448,3)
1096
- 00066/0494 7 (256,448,3)
1097
- 00066/0496 7 (256,448,3)
1098
- 00066/0680 7 (256,448,3)
1099
- 00066/0700 7 (256,448,3)
1100
- 00066/0887 7 (256,448,3)
1101
- 00066/0910 7 (256,448,3)
1102
- 00066/0918 7 (256,448,3)
1103
- 00067/0024 7 (256,448,3)
1104
- 00067/0059 7 (256,448,3)
1105
- 00067/0408 7 (256,448,3)
1106
- 00067/0414 7 (256,448,3)
1107
- 00067/0417 7 (256,448,3)
1108
- 00067/0419 7 (256,448,3)
1109
- 00067/0423 7 (256,448,3)
1110
- 00067/0441 7 (256,448,3)
1111
- 00067/0467 7 (256,448,3)
1112
- 00067/0471 7 (256,448,3)
1113
- 00067/0487 7 (256,448,3)
1114
- 00067/0494 7 (256,448,3)
1115
- 00067/0497 7 (256,448,3)
1116
- 00067/0513 7 (256,448,3)
1117
- 00067/0521 7 (256,448,3)
1118
- 00068/0111 7 (256,448,3)
1119
- 00068/0123 7 (256,448,3)
1120
- 00068/0126 7 (256,448,3)
1121
- 00068/0129 7 (256,448,3)
1122
- 00068/0270 7 (256,448,3)
1123
- 00068/0330 7 (256,448,3)
1124
- 00068/0407 7 (256,448,3)
1125
- 00068/0428 7 (256,448,3)
1126
- 00068/0544 7 (256,448,3)
1127
- 00068/0635 7 (256,448,3)
1128
- 00068/0637 7 (256,448,3)
1129
- 00068/0736 7 (256,448,3)
1130
- 00068/0738 7 (256,448,3)
1131
- 00068/0747 7 (256,448,3)
1132
- 00068/0748 7 (256,448,3)
1133
- 00068/0749 7 (256,448,3)
1134
- 00068/0762 7 (256,448,3)
1135
- 00068/0815 7 (256,448,3)
1136
- 00068/0981 7 (256,448,3)
1137
- 00068/0982 7 (256,448,3)
1138
- 00069/0187 7 (256,448,3)
1139
- 00069/0191 7 (256,448,3)
1140
- 00070/0001 7 (256,448,3)
1141
- 00070/0003 7 (256,448,3)
1142
- 00070/0340 7 (256,448,3)
1143
- 00070/0341 7 (256,448,3)
1144
- 00070/0342 7 (256,448,3)
1145
- 00070/0347 7 (256,448,3)
1146
- 00070/0372 7 (256,448,3)
1147
- 00070/0383 7 (256,448,3)
1148
- 00070/0389 7 (256,448,3)
1149
- 00070/0728 7 (256,448,3)
1150
- 00070/0813 7 (256,448,3)
1151
- 00070/0814 7 (256,448,3)
1152
- 00070/0823 7 (256,448,3)
1153
- 00070/0840 7 (256,448,3)
1154
- 00070/0843 7 (256,448,3)
1155
- 00070/0861 7 (256,448,3)
1156
- 00071/0111 7 (256,448,3)
1157
- 00071/0138 7 (256,448,3)
1158
- 00071/0143 7 (256,448,3)
1159
- 00071/0150 7 (256,448,3)
1160
- 00071/0508 7 (256,448,3)
1161
- 00071/0514 7 (256,448,3)
1162
- 00071/0550 7 (256,448,3)
1163
- 00071/0556 7 (256,448,3)
1164
- 00071/0600 7 (256,448,3)
1165
- 00071/0665 7 (256,448,3)
1166
- 00071/0670 7 (256,448,3)
1167
- 00071/0672 7 (256,448,3)
1168
- 00071/0673 7 (256,448,3)
1169
- 00071/0705 7 (256,448,3)
1170
- 00071/0706 7 (256,448,3)
1171
- 00071/0707 7 (256,448,3)
1172
- 00071/0774 7 (256,448,3)
1173
- 00071/0799 7 (256,448,3)
1174
- 00071/0814 7 (256,448,3)
1175
- 00071/0816 7 (256,448,3)
1176
- 00071/0819 7 (256,448,3)
1177
- 00071/0823 7 (256,448,3)
1178
- 00071/0828 7 (256,448,3)
1179
- 00071/0830 7 (256,448,3)
1180
- 00071/0839 7 (256,448,3)
1181
- 00071/0841 7 (256,448,3)
1182
- 00072/0192 7 (256,448,3)
1183
- 00072/0194 7 (256,448,3)
1184
- 00072/0197 7 (256,448,3)
1185
- 00072/0199 7 (256,448,3)
1186
- 00072/0285 7 (256,448,3)
1187
- 00072/0586 7 (256,448,3)
1188
- 00072/0795 7 (256,448,3)
1189
- 00072/0811 7 (256,448,3)
1190
- 00072/0812 7 (256,448,3)
1191
- 00072/0824 7 (256,448,3)
1192
- 00072/0831 7 (256,448,3)
1193
- 00072/0835 7 (256,448,3)
1194
- 00072/0837 7 (256,448,3)
1195
- 00072/0841 7 (256,448,3)
1196
- 00072/0962 7 (256,448,3)
1197
- 00073/0296 7 (256,448,3)
1198
- 00073/0299 7 (256,448,3)
1199
- 00073/0300 7 (256,448,3)
1200
- 00073/0301 7 (256,448,3)
1201
- 00073/0427 7 (256,448,3)
1202
- 00073/0428 7 (256,448,3)
1203
- 00073/0494 7 (256,448,3)
1204
- 00073/0615 7 (256,448,3)
1205
- 00073/0620 7 (256,448,3)
1206
- 00073/0624 7 (256,448,3)
1207
- 00073/0979 7 (256,448,3)
1208
- 00074/0226 7 (256,448,3)
1209
- 00074/0250 7 (256,448,3)
1210
- 00074/0284 7 (256,448,3)
1211
- 00074/0503 7 (256,448,3)
1212
- 00074/0614 7 (256,448,3)
1213
- 00074/0629 7 (256,448,3)
1214
- 00074/0762 7 (256,448,3)
1215
- 00074/0765 7 (256,448,3)
1216
- 00074/0900 7 (256,448,3)
1217
- 00074/0908 7 (256,448,3)
1218
- 00075/0352 7 (256,448,3)
1219
- 00075/0360 7 (256,448,3)
1220
- 00075/0361 7 (256,448,3)
1221
- 00075/0365 7 (256,448,3)
1222
- 00075/0383 7 (256,448,3)
1223
- 00075/0384 7 (256,448,3)
1224
- 00075/0386 7 (256,448,3)
1225
- 00075/0407 7 (256,448,3)
1226
- 00075/0410 7 (256,448,3)
1227
- 00075/0412 7 (256,448,3)
1228
- 00075/0413 7 (256,448,3)
1229
- 00075/0459 7 (256,448,3)
1230
- 00075/0504 7 (256,448,3)
1231
- 00075/0515 7 (256,448,3)
1232
- 00075/0518 7 (256,448,3)
1233
- 00075/0567 7 (256,448,3)
1234
- 00075/0681 7 (256,448,3)
1235
- 00075/0693 7 (256,448,3)
1236
- 00075/0728 7 (256,448,3)
1237
- 00075/0731 7 (256,448,3)
1238
- 00075/0804 7 (256,448,3)
1239
- 00075/0974 7 (256,448,3)
1240
- 00075/0975 7 (256,448,3)
1241
- 00075/0983 7 (256,448,3)
1242
- 00075/0997 7 (256,448,3)
1243
- 00076/0006 7 (256,448,3)
1244
- 00076/0007 7 (256,448,3)
1245
- 00076/0011 7 (256,448,3)
1246
- 00076/0013 7 (256,448,3)
1247
- 00076/0014 7 (256,448,3)
1248
- 00076/0027 7 (256,448,3)
1249
- 00076/0029 7 (256,448,3)
1250
- 00076/0037 7 (256,448,3)
1251
- 00076/0041 7 (256,448,3)
1252
- 00076/0055 7 (256,448,3)
1253
- 00076/0071 7 (256,448,3)
1254
- 00076/0172 7 (256,448,3)
1255
- 00076/0275 7 (256,448,3)
1256
- 00076/0286 7 (256,448,3)
1257
- 00076/0467 7 (256,448,3)
1258
- 00076/0481 7 (256,448,3)
1259
- 00076/0527 7 (256,448,3)
1260
- 00076/0895 7 (256,448,3)
1261
- 00076/0896 7 (256,448,3)
1262
- 00076/0906 7 (256,448,3)
1263
- 00076/0924 7 (256,448,3)
1264
- 00076/0964 7 (256,448,3)
1265
- 00076/0984 7 (256,448,3)
1266
- 00077/0317 7 (256,448,3)
1267
- 00077/0322 7 (256,448,3)
1268
- 00077/0333 7 (256,448,3)
1269
- 00077/0334 7 (256,448,3)
1270
- 00077/0480 7 (256,448,3)
1271
- 00077/0488 7 (256,448,3)
1272
- 00077/0490 7 (256,448,3)
1273
- 00077/0582 7 (256,448,3)
1274
- 00077/0586 7 (256,448,3)
1275
- 00077/0969 7 (256,448,3)
1276
- 00078/0007 7 (256,448,3)
1277
- 00078/0011 7 (256,448,3)
1278
- 00078/0153 7 (256,448,3)
1279
- 00078/0289 7 (256,448,3)
1280
- 00078/0312 7 (256,448,3)
1281
- 00078/0492 7 (256,448,3)
1282
- 00078/0580 7 (256,448,3)
1283
- 00078/0595 7 (256,448,3)
1284
- 00078/0814 7 (256,448,3)
1285
- 00078/0950 7 (256,448,3)
1286
- 00078/0955 7 (256,448,3)
1287
- 00079/0060 7 (256,448,3)
1288
- 00079/0067 7 (256,448,3)
1289
- 00080/0216 7 (256,448,3)
1290
- 00080/0308 7 (256,448,3)
1291
- 00080/0504 7 (256,448,3)
1292
- 00080/0552 7 (256,448,3)
1293
- 00080/0576 7 (256,448,3)
1294
- 00080/0583 7 (256,448,3)
1295
- 00080/0837 7 (256,448,3)
1296
- 00080/0839 7 (256,448,3)
1297
- 00080/0871 7 (256,448,3)
1298
- 00080/0877 7 (256,448,3)
1299
- 00080/0880 7 (256,448,3)
1300
- 00080/0969 7 (256,448,3)
1301
- 00080/0973 7 (256,448,3)
1302
- 00080/0980 7 (256,448,3)
1303
- 00081/0202 7 (256,448,3)
1304
- 00081/0203 7 (256,448,3)
1305
- 00081/0210 7 (256,448,3)
1306
- 00081/0268 7 (256,448,3)
1307
- 00081/0281 7 (256,448,3)
1308
- 00081/0283 7 (256,448,3)
1309
- 00081/0317 7 (256,448,3)
1310
- 00081/0327 7 (256,448,3)
1311
- 00082/0018 7 (256,448,3)
1312
- 00082/0025 7 (256,448,3)
1313
- 00082/0089 7 (256,448,3)
1314
- 00082/0140 7 (256,448,3)
1315
- 00082/0442 7 (256,448,3)
1316
- 00082/0465 7 (256,448,3)
1317
- 00082/0473 7 (256,448,3)
1318
- 00082/0481 7 (256,448,3)
1319
- 00082/0492 7 (256,448,3)
1320
- 00082/0495 7 (256,448,3)
1321
- 00082/0497 7 (256,448,3)
1322
- 00082/0502 7 (256,448,3)
1323
- 00082/0504 7 (256,448,3)
1324
- 00082/0506 7 (256,448,3)
1325
- 00082/0507 7 (256,448,3)
1326
- 00082/0510 7 (256,448,3)
1327
- 00082/0519 7 (256,448,3)
1328
- 00082/0523 7 (256,448,3)
1329
- 00082/0588 7 (256,448,3)
1330
- 00082/0597 7 (256,448,3)
1331
- 00082/0632 7 (256,448,3)
1332
- 00082/0751 7 (256,448,3)
1333
- 00082/0767 7 (256,448,3)
1334
- 00082/0771 7 (256,448,3)
1335
- 00082/0790 7 (256,448,3)
1336
- 00082/0804 7 (256,448,3)
1337
- 00082/0823 7 (256,448,3)
1338
- 00083/0052 7 (256,448,3)
1339
- 00083/0056 7 (256,448,3)
1340
- 00083/0113 7 (256,448,3)
1341
- 00083/0114 7 (256,448,3)
1342
- 00083/0122 7 (256,448,3)
1343
- 00083/0137 7 (256,448,3)
1344
- 00083/0270 7 (256,448,3)
1345
- 00083/0295 7 (256,448,3)
1346
- 00083/0303 7 (256,448,3)
1347
- 00083/0308 7 (256,448,3)
1348
- 00083/0586 7 (256,448,3)
1349
- 00083/0592 7 (256,448,3)
1350
- 00083/0640 7 (256,448,3)
1351
- 00083/0648 7 (256,448,3)
1352
- 00083/0654 7 (256,448,3)
1353
- 00083/0662 7 (256,448,3)
1354
- 00083/0666 7 (256,448,3)
1355
- 00083/0668 7 (256,448,3)
1356
- 00083/0669 7 (256,448,3)
1357
- 00083/0675 7 (256,448,3)
1358
- 00083/0679 7 (256,448,3)
1359
- 00083/0681 7 (256,448,3)
1360
- 00083/0682 7 (256,448,3)
1361
- 00083/0694 7 (256,448,3)
1362
- 00083/0695 7 (256,448,3)
1363
- 00083/0697 7 (256,448,3)
1364
- 00083/0704 7 (256,448,3)
1365
- 00083/0713 7 (256,448,3)
1366
- 00083/0721 7 (256,448,3)
1367
- 00083/0855 7 (256,448,3)
1368
- 00084/0109 7 (256,448,3)
1369
- 00084/0113 7 (256,448,3)
1370
- 00084/0306 7 (256,448,3)
1371
- 00084/0442 7 (256,448,3)
1372
- 00084/0669 7 (256,448,3)
1373
- 00084/0679 7 (256,448,3)
1374
- 00084/0685 7 (256,448,3)
1375
- 00084/0691 7 (256,448,3)
1376
- 00084/0768 7 (256,448,3)
1377
- 00084/0817 7 (256,448,3)
1378
- 00085/0027 7 (256,448,3)
1379
- 00085/0035 7 (256,448,3)
1380
- 00085/0038 7 (256,448,3)
1381
- 00085/0223 7 (256,448,3)
1382
- 00085/0233 7 (256,448,3)
1383
- 00085/0281 7 (256,448,3)
1384
- 00085/0287 7 (256,448,3)
1385
- 00085/0313 7 (256,448,3)
1386
- 00085/0521 7 (256,448,3)
1387
- 00085/0848 7 (256,448,3)
1388
- 00085/0855 7 (256,448,3)
1389
- 00085/0865 7 (256,448,3)
1390
- 00085/0952 7 (256,448,3)
1391
- 00085/0964 7 (256,448,3)
1392
- 00085/0973 7 (256,448,3)
1393
- 00085/0986 7 (256,448,3)
1394
- 00085/0993 7 (256,448,3)
1395
- 00086/0070 7 (256,448,3)
1396
- 00086/0075 7 (256,448,3)
1397
- 00086/0094 7 (256,448,3)
1398
- 00086/0103 7 (256,448,3)
1399
- 00086/0112 7 (256,448,3)
1400
- 00086/0288 7 (256,448,3)
1401
- 00086/0576 7 (256,448,3)
1402
- 00086/0580 7 (256,448,3)
1403
- 00086/0584 7 (256,448,3)
1404
- 00086/0599 7 (256,448,3)
1405
- 00086/0600 7 (256,448,3)
1406
- 00086/0602 7 (256,448,3)
1407
- 00086/0612 7 (256,448,3)
1408
- 00086/0629 7 (256,448,3)
1409
- 00086/0655 7 (256,448,3)
1410
- 00086/0679 7 (256,448,3)
1411
- 00086/0694 7 (256,448,3)
1412
- 00086/0695 7 (256,448,3)
1413
- 00086/0701 7 (256,448,3)
1414
- 00086/0760 7 (256,448,3)
1415
- 00086/0786 7 (256,448,3)
1416
- 00086/0845 7 (256,448,3)
1417
- 00086/0868 7 (256,448,3)
1418
- 00086/0889 7 (256,448,3)
1419
- 00086/0891 7 (256,448,3)
1420
- 00086/0927 7 (256,448,3)
1421
- 00086/0938 7 (256,448,3)
1422
- 00086/0946 7 (256,448,3)
1423
- 00086/0963 7 (256,448,3)
1424
- 00086/0969 7 (256,448,3)
1425
- 00087/0023 7 (256,448,3)
1426
- 00087/0029 7 (256,448,3)
1427
- 00087/0144 7 (256,448,3)
1428
- 00087/0148 7 (256,448,3)
1429
- 00087/0159 7 (256,448,3)
1430
- 00087/0174 7 (256,448,3)
1431
- 00087/0283 7 (256,448,3)
1432
- 00087/0284 7 (256,448,3)
1433
- 00087/0294 7 (256,448,3)
1434
- 00087/0296 7 (256,448,3)
1435
- 00087/0498 7 (256,448,3)
1436
- 00087/0502 7 (256,448,3)
1437
- 00087/0532 7 (256,448,3)
1438
- 00087/0557 7 (256,448,3)
1439
- 00087/0559 7 (256,448,3)
1440
- 00087/0574 7 (256,448,3)
1441
- 00087/0577 7 (256,448,3)
1442
- 00088/0006 7 (256,448,3)
1443
- 00088/0268 7 (256,448,3)
1444
- 00088/0320 7 (256,448,3)
1445
- 00088/0412 7 (256,448,3)
1446
- 00088/0431 7 (256,448,3)
1447
- 00088/0432 7 (256,448,3)
1448
- 00088/0465 7 (256,448,3)
1449
- 00088/0507 7 (256,448,3)
1450
- 00088/0565 7 (256,448,3)
1451
- 00088/0629 7 (256,448,3)
1452
- 00088/0831 7 (256,448,3)
1453
- 00088/0836 7 (256,448,3)
1454
- 00088/0972 7 (256,448,3)
1455
- 00088/0974 7 (256,448,3)
1456
- 00088/0980 7 (256,448,3)
1457
- 00089/0067 7 (256,448,3)
1458
- 00089/0244 7 (256,448,3)
1459
- 00089/0404 7 (256,448,3)
1460
- 00089/0416 7 (256,448,3)
1461
- 00089/0419 7 (256,448,3)
1462
- 00089/0428 7 (256,448,3)
1463
- 00089/0712 7 (256,448,3)
1464
- 00089/0713 7 (256,448,3)
1465
- 00089/0723 7 (256,448,3)
1466
- 00089/0727 7 (256,448,3)
1467
- 00089/0770 7 (256,448,3)
1468
- 00089/0809 7 (256,448,3)
1469
- 00089/0811 7 (256,448,3)
1470
- 00089/0888 7 (256,448,3)
1471
- 00089/0898 7 (256,448,3)
1472
- 00089/0903 7 (256,448,3)
1473
- 00089/0907 7 (256,448,3)
1474
- 00089/0911 7 (256,448,3)
1475
- 00089/0915 7 (256,448,3)
1476
- 00089/0926 7 (256,448,3)
1477
- 00089/0955 7 (256,448,3)
1478
- 00090/0027 7 (256,448,3)
1479
- 00090/0028 7 (256,448,3)
1480
- 00090/0032 7 (256,448,3)
1481
- 00090/0038 7 (256,448,3)
1482
- 00090/0076 7 (256,448,3)
1483
- 00090/0081 7 (256,448,3)
1484
- 00090/0086 7 (256,448,3)
1485
- 00090/0119 7 (256,448,3)
1486
- 00090/0258 7 (256,448,3)
1487
- 00090/0261 7 (256,448,3)
1488
- 00090/0447 7 (256,448,3)
1489
- 00090/0498 7 (256,448,3)
1490
- 00090/0514 7 (256,448,3)
1491
- 00090/0523 7 (256,448,3)
1492
- 00090/0530 7 (256,448,3)
1493
- 00090/0540 7 (256,448,3)
1494
- 00090/0548 7 (256,448,3)
1495
- 00090/0565 7 (256,448,3)
1496
- 00090/0578 7 (256,448,3)
1497
- 00090/0580 7 (256,448,3)
1498
- 00090/0581 7 (256,448,3)
1499
- 00090/0780 7 (256,448,3)
1500
- 00090/0940 7 (256,448,3)
1501
- 00090/0984 7 (256,448,3)
1502
- 00091/0023 7 (256,448,3)
1503
- 00091/0051 7 (256,448,3)
1504
- 00091/0317 7 (256,448,3)
1505
- 00091/0320 7 (256,448,3)
1506
- 00091/0582 7 (256,448,3)
1507
- 00091/0585 7 (256,448,3)
1508
- 00091/0588 7 (256,448,3)
1509
- 00091/0601 7 (256,448,3)
1510
- 00091/0602 7 (256,448,3)
1511
- 00091/0603 7 (256,448,3)
1512
- 00091/0634 7 (256,448,3)
1513
- 00091/0693 7 (256,448,3)
1514
- 00091/0741 7 (256,448,3)
1515
- 00091/0966 7 (256,448,3)
1516
- 00091/0973 7 (256,448,3)
1517
- 00091/0985 7 (256,448,3)
1518
- 00092/0007 7 (256,448,3)
1519
- 00092/0132 7 (256,448,3)
1520
- 00092/0270 7 (256,448,3)
1521
- 00092/0296 7 (256,448,3)
1522
- 00092/0611 7 (256,448,3)
1523
- 00092/0625 7 (256,448,3)
1524
- 00092/0627 7 (256,448,3)
1525
- 00092/0651 7 (256,448,3)
1526
- 00092/0652 7 (256,448,3)
1527
- 00092/0910 7 (256,448,3)
1528
- 00093/0075 7 (256,448,3)
1529
- 00093/0078 7 (256,448,3)
1530
- 00093/0100 7 (256,448,3)
1531
- 00093/0132 7 (256,448,3)
1532
- 00093/0133 7 (256,448,3)
1533
- 00093/0176 7 (256,448,3)
1534
- 00093/0177 7 (256,448,3)
1535
- 00093/0178 7 (256,448,3)
1536
- 00093/0181 7 (256,448,3)
1537
- 00093/0183 7 (256,448,3)
1538
- 00093/0184 7 (256,448,3)
1539
- 00093/0286 7 (256,448,3)
1540
- 00093/0304 7 (256,448,3)
1541
- 00093/0305 7 (256,448,3)
1542
- 00093/0319 7 (256,448,3)
1543
- 00093/0324 7 (256,448,3)
1544
- 00093/0325 7 (256,448,3)
1545
- 00093/0327 7 (256,448,3)
1546
- 00093/0331 7 (256,448,3)
1547
- 00093/0444 7 (256,448,3)
1548
- 00093/0450 7 (256,448,3)
1549
- 00093/0593 7 (256,448,3)
1550
- 00094/0032 7 (256,448,3)
1551
- 00094/0057 7 (256,448,3)
1552
- 00094/0139 7 (256,448,3)
1553
- 00094/0206 7 (256,448,3)
1554
- 00094/0211 7 (256,448,3)
1555
- 00094/0215 7 (256,448,3)
1556
- 00094/0218 7 (256,448,3)
1557
- 00094/0257 7 (256,448,3)
1558
- 00094/0329 7 (256,448,3)
1559
- 00094/0331 7 (256,448,3)
1560
- 00094/0332 7 (256,448,3)
1561
- 00094/0369 7 (256,448,3)
1562
- 00094/0370 7 (256,448,3)
1563
- 00094/0383 7 (256,448,3)
1564
- 00094/0385 7 (256,448,3)
1565
- 00094/0387 7 (256,448,3)
1566
- 00094/0399 7 (256,448,3)
1567
- 00094/0605 7 (256,448,3)
1568
- 00094/0648 7 (256,448,3)
1569
- 00094/0649 7 (256,448,3)
1570
- 00094/0759 7 (256,448,3)
1571
- 00094/0800 7 (256,448,3)
1572
- 00094/0894 7 (256,448,3)
1573
- 00094/0896 7 (256,448,3)
1574
- 00095/0089 7 (256,448,3)
1575
- 00095/0108 7 (256,448,3)
1576
- 00095/0109 7 (256,448,3)
1577
- 00095/0114 7 (256,448,3)
1578
- 00095/0128 7 (256,448,3)
1579
- 00095/0133 7 (256,448,3)
1580
- 00095/0150 7 (256,448,3)
1581
- 00095/0153 7 (256,448,3)
1582
- 00095/0154 7 (256,448,3)
1583
- 00095/0196 7 (256,448,3)
1584
- 00095/0209 7 (256,448,3)
1585
- 00095/0228 7 (256,448,3)
1586
- 00095/0230 7 (256,448,3)
1587
- 00095/0231 7 (256,448,3)
1588
- 00095/0242 7 (256,448,3)
1589
- 00095/0243 7 (256,448,3)
1590
- 00095/0253 7 (256,448,3)
1591
- 00095/0280 7 (256,448,3)
1592
- 00095/0281 7 (256,448,3)
1593
- 00095/0283 7 (256,448,3)
1594
- 00095/0314 7 (256,448,3)
1595
- 00095/0868 7 (256,448,3)
1596
- 00095/0894 7 (256,448,3)
1597
- 00096/0062 7 (256,448,3)
1598
- 00096/0347 7 (256,448,3)
1599
- 00096/0348 7 (256,448,3)
1600
- 00096/0359 7 (256,448,3)
1601
- 00096/0363 7 (256,448,3)
1602
- 00096/0373 7 (256,448,3)
1603
- 00096/0378 7 (256,448,3)
1604
- 00096/0387 7 (256,448,3)
1605
- 00096/0395 7 (256,448,3)
1606
- 00096/0396 7 (256,448,3)
1607
- 00096/0404 7 (256,448,3)
1608
- 00096/0653 7 (256,448,3)
1609
- 00096/0668 7 (256,448,3)
1610
- 00096/0679 7 (256,448,3)
1611
- 00096/0729 7 (256,448,3)
1612
- 00096/0736 7 (256,448,3)
1613
- 00096/0823 7 (256,448,3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/meta_info/meta_info_Vimeo90K_train_GT.txt DELETED
The diff for this file is too large to render. See raw diff
 
basicsr/data/paired_image_dataset.py DELETED
@@ -1,106 +0,0 @@
1
- from torch.utils import data as data
2
- from torchvision.transforms.functional import normalize
3
-
4
- from basicsr.data.data_util import paired_paths_from_folder, paired_paths_from_lmdb, paired_paths_from_meta_info_file
5
- from basicsr.data.transforms import augment, paired_random_crop
6
- from basicsr.utils import FileClient, bgr2ycbcr, imfrombytes, img2tensor
7
- from basicsr.utils.registry import DATASET_REGISTRY
8
-
9
-
10
- @DATASET_REGISTRY.register()
11
- class PairedImageDataset(data.Dataset):
12
- """Paired image dataset for image restoration.
13
-
14
- Read LQ (Low Quality, e.g. LR (Low Resolution), blurry, noisy, etc) and GT image pairs.
15
-
16
- There are three modes:
17
-
18
- 1. **lmdb**: Use lmdb files. If opt['io_backend'] == lmdb.
19
- 2. **meta_info_file**: Use meta information file to generate paths. \
20
- If opt['io_backend'] != lmdb and opt['meta_info_file'] is not None.
21
- 3. **folder**: Scan folders to generate paths. The rest.
22
-
23
- Args:
24
- opt (dict): Config for train datasets. It contains the following keys:
25
- dataroot_gt (str): Data root path for gt.
26
- dataroot_lq (str): Data root path for lq.
27
- meta_info_file (str): Path for meta information file.
28
- io_backend (dict): IO backend type and other kwarg.
29
- filename_tmpl (str): Template for each filename. Note that the template excludes the file extension.
30
- Default: '{}'.
31
- gt_size (int): Cropped patched size for gt patches.
32
- use_hflip (bool): Use horizontal flips.
33
- use_rot (bool): Use rotation (use vertical flip and transposing h and w for implementation).
34
- scale (bool): Scale, which will be added automatically.
35
- phase (str): 'train' or 'val'.
36
- """
37
-
38
- def __init__(self, opt):
39
- super(PairedImageDataset, self).__init__()
40
- self.opt = opt
41
- # file client (io backend)
42
- self.file_client = None
43
- self.io_backend_opt = opt['io_backend']
44
- self.mean = opt['mean'] if 'mean' in opt else None
45
- self.std = opt['std'] if 'std' in opt else None
46
-
47
- self.gt_folder, self.lq_folder = opt['dataroot_gt'], opt['dataroot_lq']
48
- if 'filename_tmpl' in opt:
49
- self.filename_tmpl = opt['filename_tmpl']
50
- else:
51
- self.filename_tmpl = '{}'
52
-
53
- if self.io_backend_opt['type'] == 'lmdb':
54
- self.io_backend_opt['db_paths'] = [self.lq_folder, self.gt_folder]
55
- self.io_backend_opt['client_keys'] = ['lq', 'gt']
56
- self.paths = paired_paths_from_lmdb([self.lq_folder, self.gt_folder], ['lq', 'gt'])
57
- elif 'meta_info_file' in self.opt and self.opt['meta_info_file'] is not None:
58
- self.paths = paired_paths_from_meta_info_file([self.lq_folder, self.gt_folder], ['lq', 'gt'],
59
- self.opt['meta_info_file'], self.filename_tmpl)
60
- else:
61
- self.paths = paired_paths_from_folder([self.lq_folder, self.gt_folder], ['lq', 'gt'], self.filename_tmpl)
62
-
63
- def __getitem__(self, index):
64
- if self.file_client is None:
65
- self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
66
-
67
- scale = self.opt['scale']
68
-
69
- # Load gt and lq images. Dimension order: HWC; channel order: BGR;
70
- # image range: [0, 1], float32.
71
- gt_path = self.paths[index]['gt_path']
72
- img_bytes = self.file_client.get(gt_path, 'gt')
73
- img_gt = imfrombytes(img_bytes, float32=True)
74
- lq_path = self.paths[index]['lq_path']
75
- img_bytes = self.file_client.get(lq_path, 'lq')
76
- img_lq = imfrombytes(img_bytes, float32=True)
77
-
78
- # augmentation for training
79
- if self.opt['phase'] == 'train':
80
- gt_size = self.opt['gt_size']
81
- # random crop
82
- img_gt, img_lq = paired_random_crop(img_gt, img_lq, gt_size, scale, gt_path)
83
- # flip, rotation
84
- img_gt, img_lq = augment([img_gt, img_lq], self.opt['use_hflip'], self.opt['use_rot'])
85
-
86
- # color space transform
87
- if 'color' in self.opt and self.opt['color'] == 'y':
88
- img_gt = bgr2ycbcr(img_gt, y_only=True)[..., None]
89
- img_lq = bgr2ycbcr(img_lq, y_only=True)[..., None]
90
-
91
- # crop the unmatched GT images during validation or testing, especially for SR benchmark datasets
92
- # TODO: It is better to update the datasets, rather than force to crop
93
- if self.opt['phase'] != 'train':
94
- img_gt = img_gt[0:img_lq.shape[0] * scale, 0:img_lq.shape[1] * scale, :]
95
-
96
- # BGR to RGB, HWC to CHW, numpy to tensor
97
- img_gt, img_lq = img2tensor([img_gt, img_lq], bgr2rgb=True, float32=True)
98
- # normalize
99
- if self.mean is not None or self.std is not None:
100
- normalize(img_lq, self.mean, self.std, inplace=True)
101
- normalize(img_gt, self.mean, self.std, inplace=True)
102
-
103
- return {'lq': img_lq, 'gt': img_gt, 'lq_path': lq_path, 'gt_path': gt_path}
104
-
105
- def __len__(self):
106
- return len(self.paths)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/prefetch_dataloader.py DELETED
@@ -1,122 +0,0 @@
1
- import queue as Queue
2
- import threading
3
- import torch
4
- from torch.utils.data import DataLoader
5
-
6
-
7
- class PrefetchGenerator(threading.Thread):
8
- """A general prefetch generator.
9
-
10
- Reference: https://stackoverflow.com/questions/7323664/python-generator-pre-fetch
11
-
12
- Args:
13
- generator: Python generator.
14
- num_prefetch_queue (int): Number of prefetch queue.
15
- """
16
-
17
- def __init__(self, generator, num_prefetch_queue):
18
- threading.Thread.__init__(self)
19
- self.queue = Queue.Queue(num_prefetch_queue)
20
- self.generator = generator
21
- self.daemon = True
22
- self.start()
23
-
24
- def run(self):
25
- for item in self.generator:
26
- self.queue.put(item)
27
- self.queue.put(None)
28
-
29
- def __next__(self):
30
- next_item = self.queue.get()
31
- if next_item is None:
32
- raise StopIteration
33
- return next_item
34
-
35
- def __iter__(self):
36
- return self
37
-
38
-
39
- class PrefetchDataLoader(DataLoader):
40
- """Prefetch version of dataloader.
41
-
42
- Reference: https://github.com/IgorSusmelj/pytorch-styleguide/issues/5#
43
-
44
- TODO:
45
- Need to test on single gpu and ddp (multi-gpu). There is a known issue in
46
- ddp.
47
-
48
- Args:
49
- num_prefetch_queue (int): Number of prefetch queue.
50
- kwargs (dict): Other arguments for dataloader.
51
- """
52
-
53
- def __init__(self, num_prefetch_queue, **kwargs):
54
- self.num_prefetch_queue = num_prefetch_queue
55
- super(PrefetchDataLoader, self).__init__(**kwargs)
56
-
57
- def __iter__(self):
58
- return PrefetchGenerator(super().__iter__(), self.num_prefetch_queue)
59
-
60
-
61
- class CPUPrefetcher():
62
- """CPU prefetcher.
63
-
64
- Args:
65
- loader: Dataloader.
66
- """
67
-
68
- def __init__(self, loader):
69
- self.ori_loader = loader
70
- self.loader = iter(loader)
71
-
72
- def next(self):
73
- try:
74
- return next(self.loader)
75
- except StopIteration:
76
- return None
77
-
78
- def reset(self):
79
- self.loader = iter(self.ori_loader)
80
-
81
-
82
- class CUDAPrefetcher():
83
- """CUDA prefetcher.
84
-
85
- Reference: https://github.com/NVIDIA/apex/issues/304#
86
-
87
- It may consume more GPU memory.
88
-
89
- Args:
90
- loader: Dataloader.
91
- opt (dict): Options.
92
- """
93
-
94
- def __init__(self, loader, opt):
95
- self.ori_loader = loader
96
- self.loader = iter(loader)
97
- self.opt = opt
98
- self.stream = torch.cuda.Stream()
99
- self.device = torch.device('cuda' if opt['num_gpu'] != 0 else 'cpu')
100
- self.preload()
101
-
102
- def preload(self):
103
- try:
104
- self.batch = next(self.loader) # self.batch is a dict
105
- except StopIteration:
106
- self.batch = None
107
- return None
108
- # put tensors to gpu
109
- with torch.cuda.stream(self.stream):
110
- for k, v in self.batch.items():
111
- if torch.is_tensor(v):
112
- self.batch[k] = self.batch[k].to(device=self.device, non_blocking=True)
113
-
114
- def next(self):
115
- torch.cuda.current_stream().wait_stream(self.stream)
116
- batch = self.batch
117
- self.preload()
118
- return batch
119
-
120
- def reset(self):
121
- self.loader = iter(self.ori_loader)
122
- self.preload()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/realesrgan_dataset.py DELETED
@@ -1,193 +0,0 @@
1
- import cv2
2
- import math
3
- import numpy as np
4
- import os
5
- import os.path as osp
6
- import random
7
- import time
8
- import torch
9
- from torch.utils import data as data
10
-
11
- from basicsr.data.degradations import circular_lowpass_kernel, random_mixed_kernels
12
- from basicsr.data.transforms import augment
13
- from basicsr.utils import FileClient, get_root_logger, imfrombytes, img2tensor
14
- from basicsr.utils.registry import DATASET_REGISTRY
15
-
16
-
17
- @DATASET_REGISTRY.register(suffix='basicsr')
18
- class RealESRGANDataset(data.Dataset):
19
- """Dataset used for Real-ESRGAN model:
20
- Real-ESRGAN: Training Real-World Blind Super-Resolution with Pure Synthetic Data.
21
-
22
- It loads gt (Ground-Truth) images, and augments them.
23
- It also generates blur kernels and sinc kernels for generating low-quality images.
24
- Note that the low-quality images are processed in tensors on GPUS for faster processing.
25
-
26
- Args:
27
- opt (dict): Config for train datasets. It contains the following keys:
28
- dataroot_gt (str): Data root path for gt.
29
- meta_info (str): Path for meta information file.
30
- io_backend (dict): IO backend type and other kwarg.
31
- use_hflip (bool): Use horizontal flips.
32
- use_rot (bool): Use rotation (use vertical flip and transposing h and w for implementation).
33
- Please see more options in the codes.
34
- """
35
-
36
- def __init__(self, opt):
37
- super(RealESRGANDataset, self).__init__()
38
- self.opt = opt
39
- self.file_client = None
40
- self.io_backend_opt = opt['io_backend']
41
- self.gt_folder = opt['dataroot_gt']
42
-
43
- # file client (lmdb io backend)
44
- if self.io_backend_opt['type'] == 'lmdb':
45
- self.io_backend_opt['db_paths'] = [self.gt_folder]
46
- self.io_backend_opt['client_keys'] = ['gt']
47
- if not self.gt_folder.endswith('.lmdb'):
48
- raise ValueError(f"'dataroot_gt' should end with '.lmdb', but received {self.gt_folder}")
49
- with open(osp.join(self.gt_folder, 'meta_info.txt')) as fin:
50
- self.paths = [line.split('.')[0] for line in fin]
51
- else:
52
- # disk backend with meta_info
53
- # Each line in the meta_info describes the relative path to an image
54
- with open(self.opt['meta_info']) as fin:
55
- paths = [line.strip().split(' ')[0] for line in fin]
56
- self.paths = [os.path.join(self.gt_folder, v) for v in paths]
57
-
58
- # blur settings for the first degradation
59
- self.blur_kernel_size = opt['blur_kernel_size']
60
- self.kernel_list = opt['kernel_list']
61
- self.kernel_prob = opt['kernel_prob'] # a list for each kernel probability
62
- self.blur_sigma = opt['blur_sigma']
63
- self.betag_range = opt['betag_range'] # betag used in generalized Gaussian blur kernels
64
- self.betap_range = opt['betap_range'] # betap used in plateau blur kernels
65
- self.sinc_prob = opt['sinc_prob'] # the probability for sinc filters
66
-
67
- # blur settings for the second degradation
68
- self.blur_kernel_size2 = opt['blur_kernel_size2']
69
- self.kernel_list2 = opt['kernel_list2']
70
- self.kernel_prob2 = opt['kernel_prob2']
71
- self.blur_sigma2 = opt['blur_sigma2']
72
- self.betag_range2 = opt['betag_range2']
73
- self.betap_range2 = opt['betap_range2']
74
- self.sinc_prob2 = opt['sinc_prob2']
75
-
76
- # a final sinc filter
77
- self.final_sinc_prob = opt['final_sinc_prob']
78
-
79
- self.kernel_range = [2 * v + 1 for v in range(3, 11)] # kernel size ranges from 7 to 21
80
- # TODO: kernel range is now hard-coded, should be in the configure file
81
- self.pulse_tensor = torch.zeros(21, 21).float() # convolving with pulse tensor brings no blurry effect
82
- self.pulse_tensor[10, 10] = 1
83
-
84
- def __getitem__(self, index):
85
- if self.file_client is None:
86
- self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
87
-
88
- # -------------------------------- Load gt images -------------------------------- #
89
- # Shape: (h, w, c); channel order: BGR; image range: [0, 1], float32.
90
- gt_path = self.paths[index]
91
- # avoid errors caused by high latency in reading files
92
- retry = 3
93
- while retry > 0:
94
- try:
95
- img_bytes = self.file_client.get(gt_path, 'gt')
96
- except (IOError, OSError) as e:
97
- logger = get_root_logger()
98
- logger.warn(f'File client error: {e}, remaining retry times: {retry - 1}')
99
- # change another file to read
100
- index = random.randint(0, self.__len__())
101
- gt_path = self.paths[index]
102
- time.sleep(1) # sleep 1s for occasional server congestion
103
- else:
104
- break
105
- finally:
106
- retry -= 1
107
- img_gt = imfrombytes(img_bytes, float32=True)
108
-
109
- # -------------------- Do augmentation for training: flip, rotation -------------------- #
110
- img_gt = augment(img_gt, self.opt['use_hflip'], self.opt['use_rot'])
111
-
112
- # crop or pad to 400
113
- # TODO: 400 is hard-coded. You may change it accordingly
114
- h, w = img_gt.shape[0:2]
115
- crop_pad_size = 400
116
- # pad
117
- if h < crop_pad_size or w < crop_pad_size:
118
- pad_h = max(0, crop_pad_size - h)
119
- pad_w = max(0, crop_pad_size - w)
120
- img_gt = cv2.copyMakeBorder(img_gt, 0, pad_h, 0, pad_w, cv2.BORDER_REFLECT_101)
121
- # crop
122
- if img_gt.shape[0] > crop_pad_size or img_gt.shape[1] > crop_pad_size:
123
- h, w = img_gt.shape[0:2]
124
- # randomly choose top and left coordinates
125
- top = random.randint(0, h - crop_pad_size)
126
- left = random.randint(0, w - crop_pad_size)
127
- img_gt = img_gt[top:top + crop_pad_size, left:left + crop_pad_size, ...]
128
-
129
- # ------------------------ Generate kernels (used in the first degradation) ------------------------ #
130
- kernel_size = random.choice(self.kernel_range)
131
- if np.random.uniform() < self.opt['sinc_prob']:
132
- # this sinc filter setting is for kernels ranging from [7, 21]
133
- if kernel_size < 13:
134
- omega_c = np.random.uniform(np.pi / 3, np.pi)
135
- else:
136
- omega_c = np.random.uniform(np.pi / 5, np.pi)
137
- kernel = circular_lowpass_kernel(omega_c, kernel_size, pad_to=False)
138
- else:
139
- kernel = random_mixed_kernels(
140
- self.kernel_list,
141
- self.kernel_prob,
142
- kernel_size,
143
- self.blur_sigma,
144
- self.blur_sigma, [-math.pi, math.pi],
145
- self.betag_range,
146
- self.betap_range,
147
- noise_range=None)
148
- # pad kernel
149
- pad_size = (21 - kernel_size) // 2
150
- kernel = np.pad(kernel, ((pad_size, pad_size), (pad_size, pad_size)))
151
-
152
- # ------------------------ Generate kernels (used in the second degradation) ------------------------ #
153
- kernel_size = random.choice(self.kernel_range)
154
- if np.random.uniform() < self.opt['sinc_prob2']:
155
- if kernel_size < 13:
156
- omega_c = np.random.uniform(np.pi / 3, np.pi)
157
- else:
158
- omega_c = np.random.uniform(np.pi / 5, np.pi)
159
- kernel2 = circular_lowpass_kernel(omega_c, kernel_size, pad_to=False)
160
- else:
161
- kernel2 = random_mixed_kernels(
162
- self.kernel_list2,
163
- self.kernel_prob2,
164
- kernel_size,
165
- self.blur_sigma2,
166
- self.blur_sigma2, [-math.pi, math.pi],
167
- self.betag_range2,
168
- self.betap_range2,
169
- noise_range=None)
170
-
171
- # pad kernel
172
- pad_size = (21 - kernel_size) // 2
173
- kernel2 = np.pad(kernel2, ((pad_size, pad_size), (pad_size, pad_size)))
174
-
175
- # ------------------------------------- the final sinc kernel ------------------------------------- #
176
- if np.random.uniform() < self.opt['final_sinc_prob']:
177
- kernel_size = random.choice(self.kernel_range)
178
- omega_c = np.random.uniform(np.pi / 3, np.pi)
179
- sinc_kernel = circular_lowpass_kernel(omega_c, kernel_size, pad_to=21)
180
- sinc_kernel = torch.FloatTensor(sinc_kernel)
181
- else:
182
- sinc_kernel = self.pulse_tensor
183
-
184
- # BGR to RGB, HWC to CHW, numpy to tensor
185
- img_gt = img2tensor([img_gt], bgr2rgb=True, float32=True)[0]
186
- kernel = torch.FloatTensor(kernel)
187
- kernel2 = torch.FloatTensor(kernel2)
188
-
189
- return_d = {'gt': img_gt, 'kernel1': kernel, 'kernel2': kernel2, 'sinc_kernel': sinc_kernel, 'gt_path': gt_path}
190
- return return_d
191
-
192
- def __len__(self):
193
- return len(self.paths)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/realesrgan_paired_dataset.py DELETED
@@ -1,106 +0,0 @@
1
- import os
2
- from torch.utils import data as data
3
- from torchvision.transforms.functional import normalize
4
-
5
- from basicsr.data.data_util import paired_paths_from_folder, paired_paths_from_lmdb
6
- from basicsr.data.transforms import augment, paired_random_crop
7
- from basicsr.utils import FileClient, imfrombytes, img2tensor
8
- from basicsr.utils.registry import DATASET_REGISTRY
9
-
10
-
11
- @DATASET_REGISTRY.register(suffix='basicsr')
12
- class RealESRGANPairedDataset(data.Dataset):
13
- """Paired image dataset for image restoration.
14
-
15
- Read LQ (Low Quality, e.g. LR (Low Resolution), blurry, noisy, etc) and GT image pairs.
16
-
17
- There are three modes:
18
-
19
- 1. **lmdb**: Use lmdb files. If opt['io_backend'] == lmdb.
20
- 2. **meta_info_file**: Use meta information file to generate paths. \
21
- If opt['io_backend'] != lmdb and opt['meta_info_file'] is not None.
22
- 3. **folder**: Scan folders to generate paths. The rest.
23
-
24
- Args:
25
- opt (dict): Config for train datasets. It contains the following keys:
26
- dataroot_gt (str): Data root path for gt.
27
- dataroot_lq (str): Data root path for lq.
28
- meta_info (str): Path for meta information file.
29
- io_backend (dict): IO backend type and other kwarg.
30
- filename_tmpl (str): Template for each filename. Note that the template excludes the file extension.
31
- Default: '{}'.
32
- gt_size (int): Cropped patched size for gt patches.
33
- use_hflip (bool): Use horizontal flips.
34
- use_rot (bool): Use rotation (use vertical flip and transposing h and w for implementation).
35
- scale (bool): Scale, which will be added automatically.
36
- phase (str): 'train' or 'val'.
37
- """
38
-
39
- def __init__(self, opt):
40
- super(RealESRGANPairedDataset, self).__init__()
41
- self.opt = opt
42
- self.file_client = None
43
- self.io_backend_opt = opt['io_backend']
44
- # mean and std for normalizing the input images
45
- self.mean = opt['mean'] if 'mean' in opt else None
46
- self.std = opt['std'] if 'std' in opt else None
47
-
48
- self.gt_folder, self.lq_folder = opt['dataroot_gt'], opt['dataroot_lq']
49
- self.filename_tmpl = opt['filename_tmpl'] if 'filename_tmpl' in opt else '{}'
50
-
51
- # file client (lmdb io backend)
52
- if self.io_backend_opt['type'] == 'lmdb':
53
- self.io_backend_opt['db_paths'] = [self.lq_folder, self.gt_folder]
54
- self.io_backend_opt['client_keys'] = ['lq', 'gt']
55
- self.paths = paired_paths_from_lmdb([self.lq_folder, self.gt_folder], ['lq', 'gt'])
56
- elif 'meta_info' in self.opt and self.opt['meta_info'] is not None:
57
- # disk backend with meta_info
58
- # Each line in the meta_info describes the relative path to an image
59
- with open(self.opt['meta_info']) as fin:
60
- paths = [line.strip() for line in fin]
61
- self.paths = []
62
- for path in paths:
63
- gt_path, lq_path = path.split(', ')
64
- gt_path = os.path.join(self.gt_folder, gt_path)
65
- lq_path = os.path.join(self.lq_folder, lq_path)
66
- self.paths.append(dict([('gt_path', gt_path), ('lq_path', lq_path)]))
67
- else:
68
- # disk backend
69
- # it will scan the whole folder to get meta info
70
- # it will be time-consuming for folders with too many files. It is recommended using an extra meta txt file
71
- self.paths = paired_paths_from_folder([self.lq_folder, self.gt_folder], ['lq', 'gt'], self.filename_tmpl)
72
-
73
- def __getitem__(self, index):
74
- if self.file_client is None:
75
- self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
76
-
77
- scale = self.opt['scale']
78
-
79
- # Load gt and lq images. Dimension order: HWC; channel order: BGR;
80
- # image range: [0, 1], float32.
81
- gt_path = self.paths[index]['gt_path']
82
- img_bytes = self.file_client.get(gt_path, 'gt')
83
- img_gt = imfrombytes(img_bytes, float32=True)
84
- lq_path = self.paths[index]['lq_path']
85
- img_bytes = self.file_client.get(lq_path, 'lq')
86
- img_lq = imfrombytes(img_bytes, float32=True)
87
-
88
- # augmentation for training
89
- if self.opt['phase'] == 'train':
90
- gt_size = self.opt['gt_size']
91
- # random crop
92
- img_gt, img_lq = paired_random_crop(img_gt, img_lq, gt_size, scale, gt_path)
93
- # flip, rotation
94
- img_gt, img_lq = augment([img_gt, img_lq], self.opt['use_hflip'], self.opt['use_rot'])
95
-
96
- # BGR to RGB, HWC to CHW, numpy to tensor
97
- img_gt, img_lq = img2tensor([img_gt, img_lq], bgr2rgb=True, float32=True)
98
- # normalize
99
- if self.mean is not None or self.std is not None:
100
- normalize(img_lq, self.mean, self.std, inplace=True)
101
- normalize(img_gt, self.mean, self.std, inplace=True)
102
-
103
- return {'lq': img_lq, 'gt': img_gt, 'lq_path': lq_path, 'gt_path': gt_path}
104
-
105
- def __len__(self):
106
- return len(self.paths)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/reds_dataset.py DELETED
@@ -1,352 +0,0 @@
1
- import numpy as np
2
- import random
3
- import torch
4
- from pathlib import Path
5
- from torch.utils import data as data
6
-
7
- from basicsr.data.transforms import augment, paired_random_crop
8
- from basicsr.utils import FileClient, get_root_logger, imfrombytes, img2tensor
9
- from basicsr.utils.flow_util import dequantize_flow
10
- from basicsr.utils.registry import DATASET_REGISTRY
11
-
12
-
13
- @DATASET_REGISTRY.register()
14
- class REDSDataset(data.Dataset):
15
- """REDS dataset for training.
16
-
17
- The keys are generated from a meta info txt file.
18
- basicsr/data/meta_info/meta_info_REDS_GT.txt
19
-
20
- Each line contains:
21
- 1. subfolder (clip) name; 2. frame number; 3. image shape, separated by
22
- a white space.
23
- Examples:
24
- 000 100 (720,1280,3)
25
- 001 100 (720,1280,3)
26
- ...
27
-
28
- Key examples: "000/00000000"
29
- GT (gt): Ground-Truth;
30
- LQ (lq): Low-Quality, e.g., low-resolution/blurry/noisy/compressed frames.
31
-
32
- Args:
33
- opt (dict): Config for train dataset. It contains the following keys:
34
- dataroot_gt (str): Data root path for gt.
35
- dataroot_lq (str): Data root path for lq.
36
- dataroot_flow (str, optional): Data root path for flow.
37
- meta_info_file (str): Path for meta information file.
38
- val_partition (str): Validation partition types. 'REDS4' or 'official'.
39
- io_backend (dict): IO backend type and other kwarg.
40
- num_frame (int): Window size for input frames.
41
- gt_size (int): Cropped patched size for gt patches.
42
- interval_list (list): Interval list for temporal augmentation.
43
- random_reverse (bool): Random reverse input frames.
44
- use_hflip (bool): Use horizontal flips.
45
- use_rot (bool): Use rotation (use vertical flip and transposing h and w for implementation).
46
- scale (bool): Scale, which will be added automatically.
47
- """
48
-
49
- def __init__(self, opt):
50
- super(REDSDataset, self).__init__()
51
- self.opt = opt
52
- self.gt_root, self.lq_root = Path(opt['dataroot_gt']), Path(opt['dataroot_lq'])
53
- self.flow_root = Path(opt['dataroot_flow']) if opt['dataroot_flow'] is not None else None
54
- assert opt['num_frame'] % 2 == 1, (f'num_frame should be odd number, but got {opt["num_frame"]}')
55
- self.num_frame = opt['num_frame']
56
- self.num_half_frames = opt['num_frame'] // 2
57
-
58
- self.keys = []
59
- with open(opt['meta_info_file'], 'r') as fin:
60
- for line in fin:
61
- folder, frame_num, _ = line.split(' ')
62
- self.keys.extend([f'{folder}/{i:08d}' for i in range(int(frame_num))])
63
-
64
- # remove the video clips used in validation
65
- if opt['val_partition'] == 'REDS4':
66
- val_partition = ['000', '011', '015', '020']
67
- elif opt['val_partition'] == 'official':
68
- val_partition = [f'{v:03d}' for v in range(240, 270)]
69
- else:
70
- raise ValueError(f'Wrong validation partition {opt["val_partition"]}.'
71
- f"Supported ones are ['official', 'REDS4'].")
72
- self.keys = [v for v in self.keys if v.split('/')[0] not in val_partition]
73
-
74
- # file client (io backend)
75
- self.file_client = None
76
- self.io_backend_opt = opt['io_backend']
77
- self.is_lmdb = False
78
- if self.io_backend_opt['type'] == 'lmdb':
79
- self.is_lmdb = True
80
- if self.flow_root is not None:
81
- self.io_backend_opt['db_paths'] = [self.lq_root, self.gt_root, self.flow_root]
82
- self.io_backend_opt['client_keys'] = ['lq', 'gt', 'flow']
83
- else:
84
- self.io_backend_opt['db_paths'] = [self.lq_root, self.gt_root]
85
- self.io_backend_opt['client_keys'] = ['lq', 'gt']
86
-
87
- # temporal augmentation configs
88
- self.interval_list = opt['interval_list']
89
- self.random_reverse = opt['random_reverse']
90
- interval_str = ','.join(str(x) for x in opt['interval_list'])
91
- logger = get_root_logger()
92
- logger.info(f'Temporal augmentation interval list: [{interval_str}]; '
93
- f'random reverse is {self.random_reverse}.')
94
-
95
- def __getitem__(self, index):
96
- if self.file_client is None:
97
- self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
98
-
99
- scale = self.opt['scale']
100
- gt_size = self.opt['gt_size']
101
- key = self.keys[index]
102
- clip_name, frame_name = key.split('/') # key example: 000/00000000
103
- center_frame_idx = int(frame_name)
104
-
105
- # determine the neighboring frames
106
- interval = random.choice(self.interval_list)
107
-
108
- # ensure not exceeding the borders
109
- start_frame_idx = center_frame_idx - self.num_half_frames * interval
110
- end_frame_idx = center_frame_idx + self.num_half_frames * interval
111
- # each clip has 100 frames starting from 0 to 99
112
- while (start_frame_idx < 0) or (end_frame_idx > 99):
113
- center_frame_idx = random.randint(0, 99)
114
- start_frame_idx = (center_frame_idx - self.num_half_frames * interval)
115
- end_frame_idx = center_frame_idx + self.num_half_frames * interval
116
- frame_name = f'{center_frame_idx:08d}'
117
- neighbor_list = list(range(start_frame_idx, end_frame_idx + 1, interval))
118
- # random reverse
119
- if self.random_reverse and random.random() < 0.5:
120
- neighbor_list.reverse()
121
-
122
- assert len(neighbor_list) == self.num_frame, (f'Wrong length of neighbor list: {len(neighbor_list)}')
123
-
124
- # get the GT frame (as the center frame)
125
- if self.is_lmdb:
126
- img_gt_path = f'{clip_name}/{frame_name}'
127
- else:
128
- img_gt_path = self.gt_root / clip_name / f'{frame_name}.png'
129
- img_bytes = self.file_client.get(img_gt_path, 'gt')
130
- img_gt = imfrombytes(img_bytes, float32=True)
131
-
132
- # get the neighboring LQ frames
133
- img_lqs = []
134
- for neighbor in neighbor_list:
135
- if self.is_lmdb:
136
- img_lq_path = f'{clip_name}/{neighbor:08d}'
137
- else:
138
- img_lq_path = self.lq_root / clip_name / f'{neighbor:08d}.png'
139
- img_bytes = self.file_client.get(img_lq_path, 'lq')
140
- img_lq = imfrombytes(img_bytes, float32=True)
141
- img_lqs.append(img_lq)
142
-
143
- # get flows
144
- if self.flow_root is not None:
145
- img_flows = []
146
- # read previous flows
147
- for i in range(self.num_half_frames, 0, -1):
148
- if self.is_lmdb:
149
- flow_path = f'{clip_name}/{frame_name}_p{i}'
150
- else:
151
- flow_path = (self.flow_root / clip_name / f'{frame_name}_p{i}.png')
152
- img_bytes = self.file_client.get(flow_path, 'flow')
153
- cat_flow = imfrombytes(img_bytes, flag='grayscale', float32=False) # uint8, [0, 255]
154
- dx, dy = np.split(cat_flow, 2, axis=0)
155
- flow = dequantize_flow(dx, dy, max_val=20, denorm=False) # we use max_val 20 here.
156
- img_flows.append(flow)
157
- # read next flows
158
- for i in range(1, self.num_half_frames + 1):
159
- if self.is_lmdb:
160
- flow_path = f'{clip_name}/{frame_name}_n{i}'
161
- else:
162
- flow_path = (self.flow_root / clip_name / f'{frame_name}_n{i}.png')
163
- img_bytes = self.file_client.get(flow_path, 'flow')
164
- cat_flow = imfrombytes(img_bytes, flag='grayscale', float32=False) # uint8, [0, 255]
165
- dx, dy = np.split(cat_flow, 2, axis=0)
166
- flow = dequantize_flow(dx, dy, max_val=20, denorm=False) # we use max_val 20 here.
167
- img_flows.append(flow)
168
-
169
- # for random crop, here, img_flows and img_lqs have the same
170
- # spatial size
171
- img_lqs.extend(img_flows)
172
-
173
- # randomly crop
174
- img_gt, img_lqs = paired_random_crop(img_gt, img_lqs, gt_size, scale, img_gt_path)
175
- if self.flow_root is not None:
176
- img_lqs, img_flows = img_lqs[:self.num_frame], img_lqs[self.num_frame:]
177
-
178
- # augmentation - flip, rotate
179
- img_lqs.append(img_gt)
180
- if self.flow_root is not None:
181
- img_results, img_flows = augment(img_lqs, self.opt['use_hflip'], self.opt['use_rot'], img_flows)
182
- else:
183
- img_results = augment(img_lqs, self.opt['use_hflip'], self.opt['use_rot'])
184
-
185
- img_results = img2tensor(img_results)
186
- img_lqs = torch.stack(img_results[0:-1], dim=0)
187
- img_gt = img_results[-1]
188
-
189
- if self.flow_root is not None:
190
- img_flows = img2tensor(img_flows)
191
- # add the zero center flow
192
- img_flows.insert(self.num_half_frames, torch.zeros_like(img_flows[0]))
193
- img_flows = torch.stack(img_flows, dim=0)
194
-
195
- # img_lqs: (t, c, h, w)
196
- # img_flows: (t, 2, h, w)
197
- # img_gt: (c, h, w)
198
- # key: str
199
- if self.flow_root is not None:
200
- return {'lq': img_lqs, 'flow': img_flows, 'gt': img_gt, 'key': key}
201
- else:
202
- return {'lq': img_lqs, 'gt': img_gt, 'key': key}
203
-
204
- def __len__(self):
205
- return len(self.keys)
206
-
207
-
208
- @DATASET_REGISTRY.register()
209
- class REDSRecurrentDataset(data.Dataset):
210
- """REDS dataset for training recurrent networks.
211
-
212
- The keys are generated from a meta info txt file.
213
- basicsr/data/meta_info/meta_info_REDS_GT.txt
214
-
215
- Each line contains:
216
- 1. subfolder (clip) name; 2. frame number; 3. image shape, separated by
217
- a white space.
218
- Examples:
219
- 000 100 (720,1280,3)
220
- 001 100 (720,1280,3)
221
- ...
222
-
223
- Key examples: "000/00000000"
224
- GT (gt): Ground-Truth;
225
- LQ (lq): Low-Quality, e.g., low-resolution/blurry/noisy/compressed frames.
226
-
227
- Args:
228
- opt (dict): Config for train dataset. It contains the following keys:
229
- dataroot_gt (str): Data root path for gt.
230
- dataroot_lq (str): Data root path for lq.
231
- dataroot_flow (str, optional): Data root path for flow.
232
- meta_info_file (str): Path for meta information file.
233
- val_partition (str): Validation partition types. 'REDS4' or 'official'.
234
- io_backend (dict): IO backend type and other kwarg.
235
- num_frame (int): Window size for input frames.
236
- gt_size (int): Cropped patched size for gt patches.
237
- interval_list (list): Interval list for temporal augmentation.
238
- random_reverse (bool): Random reverse input frames.
239
- use_hflip (bool): Use horizontal flips.
240
- use_rot (bool): Use rotation (use vertical flip and transposing h and w for implementation).
241
- scale (bool): Scale, which will be added automatically.
242
- """
243
-
244
- def __init__(self, opt):
245
- super(REDSRecurrentDataset, self).__init__()
246
- self.opt = opt
247
- self.gt_root, self.lq_root = Path(opt['dataroot_gt']), Path(opt['dataroot_lq'])
248
- self.num_frame = opt['num_frame']
249
-
250
- self.keys = []
251
- with open(opt['meta_info_file'], 'r') as fin:
252
- for line in fin:
253
- folder, frame_num, _ = line.split(' ')
254
- self.keys.extend([f'{folder}/{i:08d}' for i in range(int(frame_num))])
255
-
256
- # remove the video clips used in validation
257
- if opt['val_partition'] == 'REDS4':
258
- val_partition = ['000', '011', '015', '020']
259
- elif opt['val_partition'] == 'official':
260
- val_partition = [f'{v:03d}' for v in range(240, 270)]
261
- else:
262
- raise ValueError(f'Wrong validation partition {opt["val_partition"]}.'
263
- f"Supported ones are ['official', 'REDS4'].")
264
- if opt['test_mode']:
265
- self.keys = [v for v in self.keys if v.split('/')[0] in val_partition]
266
- else:
267
- self.keys = [v for v in self.keys if v.split('/')[0] not in val_partition]
268
-
269
- # file client (io backend)
270
- self.file_client = None
271
- self.io_backend_opt = opt['io_backend']
272
- self.is_lmdb = False
273
- if self.io_backend_opt['type'] == 'lmdb':
274
- self.is_lmdb = True
275
- if hasattr(self, 'flow_root') and self.flow_root is not None:
276
- self.io_backend_opt['db_paths'] = [self.lq_root, self.gt_root, self.flow_root]
277
- self.io_backend_opt['client_keys'] = ['lq', 'gt', 'flow']
278
- else:
279
- self.io_backend_opt['db_paths'] = [self.lq_root, self.gt_root]
280
- self.io_backend_opt['client_keys'] = ['lq', 'gt']
281
-
282
- # temporal augmentation configs
283
- self.interval_list = opt.get('interval_list', [1])
284
- self.random_reverse = opt.get('random_reverse', False)
285
- interval_str = ','.join(str(x) for x in self.interval_list)
286
- logger = get_root_logger()
287
- logger.info(f'Temporal augmentation interval list: [{interval_str}]; '
288
- f'random reverse is {self.random_reverse}.')
289
-
290
- def __getitem__(self, index):
291
- if self.file_client is None:
292
- self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
293
-
294
- scale = self.opt['scale']
295
- gt_size = self.opt['gt_size']
296
- key = self.keys[index]
297
- clip_name, frame_name = key.split('/') # key example: 000/00000000
298
-
299
- # determine the neighboring frames
300
- interval = random.choice(self.interval_list)
301
-
302
- # ensure not exceeding the borders
303
- start_frame_idx = int(frame_name)
304
- if start_frame_idx > 100 - self.num_frame * interval:
305
- start_frame_idx = random.randint(0, 100 - self.num_frame * interval)
306
- end_frame_idx = start_frame_idx + self.num_frame * interval
307
-
308
- neighbor_list = list(range(start_frame_idx, end_frame_idx, interval))
309
-
310
- # random reverse
311
- if self.random_reverse and random.random() < 0.5:
312
- neighbor_list.reverse()
313
-
314
- # get the neighboring LQ and GT frames
315
- img_lqs = []
316
- img_gts = []
317
- for neighbor in neighbor_list:
318
- if self.is_lmdb:
319
- img_lq_path = f'{clip_name}/{neighbor:08d}'
320
- img_gt_path = f'{clip_name}/{neighbor:08d}'
321
- else:
322
- img_lq_path = self.lq_root / clip_name / f'{neighbor:08d}.png'
323
- img_gt_path = self.gt_root / clip_name / f'{neighbor:08d}.png'
324
-
325
- # get LQ
326
- img_bytes = self.file_client.get(img_lq_path, 'lq')
327
- img_lq = imfrombytes(img_bytes, float32=True)
328
- img_lqs.append(img_lq)
329
-
330
- # get GT
331
- img_bytes = self.file_client.get(img_gt_path, 'gt')
332
- img_gt = imfrombytes(img_bytes, float32=True)
333
- img_gts.append(img_gt)
334
-
335
- # randomly crop
336
- img_gts, img_lqs = paired_random_crop(img_gts, img_lqs, gt_size, scale, img_gt_path)
337
-
338
- # augmentation - flip, rotate
339
- img_lqs.extend(img_gts)
340
- img_results = augment(img_lqs, self.opt['use_hflip'], self.opt['use_rot'])
341
-
342
- img_results = img2tensor(img_results)
343
- img_gts = torch.stack(img_results[len(img_lqs) // 2:], dim=0)
344
- img_lqs = torch.stack(img_results[:len(img_lqs) // 2], dim=0)
345
-
346
- # img_lqs: (t, c, h, w)
347
- # img_gts: (t, c, h, w)
348
- # key: str
349
- return {'lq': img_lqs, 'gt': img_gts, 'key': key}
350
-
351
- def __len__(self):
352
- return len(self.keys)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/single_image_dataset.py DELETED
@@ -1,68 +0,0 @@
1
- from os import path as osp
2
- from torch.utils import data as data
3
- from torchvision.transforms.functional import normalize
4
-
5
- from basicsr.data.data_util import paths_from_lmdb
6
- from basicsr.utils import FileClient, imfrombytes, img2tensor, rgb2ycbcr, scandir
7
- from basicsr.utils.registry import DATASET_REGISTRY
8
-
9
-
10
- @DATASET_REGISTRY.register()
11
- class SingleImageDataset(data.Dataset):
12
- """Read only lq images in the test phase.
13
-
14
- Read LQ (Low Quality, e.g. LR (Low Resolution), blurry, noisy, etc).
15
-
16
- There are two modes:
17
- 1. 'meta_info_file': Use meta information file to generate paths.
18
- 2. 'folder': Scan folders to generate paths.
19
-
20
- Args:
21
- opt (dict): Config for train datasets. It contains the following keys:
22
- dataroot_lq (str): Data root path for lq.
23
- meta_info_file (str): Path for meta information file.
24
- io_backend (dict): IO backend type and other kwarg.
25
- """
26
-
27
- def __init__(self, opt):
28
- super(SingleImageDataset, self).__init__()
29
- self.opt = opt
30
- # file client (io backend)
31
- self.file_client = None
32
- self.io_backend_opt = opt['io_backend']
33
- self.mean = opt['mean'] if 'mean' in opt else None
34
- self.std = opt['std'] if 'std' in opt else None
35
- self.lq_folder = opt['dataroot_lq']
36
-
37
- if self.io_backend_opt['type'] == 'lmdb':
38
- self.io_backend_opt['db_paths'] = [self.lq_folder]
39
- self.io_backend_opt['client_keys'] = ['lq']
40
- self.paths = paths_from_lmdb(self.lq_folder)
41
- elif 'meta_info_file' in self.opt:
42
- with open(self.opt['meta_info_file'], 'r') as fin:
43
- self.paths = [osp.join(self.lq_folder, line.rstrip().split(' ')[0]) for line in fin]
44
- else:
45
- self.paths = sorted(list(scandir(self.lq_folder, full_path=True)))
46
-
47
- def __getitem__(self, index):
48
- if self.file_client is None:
49
- self.file_client = FileClient(self.io_backend_opt.pop('type'), **self.io_backend_opt)
50
-
51
- # load lq image
52
- lq_path = self.paths[index]
53
- img_bytes = self.file_client.get(lq_path, 'lq')
54
- img_lq = imfrombytes(img_bytes, float32=True)
55
-
56
- # color space transform
57
- if 'color' in self.opt and self.opt['color'] == 'y':
58
- img_lq = rgb2ycbcr(img_lq, y_only=True)[..., None]
59
-
60
- # BGR to RGB, HWC to CHW, numpy to tensor
61
- img_lq = img2tensor(img_lq, bgr2rgb=True, float32=True)
62
- # normalize
63
- if self.mean is not None or self.std is not None:
64
- normalize(img_lq, self.mean, self.std, inplace=True)
65
- return {'lq': img_lq, 'lq_path': lq_path}
66
-
67
- def __len__(self):
68
- return len(self.paths)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
basicsr/data/transforms.py DELETED
@@ -1,179 +0,0 @@
1
- import cv2
2
- import random
3
- import torch
4
-
5
-
6
- def mod_crop(img, scale):
7
- """Mod crop images, used during testing.
8
-
9
- Args:
10
- img (ndarray): Input image.
11
- scale (int): Scale factor.
12
-
13
- Returns:
14
- ndarray: Result image.
15
- """
16
- img = img.copy()
17
- if img.ndim in (2, 3):
18
- h, w = img.shape[0], img.shape[1]
19
- h_remainder, w_remainder = h % scale, w % scale
20
- img = img[:h - h_remainder, :w - w_remainder, ...]
21
- else:
22
- raise ValueError(f'Wrong img ndim: {img.ndim}.')
23
- return img
24
-
25
-
26
- def paired_random_crop(img_gts, img_lqs, gt_patch_size, scale, gt_path=None):
27
- """Paired random crop. Support Numpy array and Tensor inputs.
28
-
29
- It crops lists of lq and gt images with corresponding locations.
30
-
31
- Args:
32
- img_gts (list[ndarray] | ndarray | list[Tensor] | Tensor): GT images. Note that all images
33
- should have the same shape. If the input is an ndarray, it will
34
- be transformed to a list containing itself.
35
- img_lqs (list[ndarray] | ndarray): LQ images. Note that all images
36
- should have the same shape. If the input is an ndarray, it will
37
- be transformed to a list containing itself.
38
- gt_patch_size (int): GT patch size.
39
- scale (int): Scale factor.
40
- gt_path (str): Path to ground-truth. Default: None.
41
-
42
- Returns:
43
- list[ndarray] | ndarray: GT images and LQ images. If returned results
44
- only have one element, just return ndarray.
45
- """
46
-
47
- if not isinstance(img_gts, list):
48
- img_gts = [img_gts]
49
- if not isinstance(img_lqs, list):
50
- img_lqs = [img_lqs]
51
-
52
- # determine input type: Numpy array or Tensor
53
- input_type = 'Tensor' if torch.is_tensor(img_gts[0]) else 'Numpy'
54
-
55
- if input_type == 'Tensor':
56
- h_lq, w_lq = img_lqs[0].size()[-2:]
57
- h_gt, w_gt = img_gts[0].size()[-2:]
58
- else:
59
- h_lq, w_lq = img_lqs[0].shape[0:2]
60
- h_gt, w_gt = img_gts[0].shape[0:2]
61
- lq_patch_size = gt_patch_size // scale
62
-
63
- if h_gt != h_lq * scale or w_gt != w_lq * scale:
64
- raise ValueError(f'Scale mismatches. GT ({h_gt}, {w_gt}) is not {scale}x ',
65
- f'multiplication of LQ ({h_lq}, {w_lq}).')
66
- if h_lq < lq_patch_size or w_lq < lq_patch_size:
67
- raise ValueError(f'LQ ({h_lq}, {w_lq}) is smaller than patch size '
68
- f'({lq_patch_size}, {lq_patch_size}). '
69
- f'Please remove {gt_path}.')
70
-
71
- # randomly choose top and left coordinates for lq patch
72
- top = random.randint(0, h_lq - lq_patch_size)
73
- left = random.randint(0, w_lq - lq_patch_size)
74
-
75
- # crop lq patch
76
- if input_type == 'Tensor':
77
- img_lqs = [v[:, :, top:top + lq_patch_size, left:left + lq_patch_size] for v in img_lqs]
78
- else:
79
- img_lqs = [v[top:top + lq_patch_size, left:left + lq_patch_size, ...] for v in img_lqs]
80
-
81
- # crop corresponding gt patch
82
- top_gt, left_gt = int(top * scale), int(left * scale)
83
- if input_type == 'Tensor':
84
- img_gts = [v[:, :, top_gt:top_gt + gt_patch_size, left_gt:left_gt + gt_patch_size] for v in img_gts]
85
- else:
86
- img_gts = [v[top_gt:top_gt + gt_patch_size, left_gt:left_gt + gt_patch_size, ...] for v in img_gts]
87
- if len(img_gts) == 1:
88
- img_gts = img_gts[0]
89
- if len(img_lqs) == 1:
90
- img_lqs = img_lqs[0]
91
- return img_gts, img_lqs
92
-
93
-
94
- def augment(imgs, hflip=True, rotation=True, flows=None, return_status=False):
95
- """Augment: horizontal flips OR rotate (0, 90, 180, 270 degrees).
96
-
97
- We use vertical flip and transpose for rotation implementation.
98
- All the images in the list use the same augmentation.
99
-
100
- Args:
101
- imgs (list[ndarray] | ndarray): Images to be augmented. If the input
102
- is an ndarray, it will be transformed to a list.
103
- hflip (bool): Horizontal flip. Default: True.
104
- rotation (bool): Ratotation. Default: True.
105
- flows (list[ndarray]: Flows to be augmented. If the input is an
106
- ndarray, it will be transformed to a list.
107
- Dimension is (h, w, 2). Default: None.
108
- return_status (bool): Return the status of flip and rotation.
109
- Default: False.
110
-
111
- Returns:
112
- list[ndarray] | ndarray: Augmented images and flows. If returned
113
- results only have one element, just return ndarray.
114
-
115
- """
116
- hflip = hflip and random.random() < 0.5
117
- vflip = rotation and random.random() < 0.5
118
- rot90 = rotation and random.random() < 0.5
119
-
120
- def _augment(img):
121
- if hflip: # horizontal
122
- cv2.flip(img, 1, img)
123
- if vflip: # vertical
124
- cv2.flip(img, 0, img)
125
- if rot90:
126
- img = img.transpose(1, 0, 2)
127
- return img
128
-
129
- def _augment_flow(flow):
130
- if hflip: # horizontal
131
- cv2.flip(flow, 1, flow)
132
- flow[:, :, 0] *= -1
133
- if vflip: # vertical
134
- cv2.flip(flow, 0, flow)
135
- flow[:, :, 1] *= -1
136
- if rot90:
137
- flow = flow.transpose(1, 0, 2)
138
- flow = flow[:, :, [1, 0]]
139
- return flow
140
-
141
- if not isinstance(imgs, list):
142
- imgs = [imgs]
143
- imgs = [_augment(img) for img in imgs]
144
- if len(imgs) == 1:
145
- imgs = imgs[0]
146
-
147
- if flows is not None:
148
- if not isinstance(flows, list):
149
- flows = [flows]
150
- flows = [_augment_flow(flow) for flow in flows]
151
- if len(flows) == 1:
152
- flows = flows[0]
153
- return imgs, flows
154
- else:
155
- if return_status:
156
- return imgs, (hflip, vflip, rot90)
157
- else:
158
- return imgs
159
-
160
-
161
- def img_rotate(img, angle, center=None, scale=1.0):
162
- """Rotate image.
163
-
164
- Args:
165
- img (ndarray): Image to be rotated.
166
- angle (float): Rotation angle in degrees. Positive values mean
167
- counter-clockwise rotation.
168
- center (tuple[int]): Rotation center. If the center is None,
169
- initialize it as the center of the image. Default: None.
170
- scale (float): Isotropic scale factor. Default: 1.0.
171
- """
172
- (h, w) = img.shape[:2]
173
-
174
- if center is None:
175
- center = (w // 2, h // 2)
176
-
177
- matrix = cv2.getRotationMatrix2D(center, angle, scale)
178
- rotated_img = cv2.warpAffine(img, matrix, (w, h))
179
- return rotated_img