diff --git a/data/aligned_dataset.py b/data/aligned_dataset.py index 59a58108c22..5f7457a47d1 100644 --- a/data/aligned_dataset.py +++ b/data/aligned_dataset.py @@ -1,4 +1,5 @@ import os +import numpy as np from data.base_dataset import BaseDataset, get_params, get_transform from data.image_folder import make_dataset from PIL import Image diff --git a/data/base_dataset.py b/data/base_dataset.py index b8eb78ed51a..488d55f5440 100755 --- a/data/base_dataset.py +++ b/data/base_dataset.py @@ -78,10 +78,11 @@ def get_params(opt, size): return {'crop_pos': (x, y), 'flip': flip} -def get_transform(opt, params=None, grayscale=False, method=transforms.InterpolationMode.BICUBIC, convert=True): +def get_transform(opt, params=None, grayscale=False, method=transforms.InterpolationMode.NEAREST, convert=True): transform_list = [] - if grayscale: - transform_list.append(transforms.Grayscale(1)) + #if grayscale: + #transform_list += [transforms.ToTensor()] + #transform_list.append(transforms.Grayscale(1)) if 'resize' in opt.preprocess: osize = [opt.load_size, opt.load_size] transform_list.append(transforms.Resize(osize, method)) @@ -90,18 +91,18 @@ def get_transform(opt, params=None, grayscale=False, method=transforms.Interpola if 'crop' in opt.preprocess: if params is None: - transform_list.append(transforms.RandomCrop(opt.crop_size)) + transform_list.append(transforms.CenterCrop(opt.crop_size)) else: transform_list.append(transforms.Lambda(lambda img: __crop(img, params['crop_pos'], opt.crop_size))) - if opt.preprocess == 'none': - transform_list.append(transforms.Lambda(lambda img: __make_power_2(img, base=4, method=method))) - - if not opt.no_flip: - if params is None: - transform_list.append(transforms.RandomHorizontalFlip()) - elif params['flip']: - transform_list.append(transforms.Lambda(lambda img: __flip(img, params['flip']))) + #if opt.preprocess == 'none': + #transform_list.append(transforms.Lambda(lambda img: __make_power_2(img, base=4, method=method))) + + #if not opt.no_flip: + #if params is None: + #transform_list.append(transforms.RandomHorizontalFlip()) + #elif params['flip']: + #transform_list.append(transforms.Lambda(lambda img: __flip(img, params['flip']))) if convert: transform_list += [transforms.ToTensor()] diff --git a/data/myaligned_dataset.py b/data/myaligned_dataset.py new file mode 100644 index 00000000000..c3e281f518a --- /dev/null +++ b/data/myaligned_dataset.py @@ -0,0 +1,111 @@ +from data.base_dataset import BaseDataset, get_transform +from data.image_folder import make_dataset +import tifffile as tiff +import numpy as np +import torch +from torchvision import transforms +from PIL import Image + + +class MyAlignedDataset(BaseDataset): + """Custom aligned dataset class for TIFF images.""" + + def __init__(self, opt): + """Initialize the dataset class. + + Parameters: + opt (Option class) -- stores all the experiment flags; needs to be a subclass of BaseOptions + """ + BaseDataset.__init__(self, opt) + self.dir_AB = opt.dataroot # Assuming data is organized in pairs in the same directory + self.AB_paths = sorted(make_dataset(self.dir_AB, opt.max_dataset_size)) + input_nc = self.opt.output_nc if self.opt.direction == 'BtoA' else self.opt.input_nc + output_nc = self.opt.input_nc if self.opt.direction == 'BtoA' else self.opt.output_nc + #self.transform = transforms.Compose([ + #transforms.Grayscale(1), + #transforms.ToTensor() + #]) + self.transform = get_transform(opt, grayscale=(input_nc == 1)) + + def __getitem__(self, index): + """Return a data point and its metadata information. + + Parameters: + index (int) -- a random integer for data indexing + + Returns: + a dictionary containing A, B, A_paths, and B_paths + A (tensor) -- an image in the input domain + B (tensor) -- its corresponding image in the target domain + A_paths (str) -- path to the input image + B_paths (str) -- path to the target image + """ + AB_path = self.AB_paths[index] + AB = tiff.imread(AB_path) + w, h = AB.shape[-1] // 2, AB.shape[-2] + A = Image.fromarray(AB[:, :w]) + B = Image.fromarray(AB[:, w:]) + #A = A.convert('L') + #B = B.convert('L') + ''' + A_array = np.array(A) + B_array = np.array(B) + + if np.array_equal(A, B): + print("Images A and B are equal.") + + # Convert image to NumPy array and print all values + A_array = np.array(A) + print("\nAll values of image A:\n", A_array) + unique_values_A = np.unique(A_array) + num_unique_values_A = len(unique_values_A) + print("Number of unique values in image A:", num_unique_values_A) + print("Shape:", A_array.shape) + print("Type:", A_array.dtype) + print("Min value:", np.min(A_array)) + print("Max value:", np.max(A_array)) + + B_array = np.array(B) + print("\nAll values of image B:\n", B_array) + unique_values_B = np.unique(B_array) + num_unique_values_B = len(unique_values_B) + print("Number of unique values in image B:", num_unique_values_B) + print("Shape:", B_array.shape) + print("Type:", B_array.dtype) + print("Min value:", np.min(B_array)) + print("Max value:", np.max(B_array),"\n") + ''' + # apply the same transform to both A and B + A = self.transform(A) + B = self.transform(B) + + ''' + if np.array_equal(A, B): + print("Images A and B are equal after trasnform.") + + A_array_after = np.array(A) + print("\nAll values of image A after transform:\n", A_array_after) + unique_values_A_after = np.unique(A_array_after) + num_unique_values_A_after = len(unique_values_A_after) + print("Number of unique values in image A after transform:", num_unique_values_A_after) + print("Shape:", A_array_after.shape) + print("Type:", A_array_after.dtype) + print("Min value:", np.min(A_array_after)) + print("Max value:", np.max(A_array_after)) + + B_array_after = np.array(B) + print("\nAll values of image B after transform:\n", B_array_after) + unique_values_B_after = np.unique(B_array_after) + num_unique_values_B_after = len(unique_values_B_after) + print("Number of unique values in image B after trasnform:", num_unique_values_B_after) + print("Shape:", B_array_after.shape) + print("Type:", B_array_after.dtype) + print("Min value:", np.min(B_array_after)) + print("Max value:", np.max(B_array_after),"\n") + + ''' + return {'A': A, 'B': B, 'A_paths': AB_path, 'B_paths': AB_path} + + def __len__(self): + """Return the total number of images in the dataset.""" + return len(self.AB_paths) diff --git a/data/mydataset_dataset.py b/data/mydataset_dataset.py new file mode 100644 index 00000000000..01e49501e0d --- /dev/null +++ b/data/mydataset_dataset.py @@ -0,0 +1,44 @@ +from data.base_dataset import BaseDataset, get_transform +from data.image_folder import make_dataset +import tifffile as tiff +from PIL import Image + +class MyDataset(BaseDataset): + """Custom dataset class.""" + + def __init__(self, opt): + """Initialize this dataset class. + + Parameters: + opt (Option class) -- stores all the experiment flags; needs to be a subclass of BaseOptions + """ + BaseDataset.__init__(self, opt) + self.A_paths = sorted(make_dataset(opt.dataroot, opt.max_dataset_size)) + input_nc = self.opt.output_nc if self.opt.direction == 'BtoA' else self.opt.input_nc + self.transform = get_transform(opt, grayscale=(input_nc == 1)) + + def __getitem__(self, index): + """Return a data point and its metadata information. + + Parameters: + index - - a random integer for data indexing + + Returns a dictionary that contains A and A_paths + A(tensor) - - an image in one domain + A_paths(str) - - the path of the image + """ + A_path = self.A_paths[index] + A_img = tiff.imread(A_path) # Load the TIFF image + print("Valori dell'immagine prima del dataloader:") + print(A_img) + A_img = Image.fromarray(A_img.squeeze(), mode='L') # Convert the NumPy array to a PIL image + print("Valori dell'immagine dopo prime operazioni:") + print(A_img) + A = self.transform(A_img) + print("Valori dell'immagine dopo transform:") + print(A_img) + return {'A': A, 'A_paths': A_path} + + def __len__(self): + """Return the total number of images in the dataset.""" + return len(self.A_paths) diff --git a/models/pix2pix_model.py b/models/pix2pix_model.py index 86a2b158264..4a2eee004ed 100644 --- a/models/pix2pix_model.py +++ b/models/pix2pix_model.py @@ -29,7 +29,8 @@ def modify_commandline_options(parser, is_train=True): By default, we use vanilla GAN loss, UNet with batchnorm, and aligned datasets. """ # changing the default values to match the pix2pix paper (https://phillipi.github.io/pix2pix/) - parser.set_defaults(norm='batch', netG='unet_256', dataset_mode='aligned') + #parser.set_defaults(norm='batch', netG='unet_256', dataset_mode='aligned') + parser.set_defaults(norm='batch', netG='unet_256', dataset_mode='myaligned') if is_train: parser.set_defaults(pool_size=0, gan_mode='vanilla') parser.add_argument('--lambda_L1', type=float, default=100.0, help='weight for L1 loss') diff --git a/options/base_options.py b/options/base_options.py index 3b951f4c447..b7dc35f901b 100644 --- a/options/base_options.py +++ b/options/base_options.py @@ -26,8 +26,8 @@ def initialize(self, parser): parser.add_argument('--checkpoints_dir', type=str, default='./checkpoints', help='models are saved here') # model parameters parser.add_argument('--model', type=str, default='cycle_gan', help='chooses which model to use. [cycle_gan | pix2pix | test | colorization]') - parser.add_argument('--input_nc', type=int, default=3, help='# of input image channels: 3 for RGB and 1 for grayscale') - parser.add_argument('--output_nc', type=int, default=3, help='# of output image channels: 3 for RGB and 1 for grayscale') + parser.add_argument('--input_nc', type=int, default=1, help='# of input image channels: 3 for RGB and 1 for grayscale') + parser.add_argument('--output_nc', type=int, default=1, help='# of output image channels: 3 for RGB and 1 for grayscale') parser.add_argument('--ngf', type=int, default=64, help='# of gen filters in the last conv layer') parser.add_argument('--ndf', type=int, default=64, help='# of discrim filters in the first conv layer') parser.add_argument('--netD', type=str, default='basic', help='specify discriminator architecture [basic | n_layers | pixel]. The basic model is a 70x70 PatchGAN. n_layers allows you to specify the layers in the discriminator') @@ -38,7 +38,7 @@ def initialize(self, parser): parser.add_argument('--init_gain', type=float, default=0.02, help='scaling factor for normal, xavier and orthogonal.') parser.add_argument('--no_dropout', action='store_true', help='no dropout for the generator') # dataset parameters - parser.add_argument('--dataset_mode', type=str, default='unaligned', help='chooses how datasets are loaded. [unaligned | aligned | single | colorization]') + parser.add_argument('--dataset_mode', type=str, default='myaligned', help='chooses how datasets are loaded. [unaligned | aligned | single | colorization | mydataset | myaligned]') parser.add_argument('--direction', type=str, default='AtoB', help='AtoB or BtoA') parser.add_argument('--serial_batches', action='store_true', help='if true, takes images in order to make batches, otherwise takes them randomly') parser.add_argument('--num_threads', default=4, type=int, help='# threads for loading data') diff --git a/test.py b/test.py index b91d302fa36..3ac4f7ac3d4 100644 --- a/test.py +++ b/test.py @@ -26,7 +26,9 @@ See training and test tips at: https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix/blob/master/docs/tips.md See frequently asked questions at: https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix/blob/master/docs/qa.md """ +import tifffile import os +import numpy as np from options.test_options import TestOptions from data import create_dataset from models import create_model @@ -76,5 +78,17 @@ img_path = model.get_image_paths() # get image paths if i % 5 == 0: # save images to an HTML file print('processing (%04d)-th image... %s' % (i, img_path)) - save_images(webpage, visuals, img_path, aspect_ratio=opt.aspect_ratio, width=opt.display_winsize, use_wandb=opt.use_wandb) - webpage.save() # save the HTML + for label, image_numpy in visuals.items(): + image_path = img_path[0] if len(img_path) == 1 else img_path[i] + image_name, ext = os.path.splitext(os.path.basename(image_path)) + save_path = os.path.join(web_dir, f'{image_name}_{label}.tiff') + image_numpy = image_numpy.cpu().numpy() + # Salva l'immagine come tiff utilizzando tifffile + image_numpy = (image_numpy + 1) / 2 + tifffile.imwrite(save_path, image_numpy, dtype='float32',) #.astype(np.uint16)) + if opt.use_wandb: + wandb.save(save_path) + + #save_images(webpage, visuals, img_path, aspect_ratio=opt.aspect_ratio, width=opt.display_winsize, use_wandb=opt.use_wandb) + #webpage.save() # save the HTML +