From 5e09ee795a71c977008941b3f8c8dbcf95a05fe3 Mon Sep 17 00:00:00 2001 From: Kane de Roodt Date: Tue, 21 Mar 2023 12:10:05 +0100 Subject: [PATCH 01/24] Added the new files for pytorch version --- test_Sony_pytorch.py | 95 ++++++++++++++++++++++++++ train_Sony_pytorch.py | 151 ++++++++++++++++++++++++++++++++++++++++++ unet.py | 149 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 395 insertions(+) create mode 100644 test_Sony_pytorch.py create mode 100644 train_Sony_pytorch.py create mode 100644 unet.py diff --git a/test_Sony_pytorch.py b/test_Sony_pytorch.py new file mode 100644 index 0000000..d4c6918 --- /dev/null +++ b/test_Sony_pytorch.py @@ -0,0 +1,95 @@ +# uniform content loss + adaptive threshold + per_class_input + recursive G +# improvement upon cqf37 +from __future__ import division +import os, scipy.io, scipy.misc +import torch +import numpy as np +import rawpy +import glob + +from unet import UNetSony + +input_dir = './dataset/Sony/short/' +gt_dir = './dataset/Sony/long/' +checkpoint_dir = './checkpoint/Sony/' +result_dir = './result_Sony/' +ckpt = checkpoint_dir + 'model.pth' + +# get test IDs +test_fns = glob.glob(gt_dir + '/1*.ARW') +test_ids = [int(os.path.basename(test_fn)[0:5]) for test_fn in test_fns] + +DEBUG = 0 +if DEBUG == 1: + save_freq = 2 + test_ids = test_ids[0:5] + +def pack_raw(raw): + # pack Bayer image to 4 channels + im = raw.raw_image_visible.astype(np.float32) + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) + img_shape = im.shape + H = img_shape[0] + W = img_shape[1] + + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +unet = UNetSony() +unet.load_state_dict(torch.load(ckpt)) +unet.to(device) + +if not os.path.isdir(result_dir + 'final/'): + os.makedirs(result_dir + 'final/') + +with torch.no_grad(): + unet.eval() + for test_id in test_ids: + # test the first image in each sequence + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) + for k in range(len(in_files)): + in_path = in_files[k] + in_fn = os.path.basename(in_path) + print(in_fn) + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) + gt_path = gt_files[0] + gt_fn = os.path.basename(gt_path) + in_exposure = float(in_fn[9:-5]) + gt_exposure = float(gt_fn[9:-5]) + ratio = min(gt_exposure / in_exposure, 300) + + raw = rawpy.imread(in_path) + input_full = np.expand_dims(pack_raw(raw), axis=0) * ratio + + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + # scale_full = np.expand_dims(np.float32(im/65535.0),axis = 0)*ratio + scale_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + gt_raw = rawpy.imread(gt_path) + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + input_full = np.minimum(input_full, 1.0) + in_img = torch.from_numpy(input_full).permute(0,3,1,2).to(device) + out_img = unet(in_img) + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() + output = np.minimum(np.maximum(output, 0), 1) + + output = output[0, :, :, :] + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean( + scale_full) # scale the low-light image to the same mean of the groundtruth + + scipy.misc.toimage(output * 255, high=255, low=0, cmin=0, cmax=255).save( + result_dir + 'final/%5d_00_%d_out.png' % (test_id, ratio)) + scipy.misc.toimage(scale_full * 255, high=255, low=0, cmin=0, cmax=255).save( + result_dir + 'final/%5d_00_%d_scale.png' % (test_id, ratio)) + scipy.misc.toimage(gt_full * 255, high=255, low=0, cmin=0, cmax=255).save( + result_dir + 'final/%5d_00_%d_gt.png' % (test_id, ratio)) \ No newline at end of file diff --git a/train_Sony_pytorch.py b/train_Sony_pytorch.py new file mode 100644 index 0000000..649e1cb --- /dev/null +++ b/train_Sony_pytorch.py @@ -0,0 +1,151 @@ +# uniform content loss + adaptive threshold + per_class_input + recursive G +# improvement upon cqf37 +from __future__ import division +import os, time +import torch +from torch import optim +import numpy as np +import rawpy +import glob +from PIL import Image +from unet import UNetSony + +input_dir = './dataset/Sony/short/' +gt_dir = './dataset/Sony/long/' +checkpoint_dir = './result_Sony/' +result_dir = './result_Sony/' + +# get train IDs +train_fns = glob.glob(gt_dir + '0*.ARW') +train_ids = [int(os.path.basename(train_fn)[0:5]) for train_fn in train_fns] + +ps = 512 # patch size for training +save_freq = 500 + +DEBUG = 1 +if DEBUG == 1: + save_freq = 2 + train_ids = train_ids[0:5] + +def pack_raw(raw): + # pack Bayer image to 4 channels + im = raw.raw_image_visible.astype(np.float32) + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) + img_shape = im.shape + H = img_shape[0] + W = img_shape[1] + + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + +def criterion(out_image, gt_image): + return torch.mean(torch.abs(out_image - gt_image)) + +# Raw data takes long time to load. Keep them in memory after loaded. +gt_images = [None] * 6000 +input_images = {} +input_images['300'] = [None] * len(train_ids) +input_images['250'] = [None] * len(train_ids) +input_images['100'] = [None] * len(train_ids) + +g_loss = np.zeros((5000, 1)) + +allfolders = glob.glob(result_dir + '*0') +lastepoch = 0 +for folder in allfolders: + lastepoch = np.maximum(lastepoch, int(folder[-4:])) + +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +unet = UNetSony() +unet.to(device) +unet.train() + +learning_rate = 1e-4 +G_opt = optim.Adam(unet.parameters(), lr=learning_rate) + +for epoch in range(lastepoch, 25): + if os.path.isdir(result_dir + '%04d' % epoch): + continue + cnt = 0 + if epoch > 2000: + learning_rate = 1e-5 + + for ind in np.random.permutation(len(train_ids)): + # get the path from image id + train_id = train_ids[ind] + in_files = glob.glob(input_dir + '%05d_00*.ARW' % train_id) + in_path = in_files[np.random.random_integers(0, len(in_files) - 1)] + in_fn = os.path.basename(in_path) + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % train_id) + gt_path = gt_files[0] + gt_fn = os.path.basename(gt_path) + in_exposure = float(in_fn[9:-5]) + gt_exposure = float(gt_fn[9:-5]) + ratio = min(gt_exposure / in_exposure, 300) + + st = time.time() + cnt += 1 + + if input_images[str(ratio)[0:3]][ind] is None: + raw = rawpy.imread(in_path) + input_images[str(ratio)[0:3]][ind] = np.expand_dims(pack_raw(raw), axis=0) * ratio + + gt_raw = rawpy.imread(gt_path) + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_images[ind] = np.expand_dims(np.float32(im / 65535.0), axis=0) + + # crop + H = input_images[str(ratio)[0:3]][ind].shape[1] + W = input_images[str(ratio)[0:3]][ind].shape[2] + + xx = np.random.randint(0, W - ps) + yy = np.random.randint(0, H - ps) + input_patch = input_images[str(ratio)[0:3]][ind][:, yy:yy + ps, xx:xx + ps, :] + gt_patch = gt_images[ind][:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :] + + if np.random.randint(2, size=1)[0] == 1: # random flip + input_patch = np.flip(input_patch, axis=1) + gt_patch = np.flip(gt_patch, axis=1) + if np.random.randint(2, size=1)[0] == 1: + input_patch = np.flip(input_patch, axis=2) + gt_patch = np.flip(gt_patch, axis=2) + if np.random.randint(2, size=1)[0] == 1: # random transpose + input_patch = np.transpose(input_patch, (0, 2, 1, 3)) + gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) + + input_patch = np.minimum(input_patch, 1.0) + gt_patch = np.maximum(gt_patch, 0.0) + + in_img = torch.from_numpy(input_patch).permute(0,3,1,2).to(device) + gt_img = torch.from_numpy(gt_patch).permute(0,3,1,2).to(device) + + G_opt.zero_grad() + out_img = unet(in_img) + + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() + output = np.minimum(np.maximum(output,0),1) + + loss = criterion(out_img, gt_img) + loss.backward() + G_opt.step() + + g_loss[ind] = loss.item() + + print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) + + if epoch % save_freq == 0: + if not os.path.isdir(result_dir + '%04d' % epoch): + os.makedirs(result_dir + '%04d' % epoch) + + temp = np.concatenate((gt_patch[0, :, :, :], output[0, :, :, :]), axis=1) + temp = np.clip(temp * 255, 0, 255).astype(np.uint8) + image = Image.fromarray(temp) + image.save(result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) + + torch.save(unet.state_dict(), checkpoint_dir + 'model.pth') diff --git a/unet.py b/unet.py new file mode 100644 index 0000000..191686a --- /dev/null +++ b/unet.py @@ -0,0 +1,149 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +class lReLU(nn.Module): + def __init__(self): + super(lReLU, self).__init__() + + def forward(self, x): + return torch.max(x * 0.2, x) + +class Double_Conv2d(nn.Module): + def __init__(self, in_channel, out_channel): + super(Double_Conv2d, self).__init__() + self.double_conv2d = torch.nn.Sequential( + nn.Conv2d(in_channels=in_channel, out_channels=out_channel, kernel_size=3, padding=1), + lReLU(), + nn.Conv2d(in_channels=out_channel, out_channels=out_channel, kernel_size=3, padding=1), + lReLU() + ) + + def forward(self, x): + return self.double_conv2d(x) + +class UNetSony(nn.Module): + def __init__(self): + super(UNetSony, self).__init__() + self.conv1 = Double_Conv2d(4, 32) + self.conv2 = Double_Conv2d(32, 64) + self.conv3 = Double_Conv2d(64, 128) + self.conv4 = Double_Conv2d(128, 256) + self.conv5 = Double_Conv2d(256, 512) + self.up6 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) + self.conv6 = Double_Conv2d(512, 256) + self.up7 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) + self.conv7 = Double_Conv2d(256, 128) + self.up8 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) + self.conv8 = Double_Conv2d(128, 64) + self.up9 = nn.ConvTranspose2d(64, 32, kernel_size=2, stride=2) + self.conv9 = Double_Conv2d(64, 32) + self.conv10 = nn.Conv2d(in_channels=32, out_channels=12, kernel_size=1) + + def forward(self, x): + conv1 = self.conv1(x) + pool1 = F.max_pool2d(conv1, kernel_size=2) + + conv2 = self.conv2(pool1) + pool2 = F.max_pool2d(conv2, kernel_size=2) + + conv3 = self.conv3(pool2) + pool3 = F.max_pool2d(conv3, kernel_size=2) + + conv4 = self.conv4(pool3) + pool4 = F.max_pool2d(conv4, kernel_size=2) + + conv5 = self.conv5(pool4) + + up6 = self.up6(conv5) + up6 = torch.cat([up6, conv4], 1) + conv6 = self.conv6(up6) + + up7 = self.up7(conv6) + up7 = torch.cat([up7, conv3], 1) + conv7 = self.conv7(up7) + + up8 = self.up8(conv7) + up8 = torch.cat([up8, conv2], 1) + conv8 = self.conv8(up8) + + up9 = self.up9(conv8) + up9 = torch.cat([up9, conv1], 1) + conv9 = self.conv9(up9) + + conv10 = self.conv10(conv9) + out = F.pixel_shuffle(conv10, 2) + + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + +class UNetFuji(nn.Module): + def __init__(self): + super(UNetFuji, self).__init__() + self.conv1 = Double_Conv2d(9, 32) + self.conv2 = Double_Conv2d(32, 64) + self.conv3 = Double_Conv2d(64, 128) + self.conv4 = Double_Conv2d(128, 256) + self.conv5 = Double_Conv2d(256, 512) + self.up6 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) + self.conv6 = Double_Conv2d(512, 256) + self.up7 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) + self.conv7 = Double_Conv2d(256, 128) + self.up8 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) + self.conv8 = Double_Conv2d(128, 64) + self.up9 = nn.ConvTranspose2d(64, 32, kernel_size=2, stride=2) + self.conv9 = Double_Conv2d(64, 32) + self.conv10 = nn.Conv2d(in_channels=32, out_channels=27, kernel_size=1) + + def forward(self, x): + conv1 = self.conv1(x) + pool1 = F.max_pool2d(conv1, kernel_size=2) + + conv2 = self.conv2(pool1) + pool2 = F.max_pool2d(conv2, kernel_size=2) + + conv3 = self.conv3(pool2) + pool3 = F.max_pool2d(conv3, kernel_size=2) + + conv4 = self.conv4(pool3) + pool4 = F.max_pool2d(conv4, kernel_size=2) + + conv5 = self.conv5(pool4) + + up6 = self.up6(conv5) + up6 = torch.cat([up6, conv4], 1) + conv6 = self.conv6(up6) + + up7 = self.up7(conv6) + up7 = torch.cat([up7, conv3], 1) + conv7 = self.conv7(up7) + + up8 = self.up8(conv7) + up8 = torch.cat([up8, conv2], 1) + conv8 = self.conv8(up8) + + up9 = self.up9(conv8) + up9 = torch.cat([up9, conv1], 1) + conv9 = self.conv9(up9) + + conv10 = self.conv10(conv9) + out = F.pixel_shuffle(conv10, 3) + + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) \ No newline at end of file From cd129dd9a80abfba30c261bd86e198392a1fe50a Mon Sep 17 00:00:00 2001 From: Daan Scherrenburg Date: Tue, 21 Mar 2023 12:16:02 +0100 Subject: [PATCH 02/24] Create .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af5bb41 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +*.ARW From 096579292eda8f07e9240db02511e4f16cc331c4 Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Fri, 24 Mar 2023 17:24:08 +0100 Subject: [PATCH 03/24] Create Train_Sony_To_Pytorch.py --- Train_Sony_To_Pytorch.py | 291 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 Train_Sony_To_Pytorch.py diff --git a/Train_Sony_To_Pytorch.py b/Train_Sony_To_Pytorch.py new file mode 100644 index 0000000..7134f9f --- /dev/null +++ b/Train_Sony_To_Pytorch.py @@ -0,0 +1,291 @@ +from __future__ import division +import os, time +import numpy as np +import rawpy +import glob +from PIL import Image + +import torch +import torch.nn as nn + +input_dir = './dataset/Sony/short/' # Path to the short exposure images +gt_dir = './dataset/Sony/long/' # Path to the long exposure images +checkpoint_dir = './result_Sony/' # Path to the checkpoint directory +result_dir = './result_Sony/' # Path to the result directory + + +# get train IDs +train_fns = glob.glob(gt_dir + '0*.ARW') +train_ids = [int(os.path.basename(train_fn)[0:5]) for train_fn in train_fns] + +ps = 512 # patch size for training +save_freq = 500 + +# Debug mode that only uses 5 images from the dataset +DEBUG = 0 +if DEBUG == 1: + save_freq = 2 + train_ids = train_ids[0:5] + +# Leaky relu function with slope 0.2 +def lrelu(x): + outt = torch.max(0.2*x, x) + return outt + +# Unet class +class UNet(nn.Module): + def __init__(self): + super(UNet, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.pool1 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) + + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.conv1(x)) + conv1 = lrelu(self.conv1_2(conv1)) + pool1 = self.pool1(conv1) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.conv2(pool1)) + conv2 = lrelu(self.conv2_2(conv2)) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.conv3(pool2)) + conv3 = lrelu(self.conv3_2(conv3)) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.conv4(pool3)) + conv4 = lrelu(self.conv4_2(conv4)) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.conv5(pool4)) + conv5 = lrelu(self.conv5_2(conv5)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.conv6(up6)) + conv6 = lrelu(self.conv6_2(conv6)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.conv7(up7)) + conv7 = lrelu(self.conv7_2(conv7)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.conv8(up8)) + conv8 = lrelu(self.conv8_2(conv8)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.conv9(up9)) + conv9 = lrelu(self.conv9_2(conv9)) + + # Forward pass through the convolutional layer + conv10 = self.conv10(conv9) + + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + +# Pack the raw image into 4 channels using the bayer pattern +def pack_raw(raw): + im = raw.raw_image_visible.astype(np.float32) # Change data to float32 + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + + # Channel concatenation for the bayer pattern + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss + +# Raw data takes long time to load. Keep them in memory after loaded. +gt_images = [None] * 6000 +input_images = {} +input_images['300'] = [None] * len(train_ids) +input_images['250'] = [None] * len(train_ids) +input_images['100'] = [None] * len(train_ids) + +# Array to store the loss values +g_loss = np.zeros((5000, 1)) + +allfolders = glob.glob(result_dir + '*0') # Get all the folders in the result directory +lastepoch = 0 # Initialize the last epoch to 0 + +# Get the last epoch number +for folder in allfolders: + lastepoch = np.maximum(lastepoch, int(folder[-4:])) + +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +unet = UNet() # Initialize the model +unet.to(device) # assign the model to the GPU or CPU +unet.train() # Set the model to training mode + +learning_rate = 1e-4 # Set the learning rate + +G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer + +# Training loop +for epoch in range(lastepoch, 4001): + # Check if the folder exists and skip the epoch if it does + if os.path.isdir(result_dir + '%04d' % epoch): + continue + cnt = 0 # Initialize the counter to 0 + + # Set the learning rate to 1e-5 after 2000 epochs + if epoch > 2000: + learning_rate = 1e-5 + + # Loop through the training images + for ind in np.random.permutation(len(train_ids)): + train_id = train_ids[ind] # Get the training id + in_files = glob.glob(input_dir + '%05d_00*.ARW' % train_id) # Get the input images + in_path = in_files[np.random.randint(0, len(in_files))] # Get a random input image + in_fn = os.path.basename(in_path) # Get the file name of the image + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % train_id) # Get the ground truth images + gt_path = gt_files[0] # Get the first ground truth image + gt_fn = os.path.basename(gt_path) # Get the file name of the ground truth image + in_exposure = float(in_fn[9:-5]) # Get the exposure time for the input image + gt_exposure = float(gt_fn[9:-5]) # Get the exposure time for the ground truth image + ratio = min(gt_exposure / in_exposure, 300) # Get the ratio between the exposure times + + st = time.time() # Get the current time + cnt += 1 # Increment the counter + + # Check if the image is loaded and load it if it is not + if input_images[str(ratio)[0:3]][ind] is None: + raw = rawpy.imread(in_path) # Read the raw image + input_images[str(ratio)[0:3]][ind] = np.expand_dims(pack_raw(raw), axis=0) * ratio # Pack the raw image and store it in the input images array depending on the ratio + + gt_raw = rawpy.imread(gt_path) # Read the ground truth image + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Postprocess the ground truth image + gt_images[ind] = np.expand_dims(np.float32(im / 65535.0), axis=0) # Store the ground truth image in the ground thruth images array + + # Crop the image to the required size + H = input_images[str(ratio)[0:3]][ind].shape[1] # Get the height of the image + W = input_images[str(ratio)[0:3]][ind].shape[2] # Get the width of the image + + # Get a random start location on the image + xx = np.random.randint(0, W - ps) + yy = np.random.randint(0, H - ps) + + # Get the data used for training + input_patch = input_images[str(ratio)[0:3]][ind][:, yy:yy + ps, xx:xx + ps, :] + gt_patch = gt_images[ind][:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :] + + # Data augmentation + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 1 + input_patch = np.flip(input_patch, axis=1) + gt_patch = np.flip(gt_patch, axis=1) + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 2 + input_patch = np.flip(input_patch, axis=2) + gt_patch = np.flip(gt_patch, axis=2) + if np.random.randint(2, size=1)[0] == 1: # random transpose + input_patch = np.transpose(input_patch, (0, 2, 1, 3)) + gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) + + input_patch = np.minimum(input_patch, 1.0) # Input patch should be between 0 and 1 + input_patch = torch.from_numpy(input_patch) # Convert the input patch to a tensor + input_patch = input_patch.permute(0, 3, 1, 2) # Permute the tensor + input_patch = input_patch.to(device) # Assign the tensor to the GPU or CPU + + gt_patch = np.minimum(gt_patch, 1.0) # Ground truth patch should be between 0 and 1 + gt_patch = torch.from_numpy(gt_patch) # Convert the ground truth patch to a tensor + gt_patch = gt_patch.permute(0, 3, 1, 2) # Permute the tensor + gt_patch = gt_patch.to(device) # Assign the tensor to the GPU or CPU + + # Run the model + G_opt.zero_grad() # Set the gradient to 0 + out_image = unet(input_patch) # Get the output image + + # Calculate the loss + loss = loss_function(out_image, gt_patch) + loss.backward() # Calculate the gradients + G_opt.step() # Update the weights + g_loss[ind] = loss.item() # Store the loss + + print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) # Print the loss and time + + output = out_image.permute(0, 2, 3, 1).cpu().data. numpy()# Get the output image and convert it to numpy + output = np.minimum(np.maximum(output, 0), 1) # Output should be between 0 and 1 + + # Save the results + if epoch % save_freq == 0: + # Create the directory if it does not exist + if not os.path.isdir(result_dir + '%04d' % epoch): + os.makedirs(result_dir + '%04d' % epoch) + + # Save the image + temp = np.concatenate((gt_patch[0, :, :, :], output[0, :, :, :]), axis=1) # Concatenate the ground truth and output images + Image.fromarray((temp * 255).astype(np.uint8)).save(result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) # Save the image + + # Save the model + torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') From eb75a6383613ec02d866e74f66f7e8ed7f4038d6 Mon Sep 17 00:00:00 2001 From: Kane de Roodt Date: Sun, 26 Mar 2023 12:19:35 +0200 Subject: [PATCH 04/24] Made some changes to train file to make concatenation dimensions equal for ground truth and output images. Also made initial code for test --- Test_Sony_To_Pytorch.py | 220 +++++++++++++++++++++++++++++++++++++++ Train_Sony_To_Pytorch.py | 22 ++-- 2 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 Test_Sony_To_Pytorch.py diff --git a/Test_Sony_To_Pytorch.py b/Test_Sony_To_Pytorch.py new file mode 100644 index 0000000..9913361 --- /dev/null +++ b/Test_Sony_To_Pytorch.py @@ -0,0 +1,220 @@ +from __future__ import division +import os +import numpy as np +import rawpy +import glob +from PIL import Image +import torch +import torch.nn as nn + +input_dir = './dataset/Sony/short/' # Path to the short exposure images +gt_dir = './dataset/Sony/long/' # Path to the long exposure images +checkpoint_dir = './result_Sony/' # Path to the checkpoint directory +result_dir = './result_Sony/' # Path to the result directory +ckpt = checkpoint_dir + 'model.ckpt' # Path to the model + +# get test IDs +test_fns = glob.glob(gt_dir + '/1*.ARW') +test_ids = [int(os.path.basename(test_fn)[0:5]) for test_fn in test_fns] + +# Debug mode that only uses 5 images from the dataset +DEBUG = 1 +if DEBUG == 1: + save_freq = 2 + test_ids = test_ids[0:5] + + +# Leaky relu function with slope 0.2 +def lrelu(x): + outt = torch.max(0.2 * x, x) + return outt + + +# Unet class +class UNet(nn.Module): + def __init__(self): + super(UNet, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.pool1 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) + + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.conv1(x)) + conv1 = lrelu(self.conv1_2(conv1)) + pool1 = self.pool1(conv1) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.conv2(pool1)) + conv2 = lrelu(self.conv2_2(conv2)) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.conv3(pool2)) + conv3 = lrelu(self.conv3_2(conv3)) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.conv4(pool3)) + conv4 = lrelu(self.conv4_2(conv4)) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.conv5(pool4)) + conv5 = lrelu(self.conv5_2(conv5)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.conv6(up6)) + conv6 = lrelu(self.conv6_2(conv6)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.conv7(up7)) + conv7 = lrelu(self.conv7_2(conv7)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.conv8(up8)) + conv8 = lrelu(self.conv8_2(conv8)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.conv9(up9)) + conv9 = lrelu(self.conv9_2(conv9)) + + # Forward pass through the convolutional layer + conv10 = self.conv10(conv9) + + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + + +# Pack the raw image into 4 channels using the bayer pattern +def pack_raw(raw): + im = raw.raw_image_visible.astype(np.float32) # Change data to float32 + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + + # Channel concatenation for the bayer pattern + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + + +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss + + +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +unet = UNet() # Initialize the model +unet.to(device) # assign the model to the GPU or CPU +unet.train() # Set the model to training mode + +if not os.path.isdir(result_dir + 'final/'): + os.makedirs(result_dir + 'final/') + +with torch.no_grad(): + unet.eval() # Set the model to evaluation mode + for test_id in test_ids: # Iterate over test_ids + # test the first image in each sequence + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) + for k in range(len(in_files)): + in_path = in_files[k] + in_fn = os.path.basename(in_path) + print(in_fn) + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Find ground truth files matching the given pattern + gt_path = gt_files[0] + gt_fn = os.path.basename(gt_path) + + in_exposure = float(in_fn[9:-5]) # Extract exposure information from the file names + gt_exposure = float(gt_fn[9:-5]) + ratio = min(gt_exposure / in_exposure, 300) # Calculate the ratio of exposures + + raw = rawpy.imread(in_path) # Read and preprocess the input raw image + input_full = np.expand_dims(pack_raw(raw), axis=0) * ratio + + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Post-process the input raw image + scale_full = np.expand_dims(np.float32(im/65535.0),axis = 0)*ratio + + gt_raw = rawpy.imread(gt_path) # Read and post-process the ground truth raw image + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + input_full = np.minimum(input_full, 1.0) # Clamp the input_full to [0, 1] range + in_img = torch.from_numpy(input_full).permute(0,3,1,2).to(device) # Convert input_full to PyTorch tensor and move to device + out_img = unet(in_img) # Apply the model to the input image + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() # Convert the output tensor back to NumPy array + output = np.minimum(np.maximum(output, 0), 1) + + output = output[0, :, :, :] # Remove the batch dimension + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) # Scale the low-light image to the same mean of the groundtruth + + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) # Save the images + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) + Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) \ No newline at end of file diff --git a/Train_Sony_To_Pytorch.py b/Train_Sony_To_Pytorch.py index 7134f9f..ab22546 100644 --- a/Train_Sony_To_Pytorch.py +++ b/Train_Sony_To_Pytorch.py @@ -22,7 +22,7 @@ save_freq = 500 # Debug mode that only uses 5 images from the dataset -DEBUG = 0 +DEBUG = 1 if DEBUG == 1: save_freq = 2 train_ids = train_ids[0:5] @@ -193,7 +193,7 @@ def loss_function(out_image, gt_image): G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer # Training loop -for epoch in range(lastepoch, 4001): +for epoch in range(lastepoch, 30): # Check if the folder exists and skip the epoch if it does if os.path.isdir(result_dir + '%04d' % epoch): continue @@ -253,28 +253,28 @@ def loss_function(out_image, gt_image): gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) input_patch = np.minimum(input_patch, 1.0) # Input patch should be between 0 and 1 - input_patch = torch.from_numpy(input_patch) # Convert the input patch to a tensor - input_patch = input_patch.permute(0, 3, 1, 2) # Permute the tensor - input_patch = input_patch.to(device) # Assign the tensor to the GPU or CPU + input_img = torch.from_numpy(input_patch) # Convert the input patch to a tensor + input_img = input_img.permute(0, 3, 1, 2) # Permute the tensor + input_img = input_img.to(device) # Assign the tensor to the GPU or CPU gt_patch = np.minimum(gt_patch, 1.0) # Ground truth patch should be between 0 and 1 - gt_patch = torch.from_numpy(gt_patch) # Convert the ground truth patch to a tensor - gt_patch = gt_patch.permute(0, 3, 1, 2) # Permute the tensor - gt_patch = gt_patch.to(device) # Assign the tensor to the GPU or CPU + gt_img = torch.from_numpy(gt_patch) # Convert the ground truth patch to a tensor + gt_img = gt_img.permute(0, 3, 1, 2) # Permute the tensor + gt_img = gt_img.to(device) # Assign the tensor to the GPU or CPU # Run the model G_opt.zero_grad() # Set the gradient to 0 - out_image = unet(input_patch) # Get the output image + out_image = unet(input_img) # Get the output image # Calculate the loss - loss = loss_function(out_image, gt_patch) + loss = loss_function(out_image, gt_img) loss.backward() # Calculate the gradients G_opt.step() # Update the weights g_loss[ind] = loss.item() # Store the loss print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) # Print the loss and time - output = out_image.permute(0, 2, 3, 1).cpu().data. numpy()# Get the output image and convert it to numpy + output = out_image.permute(0, 2, 3, 1).cpu().data.numpy() # Get the output image and convert it to numpy output = np.minimum(np.maximum(output, 0), 1) # Output should be between 0 and 1 # Save the results From adc0d258024ed728c274696a9195833ae1381465 Mon Sep 17 00:00:00 2001 From: Daan Scherrenburg Date: Tue, 28 Mar 2023 09:57:43 +0200 Subject: [PATCH 05/24] Changed gitignore --- .gitignore | 3 +++ train_Sony.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index af5bb41..8468ea4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ *.ARW +*.pyc +*.jpg +result_Sony/model.pth diff --git a/train_Sony.py b/train_Sony.py index 5752a83..ce0642a 100644 --- a/train_Sony.py +++ b/train_Sony.py @@ -20,7 +20,7 @@ ps = 512 # patch size for training save_freq = 500 -DEBUG = 0 +DEBUG = 1 if DEBUG == 1: save_freq = 2 train_ids = train_ids[0:5] From 0eb7920884a7633037fe447b88a1c4a39a68e748 Mon Sep 17 00:00:00 2001 From: Kane de Roodt Date: Tue, 28 Mar 2023 12:46:22 +0200 Subject: [PATCH 06/24] Fixed the correct output image by removing the state of UNet model and some other minor changes. --- Test_Sony_To_Pytorch.py | 110 +++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/Test_Sony_To_Pytorch.py b/Test_Sony_To_Pytorch.py index 9913361..8f79e7e 100644 --- a/Test_Sony_To_Pytorch.py +++ b/Test_Sony_To_Pytorch.py @@ -10,7 +10,7 @@ input_dir = './dataset/Sony/short/' # Path to the short exposure images gt_dir = './dataset/Sony/long/' # Path to the long exposure images checkpoint_dir = './result_Sony/' # Path to the checkpoint directory -result_dir = './result_Sony/' # Path to the result directory +result_dir = './result_Sony/final' # Path to the result directory ckpt = checkpoint_dir + 'model.ckpt' # Path to the model # get test IDs @@ -145,9 +145,7 @@ def _initialize_weights(self): # Pack the raw image into 4 channels using the bayer pattern def pack_raw(raw): - im = raw.raw_image_visible.astype(np.float32) # Change data to float32 - im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level - + im = np.maximum(raw - 512, 0) / (16383 - 512) # subtract the black level im = np.expand_dims(im, axis=2) # Add a channel dimension img_shape = im.shape # Get the shape of the image H = img_shape[0] # Get the height of the image @@ -161,60 +159,56 @@ def pack_raw(raw): return out -# loss function using absolute difference between the output and ground truth -def loss_function(out_image, gt_image): - loss = torch.mean(torch.abs(out_image - gt_image)) - return loss - device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available unet = UNet() # Initialize the model -unet.to(device) # assign the model to the GPU or CPU -unet.train() # Set the model to training mode - -if not os.path.isdir(result_dir + 'final/'): - os.makedirs(result_dir + 'final/') - -with torch.no_grad(): - unet.eval() # Set the model to evaluation mode - for test_id in test_ids: # Iterate over test_ids - # test the first image in each sequence - in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) - for k in range(len(in_files)): - in_path = in_files[k] - in_fn = os.path.basename(in_path) - print(in_fn) - - gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Find ground truth files matching the given pattern - gt_path = gt_files[0] - gt_fn = os.path.basename(gt_path) - - in_exposure = float(in_fn[9:-5]) # Extract exposure information from the file names - gt_exposure = float(gt_fn[9:-5]) - ratio = min(gt_exposure / in_exposure, 300) # Calculate the ratio of exposures - - raw = rawpy.imread(in_path) # Read and preprocess the input raw image - input_full = np.expand_dims(pack_raw(raw), axis=0) * ratio - - im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Post-process the input raw image - scale_full = np.expand_dims(np.float32(im/65535.0),axis = 0)*ratio - - gt_raw = rawpy.imread(gt_path) # Read and post-process the ground truth raw image - im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) - gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) - - input_full = np.minimum(input_full, 1.0) # Clamp the input_full to [0, 1] range - in_img = torch.from_numpy(input_full).permute(0,3,1,2).to(device) # Convert input_full to PyTorch tensor and move to device - out_img = unet(in_img) # Apply the model to the input image - output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() # Convert the output tensor back to NumPy array - output = np.minimum(np.maximum(output, 0), 1) - - output = output[0, :, :, :] # Remove the batch dimension - gt_full = gt_full[0, :, :, :] - scale_full = scale_full[0, :, :, :] - scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) # Scale the low-light image to the same mean of the groundtruth - - Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) # Save the images - Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) - Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) - Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) \ No newline at end of file + +unet.load_state_dict(torch.load(ckpt,map_location={'cuda:1':'cuda:0'})) +model = unet.to(device) +if not os.path.isdir(result_dir): + os.makedirs(result_dir) + +for test_id in test_ids: # Loop through all test_ids + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) # Get input image files (first image in each sequence) based on the test_id + + for k in range(len(in_files)): # Iterate through all input files + in_path = in_files[k] + _, in_fn = os.path.split(in_path) + print(in_fn) + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Get the ground truth files for the current test_id + + _, gt_fn = os.path.split(gt_files[0]) + in_exposure = float(in_fn[9:-5]) # Extract exposure values from input + gt_exposure = float(gt_fn[9:-5]) # Extract exposure values from ground truth + ratio = min(gt_exposure / in_exposure, 300) # Calculate the exposure ratio and limit it to 300 + + raw = rawpy.imread(in_path) # Read the raw input image + im = raw.raw_image_visible.astype(np.float32) # Convert it to a visible float32 image + input_full = np.expand_dims(pack_raw(im), axis=0) * ratio # Multiply image with exposure ratio + + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + scale_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + gt_raw = rawpy.imread(gt_files[0]) # Read the raw ground truth image and post-process it + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + input_full = np.minimum(input_full, 1.0) # Clip the input image to the range [0, 1] + + in_img = torch.from_numpy(input_full).permute(0, 3, 1, 2).to(device) # Convert the input image to a PyTorch tensor + out_img = unet(in_img) # Perform the image enhancement using the UNet model + + # Convert to numpy array and clip between 0 and 1 + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() + output = np.minimum(np.maximum(output, 0), 1) + + # Remove the batch dimension from the images + output = output[0, :, :, :] + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) # scale the low-light image to the same mean of the groundtruth + + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) + Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) \ No newline at end of file From 1c0daee274e0a9ee814933f6e7b96aa3fe0e23e6 Mon Sep 17 00:00:00 2001 From: Kane de Roodt Date: Tue, 28 Mar 2023 12:48:26 +0200 Subject: [PATCH 07/24] Fixed the output images and some minor other changes. --- Test_Sony_To_Pytorch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Test_Sony_To_Pytorch.py b/Test_Sony_To_Pytorch.py index 8f79e7e..754fdac 100644 --- a/Test_Sony_To_Pytorch.py +++ b/Test_Sony_To_Pytorch.py @@ -206,7 +206,7 @@ def pack_raw(raw): output = output[0, :, :, :] gt_full = gt_full[0, :, :, :] scale_full = scale_full[0, :, :, :] - scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) # scale the low-light image to the same mean of the groundtruth + scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) From eadd171086a62eb7bcabcd692dfedd29854d2185 Mon Sep 17 00:00:00 2001 From: Daan Scherrenburg Date: Tue, 28 Mar 2023 16:46:42 +0200 Subject: [PATCH 08/24] Create .gitignore --- dataset/Sony/short/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 dataset/Sony/short/.gitignore diff --git a/dataset/Sony/short/.gitignore b/dataset/Sony/short/.gitignore new file mode 100644 index 0000000..8468ea4 --- /dev/null +++ b/dataset/Sony/short/.gitignore @@ -0,0 +1,5 @@ + +*.ARW +*.pyc +*.jpg +result_Sony/model.pth From f93b607783a70e72266ae61f34df247a05321e06 Mon Sep 17 00:00:00 2001 From: Daan Scherrenburg Date: Tue, 28 Mar 2023 16:53:41 +0200 Subject: [PATCH 09/24] Minor changes --- .gitignore | 1 + dataset/Sony/short/.gitignore | 5 ----- images/fig1.png | Bin 399869 -> 0 bytes 3 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 dataset/Sony/short/.gitignore delete mode 100644 images/fig1.png diff --git a/.gitignore b/.gitignore index 8468ea4..54e9a94 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.pyc *.jpg result_Sony/model.pth +*.ckpt diff --git a/dataset/Sony/short/.gitignore b/dataset/Sony/short/.gitignore deleted file mode 100644 index 8468ea4..0000000 --- a/dataset/Sony/short/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ - -*.ARW -*.pyc -*.jpg -result_Sony/model.pth diff --git a/images/fig1.png b/images/fig1.png deleted file mode 100644 index 2dc6ef363e4ea866cf21adac3588bc66814876f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399869 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 q~6 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
A^$)KqD)d%QzSVgas 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 z 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 From fa797e3d91b7fe74a7e2f278d7554ac9bd8d7491 Mon Sep 17 00:00:00 2001 From: Daan Scherrenburg Date: Tue, 28 Mar 2023 16:55:16 +0200 Subject: [PATCH 10/24] Create .gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb4a5ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +*.jpg +*.ARW +*.ckpt From baaa4b6071fa326a40ce9f1ae6b622192d14a354 Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:31:06 +0100 Subject: [PATCH 11/24] Create Batchnorm_train.py --- Batchnorm_train.py | 300 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 Batchnorm_train.py diff --git a/Batchnorm_train.py b/Batchnorm_train.py new file mode 100644 index 0000000..7800d17 --- /dev/null +++ b/Batchnorm_train.py @@ -0,0 +1,300 @@ +from __future__ import division +import os, time +import numpy as np +import rawpy +import glob +from PIL import Image + +import torch +import torch.nn as nn + +input_dir = './dataset/Sony/short/' # Path to the short exposure images +gt_dir = './dataset/Sony/long/' # Path to the long exposure images +checkpoint_dir = './result_Sony/' # Path to the checkpoint directory +result_dir = './result_Sony/' # Path to the result directory + + +# get train IDs +train_fns = glob.glob(gt_dir + '0*.ARW') +train_ids = [int(os.path.basename(train_fn)[0:5]) for train_fn in train_fns] + +ps = 512 # patch size for training +save_freq = 500 + +# Debug mode that only uses 5 images from the dataset +DEBUG = 1 +if DEBUG == 1: + save_freq = 2 + train_ids = train_ids[0:5] + +# Leaky relu function with slope 0.2 +def lrelu(x): + outt = torch.max(0.2*x, x) + return outt + +# Unet class +class UNet(nn.Module): + def __init__(self): + super(UNet, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn1 = nn.BatchNorm2d(32) + self.pool1 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn2 = nn.BatchNorm2d(64) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn3 = nn.BatchNorm2d(128) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn4 = nn.BatchNorm2d(256) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + self.bn5 = nn.BatchNorm2d(512) + + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn6 = nn.BatchNorm2d(256) + + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn7 = nn.BatchNorm2d(128) + + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn8 = nn.BatchNorm2d(64) + + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn9 = nn.BatchNorm2d(32) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) + + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.conv1(x)) + conv1 = lrelu(self.bn1(self.conv1_2(conv1))) + pool1 = self.pool1(conv1) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.conv2(pool1)) + conv2 = lrelu(self.bn2(self.conv2_2(conv2))) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.conv3(pool2)) + conv3 = lrelu(self.bn3(self.conv3_2(conv3))) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.conv4(pool3)) + conv4 = lrelu(self.bn4(self.conv4_2(conv4))) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.conv5(pool4)) + conv5 = lrelu(self.bn5(self.conv5_2(conv5))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.conv6(up6)) + conv6 = lrelu(self.bn6(self.conv6_2(conv6))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.conv7(up7)) + conv7 = lrelu(self.bn7(self.conv7_2(conv7))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.conv8(up8)) + conv8 = lrelu(self.bn8(self.conv8_2(conv8))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.conv9(up9)) + conv9 = lrelu(self.bn9(self.conv9_2(conv9))) + + # Forward pass through the convolutional layer + conv10 = self.conv10(conv9) + + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + +# Pack the raw image into 4 channels using the bayer pattern +def pack_raw(raw): + im = raw.raw_image_visible.astype(np.float32) # Change data to float32 + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + + # Channel concatenation for the bayer pattern + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss + +# Raw data takes long time to load. Keep them in memory after loaded. +gt_images = [None] * 6000 +input_images = {} +input_images['300'] = [None] * len(train_ids) +input_images['250'] = [None] * len(train_ids) +input_images['100'] = [None] * len(train_ids) + +# Array to store the loss values +g_loss = np.zeros((5000, 1)) + +allfolders = glob.glob(result_dir + '*0') # Get all the folders in the result directory +lastepoch = 0 # Initialize the last epoch to 0 + +# Get the last epoch number +for folder in allfolders: + lastepoch = np.maximum(lastepoch, int(folder[-4:])) + +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +unet = UNet() # Initialize the model +unet.to(device) # assign the model to the GPU or CPU +unet.train() # Set the model to training mode + +learning_rate = 1e-4 # Set the learning rate + +G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer + +# Training loop +for epoch in range(lastepoch, 21): + # Check if the folder exists and skip the epoch if it does + if os.path.isdir(result_dir + '%04d' % epoch): + continue + cnt = 0 # Initialize the counter to 0 + + # Set the learning rate to 1e-5 after 2000 epochs + if epoch > 2000: + learning_rate = 1e-5 + + # Loop through the training images + for ind in np.random.permutation(len(train_ids)): + train_id = train_ids[ind] # Get the training id + in_files = glob.glob(input_dir + '%05d_00*.ARW' % train_id) # Get the input images + in_path = in_files[np.random.randint(0, len(in_files))] # Get a random input image + in_fn = os.path.basename(in_path) # Get the file name of the image + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % train_id) # Get the ground truth images + gt_path = gt_files[0] # Get the first ground truth image + gt_fn = os.path.basename(gt_path) # Get the file name of the ground truth image + in_exposure = float(in_fn[9:-5]) # Get the exposure time for the input image + gt_exposure = float(gt_fn[9:-5]) # Get the exposure time for the ground truth image + ratio = min(gt_exposure / in_exposure, 300) # Get the ratio between the exposure times + + st = time.time() # Get the current time + cnt += 1 # Increment the counter + + # Check if the image is loaded and load it if it is not + if input_images[str(ratio)[0:3]][ind] is None: + raw = rawpy.imread(in_path) # Read the raw image + input_images[str(ratio)[0:3]][ind] = np.expand_dims(pack_raw(raw), axis=0) * ratio # Pack the raw image and store it in the input images array depending on the ratio + + gt_raw = rawpy.imread(gt_path) # Read the ground truth image + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Postprocess the ground truth image + gt_images[ind] = np.expand_dims(np.float32(im / 65535.0), axis=0) # Store the ground truth image in the ground thruth images array + + # Crop the image to the required size + H = input_images[str(ratio)[0:3]][ind].shape[1] # Get the height of the image + W = input_images[str(ratio)[0:3]][ind].shape[2] # Get the width of the image + + # Get a random start location on the image + xx = np.random.randint(0, W - ps) + yy = np.random.randint(0, H - ps) + + # Get the data used for training + input_patch = input_images[str(ratio)[0:3]][ind][:, yy:yy + ps, xx:xx + ps, :] + gt_patch = gt_images[ind][:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :] + + # Data augmentation + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 1 + input_patch = np.flip(input_patch, axis=1) + gt_patch = np.flip(gt_patch, axis=1) + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 2 + input_patch = np.flip(input_patch, axis=2) + gt_patch = np.flip(gt_patch, axis=2) + if np.random.randint(2, size=1)[0] == 1: # random transpose + input_patch = np.transpose(input_patch, (0, 2, 1, 3)) + gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) + + input_patch = np.minimum(input_patch, 1.0) # Input patch should be between 0 and 1 + input_img = torch.from_numpy(input_patch) # Convert the input patch to a tensor + input_img = input_img.permute(0, 3, 1, 2) # Permute the tensor + input_img = input_img.to(device) # Assign the tensor to the GPU or CPU + + gt_patch = np.minimum(gt_patch, 1.0) # Ground truth patch should be between 0 and 1 + gt_img = torch.from_numpy(gt_patch) # Convert the ground truth patch to a tensor + gt_img = gt_img.permute(0, 3, 1, 2) # Permute the tensor + gt_img = gt_img.to(device) # Assign the tensor to the GPU or CPU + + # Run the model + G_opt.zero_grad() # Set the gradient to 0 + out_image = unet(input_img) # Get the output image + + # Calculate the loss + loss = loss_function(out_image, gt_img) + loss.backward() # Calculate the gradients + G_opt.step() # Update the weights + g_loss[ind] = loss.item() # Store the loss + + print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) # Print the loss and time + + output = out_image.permute(0, 2, 3, 1).cpu().data.numpy() # Get the output image and convert it to numpy + output = np.minimum(np.maximum(output, 0), 1) # Output should be between 0 and 1 + + # Save the results + if epoch % save_freq == 0: + # Create the directory if it does not exist + if not os.path.isdir(result_dir + '%04d' % epoch): + os.makedirs(result_dir + '%04d' % epoch) + + # Save the image + temp = np.concatenate((gt_patch[0, :, :, :], output[0, :, :, :]), axis=1) # Concatenate the ground truth and output images + Image.fromarray((temp * 255).astype(np.uint8)).save(result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) # Save the image + + # Save the model + torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') From 895a757be7268ca14c855909fe3ac69f8d230b15 Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:32:48 +0100 Subject: [PATCH 12/24] Create Batchnorm_test.py --- Batchnorm_test.py | 236 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 Batchnorm_test.py diff --git a/Batchnorm_test.py b/Batchnorm_test.py new file mode 100644 index 0000000..1fbe0aa --- /dev/null +++ b/Batchnorm_test.py @@ -0,0 +1,236 @@ +from __future__ import division +import os +import numpy as np +import rawpy +import glob +from PIL import Image +import torch +import torch.nn as nn +from GPUtil import showUtilization as gpu_usage +from numba import cuda + + + +input_dir = './dataset/Sony/short/' # Path to the short exposure images +gt_dir = './dataset/Sony/long/' # Path to the long exposure images +checkpoint_dir = './result_Sony/' # Path to the checkpoint directory +result_dir = './result_Sony/' # Path to the result directory +ckpt = checkpoint_dir + 'model.ckpt' # Path to the model + +# get test IDs +test_fns = glob.glob(gt_dir + '/1*.ARW') +test_ids = [int(os.path.basename(test_fn)[0:5]) for test_fn in test_fns] + + +# Debug mode that only uses 5 images from the dataset +DEBUG = 1 +if DEBUG == 1: + save_freq = 2 + test_ids = test_ids[0:5] + + +# Leaky relu function with slope 0.2 +def lrelu(x): + outt = torch.max(0.2 * x, x) + return outt + + +# Unet class +class UNet(nn.Module): + def __init__(self): + super(UNet, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn1 = nn.BatchNorm2d(32) + self.pool1 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn2 = nn.BatchNorm2d(64) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn3 = nn.BatchNorm2d(128) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn4 = nn.BatchNorm2d(256) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + self.bn5 = nn.BatchNorm2d(512) + + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn6 = nn.BatchNorm2d(256) + + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn7 = nn.BatchNorm2d(128) + + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn8 = nn.BatchNorm2d(64) + + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn9 = nn.BatchNorm2d(32) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) + + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.conv1(x)) + conv1 = lrelu(self.bn1(self.conv1_2(conv1))) + pool1 = self.pool1(conv1) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.conv2(pool1)) + conv2 = lrelu(self.bn2(self.conv2_2(conv2))) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.conv3(pool2)) + conv3 = lrelu(self.bn3(self.conv3_2(conv3))) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.conv4(pool3)) + conv4 = lrelu(self.bn4(self.conv4_2(conv4))) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.conv5(pool4)) + conv5 = lrelu(self.bn5(self.conv5_2(conv5))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.conv6(up6)) + conv6 = lrelu(self.bn6(self.conv6_2(conv6))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.conv7(up7)) + conv7 = lrelu(self.bn7(self.conv7_2(conv7))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.conv8(up8)) + conv8 = lrelu(self.bn8(self.conv8_2(conv8))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.conv9(up9)) + conv9 = lrelu(self.bn9(self.conv9_2(conv9))) + + # Forward pass through the convolutional layer + conv10 = self.conv10(conv9) + + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + + +# Pack the raw image into 4 channels using the bayer pattern +def pack_raw(raw): + im = raw.raw_image_visible.astype(np.float32) # Change data to float32 + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + + # Channel concatenation for the bayer pattern + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + + +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss + + +#device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +device = torch.device("cpu") # check if GPU is available + +unet = UNet() # Initialize the model +unet.to(device) # assign the model to the GPU or CPU +unet.train() # Set the model to training mode + +if not os.path.isdir(result_dir + 'final/'): + os.makedirs(result_dir + 'final/') + +with torch.no_grad(): + unet.eval() # Set the model to evaluation mode + for test_id in test_ids: # Iterate over test_ids + # test the first image in each sequence + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) + for k in range(len(in_files)): + in_path = in_files[k] + in_fn = os.path.basename(in_path) + print(in_fn) + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Find ground truth files matching the given pattern + gt_path = gt_files[0] + gt_fn = os.path.basename(gt_path) + + in_exposure = float(in_fn[9:-5]) # Extract exposure information from the file names + gt_exposure = float(gt_fn[9:-5]) + ratio = min(gt_exposure / in_exposure, 300) # Calculate the ratio of exposures + + raw = rawpy.imread(in_path) # Read and preprocess the input raw image + input_full = np.expand_dims(pack_raw(raw), axis=0) * ratio + + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Post-process the input raw image + scale_full = np.expand_dims(np.float32(im/65535.0),axis = 0)*ratio + + gt_raw = rawpy.imread(gt_path) # Read and post-process the ground truth raw image + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + input_full = np.minimum(input_full, 1.0) # Clamp the input_full to [0, 1] range + in_img = torch.from_numpy(input_full).permute(0,3,1,2).to(device) # Convert input_full to PyTorch tensor and move to device + out_img = unet(in_img) # Apply the model to the input image + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() # Convert the output tensor back to NumPy array + output = np.minimum(np.maximum(output, 0), 1) + + output = output[0, :, :, :] # Remove the batch dimension + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) # Scale the low-light image to the same mean of the groundtruth + + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) # Save the images + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) + Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) From 50893aacd611bab049cf99468cda0832c10ebe1a Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:41:50 +0100 Subject: [PATCH 13/24] Update Batchnorm_test.py --- Batchnorm_test.py | 101 +++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/Batchnorm_test.py b/Batchnorm_test.py index 1fbe0aa..89f2be9 100644 --- a/Batchnorm_test.py +++ b/Batchnorm_test.py @@ -103,7 +103,7 @@ def forward(self, x): # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer conv2 = lrelu(self.conv2(pool1)) - conv2 = lrelu(self.bn2(self.conv2_2(conv2))) + conv2 = lrelu(self.b n2(self.conv2_2(conv2))) pool2 = self.pool2(conv2) # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer @@ -185,52 +185,53 @@ def loss_function(out_image, gt_image): device = torch.device("cpu") # check if GPU is available unet = UNet() # Initialize the model -unet.to(device) # assign the model to the GPU or CPU -unet.train() # Set the model to training mode - -if not os.path.isdir(result_dir + 'final/'): - os.makedirs(result_dir + 'final/') - -with torch.no_grad(): - unet.eval() # Set the model to evaluation mode - for test_id in test_ids: # Iterate over test_ids - # test the first image in each sequence - in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) - for k in range(len(in_files)): - in_path = in_files[k] - in_fn = os.path.basename(in_path) - print(in_fn) - - gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Find ground truth files matching the given pattern - gt_path = gt_files[0] - gt_fn = os.path.basename(gt_path) - - in_exposure = float(in_fn[9:-5]) # Extract exposure information from the file names - gt_exposure = float(gt_fn[9:-5]) - ratio = min(gt_exposure / in_exposure, 300) # Calculate the ratio of exposures - - raw = rawpy.imread(in_path) # Read and preprocess the input raw image - input_full = np.expand_dims(pack_raw(raw), axis=0) * ratio - - im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Post-process the input raw image - scale_full = np.expand_dims(np.float32(im/65535.0),axis = 0)*ratio - - gt_raw = rawpy.imread(gt_path) # Read and post-process the ground truth raw image - im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) - gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) - - input_full = np.minimum(input_full, 1.0) # Clamp the input_full to [0, 1] range - in_img = torch.from_numpy(input_full).permute(0,3,1,2).to(device) # Convert input_full to PyTorch tensor and move to device - out_img = unet(in_img) # Apply the model to the input image - output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() # Convert the output tensor back to NumPy array - output = np.minimum(np.maximum(output, 0), 1) - - output = output[0, :, :, :] # Remove the batch dimension - gt_full = gt_full[0, :, :, :] - scale_full = scale_full[0, :, :, :] - scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) # Scale the low-light image to the same mean of the groundtruth - - Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) # Save the images - Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) - Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) - Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) + +unet.load_state_dict(torch.load(ckpt,map_location={'cuda:1':'cuda:0'})) +model = unet.to(device) +if not os.path.isdir(result_dir): + os.makedirs(result_dir) + +for test_id in test_ids: # Loop through all test_ids + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) # Get input image files (first image in each sequence) based on the test_id + + for k in range(len(in_files)): # Iterate through all input files + in_path = in_files[k] + _, in_fn = os.path.split(in_path) + print(in_fn) + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Get the ground truth files for the current test_id + + _, gt_fn = os.path.split(gt_files[0]) + in_exposure = float(in_fn[9:-5]) # Extract exposure values from input + gt_exposure = float(gt_fn[9:-5]) # Extract exposure values from ground truth + ratio = min(gt_exposure / in_exposure, 300) # Calculate the exposure ratio and limit it to 300 + + raw = rawpy.imread(in_path) # Read the raw input image + im = raw.raw_image_visible.astype(np.float32) # Convert it to a visible float32 image + input_full = np.expand_dims(pack_raw(im), axis=0) * ratio # Multiply image with exposure ratio + + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + scale_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + gt_raw = rawpy.imread(gt_files[0]) # Read the raw ground truth image and post-process it + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + input_full = np.minimum(input_full, 1.0) # Clip the input image to the range [0, 1] + + in_img = torch.from_numpy(input_full).permute(0, 3, 1, 2).to(device) # Convert the input image to a PyTorch tensor + out_img = unet(in_img) # Perform the image enhancement using the UNet model + + # Convert to numpy array and clip between 0 and 1 + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() + output = np.minimum(np.maximum(output, 0), 1) + + # Remove the batch dimension from the images + output = output[0, :, :, :] + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) + + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) + Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) From c77b382446783f2b8c5e18a9f2a6890865eb4112 Mon Sep 17 00:00:00 2001 From: Daan1289 Date: Wed, 29 Mar 2023 12:01:05 +0200 Subject: [PATCH 14/24] Update savefolder --- .gitignore | 1 + Batchnorm_test.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 54e9a94..6ed4a5e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.jpg result_Sony/model.pth *.ckpt +*.png diff --git a/Batchnorm_test.py b/Batchnorm_test.py index 1fbe0aa..3e1ed64 100644 --- a/Batchnorm_test.py +++ b/Batchnorm_test.py @@ -6,15 +6,15 @@ from PIL import Image import torch import torch.nn as nn -from GPUtil import showUtilization as gpu_usage -from numba import cuda +# from GPUtil import showUtilization as gpu_usage +# from numba import cuda input_dir = './dataset/Sony/short/' # Path to the short exposure images gt_dir = './dataset/Sony/long/' # Path to the long exposure images checkpoint_dir = './result_Sony/' # Path to the checkpoint directory -result_dir = './result_Sony/' # Path to the result directory +result_dir = './result_Sony/final/' # Path to the result directory ckpt = checkpoint_dir + 'model.ckpt' # Path to the model # get test IDs From 6f970cdd605113d37be5dab90bab4b63d0001790 Mon Sep 17 00:00:00 2001 From: Daan1289 Date: Wed, 29 Mar 2023 12:06:55 +0200 Subject: [PATCH 15/24] Update Test_Sony_To_Pytorch.py --- Test_Sony_To_Pytorch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Test_Sony_To_Pytorch.py b/Test_Sony_To_Pytorch.py index 754fdac..aae34cd 100644 --- a/Test_Sony_To_Pytorch.py +++ b/Test_Sony_To_Pytorch.py @@ -160,7 +160,8 @@ def pack_raw(raw): -device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +device = torch.device("cpu") unet = UNet() # Initialize the model unet.load_state_dict(torch.load(ckpt,map_location={'cuda:1':'cuda:0'})) From 02aa162dfa3f8216b82e32e13b73c8dfc100f6e8 Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Wed, 29 Mar 2023 11:12:19 +0100 Subject: [PATCH 16/24] Update Batchnorm_test.py --- Batchnorm_test.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Batchnorm_test.py b/Batchnorm_test.py index 89f2be9..bf35eca 100644 --- a/Batchnorm_test.py +++ b/Batchnorm_test.py @@ -103,7 +103,7 @@ def forward(self, x): # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer conv2 = lrelu(self.conv2(pool1)) - conv2 = lrelu(self.b n2(self.conv2_2(conv2))) + conv2 = lrelu(self.bn2(self.conv2_2(conv2))) pool2 = self.pool2(conv2) # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer @@ -159,9 +159,7 @@ def _initialize_weights(self): # Pack the raw image into 4 channels using the bayer pattern def pack_raw(raw): - im = raw.raw_image_visible.astype(np.float32) # Change data to float32 - im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level - + im = np.maximum(raw - 512, 0) / (16383 - 512) # subtract the black level im = np.expand_dims(im, axis=2) # Add a channel dimension img_shape = im.shape # Get the shape of the image H = img_shape[0] # Get the height of the image @@ -174,7 +172,6 @@ def pack_raw(raw): im[1:H:2, 0:W:2, :]), axis=2) return out - # loss function using absolute difference between the output and ground truth def loss_function(out_image, gt_image): loss = torch.mean(torch.abs(out_image - gt_image)) From 93005834e2e57c7c7decebb5a4428e5f283453ba Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Thu, 30 Mar 2023 08:47:05 +0100 Subject: [PATCH 17/24] Create Double_batch_test.py --- Double_batch_test.py | 243 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 Double_batch_test.py diff --git a/Double_batch_test.py b/Double_batch_test.py new file mode 100644 index 0000000..cdbf645 --- /dev/null +++ b/Double_batch_test.py @@ -0,0 +1,243 @@ +from __future__ import division +import os +import numpy as np +import rawpy +import glob +from PIL import Image +import torch +import torch.nn as nn +from GPUtil import showUtilization as gpu_usage +from numba import cuda + + + +input_dir = './dataset/Sony/short/' # Path to the short exposure images +gt_dir = './dataset/Sony/long/' # Path to the long exposure images +checkpoint_dir = './result_Sony/' # Path to the checkpoint directory +result_dir = './result_Sony/' # Path to the result directory +ckpt = checkpoint_dir + 'model.ckpt' # Path to the model + +# get test IDs +test_fns = glob.glob(gt_dir + '/1*.ARW') +test_ids = [int(os.path.basename(test_fn)[0:5]) for test_fn in test_fns] + + +# Debug mode that only uses 5 images from the dataset +DEBUG = 1 +if DEBUG == 1: + save_freq = 2 + test_ids = test_ids[0:5] + + +# Leaky relu function with slope 0.2 +def lrelu(x): + outt = torch.max(0.2 * x, x) + return outt + + +# Unet class +class UNet(nn.Module): + def __init__(self): + super(UNet, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.bn1 = nn.BatchNorm2d(32) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn1_1 = nn.BatchNorm2d(32) + self.pool1 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.bn2 = nn.BatchNorm2d(64) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn2_1 = nn.BatchNorm2d(64) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.bn3 = nn.BatchNorm2d(128) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn3_1 = nn.BatchNorm2d(128) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.bn4 = nn.BatchNorm2d(256) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn4_1 = nn.BatchNorm2d(256) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.bn5 = nn.BatchNorm2d(512) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + self.bn5_1 = nn.BatchNorm2d(512) + + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.bn6 = nn.BatchNorm2d(256) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn6_1 = nn.BatchNorm2d(256) + + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.bn7 = nn.BatchNorm2d(128) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn7_1 = nn.BatchNorm2d(128) + + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.bn8 = nn.BatchNorm2d(64) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn8_1 = nn.BatchNorm2d(64) + + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.bn9 = nn.BatchNorm2d(32) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn9_1 = nn.BatchNorm2d(32) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) + + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.bn1(self.conv1(x))) + conv1 = lrelu(self.bn1_1(self.conv1_2(conv1))) + pool1 = self.pool1(conv1) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.bn2(self.conv2(pool1))) + conv2 = lrelu(self.bn2_1(self.conv2_2(conv2))) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.bn3(self.conv3(pool2))) + conv3 = lrelu(self.bn3_1(self.conv3_2(conv3))) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.bn4(self.conv4(pool3))) + conv4 = lrelu(self.bn4_1(self.conv4_2(conv4))) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.bn5(self.conv5(pool4))) + conv5 = lrelu(self.bn5_1(self.conv5_2(conv5))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.bn6(self.conv6(up6))) + conv6 = lrelu(self.bn6_1(self.conv6_2(conv6))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.bn7(self.conv7(up7))) + conv7 = lrelu(self.bn7_1(self.conv7_2(conv7))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.bn8(self.conv8(up8))) + conv8 = lrelu(self.bn8_1(self.conv8_2(conv8))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.bn9(self.conv9(up9))) + conv9 = lrelu(self.bn9_1(self.conv9_2(conv9))) + + # Forward pass through the convolutional layer + conv10 = self.conv10(conv9) + + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + + +# Pack the raw image into 4 channels using the bayer pattern +def pack_raw(raw): + im = np.maximum(raw - 512, 0) / (16383 - 512) # subtract the black level + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + + # Channel concatenation for the bayer pattern + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss + + +#device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +device = torch.device("cpu") # check if GPU is available + +unet = UNet() # Initialize the model + +unet.load_state_dict(torch.load(ckpt,map_location={'cuda:1':'cuda:0'})) +model = unet.to(device) +if not os.path.isdir(result_dir): + os.makedirs(result_dir) + +for test_id in test_ids: # Loop through all test_ids + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) # Get input image files (first image in each sequence) based on the test_id + + for k in range(len(in_files)): # Iterate through all input files + in_path = in_files[k] + _, in_fn = os.path.split(in_path) + print(in_fn) + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Get the ground truth files for the current test_id + + _, gt_fn = os.path.split(gt_files[0]) + in_exposure = float(in_fn[9:-5]) # Extract exposure values from input + gt_exposure = float(gt_fn[9:-5]) # Extract exposure values from ground truth + ratio = min(gt_exposure / in_exposure, 300) # Calculate the exposure ratio and limit it to 300 + + raw = rawpy.imread(in_path) # Read the raw input image + im = raw.raw_image_visible.astype(np.float32) # Convert it to a visible float32 image + input_full = np.expand_dims(pack_raw(im), axis=0) * ratio # Multiply image with exposure ratio + + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + scale_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + gt_raw = rawpy.imread(gt_files[0]) # Read the raw ground truth image and post-process it + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + input_full = np.minimum(input_full, 1.0) # Clip the input image to the range [0, 1] + + in_img = torch.from_numpy(input_full).permute(0, 3, 1, 2).to(device) # Convert the input image to a PyTorch tensor + out_img = unet(in_img) # Perform the image enhancement using the UNet model + + # Convert to numpy array and clip between 0 and 1 + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() + output = np.minimum(np.maximum(output, 0), 1) + + # Remove the batch dimension from the images + output = output[0, :, :, :] + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) + + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) + Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) From 038b79cf17abe242988a11423ef5072d90a59af8 Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Thu, 30 Mar 2023 08:47:39 +0100 Subject: [PATCH 18/24] Create Double_batch_train.py --- Double_batch_train.py | 309 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 Double_batch_train.py diff --git a/Double_batch_train.py b/Double_batch_train.py new file mode 100644 index 0000000..0a0603c --- /dev/null +++ b/Double_batch_train.py @@ -0,0 +1,309 @@ +from __future__ import division +import os, time +import numpy as np +import rawpy +import glob +from PIL import Image + +import torch +import torch.nn as nn + +input_dir = './dataset/Sony/short/' # Path to the short exposure images +gt_dir = './dataset/Sony/long/' # Path to the long exposure images +checkpoint_dir = './result_Sony/' # Path to the checkpoint directory +result_dir = './result_Sony/' # Path to the result directory + + +# get train IDs +train_fns = glob.glob(gt_dir + '0*.ARW') +train_ids = [int(os.path.basename(train_fn)[0:5]) for train_fn in train_fns] + +ps = 512 # patch size for training +save_freq = 500 + +# Debug mode that only uses 5 images from the dataset +DEBUG = 1 +if DEBUG == 1: + save_freq = 2 + train_ids = train_ids[0:5] + +# Leaky relu function with slope 0.2 +def lrelu(x): + outt = torch.max(0.2*x, x) + return outt + +# Unet class +class UNet(nn.Module): + def __init__(self): + super(UNet, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.bn1 = nn.BatchNorm2d(32) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn1_1 = nn.BatchNorm2d(32) + self.pool1 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.bn2 = nn.BatchNorm2d(64) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn2_1 = nn.BatchNorm2d(64) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.bn3 = nn.BatchNorm2d(128) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn3_1 = nn.BatchNorm2d(128) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.bn4 = nn.BatchNorm2d(256) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn4_1 = nn.BatchNorm2d(256) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.bn5 = nn.BatchNorm2d(512) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + self.bn5_1 = nn.BatchNorm2d(512) + + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.bn6 = nn.BatchNorm2d(256) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn6_1 = nn.BatchNorm2d(256) + + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.bn7 = nn.BatchNorm2d(128) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn7_1 = nn.BatchNorm2d(128) + + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.bn8 = nn.BatchNorm2d(64) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn8_1 = nn.BatchNorm2d(64) + + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.bn9 = nn.BatchNorm2d(32) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn9_1 = nn.BatchNorm2d(32) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) + + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.bn1(self.conv1(x))) + conv1 = lrelu(self.bn1_1(self.conv1_2(conv1))) + pool1 = self.pool1(conv1) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.bn2(self.conv2(pool1))) + conv2 = lrelu(self.bn2_1(self.conv2_2(conv2))) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.bn3(self.conv3(pool2))) + conv3 = lrelu(self.bn3_1(self.conv3_2(conv3))) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.bn4(self.conv4(pool3))) + conv4 = lrelu(self.bn4_1(self.conv4_2(conv4))) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.bn5(self.conv5(pool4))) + conv5 = lrelu(self.bn5_1(self.conv5_2(conv5))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.bn6(self.conv6(up6))) + conv6 = lrelu(self.bn6_1(self.conv6_2(conv6))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.bn7(self.conv7(up7))) + conv7 = lrelu(self.bn7_1(self.conv7_2(conv7))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.bn8(self.conv8(up8))) + conv8 = lrelu(self.bn8_1(self.conv8_2(conv8))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.bn9(self.conv9(up9))) + conv9 = lrelu(self.bn9_1(self.conv9_2(conv9))) + + # Forward pass through the convolutional layer + conv10 = self.conv10(conv9) + + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + +# Pack the raw image into 4 channels using the bayer pattern +def pack_raw(raw): + im = raw.raw_image_visible.astype(np.float32) # Change data to float32 + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + + # Channel concatenation for the bayer pattern + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss + +# Raw data takes long time to load. Keep them in memory after loaded. +gt_images = [None] * 6000 +input_images = {} +input_images['300'] = [None] * len(train_ids) +input_images['250'] = [None] * len(train_ids) +input_images['100'] = [None] * len(train_ids) + +# Array to store the loss values +g_loss = np.zeros((5000, 1)) + +allfolders = glob.glob(result_dir + '*0') # Get all the folders in the result directory +lastepoch = 0 # Initialize the last epoch to 0 + +# Get the last epoch number +for folder in allfolders: + lastepoch = np.maximum(lastepoch, int(folder[-4:])) + +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available +unet = UNet() # Initialize the model +unet.to(device) # assign the model to the GPU or CPU +unet.train() # Set the model to training mode + +learning_rate = 1e-4 # Set the learning rate + +G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer + +# Training loop +for epoch in range(lastepoch, 21): + # Check if the folder exists and skip the epoch if it does + if os.path.isdir(result_dir + '%04d' % epoch): + continue + cnt = 0 # Initialize the counter to 0 + + # Set the learning rate to 1e-5 after 2000 epochs + if epoch > 2000: + learning_rate = 1e-5 + + # Loop through the training images + for ind in np.random.permutation(len(train_ids)): + train_id = train_ids[ind] # Get the training id + in_files = glob.glob(input_dir + '%05d_00*.ARW' % train_id) # Get the input images + in_path = in_files[np.random.randint(0, len(in_files))] # Get a random input image + in_fn = os.path.basename(in_path) # Get the file name of the image + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % train_id) # Get the ground truth images + gt_path = gt_files[0] # Get the first ground truth image + gt_fn = os.path.basename(gt_path) # Get the file name of the ground truth image + in_exposure = float(in_fn[9:-5]) # Get the exposure time for the input image + gt_exposure = float(gt_fn[9:-5]) # Get the exposure time for the ground truth image + ratio = min(gt_exposure / in_exposure, 300) # Get the ratio between the exposure times + + st = time.time() # Get the current time + cnt += 1 # Increment the counter + + # Check if the image is loaded and load it if it is not + if input_images[str(ratio)[0:3]][ind] is None: + raw = rawpy.imread(in_path) # Read the raw image + input_images[str(ratio)[0:3]][ind] = np.expand_dims(pack_raw(raw), axis=0) * ratio # Pack the raw image and store it in the input images array depending on the ratio + + gt_raw = rawpy.imread(gt_path) # Read the ground truth image + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Postprocess the ground truth image + gt_images[ind] = np.expand_dims(np.float32(im / 65535.0), axis=0) # Store the ground truth image in the ground thruth images array + + # Crop the image to the required size + H = input_images[str(ratio)[0:3]][ind].shape[1] # Get the height of the image + W = input_images[str(ratio)[0:3]][ind].shape[2] # Get the width of the image + + # Get a random start location on the image + xx = np.random.randint(0, W - ps) + yy = np.random.randint(0, H - ps) + + # Get the data used for training + input_patch = input_images[str(ratio)[0:3]][ind][:, yy:yy + ps, xx:xx + ps, :] + gt_patch = gt_images[ind][:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :] + + # Data augmentation + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 1 + input_patch = np.flip(input_patch, axis=1) + gt_patch = np.flip(gt_patch, axis=1) + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 2 + input_patch = np.flip(input_patch, axis=2) + gt_patch = np.flip(gt_patch, axis=2) + if np.random.randint(2, size=1)[0] == 1: # random transpose + input_patch = np.transpose(input_patch, (0, 2, 1, 3)) + gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) + + input_patch = np.minimum(input_patch, 1.0) # Input patch should be between 0 and 1 + input_img = torch.from_numpy(input_patch) # Convert the input patch to a tensor + input_img = input_img.permute(0, 3, 1, 2) # Permute the tensor + input_img = input_img.to(device) # Assign the tensor to the GPU or CPU + + gt_patch = np.minimum(gt_patch, 1.0) # Ground truth patch should be between 0 and 1 + gt_img = torch.from_numpy(gt_patch) # Convert the ground truth patch to a tensor + gt_img = gt_img.permute(0, 3, 1, 2) # Permute the tensor + gt_img = gt_img.to(device) # Assign the tensor to the GPU or CPU + + # Run the model + G_opt.zero_grad() # Set the gradient to 0 + out_image = unet(input_img) # Get the output image + + # Calculate the loss + loss = loss_function(out_image, gt_img) + loss.backward() # Calculate the gradients + G_opt.step() # Update the weights + g_loss[ind] = loss.item() # Store the loss + + print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) # Print the loss and time + + output = out_image.permute(0, 2, 3, 1).cpu().data.numpy() # Get the output image and convert it to numpy + output = np.minimum(np.maximum(output, 0), 1) # Output should be between 0 and 1 + + # Save the results + if epoch % save_freq == 0: + # Create the directory if it does not exist + if not os.path.isdir(result_dir + '%04d' % epoch): + os.makedirs(result_dir + '%04d' % epoch) + + # Save the image + temp = np.concatenate((gt_patch[0, :, :, :], output[0, :, :, :]), axis=1) # Concatenate the ground truth and output images + Image.fromarray((temp * 255).astype(np.uint8)).save(result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) # Save the image + + # Save the model + torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') From bb606ca93d079360f11b621841205efc35ac7981 Mon Sep 17 00:00:00 2001 From: Daan1289 Date: Thu, 30 Mar 2023 13:12:33 +0200 Subject: [PATCH 19/24] Metric functions --- Batchnorm_train.py | 4 ++-- utils.py | 0 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 utils.py diff --git a/Batchnorm_train.py b/Batchnorm_train.py index 7800d17..f621ded 100644 --- a/Batchnorm_train.py +++ b/Batchnorm_train.py @@ -29,8 +29,8 @@ # Leaky relu function with slope 0.2 def lrelu(x): - outt = torch.max(0.2*x, x) - return outt + outt = torch.max(0.2*x, x) + return outt # Unet class class UNet(nn.Module): diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..e69de29 From 0cfc33ab37021ffc647a714a3aec023a9326d8da Mon Sep 17 00:00:00 2001 From: Daan1289 Date: Thu, 30 Mar 2023 15:22:13 +0200 Subject: [PATCH 20/24] Created a file to store the performance metrics --- Batchnorm_train.py | 4 ++- Double_batch_test.py | 4 +-- Double_batch_train.py | 4 ++- Test_Sony_To_Pytorch.py | 2 +- performance_measurements.py | 52 +++++++++++++++++++++++++++++++++ results_40.csv | 2 ++ utils.py | 57 +++++++++++++++++++++++++++++++++++++ 7 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 performance_measurements.py create mode 100644 results_40.csv diff --git a/Batchnorm_train.py b/Batchnorm_train.py index f621ded..f1e7f72 100644 --- a/Batchnorm_train.py +++ b/Batchnorm_train.py @@ -202,7 +202,7 @@ def loss_function(out_image, gt_image): G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer # Training loop -for epoch in range(lastepoch, 21): +for epoch in range(lastepoch, 41): # Check if the folder exists and skip the epoch if it does if os.path.isdir(result_dir + '%04d' % epoch): continue @@ -298,3 +298,5 @@ def loss_function(out_image, gt_image): # Save the model torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') + +print("\nFinished training!\n") diff --git a/Double_batch_test.py b/Double_batch_test.py index cdbf645..035de18 100644 --- a/Double_batch_test.py +++ b/Double_batch_test.py @@ -6,15 +6,13 @@ from PIL import Image import torch import torch.nn as nn -from GPUtil import showUtilization as gpu_usage -from numba import cuda input_dir = './dataset/Sony/short/' # Path to the short exposure images gt_dir = './dataset/Sony/long/' # Path to the long exposure images checkpoint_dir = './result_Sony/' # Path to the checkpoint directory -result_dir = './result_Sony/' # Path to the result directory +result_dir = './result_Sony/final/' # Path to the result directory ckpt = checkpoint_dir + 'model.ckpt' # Path to the model # get test IDs diff --git a/Double_batch_train.py b/Double_batch_train.py index 0a0603c..ca05f3b 100644 --- a/Double_batch_train.py +++ b/Double_batch_train.py @@ -211,7 +211,7 @@ def loss_function(out_image, gt_image): G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer # Training loop -for epoch in range(lastepoch, 21): +for epoch in range(lastepoch, 41): # Check if the folder exists and skip the epoch if it does if os.path.isdir(result_dir + '%04d' % epoch): continue @@ -307,3 +307,5 @@ def loss_function(out_image, gt_image): # Save the model torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') + +print("\nFinished training!\n") diff --git a/Test_Sony_To_Pytorch.py b/Test_Sony_To_Pytorch.py index aae34cd..bd2a084 100644 --- a/Test_Sony_To_Pytorch.py +++ b/Test_Sony_To_Pytorch.py @@ -10,7 +10,7 @@ input_dir = './dataset/Sony/short/' # Path to the short exposure images gt_dir = './dataset/Sony/long/' # Path to the long exposure images checkpoint_dir = './result_Sony/' # Path to the checkpoint directory -result_dir = './result_Sony/final' # Path to the result directory +result_dir = './result_Sony/final/' # Path to the result directory ckpt = checkpoint_dir + 'model.ckpt' # Path to the model # get test IDs diff --git a/performance_measurements.py b/performance_measurements.py new file mode 100644 index 0000000..dd13cb9 --- /dev/null +++ b/performance_measurements.py @@ -0,0 +1,52 @@ +import matplotlib.pyplot as plt +from PIL import ImageFile +ImageFile.LOAD_TRUNCATED_IMAGES = True +import os +import csv + +from utils import calculate_psnr, calculate_ssim + +result_dir = './result_Sony/final/' + +total_psnr = 0 +total_ssim = 0 +count = 0 + +for image in os.listdir(result_dir): + if image.endswith('out.png'): + img_out = plt.imread(result_dir + image) + img_gt = plt.imread(result_dir + image.replace('out.png', 'gt.png')) + psnr_score = calculate_psnr(img_out, img_gt) + ssim_score = calculate_ssim(img_out, img_gt) + print(image, psnr_score, ssim_score) + total_psnr += psnr_score + total_ssim += ssim_score + count += 1 + +mean_psnr = total_psnr / count +mean_ssim = total_ssim / count +print('mean psnr: ', mean_psnr) +print('mean ssim: ', mean_ssim) + + +### CHANGE THESE PARAMETERS TO CHANGE THE NAME OF THE CSV FILE AND THE MODEL NAME IN THE CSV FILE ### +results_file = 'results_40.csv' +model_name = 'Single Batch Normalization' + + +# Check if the csv file exists, if it does, append the results to the file, if not, create a new file and write the results to it +if os.path.isfile(results_file): + with open(results_file, 'a') as csvfile: + fieldnames = ['Model', 'Mean psnr', 'Mean ssim'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writerow({'Model': model_name, 'Mean psnr': mean_psnr, 'Mean ssim': mean_ssim}) +else: + with open(results_file, 'w') as csvfile: + # Create a header for rhe csv file that tores the mean metrics for different models, in this case the model is using double batch normalization + fieldnames = ['Model', 'Mean psnr', 'Mean ssim'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writeheader() + writer.writerow({'Model': model_name, 'Mean psnr': mean_psnr, 'Mean ssim': mean_ssim}) + + + \ No newline at end of file diff --git a/results_40.csv b/results_40.csv new file mode 100644 index 0000000..963e665 --- /dev/null +++ b/results_40.csv @@ -0,0 +1,2 @@ +Model,Mean psnr,Mean ssim +Double Batch Normalization,70.08534131917101,0.9992578581279 diff --git a/utils.py b/utils.py index e69de29..4108c61 100644 --- a/utils.py +++ b/utils.py @@ -0,0 +1,57 @@ +import math +import numpy as np +import cv2 + + +def calculate_psnr(img1, img2): + # img1 and img2 have range [0, 255] + img1 = img1.astype(np.float64) + img2 = img2.astype(np.float64) + mse = np.mean((img1 - img2)**2) + if mse == 0: + return float('inf') + return 20 * math.log10(255.0 / math.sqrt(mse)) + + +def ssim(img1, img2): + C1 = (0.01 * 255)**2 + C2 = (0.03 * 255)**2 + + img1 = img1.astype(np.float64) + img2 = img2.astype(np.float64) + kernel = cv2.getGaussianKernel(11, 1.5) + window = np.outer(kernel, kernel.transpose()) + + mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5] # valid + mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5] + mu1_sq = mu1**2 + mu2_sq = mu2**2 + mu1_mu2 = mu1 * mu2 + sigma1_sq = cv2.filter2D(img1**2, -1, window)[5:-5, 5:-5] - mu1_sq + sigma2_sq = cv2.filter2D(img2**2, -1, window)[5:-5, 5:-5] - mu2_sq + sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2 + + ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * + (sigma1_sq + sigma2_sq + C2)) + return ssim_map.mean() + +def calculate_ssim(img1, img2): + '''calculate SSIM + the same outputs as MATLAB's + img1, img2: [0, 255] + ''' + if not img1.shape == img2.shape: + raise ValueError('Input images must have the same dimensions.') + if img1.ndim == 2: + return ssim(img1, img2) + elif img1.ndim == 3: + if img1.shape[2] == 3: + ssims = [] + for i in range(3): + ssims.append(ssim(img1, img2)) + return np.array(ssims).mean() + elif img1.shape[2] == 1: + return ssim(np.squeeze(img1), np.squeeze(img2)) + else: + raise ValueError('Wrong input image dimensions.') + \ No newline at end of file From b5a20952eeea6dbe73a20caf04ac2cce29153510 Mon Sep 17 00:00:00 2001 From: jhagenus <109104631+jhagenus@users.noreply.github.com> Date: Fri, 31 Mar 2023 13:30:52 +0100 Subject: [PATCH 21/24] Create PSNRandSSIM.py --- PSNRandSSIM.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 PSNRandSSIM.py diff --git a/PSNRandSSIM.py b/PSNRandSSIM.py new file mode 100644 index 0000000..b6ed6d6 --- /dev/null +++ b/PSNRandSSIM.py @@ -0,0 +1,32 @@ +from PIL import Image +from skimage.metrics import peak_signal_noise_ratio +from skimage.metrics import structural_similarity as ssim +import numpy as np + + +# Load the two PNG files +img1 = Image.open("C:\\Users\\jeroe\\Downloads\\Learning-to-See-in-the-Dark-master\\Learning-to-See-in-the-Dark-master\\result_Sony\\10003_00_100_gt.png") +img2 = Image.open("C:\\Users\\jeroe\\Downloads\\Learning-to-See-in-the-Dark-master\\Learning-to-See-in-the-Dark-master\\result_Sony\\10003_00_100_out.png") + +# Convert the PIL Image objects to numpy arrays +arr1 = np.array(img1) +arr2 = np.array(img2) + +# Calculate the PSNR +psnr = peak_signal_noise_ratio(arr1, arr2) + +# Print the result +print(f"PSNR: {psnr:.2f} dB") + +img1 = img1.resize((256, 256)) +img2 = img2.resize((256, 256)) + +# Convert the PIL Image objects to numpy arrays +arr1 = np.array(img1) +arr2 = np.array(img2) + +# Calculate the SSIM +ssim_score, ssim_image = ssim(arr1, arr2, win_size=7, channel_axis=2, full=True) + +# Print the SSIM score +print(f"SSIM: {ssim_score:.2f}") From 7f346ab1aff211bb1c5ad34e4b5bc472dc4ea8b2 Mon Sep 17 00:00:00 2001 From: Daan1289 Date: Fri, 31 Mar 2023 15:15:58 +0200 Subject: [PATCH 22/24] Created a file that measures the performance --- Train_Sony_To_Pytorch.py | 4 +++- performance_measurements.py | 2 +- results_40.csv | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Train_Sony_To_Pytorch.py b/Train_Sony_To_Pytorch.py index ab22546..4816dbd 100644 --- a/Train_Sony_To_Pytorch.py +++ b/Train_Sony_To_Pytorch.py @@ -193,7 +193,7 @@ def loss_function(out_image, gt_image): G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer # Training loop -for epoch in range(lastepoch, 30): +for epoch in range(lastepoch, 41): # Check if the folder exists and skip the epoch if it does if os.path.isdir(result_dir + '%04d' % epoch): continue @@ -289,3 +289,5 @@ def loss_function(out_image, gt_image): # Save the model torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') + +print("\nFinished training!\n") diff --git a/performance_measurements.py b/performance_measurements.py index dd13cb9..97e48a6 100644 --- a/performance_measurements.py +++ b/performance_measurements.py @@ -31,7 +31,7 @@ ### CHANGE THESE PARAMETERS TO CHANGE THE NAME OF THE CSV FILE AND THE MODEL NAME IN THE CSV FILE ### results_file = 'results_40.csv' -model_name = 'Single Batch Normalization' +model_name = 'Without Normalization' # Check if the csv file exists, if it does, append the results to the file, if not, create a new file and write the results to it diff --git a/results_40.csv b/results_40.csv index 963e665..d298855 100644 --- a/results_40.csv +++ b/results_40.csv @@ -1,2 +1,4 @@ Model,Mean psnr,Mean ssim Double Batch Normalization,70.08534131917101,0.9992578581279 +Single Batch Normalization,69.09286454298345,0.9990374195471773 +Without Normalization,66.32649029769772,0.9977063206417741 From 7d08a211e3b0c5930110e992679802f7274e974f Mon Sep 17 00:00:00 2001 From: Daan1289 Date: Fri, 31 Mar 2023 23:06:09 +0200 Subject: [PATCH 23/24] Changed the entire repo and created file to train and run the different models --- calculate_metrics.py | 62 +++ .../download_dataset.py | 0 .../download_models.py | 0 test_Fuji.py => original_code/test_Fuji.py | 0 original_code/test_Sony.py | 155 +++++++ .../test_Sony_pytorch.py | 0 train_Fuji.py => original_code/train_Fuji.py | 0 original_code/train_Sony.py | 203 +++++++++ .../train_Sony_pytorch.py | 0 original_code/unet.py | 149 +++++++ .../Batchnorm_test.py | 0 .../Batchnorm_train.py | 0 .../Double_batch_test.py | 0 .../Double_batch_train.py | 0 PSNRandSSIM.py => oude_code/PSNRandSSIM.py | 4 +- .../Test_Sony_To_Pytorch.py | 0 .../Train_Sony_To_Pytorch.py | 6 +- performance_measurements.py | 52 --- run_testing.py | 25 ++ test_Sony.py | 206 ++++----- train_Sony.py | 363 ++++++++------- unet.py | 414 ++++++++++++++---- 22 files changed, 1175 insertions(+), 464 deletions(-) create mode 100644 calculate_metrics.py rename download_dataset.py => original_code/download_dataset.py (100%) rename download_models.py => original_code/download_models.py (100%) rename test_Fuji.py => original_code/test_Fuji.py (100%) create mode 100644 original_code/test_Sony.py rename test_Sony_pytorch.py => original_code/test_Sony_pytorch.py (100%) rename train_Fuji.py => original_code/train_Fuji.py (100%) create mode 100644 original_code/train_Sony.py rename train_Sony_pytorch.py => original_code/train_Sony_pytorch.py (100%) create mode 100644 original_code/unet.py rename Batchnorm_test.py => oude_code/Batchnorm_test.py (100%) rename Batchnorm_train.py => oude_code/Batchnorm_train.py (100%) rename Double_batch_test.py => oude_code/Double_batch_test.py (100%) rename Double_batch_train.py => oude_code/Double_batch_train.py (100%) rename PSNRandSSIM.py => oude_code/PSNRandSSIM.py (86%) rename Test_Sony_To_Pytorch.py => oude_code/Test_Sony_To_Pytorch.py (100%) rename Train_Sony_To_Pytorch.py => oude_code/Train_Sony_To_Pytorch.py (99%) delete mode 100644 performance_measurements.py create mode 100644 run_testing.py diff --git a/calculate_metrics.py b/calculate_metrics.py new file mode 100644 index 0000000..88dbc47 --- /dev/null +++ b/calculate_metrics.py @@ -0,0 +1,62 @@ +import matplotlib.pyplot as plt +from PIL import ImageFile, Image +ImageFile.LOAD_TRUNCATED_IMAGES = True +import os +import csv +import numpy as np +from skimage.metrics import peak_signal_noise_ratio as psnr, structural_similarity as ssim + + +from utils import calculate_psnr, calculate_ssim + + +def calculate_metrics(results_file, model_name): + + result_dir = './result_Sony/final/' + + total_psnr = 0 + total_ssim = 0 + count = 0 + + for image in os.listdir(result_dir): + if image.endswith('out.png'): + # img_out = plt.imread(result_dir + image) + # img_gt = plt.imread(result_dir + image.replace('out.png', 'gt.png')) + # psnr_score = calculate_psnr(img_out, img_gt) + # ssim_score = calculate_ssim(img_out, img_gt) + + img_out = np.array(Image.open(result_dir + image)) + img_gt = np.array(Image.open(result_dir + image.replace('out.png', 'gt.png'))) + psnr_score = psnr(img_gt, img_out) + ssim_score = ssim(img_gt, img_out, win_size=7, channel_axis=2, full=True)[0] + + print(image, psnr_score, ssim_score) + total_psnr += psnr_score + total_ssim += ssim_score + count += 1 + + mean_psnr = total_psnr / count + mean_ssim = total_ssim / count + print('mean psnr: ', mean_psnr) + print('mean ssim: ', mean_ssim) + + # Check if the csv file exists, if it does, append the results to the file, if not, create a new file and write the results to it + if os.path.isfile(results_file): + with open(results_file, 'a') as csvfile: + fieldnames = ['Model', 'Mean psnr', 'Mean ssim'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writerow({'Model': model_name, 'Mean psnr': mean_psnr, 'Mean ssim': mean_ssim}) + else: + with open(results_file, 'w') as csvfile: + # Create a header for rhe csv file that tores the mean metrics for different models, in this case the model is using double batch normalization + fieldnames = ['Model', 'Mean psnr', 'Mean ssim'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writeheader() + writer.writerow({'Model': model_name, 'Mean psnr': mean_psnr, 'Mean ssim': mean_ssim}) + + +if __name__ == '__main__': + ### CHANGE THESE PARAMETERS TO CHANGE THE NAME OF THE CSV FILE AND THE MODEL NAME IN THE CSV FILE ### + results_file = 'results_40.csv' + model_name = 'Without Normalization' + calculate_metrics(results_file=results_file, model_name=model_name) \ No newline at end of file diff --git a/download_dataset.py b/original_code/download_dataset.py similarity index 100% rename from download_dataset.py rename to original_code/download_dataset.py diff --git a/download_models.py b/original_code/download_models.py similarity index 100% rename from download_models.py rename to original_code/download_models.py diff --git a/test_Fuji.py b/original_code/test_Fuji.py similarity index 100% rename from test_Fuji.py rename to original_code/test_Fuji.py diff --git a/original_code/test_Sony.py b/original_code/test_Sony.py new file mode 100644 index 0000000..b4adfcb --- /dev/null +++ b/original_code/test_Sony.py @@ -0,0 +1,155 @@ +# uniform content loss + adaptive threshold + per_class_input + recursive G +# improvement upon cqf37 +from __future__ import division +import os, scipy.io +import tensorflow as tf +import tensorflow.contrib.slim as slim +import numpy as np +import rawpy +import glob + +input_dir = './dataset/Sony/short/' +gt_dir = './dataset/Sony/long/' +checkpoint_dir = './checkpoint/Sony/' +result_dir = './result_Sony/' + +# get test IDs +test_fns = glob.glob(gt_dir + '/1*.ARW') +test_ids = [int(os.path.basename(test_fn)[0:5]) for test_fn in test_fns] + +DEBUG = 0 +if DEBUG == 1: + save_freq = 2 + test_ids = test_ids[0:5] + + +def lrelu(x): + return tf.maximum(x * 0.2, x) + + +def upsample_and_concat(x1, x2, output_channels, in_channels): + pool_size = 2 + deconv_filter = tf.Variable(tf.truncated_normal([pool_size, pool_size, output_channels, in_channels], stddev=0.02)) + deconv = tf.nn.conv2d_transpose(x1, deconv_filter, tf.shape(x2), strides=[1, pool_size, pool_size, 1]) + + deconv_output = tf.concat([deconv, x2], 3) + deconv_output.set_shape([None, None, None, output_channels * 2]) + + return deconv_output + + +def network(input): + conv1 = slim.conv2d(input, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_1') + conv1 = slim.conv2d(conv1, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_2') + pool1 = slim.max_pool2d(conv1, [2, 2], padding='SAME') + + conv2 = slim.conv2d(pool1, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_1') + conv2 = slim.conv2d(conv2, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_2') + pool2 = slim.max_pool2d(conv2, [2, 2], padding='SAME') + + conv3 = slim.conv2d(pool2, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_1') + conv3 = slim.conv2d(conv3, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_2') + pool3 = slim.max_pool2d(conv3, [2, 2], padding='SAME') + + conv4 = slim.conv2d(pool3, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_1') + conv4 = slim.conv2d(conv4, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_2') + pool4 = slim.max_pool2d(conv4, [2, 2], padding='SAME') + + conv5 = slim.conv2d(pool4, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_1') + conv5 = slim.conv2d(conv5, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_2') + + up6 = upsample_and_concat(conv5, conv4, 256, 512) + conv6 = slim.conv2d(up6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_1') + conv6 = slim.conv2d(conv6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_2') + + up7 = upsample_and_concat(conv6, conv3, 128, 256) + conv7 = slim.conv2d(up7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_1') + conv7 = slim.conv2d(conv7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_2') + + up8 = upsample_and_concat(conv7, conv2, 64, 128) + conv8 = slim.conv2d(up8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_1') + conv8 = slim.conv2d(conv8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_2') + + up9 = upsample_and_concat(conv8, conv1, 32, 64) + conv9 = slim.conv2d(up9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_1') + conv9 = slim.conv2d(conv9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_2') + + conv10 = slim.conv2d(conv9, 12, [1, 1], rate=1, activation_fn=None, scope='g_conv10') + out = tf.depth_to_space(conv10, 2) + return out + + +def pack_raw(raw): + # pack Bayer image to 4 channels + im = raw.raw_image_visible.astype(np.float32) + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) + img_shape = im.shape + H = img_shape[0] + W = img_shape[1] + + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + + +sess = tf.Session() +in_image = tf.placeholder(tf.float32, [None, None, None, 4]) +gt_image = tf.placeholder(tf.float32, [None, None, None, 3]) +out_image = network(in_image) + +saver = tf.train.Saver() +sess.run(tf.global_variables_initializer()) +ckpt = tf.train.get_checkpoint_state(checkpoint_dir) +if ckpt: + print('loaded ' + ckpt.model_checkpoint_path) + saver.restore(sess, ckpt.model_checkpoint_path) + +if not os.path.isdir(result_dir + 'final/'): + os.makedirs(result_dir + 'final/') + +for test_id in test_ids: + # test the first image in each sequence + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) + for k in range(len(in_files)): + in_path = in_files[k] + in_fn = os.path.basename(in_path) + print(in_fn) + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) + gt_path = gt_files[0] + gt_fn = os.path.basename(gt_path) + in_exposure = float(in_fn[9:-5]) + gt_exposure = float(gt_fn[9:-5]) + ratio = min(gt_exposure / in_exposure, 300) + + raw = rawpy.imread(in_path) + input_full = np.expand_dims(pack_raw(raw), axis=0) * ratio + + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + # scale_full = np.expand_dims(np.float32(im/65535.0),axis = 0)*ratio + scale_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + gt_raw = rawpy.imread(gt_path) + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) + + input_full = np.minimum(input_full, 1.0) + + output = sess.run(out_image, feed_dict={in_image: input_full}) + output = np.minimum(np.maximum(output, 0), 1) + + output = output[0, :, :, :] + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean( + scale_full) # scale the low-light image to the same mean of the groundtruth + + scipy.misc.toimage(output * 255, high=255, low=0, cmin=0, cmax=255).save( + result_dir + 'final/%5d_00_%d_out.png' % (test_id, ratio)) + scipy.misc.toimage(scale_full * 255, high=255, low=0, cmin=0, cmax=255).save( + result_dir + 'final/%5d_00_%d_scale.png' % (test_id, ratio)) + scipy.misc.toimage(gt_full * 255, high=255, low=0, cmin=0, cmax=255).save( + result_dir + 'final/%5d_00_%d_gt.png' % (test_id, ratio)) diff --git a/test_Sony_pytorch.py b/original_code/test_Sony_pytorch.py similarity index 100% rename from test_Sony_pytorch.py rename to original_code/test_Sony_pytorch.py diff --git a/train_Fuji.py b/original_code/train_Fuji.py similarity index 100% rename from train_Fuji.py rename to original_code/train_Fuji.py diff --git a/original_code/train_Sony.py b/original_code/train_Sony.py new file mode 100644 index 0000000..ce0642a --- /dev/null +++ b/original_code/train_Sony.py @@ -0,0 +1,203 @@ +# uniform content loss + adaptive threshold + per_class_input + recursive G +# improvement upon cqf37 +from __future__ import division +import os, time, scipy.io +import tensorflow as tf +import tensorflow.contrib.slim as slim +import numpy as np +import rawpy +import glob + +input_dir = './dataset/Sony/short/' +gt_dir = './dataset/Sony/long/' +checkpoint_dir = './result_Sony/' +result_dir = './result_Sony/' + +# get train IDs +train_fns = glob.glob(gt_dir + '0*.ARW') +train_ids = [int(os.path.basename(train_fn)[0:5]) for train_fn in train_fns] + +ps = 512 # patch size for training +save_freq = 500 + +DEBUG = 1 +if DEBUG == 1: + save_freq = 2 + train_ids = train_ids[0:5] + + +def lrelu(x): + return tf.maximum(x * 0.2, x) + + +def upsample_and_concat(x1, x2, output_channels, in_channels): + pool_size = 2 + deconv_filter = tf.Variable(tf.truncated_normal([pool_size, pool_size, output_channels, in_channels], stddev=0.02)) + deconv = tf.nn.conv2d_transpose(x1, deconv_filter, tf.shape(x2), strides=[1, pool_size, pool_size, 1]) + + deconv_output = tf.concat([deconv, x2], 3) + deconv_output.set_shape([None, None, None, output_channels * 2]) + + return deconv_output + + +def network(input): + conv1 = slim.conv2d(input, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_1') + conv1 = slim.conv2d(conv1, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_2') + pool1 = slim.max_pool2d(conv1, [2, 2], padding='SAME') + + conv2 = slim.conv2d(pool1, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_1') + conv2 = slim.conv2d(conv2, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_2') + pool2 = slim.max_pool2d(conv2, [2, 2], padding='SAME') + + conv3 = slim.conv2d(pool2, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_1') + conv3 = slim.conv2d(conv3, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_2') + pool3 = slim.max_pool2d(conv3, [2, 2], padding='SAME') + + conv4 = slim.conv2d(pool3, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_1') + conv4 = slim.conv2d(conv4, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_2') + pool4 = slim.max_pool2d(conv4, [2, 2], padding='SAME') + + conv5 = slim.conv2d(pool4, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_1') + conv5 = slim.conv2d(conv5, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_2') + + up6 = upsample_and_concat(conv5, conv4, 256, 512) + conv6 = slim.conv2d(up6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_1') + conv6 = slim.conv2d(conv6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_2') + + up7 = upsample_and_concat(conv6, conv3, 128, 256) + conv7 = slim.conv2d(up7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_1') + conv7 = slim.conv2d(conv7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_2') + + up8 = upsample_and_concat(conv7, conv2, 64, 128) + conv8 = slim.conv2d(up8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_1') + conv8 = slim.conv2d(conv8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_2') + + up9 = upsample_and_concat(conv8, conv1, 32, 64) + conv9 = slim.conv2d(up9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_1') + conv9 = slim.conv2d(conv9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_2') + + conv10 = slim.conv2d(conv9, 12, [1, 1], rate=1, activation_fn=None, scope='g_conv10') + out = tf.depth_to_space(conv10, 2) + return out + + +def pack_raw(raw): + # pack Bayer image to 4 channels + im = raw.raw_image_visible.astype(np.float32) + im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + + im = np.expand_dims(im, axis=2) + img_shape = im.shape + H = img_shape[0] + W = img_shape[1] + + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out + + +sess = tf.Session() +in_image = tf.placeholder(tf.float32, [None, None, None, 4]) +gt_image = tf.placeholder(tf.float32, [None, None, None, 3]) +out_image = network(in_image) + +G_loss = tf.reduce_mean(tf.abs(out_image - gt_image)) + +t_vars = tf.trainable_variables() +lr = tf.placeholder(tf.float32) +G_opt = tf.train.AdamOptimizer(learning_rate=lr).minimize(G_loss) + +saver = tf.train.Saver() +sess.run(tf.global_variables_initializer()) +ckpt = tf.train.get_checkpoint_state(checkpoint_dir) +if ckpt: + print('loaded ' + ckpt.model_checkpoint_path) + saver.restore(sess, ckpt.model_checkpoint_path) + +# Raw data takes long time to load. Keep them in memory after loaded. +gt_images = [None] * 6000 +input_images = {} +input_images['300'] = [None] * len(train_ids) +input_images['250'] = [None] * len(train_ids) +input_images['100'] = [None] * len(train_ids) + +g_loss = np.zeros((5000, 1)) + +allfolders = glob.glob(result_dir + '*0') +lastepoch = 0 +for folder in allfolders: + lastepoch = np.maximum(lastepoch, int(folder[-4:])) + +learning_rate = 1e-4 +for epoch in range(lastepoch, 4001): + if os.path.isdir(result_dir + '%04d' % epoch): + continue + cnt = 0 + if epoch > 2000: + learning_rate = 1e-5 + + for ind in np.random.permutation(len(train_ids)): + # get the path from image id + train_id = train_ids[ind] + in_files = glob.glob(input_dir + '%05d_00*.ARW' % train_id) + in_path = in_files[np.random.random_integers(0, len(in_files) - 1)] + in_fn = os.path.basename(in_path) + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % train_id) + gt_path = gt_files[0] + gt_fn = os.path.basename(gt_path) + in_exposure = float(in_fn[9:-5]) + gt_exposure = float(gt_fn[9:-5]) + ratio = min(gt_exposure / in_exposure, 300) + + st = time.time() + cnt += 1 + + if input_images[str(ratio)[0:3]][ind] is None: + raw = rawpy.imread(in_path) + input_images[str(ratio)[0:3]][ind] = np.expand_dims(pack_raw(raw), axis=0) * ratio + + gt_raw = rawpy.imread(gt_path) + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_images[ind] = np.expand_dims(np.float32(im / 65535.0), axis=0) + + # crop + H = input_images[str(ratio)[0:3]][ind].shape[1] + W = input_images[str(ratio)[0:3]][ind].shape[2] + + xx = np.random.randint(0, W - ps) + yy = np.random.randint(0, H - ps) + input_patch = input_images[str(ratio)[0:3]][ind][:, yy:yy + ps, xx:xx + ps, :] + gt_patch = gt_images[ind][:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :] + + if np.random.randint(2, size=1)[0] == 1: # random flip + input_patch = np.flip(input_patch, axis=1) + gt_patch = np.flip(gt_patch, axis=1) + if np.random.randint(2, size=1)[0] == 1: + input_patch = np.flip(input_patch, axis=2) + gt_patch = np.flip(gt_patch, axis=2) + if np.random.randint(2, size=1)[0] == 1: # random transpose + input_patch = np.transpose(input_patch, (0, 2, 1, 3)) + gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) + + input_patch = np.minimum(input_patch, 1.0) + + _, G_current, output = sess.run([G_opt, G_loss, out_image], + feed_dict={in_image: input_patch, gt_image: gt_patch, lr: learning_rate}) + output = np.minimum(np.maximum(output, 0), 1) + g_loss[ind] = G_current + + print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) + + if epoch % save_freq == 0: + if not os.path.isdir(result_dir + '%04d' % epoch): + os.makedirs(result_dir + '%04d' % epoch) + + temp = np.concatenate((gt_patch[0, :, :, :], output[0, :, :, :]), axis=1) + scipy.misc.toimage(temp * 255, high=255, low=0, cmin=0, cmax=255).save( + result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) + + saver.save(sess, checkpoint_dir + 'model.ckpt') diff --git a/train_Sony_pytorch.py b/original_code/train_Sony_pytorch.py similarity index 100% rename from train_Sony_pytorch.py rename to original_code/train_Sony_pytorch.py diff --git a/original_code/unet.py b/original_code/unet.py new file mode 100644 index 0000000..191686a --- /dev/null +++ b/original_code/unet.py @@ -0,0 +1,149 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +class lReLU(nn.Module): + def __init__(self): + super(lReLU, self).__init__() + + def forward(self, x): + return torch.max(x * 0.2, x) + +class Double_Conv2d(nn.Module): + def __init__(self, in_channel, out_channel): + super(Double_Conv2d, self).__init__() + self.double_conv2d = torch.nn.Sequential( + nn.Conv2d(in_channels=in_channel, out_channels=out_channel, kernel_size=3, padding=1), + lReLU(), + nn.Conv2d(in_channels=out_channel, out_channels=out_channel, kernel_size=3, padding=1), + lReLU() + ) + + def forward(self, x): + return self.double_conv2d(x) + +class UNetSony(nn.Module): + def __init__(self): + super(UNetSony, self).__init__() + self.conv1 = Double_Conv2d(4, 32) + self.conv2 = Double_Conv2d(32, 64) + self.conv3 = Double_Conv2d(64, 128) + self.conv4 = Double_Conv2d(128, 256) + self.conv5 = Double_Conv2d(256, 512) + self.up6 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) + self.conv6 = Double_Conv2d(512, 256) + self.up7 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) + self.conv7 = Double_Conv2d(256, 128) + self.up8 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) + self.conv8 = Double_Conv2d(128, 64) + self.up9 = nn.ConvTranspose2d(64, 32, kernel_size=2, stride=2) + self.conv9 = Double_Conv2d(64, 32) + self.conv10 = nn.Conv2d(in_channels=32, out_channels=12, kernel_size=1) + + def forward(self, x): + conv1 = self.conv1(x) + pool1 = F.max_pool2d(conv1, kernel_size=2) + + conv2 = self.conv2(pool1) + pool2 = F.max_pool2d(conv2, kernel_size=2) + + conv3 = self.conv3(pool2) + pool3 = F.max_pool2d(conv3, kernel_size=2) + + conv4 = self.conv4(pool3) + pool4 = F.max_pool2d(conv4, kernel_size=2) + + conv5 = self.conv5(pool4) + + up6 = self.up6(conv5) + up6 = torch.cat([up6, conv4], 1) + conv6 = self.conv6(up6) + + up7 = self.up7(conv6) + up7 = torch.cat([up7, conv3], 1) + conv7 = self.conv7(up7) + + up8 = self.up8(conv7) + up8 = torch.cat([up8, conv2], 1) + conv8 = self.conv8(up8) + + up9 = self.up9(conv8) + up9 = torch.cat([up9, conv1], 1) + conv9 = self.conv9(up9) + + conv10 = self.conv10(conv9) + out = F.pixel_shuffle(conv10, 2) + + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) + +class UNetFuji(nn.Module): + def __init__(self): + super(UNetFuji, self).__init__() + self.conv1 = Double_Conv2d(9, 32) + self.conv2 = Double_Conv2d(32, 64) + self.conv3 = Double_Conv2d(64, 128) + self.conv4 = Double_Conv2d(128, 256) + self.conv5 = Double_Conv2d(256, 512) + self.up6 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) + self.conv6 = Double_Conv2d(512, 256) + self.up7 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) + self.conv7 = Double_Conv2d(256, 128) + self.up8 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) + self.conv8 = Double_Conv2d(128, 64) + self.up9 = nn.ConvTranspose2d(64, 32, kernel_size=2, stride=2) + self.conv9 = Double_Conv2d(64, 32) + self.conv10 = nn.Conv2d(in_channels=32, out_channels=27, kernel_size=1) + + def forward(self, x): + conv1 = self.conv1(x) + pool1 = F.max_pool2d(conv1, kernel_size=2) + + conv2 = self.conv2(pool1) + pool2 = F.max_pool2d(conv2, kernel_size=2) + + conv3 = self.conv3(pool2) + pool3 = F.max_pool2d(conv3, kernel_size=2) + + conv4 = self.conv4(pool3) + pool4 = F.max_pool2d(conv4, kernel_size=2) + + conv5 = self.conv5(pool4) + + up6 = self.up6(conv5) + up6 = torch.cat([up6, conv4], 1) + conv6 = self.conv6(up6) + + up7 = self.up7(conv6) + up7 = torch.cat([up7, conv3], 1) + conv7 = self.conv7(up7) + + up8 = self.up8(conv7) + up8 = torch.cat([up8, conv2], 1) + conv8 = self.conv8(up8) + + up9 = self.up9(conv8) + up9 = torch.cat([up9, conv1], 1) + conv9 = self.conv9(up9) + + conv10 = self.conv10(conv9) + out = F.pixel_shuffle(conv10, 3) + + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) \ No newline at end of file diff --git a/Batchnorm_test.py b/oude_code/Batchnorm_test.py similarity index 100% rename from Batchnorm_test.py rename to oude_code/Batchnorm_test.py diff --git a/Batchnorm_train.py b/oude_code/Batchnorm_train.py similarity index 100% rename from Batchnorm_train.py rename to oude_code/Batchnorm_train.py diff --git a/Double_batch_test.py b/oude_code/Double_batch_test.py similarity index 100% rename from Double_batch_test.py rename to oude_code/Double_batch_test.py diff --git a/Double_batch_train.py b/oude_code/Double_batch_train.py similarity index 100% rename from Double_batch_train.py rename to oude_code/Double_batch_train.py diff --git a/PSNRandSSIM.py b/oude_code/PSNRandSSIM.py similarity index 86% rename from PSNRandSSIM.py rename to oude_code/PSNRandSSIM.py index b6ed6d6..00dd0f9 100644 --- a/PSNRandSSIM.py +++ b/oude_code/PSNRandSSIM.py @@ -1,6 +1,6 @@ from PIL import Image -from skimage.metrics import peak_signal_noise_ratio -from skimage.metrics import structural_similarity as ssim +from skimage.metrics import peak_signal_noise_ratio, structural_similarity as ssim +# from skimage.metrics import structural_similarity as ssim import numpy as np diff --git a/Test_Sony_To_Pytorch.py b/oude_code/Test_Sony_To_Pytorch.py similarity index 100% rename from Test_Sony_To_Pytorch.py rename to oude_code/Test_Sony_To_Pytorch.py diff --git a/Train_Sony_To_Pytorch.py b/oude_code/Train_Sony_To_Pytorch.py similarity index 99% rename from Train_Sony_To_Pytorch.py rename to oude_code/Train_Sony_To_Pytorch.py index 4816dbd..509ec66 100644 --- a/Train_Sony_To_Pytorch.py +++ b/oude_code/Train_Sony_To_Pytorch.py @@ -193,7 +193,7 @@ def loss_function(out_image, gt_image): G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer # Training loop -for epoch in range(lastepoch, 41): +for epoch in range(lastepoch, 30): # Check if the folder exists and skip the epoch if it does if os.path.isdir(result_dir + '%04d' % epoch): continue @@ -288,6 +288,4 @@ def loss_function(out_image, gt_image): Image.fromarray((temp * 255).astype(np.uint8)).save(result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) # Save the image # Save the model - torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') - -print("\nFinished training!\n") + torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') \ No newline at end of file diff --git a/performance_measurements.py b/performance_measurements.py deleted file mode 100644 index 97e48a6..0000000 --- a/performance_measurements.py +++ /dev/null @@ -1,52 +0,0 @@ -import matplotlib.pyplot as plt -from PIL import ImageFile -ImageFile.LOAD_TRUNCATED_IMAGES = True -import os -import csv - -from utils import calculate_psnr, calculate_ssim - -result_dir = './result_Sony/final/' - -total_psnr = 0 -total_ssim = 0 -count = 0 - -for image in os.listdir(result_dir): - if image.endswith('out.png'): - img_out = plt.imread(result_dir + image) - img_gt = plt.imread(result_dir + image.replace('out.png', 'gt.png')) - psnr_score = calculate_psnr(img_out, img_gt) - ssim_score = calculate_ssim(img_out, img_gt) - print(image, psnr_score, ssim_score) - total_psnr += psnr_score - total_ssim += ssim_score - count += 1 - -mean_psnr = total_psnr / count -mean_ssim = total_ssim / count -print('mean psnr: ', mean_psnr) -print('mean ssim: ', mean_ssim) - - -### CHANGE THESE PARAMETERS TO CHANGE THE NAME OF THE CSV FILE AND THE MODEL NAME IN THE CSV FILE ### -results_file = 'results_40.csv' -model_name = 'Without Normalization' - - -# Check if the csv file exists, if it does, append the results to the file, if not, create a new file and write the results to it -if os.path.isfile(results_file): - with open(results_file, 'a') as csvfile: - fieldnames = ['Model', 'Mean psnr', 'Mean ssim'] - writer = csv.DictWriter(csvfile, fieldnames=fieldnames) - writer.writerow({'Model': model_name, 'Mean psnr': mean_psnr, 'Mean ssim': mean_ssim}) -else: - with open(results_file, 'w') as csvfile: - # Create a header for rhe csv file that tores the mean metrics for different models, in this case the model is using double batch normalization - fieldnames = ['Model', 'Mean psnr', 'Mean ssim'] - writer = csv.DictWriter(csvfile, fieldnames=fieldnames) - writer.writeheader() - writer.writerow({'Model': model_name, 'Mean psnr': mean_psnr, 'Mean ssim': mean_ssim}) - - - \ No newline at end of file diff --git a/run_testing.py b/run_testing.py new file mode 100644 index 0000000..badd56b --- /dev/null +++ b/run_testing.py @@ -0,0 +1,25 @@ +from unet import UNet_original, UNet_single_batchnorm, UNet_double_batchnorm +from Train_Sony import train_sony +from Test_Sony import test_sony +from calculate_metrics import calculate_metrics + +if __name__ == '__main__': + + # PARAMETERS TO CHANGE + n_epochs = 5 + DEBUG = True + train_device = 'cuda:0' + test_device = 'cpu' + ###################### + + + # name of results file containing number of epochs + results_file = 'results_' + str(n_epochs) + '.txt' + + unet_models = {"Without Batch Normalization": UNet_original(), + "With Single Batch Normalization": UNet_single_batchnorm(), + "With Double Batch Normalization": UNet_double_batchnorm()} + for model_name, model in unet_models.items(): + train_sony(model, n_epochs=n_epochs, DEBUG=DEBUG, TRAIN_FROM_SCRATCH=True, device=train_device) + test_sony(model, DEBUG=True, device=test_device) + calculate_metrics(results_file=results_file, model_name=model_name) \ No newline at end of file diff --git a/test_Sony.py b/test_Sony.py index b4adfcb..f3f06ed 100644 --- a/test_Sony.py +++ b/test_Sony.py @@ -1,155 +1,111 @@ -# uniform content loss + adaptive threshold + per_class_input + recursive G -# improvement upon cqf37 from __future__ import division -import os, scipy.io -import tensorflow as tf -import tensorflow.contrib.slim as slim +import os import numpy as np import rawpy import glob +from PIL import Image +import torch -input_dir = './dataset/Sony/short/' -gt_dir = './dataset/Sony/long/' -checkpoint_dir = './checkpoint/Sony/' -result_dir = './result_Sony/' +from unet import UNet_original, UNet_single_batchnorm, UNet_double_batchnorm -# get test IDs -test_fns = glob.glob(gt_dir + '/1*.ARW') -test_ids = [int(os.path.basename(test_fn)[0:5]) for test_fn in test_fns] -DEBUG = 0 -if DEBUG == 1: - save_freq = 2 - test_ids = test_ids[0:5] +# Pack the raw image into 4 channels using the bayer pattern +def pack_raw(raw): + im = np.maximum(raw - 512, 0) / (16383 - 512) # subtract the black level + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + # Channel concatenation for the bayer pattern + out = np.concatenate((im[0:H:2, 0:W:2, :], + im[0:H:2, 1:W:2, :], + im[1:H:2, 1:W:2, :], + im[1:H:2, 0:W:2, :]), axis=2) + return out -def lrelu(x): - return tf.maximum(x * 0.2, x) +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss -def upsample_and_concat(x1, x2, output_channels, in_channels): - pool_size = 2 - deconv_filter = tf.Variable(tf.truncated_normal([pool_size, pool_size, output_channels, in_channels], stddev=0.02)) - deconv = tf.nn.conv2d_transpose(x1, deconv_filter, tf.shape(x2), strides=[1, pool_size, pool_size, 1]) +def test_sony(unet, DEBUG=True, device='cuda:0'): + """Function to train the model""" - deconv_output = tf.concat([deconv, x2], 3) - deconv_output.set_shape([None, None, None, output_channels * 2]) + # Required paths to the datasets + input_dir = './dataset/Sony/short/' # Path to the short exposure images + gt_dir = './dataset/Sony/long/' # Path to the long exposure images + checkpoint_dir = './result_Sony/' # Path to the checkpoint directory + result_dir = './result_Sony/final/' # Path to the result directory + ckpt = checkpoint_dir + 'model.ckpt' # Path to the model - return deconv_output + # get test IDs + test_fns = glob.glob(gt_dir + '/1*.ARW') + test_ids = [int(os.path.basename(test_fn)[0:5]) for test_fn in test_fns] + # Debug mode that only uses 5 images from the dataset + if DEBUG: + test_ids = test_ids[0:5] -def network(input): - conv1 = slim.conv2d(input, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_1') - conv1 = slim.conv2d(conv1, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_2') - pool1 = slim.max_pool2d(conv1, [2, 2], padding='SAME') + # device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # check if GPU is available + device = torch.device(device) - conv2 = slim.conv2d(pool1, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_1') - conv2 = slim.conv2d(conv2, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_2') - pool2 = slim.max_pool2d(conv2, [2, 2], padding='SAME') + unet.load_state_dict(torch.load(ckpt,map_location={'cuda:1':'cuda:0'})) + model = unet.to(device) + if not os.path.isdir(result_dir): + os.makedirs(result_dir) - conv3 = slim.conv2d(pool2, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_1') - conv3 = slim.conv2d(conv3, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_2') - pool3 = slim.max_pool2d(conv3, [2, 2], padding='SAME') + for test_id in test_ids: # Loop through all test_ids + in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) # Get input image files (first image in each sequence) based on the test_id - conv4 = slim.conv2d(pool3, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_1') - conv4 = slim.conv2d(conv4, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_2') - pool4 = slim.max_pool2d(conv4, [2, 2], padding='SAME') + for k in range(len(in_files)): # Iterate through all input files + in_path = in_files[k] + _, in_fn = os.path.split(in_path) + print(in_fn) + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) # Get the ground truth files for the current test_id - conv5 = slim.conv2d(pool4, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_1') - conv5 = slim.conv2d(conv5, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_2') + _, gt_fn = os.path.split(gt_files[0]) + in_exposure = float(in_fn[9:-5]) # Extract exposure values from input + gt_exposure = float(gt_fn[9:-5]) # Extract exposure values from ground truth + ratio = min(gt_exposure / in_exposure, 300) # Calculate the exposure ratio and limit it to 300 - up6 = upsample_and_concat(conv5, conv4, 256, 512) - conv6 = slim.conv2d(up6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_1') - conv6 = slim.conv2d(conv6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_2') + raw = rawpy.imread(in_path) # Read the raw input image + im = raw.raw_image_visible.astype(np.float32) # Convert it to a visible float32 image + input_full = np.expand_dims(pack_raw(im), axis=0) * ratio # Multiply image with exposure ratio - up7 = upsample_and_concat(conv6, conv3, 128, 256) - conv7 = slim.conv2d(up7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_1') - conv7 = slim.conv2d(conv7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_2') + im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + scale_full = np.expand_dims(np.float32(im / 65535.0), axis=0) - up8 = upsample_and_concat(conv7, conv2, 64, 128) - conv8 = slim.conv2d(up8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_1') - conv8 = slim.conv2d(conv8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_2') + gt_raw = rawpy.imread(gt_files[0]) # Read the raw ground truth image and post-process it + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) + gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) - up9 = upsample_and_concat(conv8, conv1, 32, 64) - conv9 = slim.conv2d(up9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_1') - conv9 = slim.conv2d(conv9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_2') + input_full = np.minimum(input_full, 1.0) # Clip the input image to the range [0, 1] - conv10 = slim.conv2d(conv9, 12, [1, 1], rate=1, activation_fn=None, scope='g_conv10') - out = tf.depth_to_space(conv10, 2) - return out + in_img = torch.from_numpy(input_full).permute(0, 3, 1, 2).to(device) # Convert the input image to a PyTorch tensor + out_img = unet(in_img) # Perform the image enhancement using the UNet model + # Convert to numpy array and clip between 0 and 1 + output = out_img.permute(0, 2, 3, 1).cpu().data.numpy() + output = np.minimum(np.maximum(output, 0), 1) -def pack_raw(raw): - # pack Bayer image to 4 channels - im = raw.raw_image_visible.astype(np.float32) - im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level + # Remove the batch dimension from the images + output = output[0, :, :, :] + gt_full = gt_full[0, :, :, :] + scale_full = scale_full[0, :, :, :] + scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) - im = np.expand_dims(im, axis=2) - img_shape = im.shape - H = img_shape[0] - W = img_shape[1] + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) + Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) + Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) + Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) - out = np.concatenate((im[0:H:2, 0:W:2, :], - im[0:H:2, 1:W:2, :], - im[1:H:2, 1:W:2, :], - im[1:H:2, 0:W:2, :]), axis=2) - return out + print("\nFinished testing!\n") +if __name__ == '__main__': + unet = UNet_original() # Create the model + DEBUG = True # Set the debug flag + device = "cuda:0" if torch.cuda.is_available() else "cpu" # Set the device to use -sess = tf.Session() -in_image = tf.placeholder(tf.float32, [None, None, None, 4]) -gt_image = tf.placeholder(tf.float32, [None, None, None, 3]) -out_image = network(in_image) - -saver = tf.train.Saver() -sess.run(tf.global_variables_initializer()) -ckpt = tf.train.get_checkpoint_state(checkpoint_dir) -if ckpt: - print('loaded ' + ckpt.model_checkpoint_path) - saver.restore(sess, ckpt.model_checkpoint_path) - -if not os.path.isdir(result_dir + 'final/'): - os.makedirs(result_dir + 'final/') - -for test_id in test_ids: - # test the first image in each sequence - in_files = glob.glob(input_dir + '%05d_00*.ARW' % test_id) - for k in range(len(in_files)): - in_path = in_files[k] - in_fn = os.path.basename(in_path) - print(in_fn) - gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % test_id) - gt_path = gt_files[0] - gt_fn = os.path.basename(gt_path) - in_exposure = float(in_fn[9:-5]) - gt_exposure = float(gt_fn[9:-5]) - ratio = min(gt_exposure / in_exposure, 300) - - raw = rawpy.imread(in_path) - input_full = np.expand_dims(pack_raw(raw), axis=0) * ratio - - im = raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) - # scale_full = np.expand_dims(np.float32(im/65535.0),axis = 0)*ratio - scale_full = np.expand_dims(np.float32(im / 65535.0), axis=0) - - gt_raw = rawpy.imread(gt_path) - im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) - gt_full = np.expand_dims(np.float32(im / 65535.0), axis=0) - - input_full = np.minimum(input_full, 1.0) - - output = sess.run(out_image, feed_dict={in_image: input_full}) - output = np.minimum(np.maximum(output, 0), 1) - - output = output[0, :, :, :] - gt_full = gt_full[0, :, :, :] - scale_full = scale_full[0, :, :, :] - scale_full = scale_full * np.mean(gt_full) / np.mean( - scale_full) # scale the low-light image to the same mean of the groundtruth - - scipy.misc.toimage(output * 255, high=255, low=0, cmin=0, cmax=255).save( - result_dir + 'final/%5d_00_%d_out.png' % (test_id, ratio)) - scipy.misc.toimage(scale_full * 255, high=255, low=0, cmin=0, cmax=255).save( - result_dir + 'final/%5d_00_%d_scale.png' % (test_id, ratio)) - scipy.misc.toimage(gt_full * 255, high=255, low=0, cmin=0, cmax=255).save( - result_dir + 'final/%5d_00_%d_gt.png' % (test_id, ratio)) + test_sony(unet, DEBUG=DEBUG, device=device) # Train the model diff --git a/train_Sony.py b/train_Sony.py index ce0642a..91e9c82 100644 --- a/train_Sony.py +++ b/train_Sony.py @@ -1,203 +1,194 @@ -# uniform content loss + adaptive threshold + per_class_input + recursive G -# improvement upon cqf37 from __future__ import division -import os, time, scipy.io -import tensorflow as tf -import tensorflow.contrib.slim as slim +import os, time import numpy as np import rawpy import glob +from PIL import Image +import torch +import shutil -input_dir = './dataset/Sony/short/' -gt_dir = './dataset/Sony/long/' -checkpoint_dir = './result_Sony/' -result_dir = './result_Sony/' - -# get train IDs -train_fns = glob.glob(gt_dir + '0*.ARW') -train_ids = [int(os.path.basename(train_fn)[0:5]) for train_fn in train_fns] - -ps = 512 # patch size for training -save_freq = 500 - -DEBUG = 1 -if DEBUG == 1: - save_freq = 2 - train_ids = train_ids[0:5] - - -def lrelu(x): - return tf.maximum(x * 0.2, x) - - -def upsample_and_concat(x1, x2, output_channels, in_channels): - pool_size = 2 - deconv_filter = tf.Variable(tf.truncated_normal([pool_size, pool_size, output_channels, in_channels], stddev=0.02)) - deconv = tf.nn.conv2d_transpose(x1, deconv_filter, tf.shape(x2), strides=[1, pool_size, pool_size, 1]) - - deconv_output = tf.concat([deconv, x2], 3) - deconv_output.set_shape([None, None, None, output_channels * 2]) - - return deconv_output - - -def network(input): - conv1 = slim.conv2d(input, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_1') - conv1 = slim.conv2d(conv1, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_2') - pool1 = slim.max_pool2d(conv1, [2, 2], padding='SAME') - - conv2 = slim.conv2d(pool1, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_1') - conv2 = slim.conv2d(conv2, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv2_2') - pool2 = slim.max_pool2d(conv2, [2, 2], padding='SAME') - - conv3 = slim.conv2d(pool2, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_1') - conv3 = slim.conv2d(conv3, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv3_2') - pool3 = slim.max_pool2d(conv3, [2, 2], padding='SAME') - - conv4 = slim.conv2d(pool3, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_1') - conv4 = slim.conv2d(conv4, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv4_2') - pool4 = slim.max_pool2d(conv4, [2, 2], padding='SAME') - - conv5 = slim.conv2d(pool4, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_1') - conv5 = slim.conv2d(conv5, 512, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv5_2') - - up6 = upsample_and_concat(conv5, conv4, 256, 512) - conv6 = slim.conv2d(up6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_1') - conv6 = slim.conv2d(conv6, 256, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv6_2') - - up7 = upsample_and_concat(conv6, conv3, 128, 256) - conv7 = slim.conv2d(up7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_1') - conv7 = slim.conv2d(conv7, 128, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv7_2') - - up8 = upsample_and_concat(conv7, conv2, 64, 128) - conv8 = slim.conv2d(up8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_1') - conv8 = slim.conv2d(conv8, 64, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv8_2') - - up9 = upsample_and_concat(conv8, conv1, 32, 64) - conv9 = slim.conv2d(up9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_1') - conv9 = slim.conv2d(conv9, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv9_2') - - conv10 = slim.conv2d(conv9, 12, [1, 1], rate=1, activation_fn=None, scope='g_conv10') - out = tf.depth_to_space(conv10, 2) - return out +from unet import UNet_original, UNet_single_batchnorm, UNet_double_batchnorm +# Pack the raw image into 4 channels using the bayer pattern def pack_raw(raw): - # pack Bayer image to 4 channels - im = raw.raw_image_visible.astype(np.float32) + im = raw.raw_image_visible.astype(np.float32) # Change data to float32 im = np.maximum(im - 512, 0) / (16383 - 512) # subtract the black level - im = np.expand_dims(im, axis=2) - img_shape = im.shape - H = img_shape[0] - W = img_shape[1] + im = np.expand_dims(im, axis=2) # Add a channel dimension + img_shape = im.shape # Get the shape of the image + H = img_shape[0] # Get the height of the image + W = img_shape[1] # Get the width of the image + # Channel concatenation for the bayer pattern out = np.concatenate((im[0:H:2, 0:W:2, :], im[0:H:2, 1:W:2, :], im[1:H:2, 1:W:2, :], im[1:H:2, 0:W:2, :]), axis=2) return out - -sess = tf.Session() -in_image = tf.placeholder(tf.float32, [None, None, None, 4]) -gt_image = tf.placeholder(tf.float32, [None, None, None, 3]) -out_image = network(in_image) - -G_loss = tf.reduce_mean(tf.abs(out_image - gt_image)) - -t_vars = tf.trainable_variables() -lr = tf.placeholder(tf.float32) -G_opt = tf.train.AdamOptimizer(learning_rate=lr).minimize(G_loss) - -saver = tf.train.Saver() -sess.run(tf.global_variables_initializer()) -ckpt = tf.train.get_checkpoint_state(checkpoint_dir) -if ckpt: - print('loaded ' + ckpt.model_checkpoint_path) - saver.restore(sess, ckpt.model_checkpoint_path) - -# Raw data takes long time to load. Keep them in memory after loaded. -gt_images = [None] * 6000 -input_images = {} -input_images['300'] = [None] * len(train_ids) -input_images['250'] = [None] * len(train_ids) -input_images['100'] = [None] * len(train_ids) - -g_loss = np.zeros((5000, 1)) - -allfolders = glob.glob(result_dir + '*0') -lastepoch = 0 -for folder in allfolders: - lastepoch = np.maximum(lastepoch, int(folder[-4:])) - -learning_rate = 1e-4 -for epoch in range(lastepoch, 4001): - if os.path.isdir(result_dir + '%04d' % epoch): - continue - cnt = 0 - if epoch > 2000: - learning_rate = 1e-5 - - for ind in np.random.permutation(len(train_ids)): - # get the path from image id - train_id = train_ids[ind] - in_files = glob.glob(input_dir + '%05d_00*.ARW' % train_id) - in_path = in_files[np.random.random_integers(0, len(in_files) - 1)] - in_fn = os.path.basename(in_path) - - gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % train_id) - gt_path = gt_files[0] - gt_fn = os.path.basename(gt_path) - in_exposure = float(in_fn[9:-5]) - gt_exposure = float(gt_fn[9:-5]) - ratio = min(gt_exposure / in_exposure, 300) - - st = time.time() - cnt += 1 - - if input_images[str(ratio)[0:3]][ind] is None: - raw = rawpy.imread(in_path) - input_images[str(ratio)[0:3]][ind] = np.expand_dims(pack_raw(raw), axis=0) * ratio - - gt_raw = rawpy.imread(gt_path) - im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) - gt_images[ind] = np.expand_dims(np.float32(im / 65535.0), axis=0) - - # crop - H = input_images[str(ratio)[0:3]][ind].shape[1] - W = input_images[str(ratio)[0:3]][ind].shape[2] - - xx = np.random.randint(0, W - ps) - yy = np.random.randint(0, H - ps) - input_patch = input_images[str(ratio)[0:3]][ind][:, yy:yy + ps, xx:xx + ps, :] - gt_patch = gt_images[ind][:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :] - - if np.random.randint(2, size=1)[0] == 1: # random flip - input_patch = np.flip(input_patch, axis=1) - gt_patch = np.flip(gt_patch, axis=1) - if np.random.randint(2, size=1)[0] == 1: - input_patch = np.flip(input_patch, axis=2) - gt_patch = np.flip(gt_patch, axis=2) - if np.random.randint(2, size=1)[0] == 1: # random transpose - input_patch = np.transpose(input_patch, (0, 2, 1, 3)) - gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) - - input_patch = np.minimum(input_patch, 1.0) - - _, G_current, output = sess.run([G_opt, G_loss, out_image], - feed_dict={in_image: input_patch, gt_image: gt_patch, lr: learning_rate}) - output = np.minimum(np.maximum(output, 0), 1) - g_loss[ind] = G_current - - print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) - - if epoch % save_freq == 0: - if not os.path.isdir(result_dir + '%04d' % epoch): - os.makedirs(result_dir + '%04d' % epoch) - - temp = np.concatenate((gt_patch[0, :, :, :], output[0, :, :, :]), axis=1) - scipy.misc.toimage(temp * 255, high=255, low=0, cmin=0, cmax=255).save( - result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) - - saver.save(sess, checkpoint_dir + 'model.ckpt') +# loss function using absolute difference between the output and ground truth +def loss_function(out_image, gt_image): + loss = torch.mean(torch.abs(out_image - gt_image)) + return loss + + +def train_sony(unet, n_epochs=40, DEBUG=True, TRAIN_FROM_SCRATCH=False, device='cuda:0'): + """Function to train the model""" + + # Required paths to the datasets + input_dir = './dataset/Sony/short/' # Path to the short exposure images + gt_dir = './dataset/Sony/long/' # Path to the long exposure images + checkpoint_dir = './result_Sony/' # Path to the checkpoint directory + result_dir = './result_Sony/' # Path to the result directory + + # get train IDs + train_fns = glob.glob(gt_dir + '0*.ARW') + train_ids = [int(os.path.basename(train_fn)[0:5]) for train_fn in train_fns] + + ps = 512 # patch size for training + save_freq = 500 + + # If debug is set to true, then set the save frequency to 2 and train on 5 images + if DEBUG: + save_freq = 2 + train_ids = train_ids[0:5] + + # Delete the result directory if boolean to rerun the training is set to true + if TRAIN_FROM_SCRATCH: + if os.path.isdir(result_dir): + shutil.rmtree(result_dir) + + # Raw data takes long time to load. Keep them in memory after loaded. + gt_images = [None] * 6000 + input_images = {} + input_images['300'] = [None] * len(train_ids) + input_images['250'] = [None] * len(train_ids) + input_images['100'] = [None] * len(train_ids) + + # Array to store the loss values + g_loss = np.zeros((5000, 1)) + + allfolders = glob.glob(result_dir + '*0') # Get all the folders in the result directory + lastepoch = 0 # Initialize the last epoch to 0 + + # Get the last epoch number + for folder in allfolders: + lastepoch = np.maximum(lastepoch, int(folder[-4:])) + + device = torch.device(device) # check if GPU is available + unet.to(device) # assign the model to the GPU or CPU + unet.train() # Set the model to training mode + + learning_rate = 1e-4 # Set the learning rate + + G_opt = torch.optim.Adam(unet.parameters(), lr=learning_rate) # Set the optimizer + + # Training loop + for epoch in range(lastepoch, n_epochs): + # Check if the folder exists and skip the epoch if it does + if os.path.isdir(result_dir + '%04d' % epoch): + continue + cnt = 0 # Initialize the counter to 0 + + # Set the learning rate to 1e-5 after 2000 epochs + if epoch > 2000: + learning_rate = 1e-5 + + # Loop through the training images + for ind in np.random.permutation(len(train_ids)): + train_id = train_ids[ind] # Get the training id + in_files = glob.glob(input_dir + '%05d_00*.ARW' % train_id) # Get the input images + in_path = in_files[np.random.randint(0, len(in_files))] # Get a random input image + in_fn = os.path.basename(in_path) # Get the file name of the image + + gt_files = glob.glob(gt_dir + '%05d_00*.ARW' % train_id) # Get the ground truth images + gt_path = gt_files[0] # Get the first ground truth image + gt_fn = os.path.basename(gt_path) # Get the file name of the ground truth image + in_exposure = float(in_fn[9:-5]) # Get the exposure time for the input image + gt_exposure = float(gt_fn[9:-5]) # Get the exposure time for the ground truth image + ratio = min(gt_exposure / in_exposure, 300) # Get the ratio between the exposure times + + st = time.time() # Get the current time + cnt += 1 # Increment the counter + + # Check if the image is loaded and load it if it is not + if input_images[str(ratio)[0:3]][ind] is None: + raw = rawpy.imread(in_path) # Read the raw image + input_images[str(ratio)[0:3]][ind] = np.expand_dims(pack_raw(raw), axis=0) * ratio # Pack the raw image and store it in the input images array depending on the ratio + + gt_raw = rawpy.imread(gt_path) # Read the ground truth image + im = gt_raw.postprocess(use_camera_wb=True, half_size=False, no_auto_bright=True, output_bps=16) # Postprocess the ground truth image + gt_images[ind] = np.expand_dims(np.float32(im / 65535.0), axis=0) # Store the ground truth image in the ground thruth images array + + # Crop the image to the required size + H = input_images[str(ratio)[0:3]][ind].shape[1] # Get the height of the image + W = input_images[str(ratio)[0:3]][ind].shape[2] # Get the width of the image + + # Get a random start location on the image + xx = np.random.randint(0, W - ps) + yy = np.random.randint(0, H - ps) + + # Get the data used for training + input_patch = input_images[str(ratio)[0:3]][ind][:, yy:yy + ps, xx:xx + ps, :] + gt_patch = gt_images[ind][:, yy * 2:yy * 2 + ps * 2, xx * 2:xx * 2 + ps * 2, :] + + # Data augmentation + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 1 + input_patch = np.flip(input_patch, axis=1) + gt_patch = np.flip(gt_patch, axis=1) + if np.random.randint(2, size=1)[0] == 1: # random flip around axis 2 + input_patch = np.flip(input_patch, axis=2) + gt_patch = np.flip(gt_patch, axis=2) + if np.random.randint(2, size=1)[0] == 1: # random transpose + input_patch = np.transpose(input_patch, (0, 2, 1, 3)) + gt_patch = np.transpose(gt_patch, (0, 2, 1, 3)) + + input_patch = np.minimum(input_patch, 1.0) # Input patch should be between 0 and 1 + input_img = torch.from_numpy(input_patch) # Convert the input patch to a tensor + input_img = input_img.permute(0, 3, 1, 2) # Permute the tensor + input_img = input_img.to(device) # Assign the tensor to the GPU or CPU + + gt_patch = np.minimum(gt_patch, 1.0) # Ground truth patch should be between 0 and 1 + gt_img = torch.from_numpy(gt_patch) # Convert the ground truth patch to a tensor + gt_img = gt_img.permute(0, 3, 1, 2) # Permute the tensor + gt_img = gt_img.to(device) # Assign the tensor to the GPU or CPU + + # Run the model + G_opt.zero_grad() # Set the gradient to 0 + out_image = unet(input_img) # Get the output image + + # Calculate the loss + loss = loss_function(out_image, gt_img) + loss.backward() # Calculate the gradients + G_opt.step() # Update the weights + g_loss[ind] = loss.item() # Store the loss + + print("%d %d Loss=%.3f Time=%.3f" % (epoch, cnt, np.mean(g_loss[np.where(g_loss)]), time.time() - st)) # Print the loss and time + + output = out_image.permute(0, 2, 3, 1).cpu().data.numpy() # Get the output image and convert it to numpy + output = np.minimum(np.maximum(output, 0), 1) # Output should be between 0 and 1 + + # Save the results + if epoch % save_freq == 0: + # Create the directory if it does not exist + if not os.path.isdir(result_dir + '%04d' % epoch): + os.makedirs(result_dir + '%04d' % epoch) + + # Save the image + temp = np.concatenate((gt_patch[0, :, :, :], output[0, :, :, :]), axis=1) # Concatenate the ground truth and output images + Image.fromarray((temp * 255).astype(np.uint8)).save(result_dir + '%04d/%05d_00_train_%d.jpg' % (epoch, train_id, ratio)) # Save the image + + # Save the model + torch.save(unet.state_dict(), checkpoint_dir + 'model.ckpt') + + print("\nFinished training!\n") + +if __name__ == '__main__': + unet = UNet_double_batchnorm() # Create the model + n_epochs = 40 # Set the number of epochs + DEBUG = True # Set the debug flag + TRAIN_FROM_SCRATCH = True # Set the flag to train from scratch + device = "cuda:0" if torch.cuda.is_available() else "cpu" # Set the device to GPU or CPU + + train_sony(unet, n_epochs=n_epochs, DEBUG=DEBUG, TRAIN_FROM_SCRATCH=TRAIN_FROM_SCRATCH, device=device) # Train the model diff --git a/unet.py b/unet.py index 191686a..ddf4c5a 100644 --- a/unet.py +++ b/unet.py @@ -1,79 +1,235 @@ -import torch import torch.nn as nn -import torch.nn.functional as F +import torch -class lReLU(nn.Module): + +# Leaky relu function with slope 0.2 +def lrelu(x): + outt = torch.max(0.2*x, x) + return outt + +# Original Unet class +class UNet_original(nn.Module): def __init__(self): - super(lReLU, self).__init__() + super(UNet_original, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.pool1 = nn.MaxPool2d(kernel_size=2) - def forward(self, x): - return torch.max(x * 0.2, x) - -class Double_Conv2d(nn.Module): - def __init__(self, in_channel, out_channel): - super(Double_Conv2d, self).__init__() - self.double_conv2d = torch.nn.Sequential( - nn.Conv2d(in_channels=in_channel, out_channels=out_channel, kernel_size=3, padding=1), - lReLU(), - nn.Conv2d(in_channels=out_channel, out_channels=out_channel, kernel_size=3, padding=1), - lReLU() - ) + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) def forward(self, x): - return self.double_conv2d(x) + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.conv1(x)) + conv1 = lrelu(self.conv1_2(conv1)) + pool1 = self.pool1(conv1) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.conv2(pool1)) + conv2 = lrelu(self.conv2_2(conv2)) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.conv3(pool2)) + conv3 = lrelu(self.conv3_2(conv3)) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.conv4(pool3)) + conv4 = lrelu(self.conv4_2(conv4)) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.conv5(pool4)) + conv5 = lrelu(self.conv5_2(conv5)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.conv6(up6)) + conv6 = lrelu(self.conv6_2(conv6)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.conv7(up7)) + conv7 = lrelu(self.conv7_2(conv7)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.conv8(up8)) + conv8 = lrelu(self.conv8_2(conv8)) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.conv9(up9)) + conv9 = lrelu(self.conv9_2(conv9)) + + # Forward pass through the convolutional layer + conv10 = self.conv10(conv9) + + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) + return out + + def _initialize_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + m.weight.data.normal_(0.0, 0.02) + if m.bias is not None: + m.bias.data.normal_(0.0, 0.02) + if isinstance(m, nn.ConvTranspose2d): + m.weight.data.normal_(0.0, 0.02) -class UNetSony(nn.Module): + +# Unet class with a single batch normalization layer +class UNet_single_batchnorm(nn.Module): def __init__(self): - super(UNetSony, self).__init__() - self.conv1 = Double_Conv2d(4, 32) - self.conv2 = Double_Conv2d(32, 64) - self.conv3 = Double_Conv2d(64, 128) - self.conv4 = Double_Conv2d(128, 256) - self.conv5 = Double_Conv2d(256, 512) - self.up6 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) - self.conv6 = Double_Conv2d(512, 256) - self.up7 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) - self.conv7 = Double_Conv2d(256, 128) - self.up8 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) - self.conv8 = Double_Conv2d(128, 64) - self.up9 = nn.ConvTranspose2d(64, 32, kernel_size=2, stride=2) - self.conv9 = Double_Conv2d(64, 32) - self.conv10 = nn.Conv2d(in_channels=32, out_channels=12, kernel_size=1) + super(UNet_single_batchnorm, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn1 = nn.BatchNorm2d(32) + self.pool1 = nn.MaxPool2d(kernel_size=2) - def forward(self, x): - conv1 = self.conv1(x) - pool1 = F.max_pool2d(conv1, kernel_size=2) + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn2 = nn.BatchNorm2d(64) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn3 = nn.BatchNorm2d(128) + self.pool3 = nn.MaxPool2d(kernel_size=2) - conv2 = self.conv2(pool1) - pool2 = F.max_pool2d(conv2, kernel_size=2) + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn4 = nn.BatchNorm2d(256) + self.pool4 = nn.MaxPool2d(kernel_size=2) - conv3 = self.conv3(pool2) - pool3 = F.max_pool2d(conv3, kernel_size=2) + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + self.bn5 = nn.BatchNorm2d(512) - conv4 = self.conv4(pool3) - pool4 = F.max_pool2d(conv4, kernel_size=2) + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn6 = nn.BatchNorm2d(256) - conv5 = self.conv5(pool4) + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn7 = nn.BatchNorm2d(128) - up6 = self.up6(conv5) - up6 = torch.cat([up6, conv4], 1) - conv6 = self.conv6(up6) + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn8 = nn.BatchNorm2d(64) - up7 = self.up7(conv6) - up7 = torch.cat([up7, conv3], 1) - conv7 = self.conv7(up7) + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn9 = nn.BatchNorm2d(32) + + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) + + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.conv1(x)) + conv1 = lrelu(self.bn1(self.conv1_2(conv1))) + pool1 = self.pool1(conv1) - up8 = self.up8(conv7) - up8 = torch.cat([up8, conv2], 1) - conv8 = self.conv8(up8) + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.conv2(pool1)) + conv2 = lrelu(self.bn2(self.conv2_2(conv2))) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.conv3(pool2)) + conv3 = lrelu(self.bn3(self.conv3_2(conv3))) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.conv4(pool3)) + conv4 = lrelu(self.bn4(self.conv4_2(conv4))) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.conv5(pool4)) + conv5 = lrelu(self.bn5(self.conv5_2(conv5))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.conv6(up6)) + conv6 = lrelu(self.bn6(self.conv6_2(conv6))) - up9 = self.up9(conv8) - up9 = torch.cat([up9, conv1], 1) - conv9 = self.conv9(up9) + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.conv7(up7)) + conv7 = lrelu(self.bn7(self.conv7_2(conv7))) + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.conv8(up8)) + conv8 = lrelu(self.bn8(self.conv8_2(conv8))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.conv9(up9)) + conv9 = lrelu(self.bn9(self.conv9_2(conv9))) + + # Forward pass through the convolutional layer conv10 = self.conv10(conv9) - out = F.pixel_shuffle(conv10, 2) + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) return out def _initialize_weights(self): @@ -85,58 +241,126 @@ def _initialize_weights(self): if isinstance(m, nn.ConvTranspose2d): m.weight.data.normal_(0.0, 0.02) -class UNetFuji(nn.Module): + +# Unet class with double normalization layer +class UNet_double_batchnorm(nn.Module): def __init__(self): - super(UNetFuji, self).__init__() - self.conv1 = Double_Conv2d(9, 32) - self.conv2 = Double_Conv2d(32, 64) - self.conv3 = Double_Conv2d(64, 128) - self.conv4 = Double_Conv2d(128, 256) - self.conv5 = Double_Conv2d(256, 512) - self.up6 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) - self.conv6 = Double_Conv2d(512, 256) - self.up7 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) - self.conv7 = Double_Conv2d(256, 128) - self.up8 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) - self.conv8 = Double_Conv2d(128, 64) - self.up9 = nn.ConvTranspose2d(64, 32, kernel_size=2, stride=2) - self.conv9 = Double_Conv2d(64, 32) - self.conv10 = nn.Conv2d(in_channels=32, out_channels=27, kernel_size=1) + super(UNet_double_batchnorm, self).__init__() # Call the init function of the parent class + # Double convolutional layer and one maxpooling layer + self.conv1 = nn.Conv2d(4, 32, kernel_size=3, stride=1, padding=1) + self.bn1 = nn.BatchNorm2d(32) + self.conv1_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn1_1 = nn.BatchNorm2d(32) + self.pool1 = nn.MaxPool2d(kernel_size=2) - def forward(self, x): - conv1 = self.conv1(x) - pool1 = F.max_pool2d(conv1, kernel_size=2) + # Double convolutional layer and one maxpooling layer + self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.bn2 = nn.BatchNorm2d(64) + self.conv2_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn2_1 = nn.BatchNorm2d(64) + self.pool2 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) + self.bn3 = nn.BatchNorm2d(128) + self.conv3_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn3_1 = nn.BatchNorm2d(128) + self.pool3 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) + self.bn4 = nn.BatchNorm2d(256) + self.conv4_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn4_1 = nn.BatchNorm2d(256) + self.pool4 = nn.MaxPool2d(kernel_size=2) + + # Double convolutional layer and one maxpooling layer + self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) + self.bn5 = nn.BatchNorm2d(512) + self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) + self.bn5_1 = nn.BatchNorm2d(512) - conv2 = self.conv2(pool1) - pool2 = F.max_pool2d(conv2, kernel_size=2) + # One upsample layer, double convolutional layer + self.up6 = nn.ConvTranspose2d(512, 256, 2, stride=2) + self.conv6 = nn.Conv2d(512, 256, kernel_size=3, stride=1, padding=1) + self.bn6 = nn.BatchNorm2d(256) + self.conv6_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1) + self.bn6_1 = nn.BatchNorm2d(256) - conv3 = self.conv3(pool2) - pool3 = F.max_pool2d(conv3, kernel_size=2) + # One upsample layer, double convolutional layer + self.up7 = nn.ConvTranspose2d(256, 128, 2, stride=2) + self.conv7 = nn.Conv2d(256, 128, kernel_size=3, stride=1, padding=1) + self.bn7 = nn.BatchNorm2d(128) + self.conv7_2 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1) + self.bn7_1 = nn.BatchNorm2d(128) - conv4 = self.conv4(pool3) - pool4 = F.max_pool2d(conv4, kernel_size=2) + # One upsample layer, double convolutional layer + self.up8 = nn.ConvTranspose2d(128, 64, 2, stride=2) + self.conv8 = nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) + self.bn8 = nn.BatchNorm2d(64) + self.conv8_2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) + self.bn8_1 = nn.BatchNorm2d(64) - conv5 = self.conv5(pool4) + # One upsample layer, double convolutional layer w + self.up9 = nn.ConvTranspose2d(64, 32, 2, stride=2) + self.conv9 = nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) + self.bn9 = nn.BatchNorm2d(32) + self.conv9_2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1) + self.bn9_1 = nn.BatchNorm2d(32) - up6 = self.up6(conv5) - up6 = torch.cat([up6, conv4], 1) - conv6 = self.conv6(up6) + # One convolutional layer + self.conv10 = nn.Conv2d(32, 12, kernel_size=3, stride=1, padding=1) - up7 = self.up7(conv6) - up7 = torch.cat([up7, conv3], 1) - conv7 = self.conv7(up7) + def forward(self, x): + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv1 = lrelu(self.bn1(self.conv1(x))) + conv1 = lrelu(self.bn1_1(self.conv1_2(conv1))) + pool1 = self.pool1(conv1) - up8 = self.up8(conv7) - up8 = torch.cat([up8, conv2], 1) - conv8 = self.conv8(up8) + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv2 = lrelu(self.bn2(self.conv2(pool1))) + conv2 = lrelu(self.bn2_1(self.conv2_2(conv2))) + pool2 = self.pool2(conv2) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv3 = lrelu(self.bn3(self.conv3(pool2))) + conv3 = lrelu(self.bn3_1(self.conv3_2(conv3))) + pool3 = self.pool3(conv3) + + # Forward pass through the double convolutional layer leaky relu activation and maxpooling layer + conv4 = lrelu(self.bn4(self.conv4(pool3))) + conv4 = lrelu(self.bn4_1(self.conv4_2(conv4))) + pool4 = self.pool4(conv4) + + # Forward pass through the double convolutional layer leaky relu activation + conv5 = lrelu(self.bn5(self.conv5(pool4))) + conv5 = lrelu(self.bn5_1(self.conv5_2(conv5))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up6 = torch.cat([self.up6(conv5), conv4], 1) + conv6 = lrelu(self.bn6(self.conv6(up6))) + conv6 = lrelu(self.bn6_1(self.conv6_2(conv6))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up7 = torch.cat([self.up7(conv6), conv3], 1) + conv7 = lrelu(self.bn7(self.conv7(up7))) + conv7 = lrelu(self.bn7_1(self.conv7_2(conv7))) + + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up8 = torch.cat([self.up8(conv7), conv2], 1) + conv8 = lrelu(self.bn8(self.conv8(up8))) + conv8 = lrelu(self.bn8_1(self.conv8_2(conv8))) - up9 = self.up9(conv8) - up9 = torch.cat([up9, conv1], 1) - conv9 = self.conv9(up9) + # Forward pass through the upsample layer and double convolutional layer with leaky relu activation + up9 = torch.cat([self.up9(conv8), conv1], 1) + conv9 = lrelu(self.bn9(self.conv9(up9))) + conv9 = lrelu(self.bn9_1(self.conv9_2(conv9))) + # Forward pass through the convolutional layer conv10 = self.conv10(conv9) - out = F.pixel_shuffle(conv10, 3) + # Pixel shuffle layer + out = nn.functional.pixel_shuffle(conv10, 2) return out def _initialize_weights(self): From 8a9e2cd6907cb7011c7d08dda37c7e5d120b314e Mon Sep 17 00:00:00 2001 From: Daan1289 Date: Mon, 3 Apr 2023 12:37:49 +0200 Subject: [PATCH 24/24] Fixed the code so that it saves the images --- {oude_code => old_code}/Batchnorm_test.py | 0 {oude_code => old_code}/Batchnorm_train.py | 0 {oude_code => old_code}/Double_batch_test.py | 0 {oude_code => old_code}/Double_batch_train.py | 0 {oude_code => old_code}/PSNRandSSIM.py | 0 {oude_code => old_code}/Test_Sony_To_Pytorch.py | 0 {oude_code => old_code}/Train_Sony_To_Pytorch.py | 0 run_testing.py | 15 +++++++++++---- test_Sony.py | 9 +++++---- 9 files changed, 16 insertions(+), 8 deletions(-) rename {oude_code => old_code}/Batchnorm_test.py (100%) rename {oude_code => old_code}/Batchnorm_train.py (100%) rename {oude_code => old_code}/Double_batch_test.py (100%) rename {oude_code => old_code}/Double_batch_train.py (100%) rename {oude_code => old_code}/PSNRandSSIM.py (100%) rename {oude_code => old_code}/Test_Sony_To_Pytorch.py (100%) rename {oude_code => old_code}/Train_Sony_To_Pytorch.py (100%) diff --git a/oude_code/Batchnorm_test.py b/old_code/Batchnorm_test.py similarity index 100% rename from oude_code/Batchnorm_test.py rename to old_code/Batchnorm_test.py diff --git a/oude_code/Batchnorm_train.py b/old_code/Batchnorm_train.py similarity index 100% rename from oude_code/Batchnorm_train.py rename to old_code/Batchnorm_train.py diff --git a/oude_code/Double_batch_test.py b/old_code/Double_batch_test.py similarity index 100% rename from oude_code/Double_batch_test.py rename to old_code/Double_batch_test.py diff --git a/oude_code/Double_batch_train.py b/old_code/Double_batch_train.py similarity index 100% rename from oude_code/Double_batch_train.py rename to old_code/Double_batch_train.py diff --git a/oude_code/PSNRandSSIM.py b/old_code/PSNRandSSIM.py similarity index 100% rename from oude_code/PSNRandSSIM.py rename to old_code/PSNRandSSIM.py diff --git a/oude_code/Test_Sony_To_Pytorch.py b/old_code/Test_Sony_To_Pytorch.py similarity index 100% rename from oude_code/Test_Sony_To_Pytorch.py rename to old_code/Test_Sony_To_Pytorch.py diff --git a/oude_code/Train_Sony_To_Pytorch.py b/old_code/Train_Sony_To_Pytorch.py similarity index 100% rename from oude_code/Train_Sony_To_Pytorch.py rename to old_code/Train_Sony_To_Pytorch.py diff --git a/run_testing.py b/run_testing.py index badd56b..3a91b92 100644 --- a/run_testing.py +++ b/run_testing.py @@ -1,6 +1,6 @@ from unet import UNet_original, UNet_single_batchnorm, UNet_double_batchnorm -from Train_Sony import train_sony -from Test_Sony import test_sony +from train_Sony import train_sony +from test_Sony import test_sony from calculate_metrics import calculate_metrics if __name__ == '__main__': @@ -19,7 +19,14 @@ unet_models = {"Without Batch Normalization": UNet_original(), "With Single Batch Normalization": UNet_single_batchnorm(), "With Double Batch Normalization": UNet_double_batchnorm()} - for model_name, model in unet_models.items(): + unet_models = [["Without_Batch_Norm", UNet_original(), "Without Batch Normalization"], + ["Single_Batch_Norm", UNet_single_batchnorm(), "With Single Batch Normalization"], + ["Double_Batch_Norm", UNet_double_batchnorm(), "With Double Batch Normalization"]] + for folder_name, model, model_name in unet_models: train_sony(model, n_epochs=n_epochs, DEBUG=DEBUG, TRAIN_FROM_SCRATCH=True, device=train_device) - test_sony(model, DEBUG=True, device=test_device) + + # name of folder to store results + result_folder = folder_name + '_' + str(n_epochs) + '_epochs' + test_sony(model, result_folder, DEBUG=True, device=test_device) + calculate_metrics(results_file=results_file, model_name=model_name) \ No newline at end of file diff --git a/test_Sony.py b/test_Sony.py index f3f06ed..513cc20 100644 --- a/test_Sony.py +++ b/test_Sony.py @@ -30,14 +30,15 @@ def loss_function(out_image, gt_image): return loss -def test_sony(unet, DEBUG=True, device='cuda:0'): +def test_sony(unet, result_folder, DEBUG=True, device='cuda:0'): """Function to train the model""" # Required paths to the datasets input_dir = './dataset/Sony/short/' # Path to the short exposure images gt_dir = './dataset/Sony/long/' # Path to the long exposure images checkpoint_dir = './result_Sony/' # Path to the checkpoint directory - result_dir = './result_Sony/final/' # Path to the result directory + # result_dir = './result_Sony/final/' # Path to the result directory + result_dir = './results/' + result_folder + '/' # Path to the result directory ckpt = checkpoint_dir + 'model.ckpt' # Path to the model # get test IDs @@ -96,9 +97,9 @@ def test_sony(unet, DEBUG=True, device='cuda:0'): scale_full = scale_full[0, :, :, :] scale_full = scale_full * np.mean(gt_full) / np.mean(scale_full) - Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) + # Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_ori.png' % (test_id, ratio)) Image.fromarray((output * 255).astype('uint8')).save(result_dir + '%5d_00_%d_out.png' % (test_id, ratio)) - Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) + # Image.fromarray((scale_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_scale.png' % (test_id, ratio)) Image.fromarray((gt_full * 255).astype('uint8')).save(result_dir + '%5d_00_%d_gt.png' % (test_id, ratio)) print("\nFinished testing!\n")