| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- from PIL import Image
- import numpy as np
- import cv2
- import torchvision.transforms as transforms
- import torch
- import io
- import os
- import functools
- class DataLoader():
- def __init__(self, opt, cv_img):
- super(DataLoader, self).__init__()
- self.dataset = Dataset()
- self.dataset.initialize(opt, cv_img)
- self.dataloader = torch.utils.data.DataLoader(
- self.dataset,
- batch_size=opt.batchSize,
- shuffle=not opt.serial_batches,
- num_workers=int(opt.nThreads))
- def load_data(self):
- return self.dataloader
- def __len__(self):
- return 1
- class Dataset(torch.utils.data.Dataset):
- def __init__(self):
- super(Dataset, self).__init__()
- def initialize(self, opt, cv_img):
- self.opt = opt
- self.root = opt.dataroot
- self.A = Image.fromarray(cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB))
- self.dataset_size = 1
-
- def __getitem__(self, index):
- transform_A = get_transform(self.opt)
- A_tensor = transform_A(self.A.convert('RGB'))
- B_tensor = inst_tensor = feat_tensor = 0
- input_dict = {'label': A_tensor, 'inst': inst_tensor, 'image': B_tensor,
- 'feat': feat_tensor, 'path': ""}
- return input_dict
- def __len__(self):
- return 1
- class DeepModel(torch.nn.Module):
- def initialize(self, opt):
- self.opt = opt
- self.gpu_ids = [] #FIX CPU
- self.netG = self.__define_G(opt.input_nc, opt.output_nc, opt.ngf, opt.netG,
- opt.n_downsample_global, opt.n_blocks_global, opt.n_local_enhancers,
- opt.n_blocks_local, opt.norm, self.gpu_ids)
- # load networks
- self.__load_network(self.netG)
-
- def inference(self, label, inst):
-
- # Encode Inputs
- input_label, inst_map, _, _ = self.__encode_input(label, inst, infer=True)
- # Fake Generation
- input_concat = input_label
-
- with torch.no_grad():
- fake_image = self.netG.forward(input_concat)
- return fake_image
-
- # helper loading function that can be used by subclasses
- def __load_network(self, network):
- save_path = os.path.join(self.opt.checkpoints_dir)
- network.load_state_dict(torch.load(save_path))
- def __encode_input(self, label_map, inst_map=None, real_image=None, feat_map=None, infer=False):
- if (len(self.gpu_ids) > 0):
- input_label = label_map.data.cuda() #GPU
- else:
- input_label = label_map.data #CPU
-
- return input_label, inst_map, real_image, feat_map
- def __weights_init(self, m):
- classname = m.__class__.__name__
- if classname.find('Conv') != -1:
- m.weight.data.normal_(0.0, 0.02)
- elif classname.find('BatchNorm2d') != -1:
- m.weight.data.normal_(1.0, 0.02)
- m.bias.data.fill_(0)
- def __define_G(self, input_nc, output_nc, ngf, netG, n_downsample_global=3, n_blocks_global=9, n_local_enhancers=1,
- n_blocks_local=3, norm='instance', gpu_ids=[]):
- norm_layer = self.__get_norm_layer(norm_type=norm)
- netG = GlobalGenerator(input_nc, output_nc, ngf, n_downsample_global, n_blocks_global, norm_layer)
-
- if len(gpu_ids) > 0:
- netG.cuda(gpu_ids[0])
- netG.apply(self.__weights_init)
- return netG
- def __get_norm_layer(self, norm_type='instance'):
- norm_layer = functools.partial(torch.nn.InstanceNorm2d, affine=False)
- return norm_layer
- ##############################################################################
- # Generator
- ##############################################################################
- class GlobalGenerator(torch.nn.Module):
- def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=torch.nn.BatchNorm2d,
- padding_type='reflect'):
- assert(n_blocks >= 0)
- super(GlobalGenerator, self).__init__()
- activation = torch.nn.ReLU(True)
- model = [torch.nn.ReflectionPad2d(3), torch.nn.Conv2d(input_nc, ngf, kernel_size=7, padding=0), norm_layer(ngf), activation]
- ### downsample
- for i in range(n_downsampling):
- mult = 2**i
- model += [torch.nn.Conv2d(ngf * mult, ngf * mult * 2, kernel_size=3, stride=2, padding=1),
- norm_layer(ngf * mult * 2), activation]
- ### resnet blocks
- mult = 2**n_downsampling
- for i in range(n_blocks):
- model += [ResnetBlock(ngf * mult, padding_type=padding_type, activation=activation, norm_layer=norm_layer)]
-
- ### upsample
- for i in range(n_downsampling):
- mult = 2**(n_downsampling - i)
- model += [torch.nn.ConvTranspose2d(ngf * mult, int(ngf * mult / 2), kernel_size=3, stride=2, padding=1, output_padding=1),
- norm_layer(int(ngf * mult / 2)), activation]
- model += [torch.nn.ReflectionPad2d(3), torch.nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0), torch.nn.Tanh()]
- self.model = torch.nn.Sequential(*model)
-
- def forward(self, input):
- return self.model(input)
-
- # Define a resnet block
- class ResnetBlock(torch.nn.Module):
- def __init__(self, dim, padding_type, norm_layer, activation=torch.nn.ReLU(True), use_dropout=False):
- super(ResnetBlock, self).__init__()
- self.conv_block = self.__build_conv_block(dim, padding_type, norm_layer, activation, use_dropout)
- def __build_conv_block(self, dim, padding_type, norm_layer, activation, use_dropout):
- conv_block = []
- p = 0
- if padding_type == 'reflect':
- conv_block += [torch.nn.ReflectionPad2d(1)]
- elif padding_type == 'replicate':
- conv_block += [torch.nn.ReplicationPad2d(1)]
- elif padding_type == 'zero':
- p = 1
- else:
- raise NotImplementedError('padding [%s] is not implemented' % padding_type)
- conv_block += [torch.nn.Conv2d(dim, dim, kernel_size=3, padding=p),
- norm_layer(dim),
- activation]
- if use_dropout:
- conv_block += [torch.nn.Dropout(0.5)]
- p = 0
- if padding_type == 'reflect':
- conv_block += [torch.nn.ReflectionPad2d(1)]
- elif padding_type == 'replicate':
- conv_block += [torch.nn.ReplicationPad2d(1)]
- elif padding_type == 'zero':
- p = 1
- else:
- raise NotImplementedError('padding [%s] is not implemented' % padding_type)
- conv_block += [torch.nn.Conv2d(dim, dim, kernel_size=3, padding=p),
- norm_layer(dim)]
- return torch.nn.Sequential(*conv_block)
- def forward(self, x):
- out = x + self.conv_block(x)
- return out
- # Data utils:
- def get_transform(opt, method=Image.BICUBIC, normalize=True):
- transform_list = []
- base = float(2 ** opt.n_downsample_global)
- if opt.netG == 'local':
- base *= (2 ** opt.n_local_enhancers)
- transform_list.append(transforms.Lambda(lambda img: __make_power_2(img, base, method)))
- transform_list += [transforms.ToTensor()]
- if normalize:
- transform_list += [transforms.Normalize((0.5, 0.5, 0.5),
- (0.5, 0.5, 0.5))]
- return transforms.Compose(transform_list)
- def __make_power_2(img, base, method=Image.BICUBIC):
- ow, oh = img.size
- h = int(round(oh / base) * base)
- w = int(round(ow / base) * base)
- if (h == oh) and (w == ow):
- return img
- return img.resize((w, h), method)
- # Converts a Tensor into a Numpy array
- # |imtype|: the desired type of the converted numpy array
- def tensor2im(image_tensor, imtype=np.uint8, normalize=True):
- if isinstance(image_tensor, list):
- image_numpy = []
- for i in range(len(image_tensor)):
- image_numpy.append(tensor2im(image_tensor[i], imtype, normalize))
- return image_numpy
- image_numpy = image_tensor.cpu().float().numpy()
- if normalize:
- image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0
- else:
- image_numpy = np.transpose(image_numpy, (1, 2, 0)) * 255.0
- image_numpy = np.clip(image_numpy, 0, 255)
- if image_numpy.shape[2] == 1 or image_numpy.shape[2] > 3:
- image_numpy = image_numpy[:,:,0]
- return image_numpy.astype(imtype)
|