├── DESOBA_DATASET └── README.md ├── DESOBA_DATASET_util ├── README.md ├── Store_TestPairs_Desoba_Dataset.py ├── Vis_Desoba_Dataset.py ├── Vis_RealCompositionImages_fromDesoba_Dataset.py ├── __init__.py ├── data │ ├── Composite_dataset.py │ ├── DesobaSyntheticImageGeneration_dataset.py │ ├── __init__.py │ ├── __init__.pyc │ ├── base_data_loader.py │ ├── base_data_loader.pyc │ ├── base_dataset.py │ └── base_dataset.pyc └── util.py ├── Examples ├── RealCompositionImages │ └── 1.png ├── TestImaes │ └── 1.png ├── compare_images.png ├── composite_images_supp.png ├── dataset-samples.png ├── real_composite_samples.png └── task_intro.png ├── LICENSE.md ├── README.md ├── TrainedModels ├── README.md └── SGRNet_TrainedModel │ └── .pth ├── data_processing ├── BT_score.py ├── Vis_Desoba_Dataset.py ├── Visualization_Examples │ ├── 12.png │ ├── 14.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png ├── __pycache__ │ └── util.cpython-36.pyc ├── compute_params.py ├── compute_params_DESOBA.py ├── data │ ├── DesobaSyntheticImageGeneration_dataset.py │ ├── __init__.py │ ├── __init__.pyc │ ├── __pycache__ │ │ ├── DesobaSyntheticImageGeneration_dataset.cpython-36.pyc │ │ ├── __init__.cpython-36.pyc │ │ ├── __init__.cpython-38.pyc │ │ ├── base_data_loader.cpython-36.pyc │ │ ├── base_data_loader.cpython-38.pyc │ │ ├── base_dataset.cpython-36.pyc │ │ └── base_dataset.cpython-38.pyc │ ├── base_data_loader.py │ ├── base_data_loader.pyc │ ├── base_dataset.py │ └── base_dataset.pyc ├── soba_training_pairs.py └── util.py ├── requirement.txt └── src ├── data ├── Composite_dataset.py ├── Compositeselect_dataset.py ├── DesobaSyntheticImageGeneration_dataset.py ├── DesobaSyntheticImageGeneration_dataset.pyc ├── ShadowGenerationDatasetInference2_dataset.py ├── ShadowGenerationDatasetInference_dataset.py ├── __init__.py ├── __init__.pyc ├── base_data_loader.py ├── base_data_loader.pyc ├── base_dataset.py ├── base_dataset.pyc ├── image_folder.py ├── image_folder.pyc ├── shadowparam_composite.py └── shadowparam_dataset.py ├── generate.py ├── models ├── ARShadowGAN_model.py ├── MaskshadowGAN_model.py ├── Pix2pix_model.py ├── SGRNet_model.py ├── ShadowGAN_model.py ├── __init__.py ├── __init__.pyc ├── base_model.py ├── base_model.pyc ├── distangle_model.py ├── loss_function.py ├── maskshadowGAN_models_guided.py ├── maskshadowGAN_utils.py ├── networks.py ├── networks.pyc ├── resnet.py ├── unet_parts.py └── vgg.py ├── options ├── __init__.py ├── base_options.py ├── test_options.py ├── test_options.pyc ├── train_options.py └── train_options.pyc ├── pytorch_ssim ├── .gitignore ├── LICENSE.txt ├── README.md ├── __init__.py ├── einstein.png ├── max_ssim.gif ├── max_ssim.py ├── pytorch_ssim │ └── __init__.py ├── setup.cfg └── setup.py ├── script ├── ARShadowGAN_RealComposite.sh ├── ARShadowGAN_test.sh ├── ARShadowGAN_train.sh ├── MaskshadowGAN_RealComposite.sh ├── MaskshadowGAN_test.sh ├── MaskshadowGAN_train.sh ├── Pix2pixRes_test.sh ├── Pix2pixRes_train.sh ├── Pix2pix_test.sh ├── Pix2pix_train.sh ├── SGRNet_RealComposite.sh ├── SGRNet_RealComposite_2.sh ├── SGRNet_test.sh ├── SGRNet_test_fromTestpairs.sh ├── SGRNet_train.sh ├── ShadowGAN_RealComposite.sh ├── ShadowGAN_test.sh ├── ShadowGAN_train.sh ├── __init__.py ├── pix2pixRes_RealComposite.sh └── pix2pix_RealComposite.sh ├── test.py ├── train.py └── util ├── __init__.py ├── __init__.pyc ├── boundding_box_utils.py ├── boundding_box_utils.pyc ├── coordconv.py ├── coordconv1.py ├── get_data.py ├── html.py ├── html.pyc ├── image_pool.py ├── ssim.py ├── util.py ├── util.pyc ├── visualizer.py └── visualizer.pyc /DESOBA_DATASET/README.md: -------------------------------------------------------------------------------- 1 | DESOBA dataset is provided in [**Baidu Cloud**](https://pan.baidu.com/s/1fYqcSjGSr52jppg2LEA1qQ) (access code: sipx), or [**Google Drive**](https://drive.google.com/file/d/114BU47G0OJV3vmx5WKxGnWDSj2Bzh6qS/view?usp=sharing). 2 | 3 | There are four subfolders in DESOBA_DATASET, including ShadowImages, DeshadowedImage, InstanceMask, ShadowMask. 4 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/README.md: -------------------------------------------------------------------------------- 1 | ## Visualizing training/testing pairs of DESOBA dataset 2 | 3 | `cd ./DESOBA_DATASET_util` 4 | 5 | - visualizing train pairs (839 train images with 11509 pairs): 6 | ```bash 7 | python Vis_Desoba_Dataset --serial_batches --isTrain 1 8 | ``` 9 | train pairs are stored in /DESOBA_DATASET/TrainTestVisualization/train/ 10 | 11 | - visulizing test bosfree pairs (34 test bosfree images with 34 pairs): 12 | ```bash 13 | python Vis_Desoba_Dataset --serial_batches --isTrain 0 --bosfree 14 | ``` 15 | test bosfree pairs are store in /DESOBA_DATASET/TrainTestVisualization/train/test_bosfree 16 | 17 | - visulizing test bos pairs (126 test bos images with 581 pairs): 18 | ```bash 19 | python Vis_Desoba_Dataset --serial_batches --isTrain 0 --bos 20 | ``` 21 | test bos pairs are stored in /DESOBA_DATASET/TrainTestVisualization/train/test_bos 22 | 23 | We show some examples of training/testing tuples in below: 24 | 25 | 26 | 27 | 28 | from left to right: synthetic composite image without foreground shadow, target image with foreground shadow, foreground object mask, foreground shadow mask, background object mask, and background shadow mask. 29 | 30 | 31 | ## Producing real composite images from test images of DESOBA 32 | 33 | `cd ./DESOBA_DATASET_util` 34 | 35 | - producing real composite images with one foreground object: 36 | ```bash 37 | python Vis_RealCompositionImages_fromDesoba_Dataset.py --foreground_object_num 1 38 | ``` 39 | real composite images with one foreground object are store in /DESOBA_DATASET/CompositeImages/1_ForegroundObject/ 40 | 41 | - producing real composite images with two foreground objects: 42 | ```bash 43 | python Vis_RealCompositionImages_fromDesoba_Dataset.py --foreground_object_num 2 44 | ``` 45 | 46 | real composite images with one foreground object are stored in /DESOBA_DATASET/CompositeImages/2_ForegroundObject/ 47 | 48 | We show a real composite image with one foreground object and a real composite image with two foreground objects below: 49 | 50 | 51 | from left to right: synthetic composite image without foreground shadow, foreground object mask, background object mask, and background shadow mask. 52 | 53 | 54 | 55 | ## Producing test pairs of DESOBA dataset for testing 56 | 57 | `cd ./DESOBA_DATASET_util` 58 | 59 | - bos test pairs 60 | ```bash 61 | python Store_TestPairs_Desoba_Dataset.py --bos 62 | ``` 63 | BOS test pairs are stored in /DESOBA_DATASET/TestSplit/bos 64 | 65 | 66 | - bosfree pairs 67 | ```bash 68 | python Store_TestPairs_Desoba_Dataset.py --bosfree 69 | ``` 70 | BOS-free test pairs are stored in /DESOBA_DATASET/TestSplit/bosfee 71 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/Store_TestPairs_Desoba_Dataset.py: -------------------------------------------------------------------------------- 1 | import argparse, os 2 | from PIL import Image 3 | from data import CreateDataLoader 4 | import util 5 | import numpy as np 6 | 7 | def get_parser(): 8 | parser = argparse.ArgumentParser() 9 | parser.add_argument('--dataroot',default='../DESOBA_DATASET/', 10 | help='path to images (should have subfolders trainA, trainB, valA, valB, etc)') 11 | parser.add_argument('--loadSize', type=int, default=256, help='scale images to this size') 12 | parser.add_argument('--dataset_mode', type=str, default='DesobaSyntheticImageGeneration', help='chooses how datasets are loaded. [unaligned | aligned | single]') 13 | parser.add_argument('--batch_size', type=int, default=1, help='scale images to this size') 14 | parser.add_argument('--serial_batches', action='store_true', help='if true, takes images in order to make batches, otherwise takes them randomly') 15 | parser.add_argument('--num_threads', default=4, type=int, help='# threads for loading data') 16 | parser.add_argument('--max_dataset_size', type=int, default=float("inf"), help='Maximum number of samples allowed per dataset. If the dataset directory contains more than max_dataset_size, only a subset is loaded.') 17 | parser.add_argument('--bosfree', action='store_true') 18 | parser.add_argument('--bos', action='store_true') 19 | 20 | 21 | parser.add_argument('--output_path', default='../DESOBA_DATASET/TestSplit/',type=str) 22 | 23 | 24 | return parser 25 | 26 | 27 | if __name__ == "__main__": 28 | # Visualizing examples 29 | parser = get_parser() 30 | opt, _ = parser.parse_known_args() 31 | opt.isTrain = False 32 | opt.shadowimg_path = opt.dataroot + '/ShadowImage' 33 | opt.shadowfree_path = opt.dataroot + '/DeshadowedImage' 34 | opt.instance_path = opt.dataroot + '/InstanceMask' 35 | opt.shadow_path = opt.dataroot + '/ShadowMask' 36 | opt.new_mask_path = opt.dataroot + '/shadownewmask' 37 | 38 | 39 | if opt.bos: 40 | opt.output_path = opt.output_path + 'bos/' 41 | elif opt.bosfree: 42 | opt.output_path = opt.output_path + 'bosfree/' 43 | 44 | 45 | data_loader = CreateDataLoader(opt) 46 | dataset = data_loader.load_data() 47 | dataset_size = len(data_loader) 48 | loadSize = opt.loadSize 49 | 50 | for i, data in enumerate(dataset): 51 | synthetic_composite_img = util.tensor2im(data['Synth_img']) 52 | shadow_img = util.tensor2im(data['Shadow_img']) 53 | fg_instance_mask = util.tensor2im(data['fg_instance_mask']) 54 | fg_shadow_mask = util.tensor2im(data['fg_shadow_mask']) 55 | bg_instance_mask = util.tensor2im(data['bg_instance_mask']) 56 | bg_shadow_mask = util.tensor2im(data['bg_shadow_mask']) 57 | 58 | synthetic_path = opt.output_path + 'shadowfree_img' 59 | gt_path = opt.output_path + 'shadow_img' 60 | fginstance_path = opt.output_path + 'foreground_object_mask' 61 | fgshadow_path = opt.output_path + 'foreground_shadow_mask' 62 | bginstance_path = opt.output_path + 'background_object_mask' 63 | bgshadow_path = opt.output_path + 'background_shadow_mask' 64 | 65 | paths = [synthetic_path, gt_path, fginstance_path, fgshadow_path, bginstance_path, bgshadow_path] 66 | imgs = [synthetic_composite_img,shadow_img, fg_instance_mask, fg_shadow_mask, bg_instance_mask,bg_shadow_mask] 67 | 68 | for j, path in enumerate(paths): 69 | if not os.path.exists(path): 70 | os.makedirs(path) 71 | output_name = '{}.png'.format(i) 72 | save_path = '%s/%s' % (path, output_name) 73 | util.save_image(imgs[j], save_path) 74 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/Vis_Desoba_Dataset.py: -------------------------------------------------------------------------------- 1 | import argparse, os 2 | from PIL import Image 3 | from data import CreateDataLoader 4 | import util 5 | import numpy as np 6 | 7 | def get_parser(): 8 | parser = argparse.ArgumentParser() 9 | parser.add_argument('--dataroot',default='../DESOBA_DATASET/', 10 | help='path to images (should have subfolders trainA, trainB, valA, valB, etc)') 11 | parser.add_argument('--output_path', default='../DESOBA_DATASET/TrainTestVisualization/',type=str) 12 | parser.add_argument('--loadSize', type=int, default=256, help='scale images to this size') 13 | parser.add_argument('--dataset_mode', type=str, default='DesobaSyntheticImageGeneration', help='chooses how datasets are loaded. [unaligned | aligned | single]') 14 | parser.add_argument('--batch_size', type=int, default=1, help='scale images to this size') 15 | parser.add_argument('--serial_batches', action='store_true', help='if true, takes images in order to make batches, otherwise takes them randomly') 16 | parser.add_argument('--num_threads', default=4, type=int, help='# threads for loading data') 17 | parser.add_argument('--max_dataset_size', type=int, default=float("inf"), help='Maximum number of samples allowed per dataset. If the dataset directory contains more than max_dataset_size, only a subset is loaded.') 18 | parser.add_argument('--isTrain', type=int, default=1) 19 | parser.add_argument('--bosfree', action='store_true') 20 | parser.add_argument('--bos', action='store_true') 21 | return parser 22 | 23 | 24 | if __name__ == "__main__": 25 | # Visualizing examples 26 | parser = get_parser() 27 | opt, _ = parser.parse_known_args() 28 | opt.shadowimg_path = opt.dataroot + '/ShadowImage' 29 | opt.shadowfree_path = opt.dataroot + '/DeshadowedImage' 30 | opt.instance_path = opt.dataroot + '/InstanceMask' 31 | opt.shadow_path = opt.dataroot + '/ShadowMask' 32 | opt.new_mask_path = opt.dataroot + '/shadownewmask' 33 | 34 | 35 | if opt.isTrain: 36 | 37 | opt.output_path = opt.output_path + 'train' 38 | else: 39 | if opt.bos: 40 | opt.output_path = opt.output_path + 'test_bos' 41 | elif opt.bosfree: 42 | opt.output_path = opt.output_path + 'test_bosfree' 43 | 44 | 45 | 46 | data_loader = CreateDataLoader(opt) 47 | dataset = data_loader.load_data() 48 | dataset_size = len(data_loader) 49 | loadSize = opt.loadSize 50 | 51 | 52 | for i, data in enumerate(dataset): 53 | row = [] 54 | new_img = Image.new('RGB', (loadSize*6, loadSize), 255) 55 | synthetic_composite_img = util.tensor2im(data['Synth_img']) 56 | shadow_img = util.tensor2im(data['Shadow_img']) 57 | fg_instance_mask = util.tensor2im(data['fg_instance_mask']) 58 | fg_shadow_mask = util.tensor2im(data['fg_shadow_mask']) 59 | bg_instance_mask = util.tensor2im(data['bg_instance_mask']) 60 | bg_shadow_mask = util.tensor2im(data['bg_shadow_mask']) 61 | 62 | row.append(synthetic_composite_img) 63 | row.append(shadow_img) 64 | row.append(fg_instance_mask) 65 | row.append(fg_shadow_mask) 66 | row.append(bg_instance_mask) 67 | row.append(bg_shadow_mask) 68 | row = tuple(row) 69 | row = np.hstack(row) 70 | 71 | if not os.path.exists(opt.output_path): 72 | os.makedirs(opt.output_path) 73 | output_name = '{}.png'.format(i) 74 | save_path = '%s/%s' % (opt.output_path, output_name) 75 | util.save_image(row, save_path) 76 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/Vis_RealCompositionImages_fromDesoba_Dataset.py: -------------------------------------------------------------------------------- 1 | import argparse, os 2 | from PIL import Image 3 | from data import CreateDataLoader 4 | import util 5 | import numpy as np 6 | import torch 7 | 8 | def get_parser(): 9 | parser = argparse.ArgumentParser() 10 | parser.add_argument('--dataroot',default='../DESOBA_DATASET/', 11 | help='path to images (should have subfolders trainA, trainB, valA, valB, etc)') 12 | parser.add_argument('--output_path', default='../DESOBA_DATASET/CompositeImages/',type=str) 13 | 14 | parser.add_argument('--loadSize', type=int, default=256, help='scale images to this size') 15 | # parser.add_argument('--dataset_mode', type=str, default='TwoForegroundObjectsComposite', help='chooses how datasets are loaded. [unaligned | aligned | single]') 16 | parser.add_argument('--dataset_mode', type=str, default='Composite', help='chooses how datasets are loaded. [unaligned | aligned | single]') 17 | 18 | parser.add_argument('--batch_size', type=int, default=1, help='scale images to this size') 19 | parser.add_argument('--serial_batches', action='store_true', help='if true, takes images in order to make batches, otherwise takes them randomly') 20 | parser.add_argument('--num_threads', default=4, type=int, help='# threads for loading data') 21 | parser.add_argument('--max_dataset_size', type=int, default=float("inf"), help='Maximum number of samples allowed per dataset. If the dataset directory contains more than max_dataset_size, only a subset is loaded.') 22 | parser.add_argument('--isTrain', type=int, default=0) 23 | parser.add_argument('--foreground_object_num', type=int, default=1) 24 | 25 | return parser 26 | 27 | 28 | if __name__ == "__main__": 29 | # Visualizing examples 30 | parser = get_parser() 31 | opt, _ = parser.parse_known_args() 32 | opt.shadowimg_path = opt.dataroot + '/ShadowImage' 33 | opt.shadowfree_path = opt.dataroot + '/DeshadowedImage' 34 | opt.instance_path = opt.dataroot + '/InstanceMask' 35 | opt.shadow_path = opt.dataroot + '/ShadowMask' 36 | opt.new_mask_path = opt.dataroot + '/shadownewmask' 37 | 38 | opt.store_path = opt.output_path + '/{}_ForegroundObject/'.format(opt.foreground_object_num) 39 | 40 | 41 | data_loader = CreateDataLoader(opt) 42 | dataset = data_loader.load_data() 43 | dataset_size = len(data_loader) 44 | loadSize = opt.loadSize 45 | length = 0 46 | 47 | for i, data_list in enumerate(dataset): 48 | for k, data in enumerate(data_list): 49 | synthetic_composite_img = util.tensor2im(data['C']) 50 | shadow_img = util.tensor2im(data['A']) 51 | fg_instance_mask = util.tensor2im(data['instancemask']) 52 | fg_shadow_mask = util.tensor2im(data['B']) 53 | bg_instance_mask = util.tensor2im(data['bg_instance']) 54 | bg_shadow_mask = util.tensor2im(data['bg_shadow']) 55 | 56 | synthetic_path = opt.store_path + 'shadowfree' 57 | gt_path = opt.store_path + 'shadowimg' 58 | fginstance_path = opt.store_path + 'foreground_object_mask' 59 | fgshadow_path = opt.store_path + 'foreground_shadow_mask' 60 | bginstance_path = opt.store_path + 'background_object_mask' 61 | bgshadow_path = opt.store_path + 'background_shadow_mask' 62 | 63 | paths = [synthetic_path, gt_path, fginstance_path, fgshadow_path, bginstance_path, bgshadow_path] 64 | imgs = [synthetic_composite_img,shadow_img, fg_instance_mask, fg_shadow_mask, bg_instance_mask,bg_shadow_mask] 65 | 66 | for j, path in enumerate(paths): 67 | if not os.path.exists(path): 68 | os.makedirs(path) 69 | output_name = '{}.png'.format(k+length) 70 | save_path = '%s/%s' % (path, output_name) 71 | util.save_image(imgs[j], save_path) 72 | 73 | length +=len(data_list) 74 | print('producing {} images'.format(length)) 75 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/data/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import torch.utils.data 3 | from data.base_data_loader import BaseDataLoader 4 | from data.base_dataset import BaseDataset 5 | 6 | 7 | def find_dataset_using_name(dataset_name): 8 | # Given the option --dataset_mode [datasetname], 9 | # the file "data/datasetname_dataset.py" 10 | # will be imported. 11 | dataset_filename = "data." + dataset_name + "_dataset" 12 | datasetlib = importlib.import_module(dataset_filename) 13 | 14 | # In the file, the class called DatasetNameDataset() will 15 | # be instantiated. It has to be a subclass of BaseDataset, 16 | # and it is case-insensitive. 17 | dataset = None 18 | target_dataset_name = dataset_name.replace('_', '') + 'dataset' 19 | for name, cls in datasetlib.__dict__.items(): 20 | if name.lower() == target_dataset_name.lower() \ 21 | and issubclass(cls, BaseDataset): 22 | dataset = cls 23 | 24 | if dataset is None: 25 | print("In %s.py, there should be a subclass of BaseDataset with class name that matches %s in lowercase." % (dataset_filename, target_dataset_name)) 26 | exit(0) 27 | 28 | return dataset 29 | 30 | 31 | def get_option_setter(dataset_name): 32 | dataset_class = find_dataset_using_name(dataset_name) 33 | return dataset_class.modify_commandline_options 34 | 35 | 36 | def create_dataset(opt): 37 | dataset = find_dataset_using_name(opt.dataset_mode) 38 | instance = dataset() 39 | instance.initialize(opt) 40 | print("dataset [%s] was created" % (instance.name())) 41 | return instance 42 | 43 | 44 | def CreateDataLoader(opt): 45 | data_loader = CustomDatasetDataLoader() 46 | data_loader.initialize(opt) 47 | return data_loader 48 | 49 | 50 | # Wrapper class of Dataset class that performs 51 | # multi-threaded data loading 52 | class CustomDatasetDataLoader(BaseDataLoader): 53 | def name(self): 54 | return 'CustomDatasetDataLoader' 55 | 56 | def initialize(self, opt): 57 | BaseDataLoader.initialize(self, opt) 58 | self.create_dataset = create_dataset 59 | self.dataset = self.create_dataset(opt) 60 | self.dataloader = torch.utils.data.DataLoader( 61 | self.dataset, 62 | batch_size=opt.batch_size, 63 | shuffle=not opt.serial_batches, 64 | num_workers=int(opt.num_threads)) 65 | 66 | def load_data(self): 67 | return self 68 | 69 | def __len__(self): 70 | return min(len(self.dataset), self.opt.max_dataset_size) 71 | 72 | def __iter__(self): 73 | for i, data in enumerate(self.dataloader): 74 | if i * self.opt.batch_size >= self.opt.max_dataset_size: 75 | break 76 | yield data 77 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/data/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/DESOBA_DATASET_util/data/__init__.pyc -------------------------------------------------------------------------------- /DESOBA_DATASET_util/data/base_data_loader.py: -------------------------------------------------------------------------------- 1 | class BaseDataLoader(): 2 | def __init__(self): 3 | pass 4 | 5 | def initialize(self, opt): 6 | self.opt = opt 7 | pass 8 | 9 | def load_data(): 10 | return None 11 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/data/base_data_loader.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/DESOBA_DATASET_util/data/base_data_loader.pyc -------------------------------------------------------------------------------- /DESOBA_DATASET_util/data/base_dataset.py: -------------------------------------------------------------------------------- 1 | import torch.utils.data as data 2 | from PIL import Image 3 | import torchvision.transforms as transforms 4 | 5 | 6 | class BaseDataset(data.Dataset): 7 | def __init__(self): 8 | super(BaseDataset, self).__init__() 9 | 10 | def name(self): 11 | return 'BaseDataset' 12 | 13 | @staticmethod 14 | def modify_commandline_options(parser, is_train): 15 | return parser 16 | 17 | def initialize(self, opt): 18 | pass 19 | 20 | def __len__(self): 21 | return 0 22 | 23 | 24 | def get_transform(opt): 25 | transform_list = [] 26 | if opt.resize_or_crop == 'resize_and_crop': 27 | osize = [opt.loadSize, opt.loadSize] 28 | transform_list.append(transforms.Resize(osize, Image.BICUBIC)) 29 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 30 | elif opt.resize_or_crop == 'resize': 31 | osize = [opt.loadSize, opt.loadSize] 32 | transform_list.append(transforms.Resize(osize, Image.BICUBIC)) 33 | elif opt.resize_or_crop == 'crop': 34 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 35 | elif opt.resize_or_crop == 'scale_width': 36 | transform_list.append(transforms.Lambda( 37 | lambda img: __scale_width(img, opt.fineSize))) 38 | elif opt.resize_or_crop == 'scale_width_and_crop': 39 | transform_list.append(transforms.Lambda( 40 | lambda img: __scale_width(img, opt.loadSize))) 41 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 42 | elif opt.resize_or_crop == 'none': 43 | transform_list.append(transforms.Lambda( 44 | lambda img: __adjust(img))) 45 | else: 46 | raise ValueError('--resize_or_crop %s is not a valid option.' % opt.resize_or_crop) 47 | 48 | if opt.isTrain and not opt.no_flip: 49 | transform_list.append(transforms.RandomHorizontalFlip()) 50 | 51 | transform_list += [transforms.ToTensor(), 52 | transforms.Normalize((0.5, 0.5, 0.5), 53 | (0.5, 0.5, 0.5))] 54 | return transforms.Compose(transform_list) 55 | 56 | 57 | # just modify the width and height to be multiple of 4 58 | def __adjust(img): 59 | ow, oh = img.size 60 | 61 | # the size needs to be a multiple of this number, 62 | # because going through generator network may change img size 63 | # and eventually cause size mismatch error 64 | mult = 4 65 | if ow % mult == 0 and oh % mult == 0: 66 | return img 67 | w = (ow - 1) // mult 68 | w = (w + 1) * mult 69 | h = (oh - 1) // mult 70 | h = (h + 1) * mult 71 | 72 | if ow != w or oh != h: 73 | __print_size_warning(ow, oh, w, h) 74 | 75 | return img.resize((w, h), Image.BICUBIC) 76 | 77 | 78 | 79 | 80 | def __scale_width(img, target_width): 81 | ow, oh = img.size 82 | 83 | # the size needs to be a multiple of this number, 84 | # because going through generator network may change img size 85 | # and eventually cause size mismatch error 86 | mult = 4 87 | assert target_width % mult == 0, "the target width needs to be multiple of %d." % mult 88 | if (ow == target_width and oh % mult == 0): 89 | return img 90 | w = target_width 91 | target_height = int(target_width * oh / ow) 92 | m = (target_height - 1) // mult 93 | h = (m + 1) * mult 94 | 95 | if target_height != h: 96 | __print_size_warning(target_width, target_height, w, h) 97 | 98 | return img.resize((w, h), Image.BICUBIC) 99 | 100 | 101 | def __print_size_warning(ow, oh, w, h): 102 | if not hasattr(__print_size_warning, 'has_printed'): 103 | print("The image size needs to be a multiple of 4. " 104 | "The loaded image size was (%d, %d), so it was adjusted to " 105 | "(%d, %d). This adjustment will be done to all images " 106 | "whose sizes are not multiples of 4" % (ow, oh, w, h)) 107 | __print_size_warning.has_printed = True 108 | -------------------------------------------------------------------------------- /DESOBA_DATASET_util/data/base_dataset.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/DESOBA_DATASET_util/data/base_dataset.pyc -------------------------------------------------------------------------------- /DESOBA_DATASET_util/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import torch 3 | import numpy as np 4 | from PIL import Image 5 | import os 6 | 7 | 8 | def sdmkdir(dir_name): 9 | if not os.path.exists(dir_name): 10 | os.mkdir(dir_name) 11 | # Converts a Tensor into an image array (numpy) 12 | # |imtype|: the desired type of the converted numpy array 13 | def tensor2cvim(input_image, imtype=np.uint8,scale=None): 14 | # print('hhhhh',np.shape(input_image)) 15 | 16 | if len(input_image.shape)<3: return None 17 | # if scale>0 and input_image.size()[1]==3: 18 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 19 | 20 | if isinstance(input_image, torch.Tensor): 21 | image_tensor = input_image.data 22 | else: 23 | return input_image 24 | image_numpy = image_tensor.data[0].cpu().float().numpy() 25 | # if image_numpy.shape[0] == 1: 26 | # image_numpy = np.tile(image_numpy, (3, 1, 1)) 27 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 28 | image_numpy[image_numpy<0] = 0 29 | image_numpy[image_numpy>255] = 255 30 | return image_numpy.astype(imtype) 31 | 32 | 33 | def tensor2imonechannel(input_image, imtype=np.uint8, scale=None): 34 | if len(input_image.shape) < 3: return None 35 | # if scale>0 and input_image.size()[1]==3: 36 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 37 | 38 | if isinstance(input_image, torch.Tensor): 39 | image_tensor = input_image.data 40 | else: 41 | return input_image 42 | image_numpy = image_tensor.data[0].cpu().float().numpy() 43 | # if image_numpy.shape[0] == 1: 44 | # image_numpy = np.tile(image_numpy, (3, 1, 1)) 45 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 46 | # image_numpy[image_numpy < 0] = 0 47 | # image_numpy[image_numpy > 255] = 255 48 | # return image_numpy.astype(imtype) 49 | return image_numpy 50 | 51 | 52 | 53 | def tensor2im(input_image, imtype=np.uint8,scale=None): 54 | 55 | if len(input_image.shape)<3: return None 56 | # if scale>0 and input_image.size()[1]==3: 57 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 58 | 59 | if isinstance(input_image, torch.Tensor): 60 | image_tensor = input_image.data 61 | else: 62 | return input_image 63 | image_numpy = image_tensor.data[0].cpu().float().numpy() 64 | if image_numpy.shape[0] == 1: 65 | image_numpy = np.tile(image_numpy, (3, 1, 1)) 66 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 67 | image_numpy[image_numpy<0] = 0 68 | image_numpy[image_numpy>255] = 255 69 | return image_numpy.astype(imtype) 70 | 71 | def tensor2im_logc(image_tensor, imtype=np.uint8,scale=255): 72 | image_numpy = image_tensor.data[0].cpu().double().numpy() 73 | image_numpy = np.transpose(image_numpy,(1,2,0)) 74 | image_numpy = (image_numpy+1) /2.0 75 | image_numpy = image_numpy * (np.log(scale+1)) 76 | image_numpy = np.exp(image_numpy) -1 77 | image_numpy = image_numpy.astype(np.uint8) 78 | 79 | return image_numpy.astype(np.uint8) 80 | 81 | 82 | def diagnose_network(net, name='network'): 83 | mean = 0.0 84 | count = 0 85 | for param in net.parameters(): 86 | if param.grad is not None: 87 | mean += torch.mean(torch.abs(param.grad.data)) 88 | count += 1 89 | if count > 0: 90 | mean = mean / count 91 | print(name) 92 | print(mean) 93 | 94 | 95 | def save_image(image_numpy, image_path): 96 | image_pil = Image.fromarray(image_numpy) 97 | image_pil.save(image_path) 98 | 99 | 100 | def print_numpy(x, val=True, shp=False): 101 | x = x.astype(np.float64) 102 | if shp: 103 | print('shape,', x.shape) 104 | if val: 105 | x = x.flatten() 106 | print('mean = %3.3f, min = %3.3f, max = %3.3f, median = %3.3f, std=%3.3f' % ( 107 | np.mean(x), np.min(x), np.max(x), np.median(x), np.std(x))) 108 | 109 | 110 | def mkdirs(paths): 111 | if isinstance(paths, list) and not isinstance(paths, str): 112 | for path in paths: 113 | mkdir(path) 114 | else: 115 | mkdir(paths) 116 | 117 | 118 | def mkdir(path): 119 | if not os.path.exists(path): 120 | os.makedirs(path) 121 | 122 | 123 | def transparent_png(img,fg_mask): 124 | img = img.convert('RGBA') 125 | W, H = img.size 126 | # fg_mask = np.array(fg_mask) 127 | for h in range(H): ###循环图片的每个像素点 128 | for l in range(W): 129 | if fg_mask.getpixel((l,h)) == 0: 130 | pixels = img.getpixel((l,h)) 131 | if h==0 and l==0: 132 | print('old',pixels) 133 | pixels = pixels[:-1] + (80,) 134 | if h==0 and l==0: 135 | print('new',tuple(pixels)) 136 | img.putpixel((l,h),pixels) 137 | img.save('/media/user/data/ShadowGeneration/HYShadowGeneration/SOBAMixFGAllData/Model_SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/SelfAttention_Illumination1_Residual0_ConditionD1_Llight0_Lpara1_Lshadowrecons10_Limagerecons10_Lgan0.1_Lstn0_Nwarp0_Lref1_Ltv0_Lganmask0/SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/web/images/0.png') 138 | # img = Image.open('/media/user/data/ShadowGeneration/HYShadowGeneration/SOBAMixFGAllData/Model_SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/SelfAttention_Illumination1_Residual0_ConditionD1_Llight0_Lpara1_Lshadowrecons10_Limagerecons10_Lgan0.1_Lstn0_Nwarp0_Lref1_Ltv0_Lganmask0/SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/web/images/0.png') 139 | # print(img.size()) 140 | return img -------------------------------------------------------------------------------- /Examples/RealCompositionImages/1.png: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Examples/TestImaes/1.png: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Examples/compare_images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/Examples/compare_images.png -------------------------------------------------------------------------------- /Examples/composite_images_supp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/Examples/composite_images_supp.png -------------------------------------------------------------------------------- /Examples/dataset-samples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/Examples/dataset-samples.png -------------------------------------------------------------------------------- /Examples/real_composite_samples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/Examples/real_composite_samples.png -------------------------------------------------------------------------------- /Examples/task_intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/Examples/task_intro.png -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 BCMI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /TrainedModels/README.md: -------------------------------------------------------------------------------- 1 | The paths of pretrained models including Pix2Pix, Pix2Pix-Res, ShadowGAN, MaskShadowGAN, ARShadowGAN, and SGRNet. 2 | -------------------------------------------------------------------------------- /TrainedModels/SGRNet_TrainedModel/.pth: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /data_processing/BT_score.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | # In[3]: 5 | 6 | # from shapedetector import ShapeDetector 7 | # from colorlabeler import ColorLabeler 8 | # import argparse 9 | # import imutils 10 | 11 | 12 | import os 13 | from os import listdir 14 | from os.path import isfile, join 15 | from PIL import Image as Image 16 | import numpy as np 17 | import pandas as pd 18 | 19 | 20 | def obtain_tuple(data_root, folders, foreground_mask_folder): 21 | store_path_paired_image = os.path.join(data_root, 'BTscore_image_comparison') 22 | store_path_list = os.path.join(data_root, 'BTscore_image_comparison_list.xlsx') 23 | if not os.path.exists(store_path_paired_image): 24 | os.makedirs(store_path_paired_image) 25 | 26 | combined_images_list = [] 27 | 28 | for root, dirs, files in os.walk(os.path.join(data_root ,foreground_mask_folder[0]) ): 29 | if (len(dirs) < 1): 30 | print(len(dirs)) 31 | print('root', root) 32 | # print('dir', dirs) 33 | unit_size = 256 34 | target_width = 256*3 35 | new_image = Image.new('RGB', (target_width, unit_size)) 36 | print(root.split('/')[-1]) 37 | 38 | root_index = root.split('/')[-1].split('s')[-1] 39 | print('root_index',root_index) 40 | for file in files: 41 | current_foreground_mask_path = os.path.join(root, file) 42 | fg_mask_image = Image.open(current_foreground_mask_path) 43 | new_image.paste(fg_mask_image, (256, 0, 256*2, unit_size)) 44 | file_index = file.split('_')[0].split('t')[-1] 45 | print('image index', file_index) 46 | for i in range(len(folders)): 47 | folder1 = folders[i] 48 | image1_root = root.replace(foreground_mask_folder[0], folder1) 49 | image1_root_filelist = [f for f in listdir(image1_root) if isfile(join(image1_root, f)) and f.endswith('png')] 50 | ###matching image 51 | for image1_name in image1_root_filelist: 52 | if image1_name.split('_')[0] == file_index: 53 | image1_path = os.path.join(image1_root, image1_name) 54 | print('image1 path', image1_path) 55 | image1 = Image.open(image1_path) 56 | new_image.paste(image1, (0, 0, 256, unit_size)) 57 | for j in range(i+1, len(folders)): 58 | folder2 = folders[j] 59 | image2_root = root.replace(foreground_mask_folder[0], folder2) 60 | image2_root_filelist = [f for f in listdir(image2_root) if isfile(join(image2_root, f)) and f.endswith('png')] 61 | ###matching image 62 | for image2_name in image2_root_filelist: 63 | if image2_name.split('_')[0] == file_index: 64 | image2_path = os.path.join(image2_root, image2_name) 65 | print('image2 path', image2_path) 66 | image2 = Image.open(image2_path) 67 | new_image.paste(image2, (256*2, 0, 256*3, unit_size)) 68 | #####complete 69 | new_image_name = 'Images{}_{}-Methods{}_{}.png'.format(root_index,file_index,i,j) 70 | new_image.save(os.path.join(store_path_paired_image, new_image_name)) 71 | combined_images_list.append([new_image_name, []]) 72 | 73 | 74 | name=['image_name','which side is more realistic (1 means the left one, 2 means the right one)'] 75 | output=pd.DataFrame(columns=name,data=combined_images_list)#数据有三列,列名分别为one,two,three 76 | # output.sort_values('image_name') 77 | output.to_excel(store_path_list, index=False) 78 | 79 | # output_excel = {'image_name':[], 'which side is more realistic (1 means the left one, 2 means the right one)':[]} 80 | # output_excel['image_name'] = combined_images_list 81 | # output_excel['which side is more realistic (1 means the left one, 2 means the right one'] = [] 82 | # output = pd.DataFrame(output_excel) 83 | # output.to_excel(store_path_list, index=False) 84 | 85 | 86 | 87 | 88 | 89 | # for i,folder in enumerate (folders): 90 | # current_dataset = os.path.join(data_root, folder) 91 | # im_list = [f for f in listdir(current_dataset) if isfile(join(current_dataset, f)) and f.endswith('jpg')] 92 | # for im in im_list[:]: 93 | # current_shadowimg_path = os.path.join(current_dataset,im) 94 | # current_shadowimg = cv2.imread(current_shadowimg_path) 95 | # store_shadowimg_path = os.path.join(store_path_shadowimage,im) 96 | # # cv2.imwrite(store_shadowimg_path, current_shadowimg) 97 | 98 | root = '/media/user/05e85ab6-e43e-4f2a-bc7b-fad887cfe312/ShadowGeneration/HYShadowGeneration/VISUALIZATION/BTscores/' 99 | folders = [ 'pix2pix', 'pix2pixresidual', 'shadowgan', 'maskshadowgan', 'arshadowgan', 'ours'] 100 | foreground_mask_folder = ['foregroundmask'] 101 | 102 | obtain_tuple(root, folders, foreground_mask_folder) -------------------------------------------------------------------------------- /data_processing/Vis_Desoba_Dataset.py: -------------------------------------------------------------------------------- 1 | import argparse, os 2 | from PIL import Image 3 | from data import CreateDataLoader 4 | import util 5 | import numpy as np 6 | 7 | def get_parser(): 8 | parser = argparse.ArgumentParser() 9 | parser.add_argument('--dataroot',default='/media/user/data/ShadowGeneration/InstanceShadowDetection/SOBA/SOBAFinalSplit/', 10 | help='path to images (should have subfolders trainA, trainB, valA, valB, etc)') 11 | parser.add_argument('--shadowimg_path', default='/media/user/data/ShadowGeneration/InstanceShadowDetection/DESOBA/ShadowImage',type=str) 12 | parser.add_argument('--shadowfree_path', default='/media/user/data/ShadowGeneration/InstanceShadowDetection/DESOBA/DeshadowedImage',type=str) 13 | parser.add_argument('--instance_path', default='/media/user/data/ShadowGeneration/InstanceShadowDetection/DESOBA/InstanceMask',type=str) 14 | parser.add_argument('--shadow_path', default='/media/user/data/ShadowGeneration/InstanceShadowDetection/DESOBA/ShadowMask',type=str) 15 | parser.add_argument('--output_path', default='/media/user/data/ShadowGeneration/InstanceShadowDetection/DESOBA/Visualization_Examples',type=str) 16 | parser.add_argument('--loadSize', type=int, default=256, help='scale images to this size') 17 | parser.add_argument('--dataset_mode', type=str, default='DesobaSyntheticImageGeneration') 18 | parser.add_argument('--batch_size', type=int, default=1, help='scale images to this size') 19 | parser.add_argument('--serial_batches', action='store_true', help='if true, takes images in order to make batches, otherwise takes them randomly') 20 | parser.add_argument('--num_threads', default=4, type=int, help='# threads for loading data') 21 | parser.add_argument('--max_dataset_size', type=int, default=float("inf"), help='Maximum number of samples allowed per dataset. If the dataset directory contains more than max_dataset_size, only a subset is loaded.') 22 | 23 | return parser 24 | 25 | 26 | if __name__ == "__main__": 27 | # Visualizing examples 28 | parser = get_parser() 29 | opt, _ = parser.parse_known_args() 30 | opt.isTrain = False 31 | data_loader = CreateDataLoader(opt) 32 | dataset = data_loader.load_data() 33 | dataset_size = len(data_loader) 34 | loadSize = opt.loadSize 35 | 36 | for i, data in enumerate(dataset): 37 | row = [] 38 | new_img = Image.new('RGB', (loadSize*6, loadSize), 255) 39 | synthetic_composite_img = util.tensor2im(data['Synth_img']) 40 | shadow_img = util.tensor2im(data['Shadow_img']) 41 | fg_instance_mask = util.tensor2im(data['fg_instance_mask']) 42 | fg_shadow_mask = util.tensor2im(data['fg_shadow_mask']) 43 | bg_instance_mask = util.tensor2im(data['bg_instance_mask']) 44 | bg_shadow_mask = util.tensor2im(data['bg_shadow_mask']) 45 | 46 | row.append(synthetic_composite_img) 47 | row.append(shadow_img) 48 | row.append(fg_instance_mask) 49 | row.append(fg_shadow_mask) 50 | row.append(bg_instance_mask) 51 | row.append(bg_shadow_mask) 52 | row = tuple(row) 53 | row = np.hstack(row) 54 | 55 | if not os.path.exists(opt.output_path): 56 | os.makedirs(opt.output_path) 57 | output_name = '{}.png'.format(i) 58 | save_path = '%s/%s' % (opt.output_path, output_name) 59 | util.save_image(row, save_path) 60 | -------------------------------------------------------------------------------- /data_processing/Visualization_Examples/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/Visualization_Examples/12.png -------------------------------------------------------------------------------- /data_processing/Visualization_Examples/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/Visualization_Examples/14.png -------------------------------------------------------------------------------- /data_processing/Visualization_Examples/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/Visualization_Examples/5.png -------------------------------------------------------------------------------- /data_processing/Visualization_Examples/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/Visualization_Examples/6.png -------------------------------------------------------------------------------- /data_processing/Visualization_Examples/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/Visualization_Examples/7.png -------------------------------------------------------------------------------- /data_processing/Visualization_Examples/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/Visualization_Examples/8.png -------------------------------------------------------------------------------- /data_processing/Visualization_Examples/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/Visualization_Examples/9.png -------------------------------------------------------------------------------- /data_processing/__pycache__/util.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/__pycache__/util.cpython-36.pyc -------------------------------------------------------------------------------- /data_processing/compute_params.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | # In[3]: 5 | 6 | 7 | import cv2 8 | import os 9 | from os import listdir 10 | from os.path import isfile, join 11 | from PIL import Image as Image 12 | import numpy as np 13 | 14 | from scipy.optimize import curve_fit 15 | 16 | def relit(x, a, b): 17 | return (a * x.astype(np.float)/255 + b)*255 18 | 19 | 20 | 21 | from matplotlib import pyplot as plt 22 | def plshow(im,title='MINE'): 23 | if len(im.shape)>2: 24 | # plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB)) 25 | plt.imshow(im) 26 | else: 27 | plt.imshow(im,cmap='gray') 28 | plt.title(title) 29 | plt.rcParams["figure.figsize"] = (80,12) 30 | plt.show() 31 | 32 | 33 | ###### ISTD dataset ##### 34 | # sd_path = '../dataset/ISTD_Dataset/train/train_A' 35 | # mask_path = '../dataset/ISTD_Dataset/train/train_B' 36 | # sdfree_path = '../dataset/ISTD_Dataset/train/train_C' 37 | # out = '../dataset/ISTD_Dataset/train/train_params/' 38 | ###### ISTD dataset ##### 39 | 40 | sd_path = '../dataset/ISTD_Dataset/test/test_A' 41 | mask_path = '../dataset/ISTD_Dataset/test/test_B' 42 | sdfree_path = '../dataset/ISTD_Dataset/train/train_C' 43 | out = '../dataset/ISTD_Dataset/test/test_params/' 44 | 45 | 46 | 47 | 48 | 49 | if not os.path.exists(out): 50 | os.makedirs(out) 51 | 52 | im_list = [f for f in listdir(sd_path) if isfile(join(sd_path, f)) and f.endswith('png')] 53 | print(len(im_list),im_list[0]) 54 | kernel = np.ones((5,5),np.uint8) 55 | 56 | 57 | def im_relit(Rpopt,Gpopt,Bpopt,dump): 58 | #some weird bugs with python 59 | sdim = dump.copy() 60 | sdim.setflags(write=1) 61 | sdim = sdim.astype(np.float) 62 | sdim[:,:,0] = (sdim[:,:,0]/255) * Rpopt[0] + Rpopt[1] 63 | sdim[:,:,1] = (sdim[:,:,1]/255) * Gpopt[0] + Gpopt[1] 64 | sdim[:,:,2] = (sdim[:,:,2]/255) * Bpopt[0] + Bpopt[1] 65 | sdim = sdim*255 66 | # print(np.amin(sdim),np.amax(sdim)) 67 | return sdim 68 | 69 | errors= [] 70 | # for im in im_list[10:20]: 71 | for im in im_list[:]: 72 | sd = np.asarray(Image.open(join(sd_path,im))) 73 | mean_sdim = np.mean(sd,axis=2) 74 | 75 | mask_ori = np.asarray(Image.open(join(mask_path,im))) 76 | mask = cv2.erode(mask_ori ,kernel,iterations = 2) 77 | 78 | 79 | sdfree = np.asarray(Image.open(join(sdfree_path,im))) 80 | 81 | ### create fake files 82 | # sdfree = 2* np.asarray(Image.open(join(sd_path,im))) 83 | 84 | 85 | mean_sdfreeim = np.mean(sdfree,axis=2) 86 | 87 | #pixels for regression funtion 88 | i, j = np.where(np.logical_and(np.logical_and(np.logical_and(mask>=1,mean_sdim>5),mean_sdfreeim<230),np.abs(mean_sdim-mean_sdfreeim)>10)) 89 | 90 | source = sd*0 91 | source[tuple([i,j])] = sd[tuple([i,j])] 92 | target = sd*0 93 | target[tuple([i,j])]= sdfree[tuple([i,j])] 94 | 95 | R_s = source[:,:,0][tuple([i,j])] 96 | G_s = source[:,:,1][tuple([i,j])] 97 | B_s = source[:,:,2][tuple([i,j])] 98 | 99 | R_t = target[:,:,0][tuple([i,j])] 100 | G_t = target[:,:,1][tuple([i,j])] 101 | B_t = target[:,:,2][tuple([i,j])] 102 | 103 | c_bounds = [[1,-0.1],[10,0.5]] 104 | 105 | 106 | Rpopt, pcov = curve_fit(relit, R_s, R_t,bounds=c_bounds) 107 | Gpopt, pcov = curve_fit(relit, G_s, G_t,bounds=c_bounds) 108 | Bpopt, pcov = curve_fit(relit, B_s, B_t,bounds=c_bounds) 109 | 110 | 111 | relitim = im_relit(Rpopt,Gpopt,Bpopt,sd) 112 | 113 | final = sd.copy() 114 | final[tuple([i,j])] = relitim[tuple([i,j])] 115 | final[final>255] =255 116 | final[final<0] = 0 117 | 118 | # plshow(final) 119 | 120 | error = np.mean(np.abs(relitim[tuple([i,j])].astype(np.float) - sdfree[tuple([i,j])]).astype(np.float)) 121 | print(error,Rpopt,Gpopt,Bpopt) 122 | f = open(join(out,im+'.txt'),"a") 123 | f.write("%f %f %f %f %f %f"%(Rpopt[1],Rpopt[0],Gpopt[1],Gpopt[0],Bpopt[1],Bpopt[0])) 124 | f.close() 125 | 126 | # print(error) 127 | errors.append(error) 128 | 129 | 130 | print(np.mean(errors)) 131 | #no bound - 8.55 132 | #### y_bound ###error 133 | # 0.5 8.86 134 | # 0.1 15.692271753155671 135 | # 0.25 10.830443545867785 136 | # 1 8.86 137 | 138 | 139 | # In[ ]: 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /data_processing/compute_params_DESOBA.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | import cv2 5 | import os 6 | from os import listdir 7 | from os.path import isfile, join 8 | from PIL import Image as Image 9 | import numpy as np 10 | 11 | from scipy.optimize import curve_fit 12 | 13 | def relit(x, a, b): 14 | return (a * x.astype(np.float)/255 + b)*255 15 | 16 | 17 | 18 | from matplotlib import pyplot as plt 19 | def plshow(im,title='MINE'): 20 | if len(im.shape)>2: 21 | # plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB)) 22 | plt.imshow(im) 23 | else: 24 | plt.imshow(im,cmap='gray') 25 | plt.title(title) 26 | plt.rcParams["figure.figsize"] = (80,12) 27 | plt.show() 28 | 29 | 30 | sd_path = '../DESOBA_DATASET/ShadowImage/' 31 | mask_path = '../DESOBA_DATASET/ShadowMask/' 32 | sdfree_path = '../DESOBA_DATASET/DeshadowedImage/' 33 | out = '../DESOBA_DATASET/SOBA_params/' 34 | 35 | 36 | 37 | if not os.path.exists(out): 38 | os.makedirs(out) 39 | 40 | im_list = [f for f in listdir(mask_path) if isfile(join(sd_path, f)) and f.endswith('')] 41 | kernel = np.ones((5,5),np.uint8) 42 | 43 | 44 | def im_relit(Rpopt,Gpopt,Bpopt,dump): 45 | #some weird bugs with python 46 | sdim = dump.copy() 47 | sdim.setflags(write=1) 48 | sdim = sdim.astype(np.float) 49 | sdim[:,:,0] = (sdim[:,:,0]/255) * Rpopt[0] + Rpopt[1] 50 | sdim[:,:,1] = (sdim[:,:,1]/255) * Gpopt[0] + Gpopt[1] 51 | sdim[:,:,2] = (sdim[:,:,2]/255) * Bpopt[0] + Bpopt[1] 52 | sdim = sdim*255 53 | # print(np.amin(sdim),np.amax(sdim)) 54 | return sdim 55 | 56 | errors= [] 57 | # for im in im_list[10:20]: 58 | for im in im_list[:]: 59 | sd = np.asarray(Image.open(join(sd_path,im))) 60 | mean_sdim = np.mean(sd,axis=2) 61 | 62 | #transfer color shadow mask into grey mask 63 | mask_ori = np.asarray(Image.open(join(mask_path,im))) 64 | mask_ori = np.array(mask_ori) 65 | mask_ori[mask_ori>1] = 255 66 | mask_ori = np.asarray(mask_ori) 67 | mask_ori = cv2.cvtColor(mask_ori,cv2.COLOR_BGR2GRAY) 68 | mask = cv2.erode(mask_ori ,kernel,iterations = 2) 69 | 70 | sdfree = np.asarray(Image.open(join(sdfree_path,im))) 71 | 72 | 73 | 74 | mean_sdfreeim = np.mean(sdfree,axis=2) 75 | 76 | #pixels for regression funtion 77 | i, j = np.where(np.logical_and(np.logical_and(np.logical_and(mask>=1,mean_sdim>5),mean_sdfreeim<230),np.abs(mean_sdim-mean_sdfreeim)>10)) 78 | 79 | source = sd*0 80 | source[tuple([i,j])] = sd[tuple([i,j])] 81 | target = sd*0 82 | target[tuple([i,j])]= sdfree[tuple([i,j])] 83 | 84 | R_s = source[:,:,0][tuple([i,j])] 85 | G_s = source[:,:,1][tuple([i,j])] 86 | B_s = source[:,:,2][tuple([i,j])] 87 | 88 | R_t = target[:,:,0][tuple([i,j])] 89 | G_t = target[:,:,1][tuple([i,j])] 90 | B_t = target[:,:,2][tuple([i,j])] 91 | 92 | c_bounds = [[1,-0.1],[10,0.5]] 93 | 94 | 95 | 96 | Rpopt, pcov = curve_fit(relit, R_s, R_t,bounds=c_bounds) 97 | Gpopt, pcov = curve_fit(relit, G_s, G_t,bounds=c_bounds) 98 | Bpopt, pcov = curve_fit(relit, B_s, B_t,bounds=c_bounds) 99 | 100 | 101 | 102 | 103 | 104 | # relitim = im_relit(Rpopt,Gpopt,Bpopt,sd) 105 | # final = sd.copy() 106 | # final[tuple([i,j])] = relitim[tuple([i,j])] 107 | # final[final>255] =255 108 | # final[final<0] = 0 109 | 110 | 111 | 112 | # error = np.mean(np.abs(relitim[tuple([i,j])].astype(np.float) - sdfree[tuple([i,j])]).astype(np.float)) 113 | f = open(join(out,im+'.txt'),"a") 114 | f.write("%f %f %f %f %f %f"%(Rpopt[1],Rpopt[0],Gpopt[1],Gpopt[0],Bpopt[1],Bpopt[0])) 115 | f.close() 116 | print('shadow params of image {} are stored in {}'.format(im,out)) 117 | # errors.append(error) 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /data_processing/data/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import torch.utils.data 3 | from data.base_data_loader import BaseDataLoader 4 | from data.base_dataset import BaseDataset 5 | 6 | 7 | def find_dataset_using_name(dataset_name): 8 | # Given the option --dataset_mode [datasetname], 9 | # the file "data/datasetname_dataset.py" 10 | # will be imported. 11 | dataset_filename = "data." + dataset_name + "_dataset" 12 | datasetlib = importlib.import_module(dataset_filename) 13 | 14 | # In the file, the class called DatasetNameDataset() will 15 | # be instantiated. It has to be a subclass of BaseDataset, 16 | # and it is case-insensitive. 17 | dataset = None 18 | target_dataset_name = dataset_name.replace('_', '') + 'dataset' 19 | for name, cls in datasetlib.__dict__.items(): 20 | if name.lower() == target_dataset_name.lower() \ 21 | and issubclass(cls, BaseDataset): 22 | dataset = cls 23 | 24 | if dataset is None: 25 | print("In %s.py, there should be a subclass of BaseDataset with class name that matches %s in lowercase." % (dataset_filename, target_dataset_name)) 26 | exit(0) 27 | 28 | return dataset 29 | 30 | 31 | def get_option_setter(dataset_name): 32 | dataset_class = find_dataset_using_name(dataset_name) 33 | return dataset_class.modify_commandline_options 34 | 35 | 36 | def create_dataset(opt): 37 | dataset = find_dataset_using_name(opt.dataset_mode) 38 | instance = dataset() 39 | instance.initialize(opt) 40 | print("dataset [%s] was created" % (instance.name())) 41 | return instance 42 | 43 | 44 | def CreateDataLoader(opt): 45 | data_loader = CustomDatasetDataLoader() 46 | data_loader.initialize(opt) 47 | return data_loader 48 | 49 | 50 | # Wrapper class of Dataset class that performs 51 | # multi-threaded data loading 52 | class CustomDatasetDataLoader(BaseDataLoader): 53 | def name(self): 54 | return 'CustomDatasetDataLoader' 55 | 56 | def initialize(self, opt): 57 | BaseDataLoader.initialize(self, opt) 58 | self.create_dataset = create_dataset 59 | self.dataset = self.create_dataset(opt) 60 | self.dataloader = torch.utils.data.DataLoader( 61 | self.dataset, 62 | batch_size=opt.batch_size, 63 | shuffle=not opt.serial_batches, 64 | num_workers=int(opt.num_threads)) 65 | 66 | def load_data(self): 67 | return self 68 | 69 | def __len__(self): 70 | return min(len(self.dataset), self.opt.max_dataset_size) 71 | 72 | def __iter__(self): 73 | for i, data in enumerate(self.dataloader): 74 | if i * self.opt.batch_size >= self.opt.max_dataset_size: 75 | break 76 | yield data 77 | -------------------------------------------------------------------------------- /data_processing/data/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__init__.pyc -------------------------------------------------------------------------------- /data_processing/data/__pycache__/DesobaSyntheticImageGeneration_dataset.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__pycache__/DesobaSyntheticImageGeneration_dataset.cpython-36.pyc -------------------------------------------------------------------------------- /data_processing/data/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /data_processing/data/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /data_processing/data/__pycache__/base_data_loader.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__pycache__/base_data_loader.cpython-36.pyc -------------------------------------------------------------------------------- /data_processing/data/__pycache__/base_data_loader.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__pycache__/base_data_loader.cpython-38.pyc -------------------------------------------------------------------------------- /data_processing/data/__pycache__/base_dataset.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__pycache__/base_dataset.cpython-36.pyc -------------------------------------------------------------------------------- /data_processing/data/__pycache__/base_dataset.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/__pycache__/base_dataset.cpython-38.pyc -------------------------------------------------------------------------------- /data_processing/data/base_data_loader.py: -------------------------------------------------------------------------------- 1 | class BaseDataLoader(): 2 | def __init__(self): 3 | pass 4 | 5 | def initialize(self, opt): 6 | self.opt = opt 7 | pass 8 | 9 | def load_data(): 10 | return None 11 | -------------------------------------------------------------------------------- /data_processing/data/base_data_loader.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/base_data_loader.pyc -------------------------------------------------------------------------------- /data_processing/data/base_dataset.py: -------------------------------------------------------------------------------- 1 | import torch.utils.data as data 2 | from PIL import Image 3 | import torchvision.transforms as transforms 4 | 5 | 6 | class BaseDataset(data.Dataset): 7 | def __init__(self): 8 | super(BaseDataset, self).__init__() 9 | 10 | def name(self): 11 | return 'BaseDataset' 12 | 13 | @staticmethod 14 | def modify_commandline_options(parser, is_train): 15 | return parser 16 | 17 | def initialize(self, opt): 18 | pass 19 | 20 | def __len__(self): 21 | return 0 22 | 23 | 24 | def get_transform(opt): 25 | transform_list = [] 26 | if opt.resize_or_crop == 'resize_and_crop': 27 | osize = [opt.loadSize, opt.loadSize] 28 | transform_list.append(transforms.Resize(osize, Image.BICUBIC)) 29 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 30 | elif opt.resize_or_crop == 'resize': 31 | osize = [opt.loadSize, opt.loadSize] 32 | transform_list.append(transforms.Resize(osize, Image.BICUBIC)) 33 | elif opt.resize_or_crop == 'crop': 34 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 35 | elif opt.resize_or_crop == 'scale_width': 36 | transform_list.append(transforms.Lambda( 37 | lambda img: __scale_width(img, opt.fineSize))) 38 | elif opt.resize_or_crop == 'scale_width_and_crop': 39 | transform_list.append(transforms.Lambda( 40 | lambda img: __scale_width(img, opt.loadSize))) 41 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 42 | elif opt.resize_or_crop == 'none': 43 | transform_list.append(transforms.Lambda( 44 | lambda img: __adjust(img))) 45 | else: 46 | raise ValueError('--resize_or_crop %s is not a valid option.' % opt.resize_or_crop) 47 | 48 | if opt.isTrain and not opt.no_flip: 49 | transform_list.append(transforms.RandomHorizontalFlip()) 50 | 51 | transform_list += [transforms.ToTensor(), 52 | transforms.Normalize((0.5, 0.5, 0.5), 53 | (0.5, 0.5, 0.5))] 54 | return transforms.Compose(transform_list) 55 | 56 | 57 | # just modify the width and height to be multiple of 4 58 | def __adjust(img): 59 | ow, oh = img.size 60 | 61 | # the size needs to be a multiple of this number, 62 | # because going through generator network may change img size 63 | # and eventually cause size mismatch error 64 | mult = 4 65 | if ow % mult == 0 and oh % mult == 0: 66 | return img 67 | w = (ow - 1) // mult 68 | w = (w + 1) * mult 69 | h = (oh - 1) // mult 70 | h = (h + 1) * mult 71 | 72 | if ow != w or oh != h: 73 | __print_size_warning(ow, oh, w, h) 74 | 75 | return img.resize((w, h), Image.BICUBIC) 76 | 77 | 78 | 79 | 80 | def __scale_width(img, target_width): 81 | ow, oh = img.size 82 | 83 | # the size needs to be a multiple of this number, 84 | # because going through generator network may change img size 85 | # and eventually cause size mismatch error 86 | mult = 4 87 | assert target_width % mult == 0, "the target width needs to be multiple of %d." % mult 88 | if (ow == target_width and oh % mult == 0): 89 | return img 90 | w = target_width 91 | target_height = int(target_width * oh / ow) 92 | m = (target_height - 1) // mult 93 | h = (m + 1) * mult 94 | 95 | if target_height != h: 96 | __print_size_warning(target_width, target_height, w, h) 97 | 98 | return img.resize((w, h), Image.BICUBIC) 99 | 100 | 101 | def __print_size_warning(ow, oh, w, h): 102 | if not hasattr(__print_size_warning, 'has_printed'): 103 | print("The image size needs to be a multiple of 4. " 104 | "The loaded image size was (%d, %d), so it was adjusted to " 105 | "(%d, %d). This adjustment will be done to all images " 106 | "whose sizes are not multiples of 4" % (ow, oh, w, h)) 107 | __print_size_warning.has_printed = True 108 | -------------------------------------------------------------------------------- /data_processing/data/base_dataset.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/data_processing/data/base_dataset.pyc -------------------------------------------------------------------------------- /data_processing/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import torch 3 | import numpy as np 4 | from PIL import Image 5 | import os 6 | 7 | 8 | def sdmkdir(dir_name): 9 | if not os.path.exists(dir_name): 10 | os.mkdir(dir_name) 11 | # Converts a Tensor into an image array (numpy) 12 | # |imtype|: the desired type of the converted numpy array 13 | def tensor2cvim(input_image, imtype=np.uint8,scale=None): 14 | # print('hhhhh',np.shape(input_image)) 15 | 16 | if len(input_image.shape)<3: return None 17 | # if scale>0 and input_image.size()[1]==3: 18 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 19 | 20 | if isinstance(input_image, torch.Tensor): 21 | image_tensor = input_image.data 22 | else: 23 | return input_image 24 | image_numpy = image_tensor.data[0].cpu().float().numpy() 25 | # if image_numpy.shape[0] == 1: 26 | # image_numpy = np.tile(image_numpy, (3, 1, 1)) 27 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 28 | image_numpy[image_numpy<0] = 0 29 | image_numpy[image_numpy>255] = 255 30 | return image_numpy.astype(imtype) 31 | 32 | 33 | def tensor2imonechannel(input_image, imtype=np.uint8, scale=None): 34 | if len(input_image.shape) < 3: return None 35 | # if scale>0 and input_image.size()[1]==3: 36 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 37 | 38 | if isinstance(input_image, torch.Tensor): 39 | image_tensor = input_image.data 40 | else: 41 | return input_image 42 | image_numpy = image_tensor.data[0].cpu().float().numpy() 43 | # if image_numpy.shape[0] == 1: 44 | # image_numpy = np.tile(image_numpy, (3, 1, 1)) 45 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 46 | # image_numpy[image_numpy < 0] = 0 47 | # image_numpy[image_numpy > 255] = 255 48 | # return image_numpy.astype(imtype) 49 | return image_numpy 50 | 51 | 52 | 53 | def tensor2im(input_image, imtype=np.uint8,scale=None): 54 | 55 | if len(input_image.shape)<3: return None 56 | # if scale>0 and input_image.size()[1]==3: 57 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 58 | 59 | if isinstance(input_image, torch.Tensor): 60 | image_tensor = input_image.data 61 | else: 62 | return input_image 63 | image_numpy = image_tensor.data[0].cpu().float().numpy() 64 | if image_numpy.shape[0] == 1: 65 | image_numpy = np.tile(image_numpy, (3, 1, 1)) 66 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 67 | image_numpy[image_numpy<0] = 0 68 | image_numpy[image_numpy>255] = 255 69 | return image_numpy.astype(imtype) 70 | 71 | def tensor2im_logc(image_tensor, imtype=np.uint8,scale=255): 72 | image_numpy = image_tensor.data[0].cpu().double().numpy() 73 | image_numpy = np.transpose(image_numpy,(1,2,0)) 74 | image_numpy = (image_numpy+1) /2.0 75 | image_numpy = image_numpy * (np.log(scale+1)) 76 | image_numpy = np.exp(image_numpy) -1 77 | image_numpy = image_numpy.astype(np.uint8) 78 | 79 | return image_numpy.astype(np.uint8) 80 | 81 | 82 | def diagnose_network(net, name='network'): 83 | mean = 0.0 84 | count = 0 85 | for param in net.parameters(): 86 | if param.grad is not None: 87 | mean += torch.mean(torch.abs(param.grad.data)) 88 | count += 1 89 | if count > 0: 90 | mean = mean / count 91 | print(name) 92 | print(mean) 93 | 94 | 95 | def save_image(image_numpy, image_path): 96 | image_pil = Image.fromarray(image_numpy) 97 | image_pil.save(image_path) 98 | 99 | 100 | def print_numpy(x, val=True, shp=False): 101 | x = x.astype(np.float64) 102 | if shp: 103 | print('shape,', x.shape) 104 | if val: 105 | x = x.flatten() 106 | print('mean = %3.3f, min = %3.3f, max = %3.3f, median = %3.3f, std=%3.3f' % ( 107 | np.mean(x), np.min(x), np.max(x), np.median(x), np.std(x))) 108 | 109 | 110 | def mkdirs(paths): 111 | if isinstance(paths, list) and not isinstance(paths, str): 112 | for path in paths: 113 | mkdir(path) 114 | else: 115 | mkdir(paths) 116 | 117 | 118 | def mkdir(path): 119 | if not os.path.exists(path): 120 | os.makedirs(path) 121 | 122 | 123 | def transparent_png(img,fg_mask): 124 | img = img.convert('RGBA') 125 | W, H = img.size 126 | # fg_mask = np.array(fg_mask) 127 | for h in range(H): ###循环图片的每个像素点 128 | for l in range(W): 129 | if fg_mask.getpixel((l,h)) == 0: 130 | pixels = img.getpixel((l,h)) 131 | if h==0 and l==0: 132 | print('old',pixels) 133 | pixels = pixels[:-1] + (80,) 134 | if h==0 and l==0: 135 | print('new',tuple(pixels)) 136 | img.putpixel((l,h),pixels) 137 | img.save('/media/user/data/ShadowGeneration/HYShadowGeneration/SOBAMixFGAllData/Model_SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/SelfAttention_Illumination1_Residual0_ConditionD1_Llight0_Lpara1_Lshadowrecons10_Limagerecons10_Lgan0.1_Lstn0_Nwarp0_Lref1_Ltv0_Lganmask0/SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/web/images/0.png') 138 | # img = Image.open('/media/user/data/ShadowGeneration/HYShadowGeneration/SOBAMixFGAllData/Model_SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/SelfAttention_Illumination1_Residual0_ConditionD1_Llight0_Lpara1_Lshadowrecons10_Limagerecons10_Lgan0.1_Lstn0_Nwarp0_Lref1_Ltv0_Lganmask0/SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/web/images/0.png') 139 | # print(img.size()) 140 | return img -------------------------------------------------------------------------------- /requirement.txt: -------------------------------------------------------------------------------- 1 | absl-py==0.12.0 2 | aiohttp==3.7.4.post0 3 | albumentations==0.5.2 4 | altair==4.1.0 5 | appdirs==1.4.4 6 | argon2-cffi==20.1.0 7 | astor==0.8.1 8 | async-generator==1.10 9 | async-timeout==3.0.1 10 | attrs==21.2.0 11 | backcall==0.2.0 12 | base58==2.1.0 13 | bleach==3.3.0 14 | blinker==1.4 15 | cachetools==4.2.2 16 | certifi==2021.5.30 17 | cffi==1.14.5 18 | chardet==4.0.0 19 | click==7.1.2 20 | cloudpickle==0.4.0 21 | cycler==0.10.0 22 | cytoolz==0.8.2 23 | dataclasses==0.7 24 | decorator==5.0.9 25 | defusedxml==0.7.1 26 | detectron2==0.1 27 | distlib==0.3.2 28 | dnf==0.0.1 29 | docopt==0.6.2 30 | dominate==2.4.0 31 | entrypoints==0.3 32 | filelock==3.0.12 33 | fsspec==2021.4.0 34 | future==0.18.2 35 | fvcore==0.1.2.post20201111 36 | gitdb==4.0.7 37 | GitPython==3.1.17 38 | google-auth==1.29.0 39 | google-auth-oauthlib==0.4.4 40 | grpcio==1.37.0 41 | idna==2.10 42 | idna-ssl==1.1.0 43 | imgaug==0.4.0 44 | importlib-metadata==4.4.0 45 | importlib-resources==5.1.4 46 | ipykernel==5.5.5 47 | ipython==7.16.1 48 | ipython-genutils==0.2.0 49 | ipywidgets==7.6.3 50 | jedi==0.18.0 51 | Jinja2==3.0.1 52 | joblib==1.0.0 53 | jsonpatch==1.26 54 | jsonpointer==2.0 55 | jsonschema==3.2.0 56 | jupyter-client==6.1.12 57 | jupyter-core==4.7.1 58 | jupyterlab-pygments==0.1.2 59 | jupyterlab-widgets==1.0.0 60 | Markdown==3.3.4 61 | MarkupSafe==2.0.1 62 | mistune==0.8.4 63 | mkl-fft==1.2.0 64 | mkl-random==1.1.1 65 | mkl-service==2.3.0 66 | multidict==5.1.0 67 | nbclient==0.5.3 68 | nbconvert==6.0.7 69 | nbformat==5.1.3 70 | nest-asyncio==1.5.1 71 | networkx==2.1 72 | notebook==6.4.0 73 | numpy==1.19.5 74 | oauthlib==3.1.0 75 | olefile==0.44 76 | omegaconf==2.0.6 77 | opencv-python==4.4.0.46 78 | opencv-python-headless==4.5.1.48 79 | packaging==20.9 80 | pandas==1.1.5 81 | pandocfilters==1.4.3 82 | parso==0.8.2 83 | pexpect==4.8.0 84 | pickleshare==0.7.5 85 | Pillow==8.2.0 86 | portalocker==2.0.0 87 | prometheus-client==0.11.0 88 | prompt-toolkit==3.0.18 89 | protobuf==3.17.1 90 | ptyprocess==0.7.0 91 | pyarrow==4.0.1 92 | pyasn1==0.4.8 93 | pyasn1-modules==0.2.8 94 | pycparser==2.20 95 | pydeck==0.6.2 96 | pydot==1.4.1 97 | Pygments==2.9.0 98 | pyparsing==2.4.7 99 | pyrsistent==0.17.3 100 | python-dateutil==2.8.1 101 | pythondialog==3.5.1 102 | pytorch-lightning==1.2.10 103 | pytz==2021.1 104 | PyYAML==5.4.1 105 | pyzmq==22.1.0 106 | requests==2.25.1 107 | requests-oauthlib==1.3.0 108 | rsa==4.7.2 109 | scikit-image==0.17.2 110 | scikit-learn==0.23.2 111 | scipy==1.3.2 112 | Send2Trash==1.5.0 113 | Shapely==1.7.1 114 | six==1.16.0 115 | sklearn==0.0 116 | smmap==4.0.0 117 | streamlit==0.82.0 118 | tabulate==0.8.7 119 | tensorboard==2.4.1 120 | tensorboard-plugin-wit==1.8.0 121 | termcolor==1.1.0 122 | terminado==0.10.0 123 | test-tube==0.7.5 124 | testpath==0.5.0 125 | threadpoolctl==2.1.0 126 | tifffile==2020.10.1 127 | toml==0.10.2 128 | toolz==0.11.1 129 | torch==1.6.0 130 | torchaudio==0.6.0a0+f17ae39 131 | torchfile==0.1.0 132 | torchmetrics==0.2.0 133 | torchvision==0.7.0 134 | tornado==6.1 135 | tqdm==4.60.0 136 | traitlets==4.3.3 137 | typing==3.6.2 138 | typing-extensions==3.10.0.0 139 | tzlocal==2.1 140 | urllib3==1.26.5 141 | validators==0.18.2 142 | virtualenv==20.4.7 143 | visdom==0.1.8 144 | watchdog==2.1.2 145 | wcwidth==0.2.5 146 | webencodings==0.5.1 147 | websocket-client==0.57.0 148 | Werkzeug==1.0.1 149 | widgetsnbextension==3.5.1 150 | yacs==0.1.8 151 | yarl==1.6.3 152 | zipp==3.4.1 153 | -------------------------------------------------------------------------------- /src/data/DesobaSyntheticImageGeneration_dataset.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/data/DesobaSyntheticImageGeneration_dataset.pyc -------------------------------------------------------------------------------- /src/data/ShadowGenerationDatasetInference2_dataset.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | import torchvision.transforms as transforms 3 | from data.base_dataset import BaseDataset, get_transform 4 | from data.image_folder import make_dataset 5 | from PIL import Image,ImageChops 6 | from PIL import ImageFilter 7 | import torch 8 | from pdb import set_trace as st 9 | import random 10 | import numpy as np 11 | import cv2 12 | import time 13 | import torchvision.transforms.functional as TF 14 | import torch.nn.functional as F 15 | import itertools 16 | 17 | 18 | ######'dir_A': shadowimage 19 | ######'dir_B': shadowmask 20 | ######'dir_C': shadowfree 21 | ######'dir_param':illumination parameter 22 | ######'dir_light': light direction 23 | ######'dir_instance':object mask 24 | 25 | def resize_pos(bbox, src_size,tar_size): 26 | x1,y1,x2,y2 = bbox 27 | w1=src_size[0] 28 | h1=src_size[1] 29 | w2=tar_size[0] 30 | h2=tar_size[1] 31 | y11= int((h2/h1)*y1) 32 | x11=int((w2/w1)*x1) 33 | y22=int((h2/h1)*y2) 34 | x22=int((w2/w1)*x2) 35 | return [x11, y11, x22, y22] 36 | 37 | def mask_to_bbox(mask, specific_pixels, new_w, new_h): 38 | #[w,h,c] 39 | w,h = np.shape(mask)[:2] 40 | valid_index = np.argwhere(mask==specific_pixels)[:,:2] 41 | if np.shape(valid_index)[0] < 1: 42 | x_left = 0 43 | x_right = 0 44 | y_bottom = 0 45 | y_top = 0 46 | else: 47 | x_left = np.min(valid_index[:,0]) 48 | x_right = np.max(valid_index[:,0]) 49 | y_bottom = np.min(valid_index[:,1]) 50 | y_top = np.max(valid_index[:,1]) 51 | origin_box = [x_left, y_bottom, x_right, y_top] 52 | resized_box = resize_pos(origin_box, [w,h], [new_w, new_h]) 53 | return resized_box 54 | 55 | def bbox_to_mask(box,mask_plain): 56 | mask_plain[box[0]:box[2], box[1]:box[3]] = 255 57 | return mask_plain 58 | 59 | 60 | class ShadowGenerationDatasetInference2dataset(BaseDataset): 61 | def initialize(self, opt): 62 | self.opt = opt 63 | self.is_train = self.opt.isTrain 64 | self.root = opt.dataroot 65 | self.dir_shadowfree = opt.shadowfree_path #os.path.join(opt.dataroot, opt.phase + 'C') 66 | self.dir_fg_instance = opt.instance_path 67 | 68 | 69 | self.birdy_deshadoweds = [] 70 | self.birdy_fg_instances = [] 71 | 72 | 73 | 74 | 75 | # for root,_,fnames in sorted(os.walk(self.dir_shadowimg)): 76 | for root,_,fnames in sorted(os.walk(self.dir_shadowfree)): 77 | fname_int = [int(fname.split('.')[0]) for fname in fnames] 78 | for name in sorted(fname_int,key=int): 79 | fname = str(name) + '.png' 80 | if fname.endswith('.png'): 81 | X=dict() 82 | X['shadowfree_path'] = os.path.join(self.dir_shadowfree,fname) 83 | X['fginstance_path'] = os.path.join(self.dir_fg_instance,fname) 84 | 85 | 86 | shadowfree = Image.open(X['shadowfree_path']).convert('RGB').resize((self.opt.loadSize, self.opt.loadSize),Image.NEAREST) 87 | instance = Image.open(X['fginstance_path']).convert('L').resize((self.opt.loadSize, self.opt.loadSize),Image.NEAREST) 88 | 89 | self.birdy_deshadoweds.append(shadowfree) 90 | self.birdy_fg_instances.append(instance) 91 | 92 | 93 | self.data_size = len(self.birdy_deshadoweds) 94 | print('datasize', self.data_size) 95 | 96 | transform_list = [transforms.ToTensor(), 97 | transforms.Normalize(mean=opt.norm_mean, 98 | std = opt.norm_std)] 99 | 100 | self.transformA = transforms.Compose(transform_list) 101 | self.transformB = transforms.Compose([transforms.ToTensor()]) 102 | 103 | self.transformAugmentation = transforms.Compose([ 104 | transforms.Resize(int(self.opt.loadSize * 1.12), Image.BICUBIC), 105 | transforms.RandomCrop(self.opt.loadSize), 106 | transforms.RandomHorizontalFlip(), 107 | transforms.ToTensor()]) 108 | 109 | def __getitem__(self,index): 110 | birdy = {} 111 | birdy['A'] = self.birdy_deshadoweds[index] 112 | birdy['C'] = self.birdy_deshadoweds[index] 113 | birdy['instancemask'] = self.birdy_fg_instances[index] 114 | 115 | zeros_mask = Image.fromarray(np.uint8(np.array(np.zeros(np.shape(np.array(birdy['instancemask']))))), mode='L') 116 | #setting background instance mask and background shadow mask as zeros 117 | birdy['B'] = zeros_mask 118 | #setting foreground shadow mask as zeros 119 | birdy['bg_shadow'] = zeros_mask 120 | birdy['bg_instance'] = zeros_mask 121 | 122 | ow = birdy['A'].size[0] 123 | oh = birdy['A'].size[1] 124 | loadSize = self.opt.loadSize 125 | if self.opt.randomSize: 126 | loadSize = np.random.randint(loadSize + 1,loadSize * 1.3 ,1)[0] 127 | if self.opt.keep_ratio: 128 | if w>h: 129 | ratio = np.float(loadSize)/np.float(h) 130 | neww = np.int(w*ratio) 131 | newh = loadSize 132 | else: 133 | ratio = np.float(loadSize)/np.float(w) 134 | neww = loadSize 135 | newh = np.int(h*ratio) 136 | else: 137 | neww = loadSize 138 | newh = loadSize 139 | 140 | 141 | if not self.is_train: 142 | for k,im in birdy.items(): 143 | birdy[k] = im.resize((neww, newh),Image.NEAREST) 144 | 145 | if self.opt.no_flip and self.opt.no_crop and self.opt.no_rotate: 146 | for k,im in birdy.items(): 147 | birdy[k] = im.resize((neww, newh),Image.NEAREST) 148 | 149 | #### flip 150 | if not self.opt.no_flip: 151 | for i in ['A', 'B', 'C', 'instancemask', 'bg_shadow', 'bg_instance']: 152 | birdy[i] = birdy[i].transpose(Image.FLIP_LEFT_RIGHT) 153 | 154 | 155 | for k,im in birdy.items(): 156 | birdy[k] = self.transformB(im) 157 | 158 | 159 | for i in ['A', 'B', 'C', 'instancemask', 'bg_shadow', 'bg_instance']: 160 | if i in birdy: 161 | birdy[i] = (birdy[i] - 0.5)*2 162 | 163 | 164 | h = birdy['A'].size()[1] 165 | w = birdy['A'].size()[2] 166 | if not self.opt.no_crop: 167 | w_offset = random.randint(0, max(0, w - self.opt.fineSize - 1)) 168 | h_offset = random.randint(0, max(0, h - self.opt.fineSize - 1)) 169 | for k, im in birdy.items(): 170 | birdy[k] = im[:, h_offset:h_offset + self.opt.fineSize, w_offset:w_offset + self.opt.fineSize] 171 | birdy[k] = im.type(torch.FloatTensor) 172 | 173 | 174 | for k,im in birdy.items(): 175 | im = F.interpolate(im.unsqueeze(0), size = self.opt.loadSize) 176 | birdy[k] = im.squeeze(0) 177 | 178 | 179 | birdy['w'] = ow 180 | birdy['h'] = oh 181 | #setting param as zeros 182 | shadow_param=[0,0,0,0,0,0] 183 | birdy['param'] = torch.FloatTensor(np.array(shadow_param)) 184 | 185 | 186 | #if the shadow area is too small, let's not change anything: 187 | return birdy 188 | def __len__(self): 189 | return self.data_size 190 | 191 | def name(self): 192 | return 'ShadowGenerationDatasetInference2' 193 | -------------------------------------------------------------------------------- /src/data/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import torch.utils.data 3 | from data.base_data_loader import BaseDataLoader 4 | from data.base_dataset import BaseDataset 5 | 6 | 7 | def find_dataset_using_name(dataset_name): 8 | # Given the option --dataset_mode [datasetname], 9 | # the file "data/datasetname_dataset.py" 10 | # will be imported. 11 | dataset_filename = "data." + dataset_name + "_dataset" 12 | datasetlib = importlib.import_module(dataset_filename) 13 | 14 | # In the file, the class called DatasetNameDataset() will 15 | # be instantiated. It has to be a subclass of BaseDataset, 16 | # and it is case-insensitive. 17 | dataset = None 18 | target_dataset_name = dataset_name.replace('_', '') + 'dataset' 19 | for name, cls in datasetlib.__dict__.items(): 20 | if name.lower() == target_dataset_name.lower() \ 21 | and issubclass(cls, BaseDataset): 22 | dataset = cls 23 | 24 | if dataset is None: 25 | print("In %s.py, there should be a subclass of BaseDataset with class name that matches %s in lowercase." % (dataset_filename, target_dataset_name)) 26 | exit(0) 27 | 28 | return dataset 29 | 30 | 31 | def get_option_setter(dataset_name): 32 | dataset_class = find_dataset_using_name(dataset_name) 33 | return dataset_class.modify_commandline_options 34 | 35 | 36 | def create_dataset(opt): 37 | dataset = find_dataset_using_name(opt.dataset_mode) 38 | instance = dataset() 39 | instance.initialize(opt) 40 | print("dataset [%s] was created" % (instance.name())) 41 | return instance 42 | 43 | 44 | def CreateDataLoader(opt): 45 | data_loader = CustomDatasetDataLoader() 46 | data_loader.initialize(opt) 47 | return data_loader 48 | 49 | 50 | # Wrapper class of Dataset class that performs 51 | # multi-threaded data loading 52 | class CustomDatasetDataLoader(BaseDataLoader): 53 | def name(self): 54 | return 'CustomDatasetDataLoader' 55 | 56 | def initialize(self, opt): 57 | BaseDataLoader.initialize(self, opt) 58 | self.create_dataset = create_dataset 59 | self.dataset = self.create_dataset(opt) 60 | self.dataloader = torch.utils.data.DataLoader( 61 | self.dataset, 62 | batch_size=opt.batch_size, 63 | shuffle=not opt.serial_batches, 64 | num_workers=int(opt.num_threads)) 65 | 66 | def load_data(self): 67 | return self 68 | 69 | def __len__(self): 70 | return min(len(self.dataset), self.opt.max_dataset_size) 71 | 72 | def __iter__(self): 73 | for i, data in enumerate(self.dataloader): 74 | if i * self.opt.batch_size >= self.opt.max_dataset_size: 75 | break 76 | yield data 77 | -------------------------------------------------------------------------------- /src/data/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/data/__init__.pyc -------------------------------------------------------------------------------- /src/data/base_data_loader.py: -------------------------------------------------------------------------------- 1 | class BaseDataLoader(): 2 | def __init__(self): 3 | pass 4 | 5 | def initialize(self, opt): 6 | self.opt = opt 7 | pass 8 | 9 | def load_data(): 10 | return None 11 | -------------------------------------------------------------------------------- /src/data/base_data_loader.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/data/base_data_loader.pyc -------------------------------------------------------------------------------- /src/data/base_dataset.py: -------------------------------------------------------------------------------- 1 | import torch.utils.data as data 2 | from PIL import Image 3 | import torchvision.transforms as transforms 4 | 5 | 6 | class BaseDataset(data.Dataset): 7 | def __init__(self): 8 | super(BaseDataset, self).__init__() 9 | 10 | def name(self): 11 | return 'BaseDataset' 12 | 13 | @staticmethod 14 | def modify_commandline_options(parser, is_train): 15 | return parser 16 | 17 | def initialize(self, opt): 18 | pass 19 | 20 | def __len__(self): 21 | return 0 22 | 23 | 24 | def get_transform(opt): 25 | transform_list = [] 26 | if opt.resize_or_crop == 'resize_and_crop': 27 | osize = [opt.loadSize, opt.loadSize] 28 | transform_list.append(transforms.Resize(osize, Image.BICUBIC)) 29 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 30 | elif opt.resize_or_crop == 'resize': 31 | osize = [opt.loadSize, opt.loadSize] 32 | transform_list.append(transforms.Resize(osize, Image.BICUBIC)) 33 | elif opt.resize_or_crop == 'crop': 34 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 35 | elif opt.resize_or_crop == 'scale_width': 36 | transform_list.append(transforms.Lambda( 37 | lambda img: __scale_width(img, opt.fineSize))) 38 | elif opt.resize_or_crop == 'scale_width_and_crop': 39 | transform_list.append(transforms.Lambda( 40 | lambda img: __scale_width(img, opt.loadSize))) 41 | transform_list.append(transforms.RandomCrop(opt.fineSize)) 42 | elif opt.resize_or_crop == 'none': 43 | transform_list.append(transforms.Lambda( 44 | lambda img: __adjust(img))) 45 | else: 46 | raise ValueError('--resize_or_crop %s is not a valid option.' % opt.resize_or_crop) 47 | 48 | if opt.isTrain and not opt.no_flip: 49 | transform_list.append(transforms.RandomHorizontalFlip()) 50 | 51 | transform_list += [transforms.ToTensor(), 52 | transforms.Normalize((0.5, 0.5, 0.5), 53 | (0.5, 0.5, 0.5))] 54 | return transforms.Compose(transform_list) 55 | 56 | 57 | # just modify the width and height to be multiple of 4 58 | def __adjust(img): 59 | ow, oh = img.size 60 | 61 | # the size needs to be a multiple of this number, 62 | # because going through generator network may change img size 63 | # and eventually cause size mismatch error 64 | mult = 4 65 | if ow % mult == 0 and oh % mult == 0: 66 | return img 67 | w = (ow - 1) // mult 68 | w = (w + 1) * mult 69 | h = (oh - 1) // mult 70 | h = (h + 1) * mult 71 | 72 | if ow != w or oh != h: 73 | __print_size_warning(ow, oh, w, h) 74 | 75 | return img.resize((w, h), Image.BICUBIC) 76 | 77 | 78 | 79 | 80 | def __scale_width(img, target_width): 81 | ow, oh = img.size 82 | 83 | # the size needs to be a multiple of this number, 84 | # because going through generator network may change img size 85 | # and eventually cause size mismatch error 86 | mult = 4 87 | assert target_width % mult == 0, "the target width needs to be multiple of %d." % mult 88 | if (ow == target_width and oh % mult == 0): 89 | return img 90 | w = target_width 91 | target_height = int(target_width * oh / ow) 92 | m = (target_height - 1) // mult 93 | h = (m + 1) * mult 94 | 95 | if target_height != h: 96 | __print_size_warning(target_width, target_height, w, h) 97 | 98 | return img.resize((w, h), Image.BICUBIC) 99 | 100 | 101 | def __print_size_warning(ow, oh, w, h): 102 | if not hasattr(__print_size_warning, 'has_printed'): 103 | print("The image size needs to be a multiple of 4. " 104 | "The loaded image size was (%d, %d), so it was adjusted to " 105 | "(%d, %d). This adjustment will be done to all images " 106 | "whose sizes are not multiples of 4" % (ow, oh, w, h)) 107 | __print_size_warning.has_printed = True 108 | -------------------------------------------------------------------------------- /src/data/base_dataset.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/data/base_dataset.pyc -------------------------------------------------------------------------------- /src/data/image_folder.py: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Code from 3 | # https://github.com/pytorch/vision/blob/master/torchvision/datasets/folder.py 4 | # Modified the original code so that it also loads images from the current 5 | # directory as well as the subdirectories 6 | ############################################################################### 7 | 8 | import torch.utils.data as data 9 | 10 | from PIL import Image 11 | import os 12 | import os.path 13 | 14 | IMG_EXTENSIONS = [ 15 | '.jpg', '.JPG', '.jpeg', '.JPEG', 16 | '.png', '.PNG', '.ppm', '.PPM', '.bmp', '.BMP', 17 | ] 18 | 19 | 20 | def is_image_file(filename): 21 | return any(filename.endswith(extension) for extension in IMG_EXTENSIONS) 22 | 23 | ''' 24 | def make_dataset(dir): 25 | images = [] 26 | assert os.path.isdir(dir), '%s is not a valid directory' % dir 27 | 28 | for root, _, fnames in sorted(os.walk(dir)): 29 | for fname in fnames: 30 | if is_image_file(fname): 31 | path = os.path.join(root, fname) 32 | images.append(path) 33 | 34 | return images 35 | ''' 36 | def make_dataset(dir): 37 | images = [] 38 | imname = [] 39 | assert os.path.isdir(dir), '%s is not a valid directory' % dir 40 | 41 | for root, _, fnames in sorted(os.walk(dir)): 42 | for fname in fnames: 43 | if is_image_file(fname): 44 | path = os.path.join(root, fname) 45 | images.append(path) 46 | imname.append(fname) 47 | return images,imname 48 | 49 | def default_loader(path): 50 | return Image.open(path).convert('RGB') 51 | 52 | 53 | class ImageFolder(data.Dataset): 54 | 55 | def __init__(self, root, transform=None, return_paths=False, 56 | loader=default_loader): 57 | imgs = make_dataset(root) 58 | if len(imgs) == 0: 59 | raise(RuntimeError("Found 0 images in: " + root + "\n" 60 | "Supported image extensions are: " + 61 | ",".join(IMG_EXTENSIONS))) 62 | 63 | self.root = root 64 | self.imgs = imgs 65 | self.transform = transform 66 | self.return_paths = return_paths 67 | self.loader = loader 68 | 69 | def __getitem__(self, index): 70 | path = self.imgs[index] 71 | img = self.loader(path) 72 | if self.transform is not None: 73 | img = self.transform(img) 74 | if self.return_paths: 75 | return img, path 76 | else: 77 | return img 78 | 79 | def __len__(self): 80 | return len(self.imgs) 81 | -------------------------------------------------------------------------------- /src/data/image_folder.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/data/image_folder.pyc -------------------------------------------------------------------------------- /src/generate.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | from options.test_options import TestOptions 3 | from data import CreateDataLoader 4 | from models import create_model 5 | from util.visualizer import Visualizer 6 | from PIL import Image 7 | import visdom 8 | from util.util import sdmkdir 9 | import time 10 | import tqdm 11 | import numpy as np 12 | import math 13 | import torch 14 | 15 | opt = TestOptions().parse() 16 | data_loader = CreateDataLoader(opt) 17 | dataset = data_loader.load_data() 18 | dataset_size = len(data_loader) 19 | model = create_model(opt) 20 | model.setup(opt) 21 | visualizer = Visualizer(opt) 22 | 23 | 24 | lengths = 0 25 | for i, data in enumerate(dataset): 26 | model.set_input(data) 27 | model.prediction() 28 | length, visual_dict = model.get_current_visuals() 29 | visualizer.display_current_results(visual_dict, i) 30 | lengths+=length 31 | 32 | if opt.bos: 33 | print('totally {} test bos images'.format(lengths)) 34 | elif opt.bosfree: 35 | print('totally {} test bosfree images'.format(lengths)) 36 | else: 37 | print('totally {} real composite images'.format(lengths)) 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/models/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | from models.base_model import BaseModel 3 | 4 | 5 | def find_model_using_name(model_name): 6 | # Given the option --model [modelname], 7 | # the file "models/modelname_model.py" 8 | # will be imported. 9 | model_filename = "models." + model_name + "_model" 10 | modellib = importlib.import_module(model_filename) 11 | 12 | # In the file, the class called ModelNameModel() will 13 | # be instantiated. It has to be a subclass of BaseModel, 14 | # and it is case-insensitive. 15 | model = None 16 | target_model_name = model_name.replace('_', '') + 'model' 17 | for name, cls in modellib.__dict__.items(): 18 | if name.lower() == target_model_name.lower() \ 19 | and issubclass(cls, BaseModel): 20 | model = cls 21 | 22 | if model is None: 23 | print("In %s.py, there should be a subclass of BaseModel with class name that matches %s in lowercase." % (model_filename, target_model_name)) 24 | exit(0) 25 | 26 | return model 27 | 28 | 29 | def get_option_setter(model_name): 30 | model_class = find_model_using_name(model_name) 31 | return model_class.modify_commandline_options 32 | 33 | 34 | def create_model(opt): 35 | model = find_model_using_name(opt.model) 36 | instance = model() 37 | instance.initialize(opt) 38 | print("model [%s] was created" % (instance.name())) 39 | return instance 40 | -------------------------------------------------------------------------------- /src/models/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/models/__init__.pyc -------------------------------------------------------------------------------- /src/models/base_model.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/models/base_model.pyc -------------------------------------------------------------------------------- /src/models/distangle_model.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from util.image_pool import ImagePool 3 | from .base_model import BaseModel 4 | from . import networks 5 | import util.util as util 6 | 7 | 8 | 9 | class DistangleModel(BaseModel): 10 | def name(self): 11 | return 'DistangleModel' 12 | 13 | @staticmethod 14 | def modify_commandline_options(parser, is_train=True): 15 | 16 | parser.set_defaults(pool_size=0, no_lsgan=True, norm='batch') 17 | parser.set_defaults(dataset_mode='aligned') 18 | parser.set_defaults(netG='RESNEXT') 19 | if is_train: 20 | parser.add_argument('--lambda_L1', type=float, default=100.0, help='weight for L1 loss') 21 | 22 | return parser 23 | 24 | def initialize(self, opt): 25 | BaseModel.initialize(self, opt) 26 | self.isTrain = opt.isTrain 27 | self.loss_names = ['G'] 28 | # specify the images you want to save/display. The program will call base_model.get_current_visuals 29 | self.visual_names = ['input_img', 'shadow_mask','out','outgt'] 30 | # specify the models you want to save to the disk. The program will call base_model.save_networks and base_model.load_networks 31 | if self.isTrain: 32 | self.model_names = ['G'] 33 | else: # during test time, only load Gs 34 | self.model_names = ['G'] 35 | # load/define networks 36 | opt.output_nc= 3 if opt.task=='sr' else 1 #3 for shadow removal, 1 for detection 37 | self.netG = networks.define_G(4, opt.output_nc, opt.ngf, 'RESNEXT', opt.norm, 38 | not opt.no_dropout, opt.init_type, opt.init_gain, self.gpu_ids) 39 | self.netG.to(self.device) 40 | print(self.netG) 41 | #self.netG.print_networks() 42 | if self.isTrain: 43 | self.fake_AB_pool = ImagePool(opt.pool_size) 44 | # define loss functions 45 | self.criterionL1 = torch.nn.L1Loss() 46 | self.bce = torch.nn.BCEWithLogitsLoss() 47 | # initialize optimizers 48 | self.optimizers = [] 49 | self.optimizer_G = torch.optim.Adam(self.netG.parameters(), 50 | lr=opt.lr, betas=(opt.beta1, 0.999),weight_decay=1e-5) 51 | self.optimizers.append(self.optimizer_G) 52 | 53 | def set_input(self, input): 54 | self.input_img = input['A'].to(self.device) 55 | self.shadow_mask = input['B'].to(self.device) 56 | self.shadow_param = input['param'].to(self.device).type(torch.float) 57 | self.shadow_mask = (self.shadow_mask>0.9).type(torch.float)*2-1 58 | self.nim = self.input_img.shape[1] 59 | self.shadowfree_img = input['C'].to(self.device) 60 | self.shadow_mask_3d= (self.shadow_mask>0).type(torch.float).expand(self.input_img.shape) 61 | 62 | 63 | def forward(self): 64 | inputG = torch.cat([self.input_img,self.shadow_mask],1) 65 | self.Gout = self.netG(inputG) 66 | self.lit = self.input_img.clone()/2+0.5 67 | 68 | add = self.Gout[:,[0,2,4]] 69 | mul = self.Gout[:,[1,3,5]] 70 | n = self.Gout.shape[0] 71 | 72 | 73 | 74 | add = add.view(n,3,1,1).expand((n,3,256,256)) 75 | mul = mul.view(n,3,1,1).expand((n,3,256,256)) 76 | 77 | 78 | addgt = self.shadow_param[:,[0,2,4]] 79 | mulgt = self.shadow_param[:,[1,3,5]] 80 | addgt = addgt.view(n,3,1,1).expand((n,3,256,256)) 81 | mulgt = mulgt.view(n,3,1,1).expand((n,3,256,256)) 82 | 83 | self.litgt = (self.input_img.clone()+1)/2 84 | 85 | self.lit = self.lit*mul + add 86 | self.litgt = self.litgt*mulgt+addgt 87 | 88 | self.out = (self.input_img/2+0.5)*(1-self.shadow_mask_3d) + self.lit*self.shadow_mask_3d 89 | self.out = self.out*2-1 90 | 91 | self.outgt = (self.input_img/2+0.5)*(1-self.shadow_mask_3d) + self.litgt*self.shadow_mask_3d 92 | self.outgt = self.outgt*2-1 93 | 94 | self.alpha = torch.mean(self.shadowfree_img / self.lit,dim=1,keepdim=True) 95 | 96 | 97 | def get_prediction(self,input): 98 | self.input_img = input['A'].to(self.device) 99 | self.shadow_mask = input['B'].to(self.device) 100 | inputG = torch.cat([self.input_img,self.shadow_mask],1) 101 | self.shadow_mask = (self.shadow_mask>0.9).type(torch.float)*2-1 102 | self.shadow_mask_3d= (self.shadow_mask>0).type(torch.float).expand(self.input_img.shape) 103 | self.Gout = self.netG(inputG) 104 | self.lit = self.input_img.clone()/2+0.5 105 | add = self.Gout[:,[0,2,4]] 106 | mul = self.Gout[:,[1,3,5]] 107 | n = self.Gout.shape[0] 108 | add = add.view(n,3,1,1).expand((n,3,256,256)) 109 | mul = mul.view(n,3,1,1).expand((n,3,256,256)) 110 | self.lit = self.lit*mul + add 111 | self.out = (self.input_img/2+0.5)*(1-self.shadow_mask_3d) + self.lit*self.shadow_mask_3d 112 | self.out = self.out*2-1 113 | return util.tensor2im(self.out,scale =0) 114 | 115 | def backward_G(self): 116 | criterion = self.criterionL1 if self.opt.task =='sr' else self.bce 117 | lambda_ = self.opt.lambda_L1 if self.opt.task =='sr' else 1 118 | self.loss_G = criterion(self.Gout, self.shadow_param) * lambda_ 119 | self.loss_G.backward() 120 | 121 | def optimize_parameters(self): 122 | self.forward() 123 | self.optimizer_G.zero_grad() 124 | self.backward_G() 125 | self.optimizer_G.step() 126 | 127 | 128 | if __name__=='__main__': 129 | parser = argparse.ArgumentParser() 130 | opt = parser.parse_args() 131 | opt.dataroot = '=/nfs/bigbox/hieule/GAN/datasets/ISTD_Dataset/train/train_' 132 | opt.name = 'test' 133 | opt.model = 'jointdistangle' 134 | 135 | opt.gpu_ids=[2] 136 | opt.log_scale = 0 137 | opt.ndf = 32 138 | opt.ngf = 64 139 | opt.norm ='batch' 140 | opt.checkpoints_dir ='/nfs/bigbox/hieule/GAN/data/test' 141 | opt.isTrain = False 142 | opt.resize_or_crop = 'none' 143 | opt.loadSize = 256 144 | opt.init_type = 'xavier' 145 | opt.init_gain = 0.02 146 | opt.fineSize = 256 147 | opt.nThreads = 1 # test code only supports nThreads = 1 148 | opt.batchSize = 1 # test code only supports batchSize = 1 149 | opt.serial_batches = False # no shuffle 150 | opt.no_flip = True # no flip 151 | opt.no_dropout = True 152 | opt.use_our_mask = True 153 | opt.task ='sr' 154 | 155 | a = DistangleModel() 156 | a.initialize(opt) 157 | -------------------------------------------------------------------------------- /src/models/loss_function.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from torch import nn 3 | import torch.nn.functional as F 4 | 5 | def smooth_loss(pred_map): 6 | def gradient(pred): 7 | D_dy = pred[:, :, 1:] - pred[:, :, :-1] 8 | D_dx = pred[:, :, :, 1:] - pred[:, :, :, :-1] 9 | return D_dx, D_dy 10 | 11 | loss = 0 12 | weight = 1. 13 | 14 | dx, dy = gradient(pred_map) 15 | dx2, dxdy = gradient(dx) 16 | dydx, dy2 = gradient(dy) 17 | loss += (dx2.abs().mean() + dxdy.abs().mean() + dydx.abs().mean() + dy2.abs().mean())*weight 18 | return loss 19 | 20 | -------------------------------------------------------------------------------- /src/models/maskshadowGAN_models_guided.py: -------------------------------------------------------------------------------- 1 | import torch.nn as nn 2 | import torch.nn.functional as F 3 | # from torchsummary import summary 4 | import torch 5 | 6 | class ResidualBlock(nn.Module): 7 | def __init__(self, in_features): 8 | super(ResidualBlock, self).__init__() 9 | 10 | conv_block = [ nn.ReflectionPad2d(1), 11 | nn.Conv2d(in_features, in_features, 3), 12 | nn.InstanceNorm2d(in_features), 13 | nn.ReLU(inplace=True), 14 | nn.ReflectionPad2d(1), 15 | nn.Conv2d(in_features, in_features, 3), 16 | nn.InstanceNorm2d(in_features) ] 17 | 18 | self.conv_block = nn.Sequential(*conv_block) 19 | 20 | def forward(self, x): 21 | return x + self.conv_block(x) 22 | 23 | class Generator_S2F(nn.Module): 24 | def __init__(self, input_nc, output_nc, n_residual_blocks=9): 25 | super(Generator_S2F, self).__init__() 26 | 27 | # Initial convolution block 28 | model = [ nn.ReflectionPad2d(3), 29 | nn.Conv2d(input_nc, 64, 7), 30 | nn.InstanceNorm2d(64), 31 | nn.ReLU(inplace=True) ] 32 | 33 | # Downsampling 34 | in_features = 64 35 | out_features = in_features*2 36 | for _ in range(2): 37 | model += [ nn.Conv2d(in_features, out_features, 3, stride=2, padding=1), 38 | nn.InstanceNorm2d(out_features), 39 | nn.ReLU(inplace=True) ] 40 | in_features = out_features 41 | out_features = in_features*2 42 | 43 | # Residual blocks 44 | for _ in range(n_residual_blocks): 45 | model += [ResidualBlock(in_features)] 46 | 47 | # Upsampling 48 | out_features = in_features//2 49 | for _ in range(2): 50 | model += [ nn.ConvTranspose2d(in_features, out_features, 3, stride=2, padding=1, output_padding=1), 51 | nn.InstanceNorm2d(out_features), 52 | nn.ReLU(inplace=True) ] 53 | in_features = out_features 54 | out_features = in_features//2 55 | 56 | # Output layer 57 | model += [ nn.ReflectionPad2d(3), 58 | nn.Conv2d(64, output_nc, 7) ] 59 | #nn.Tanh() ] 60 | 61 | self.model = nn.Sequential(*model) 62 | 63 | def forward(self, x): 64 | return (self.model(x) + x).tanh() #(min=-1, max=1) #just learn a residual 65 | 66 | 67 | class Generator_F2S(nn.Module): 68 | def __init__(self, input_nc, output_nc, n_residual_blocks=9): 69 | super(Generator_F2S, self).__init__() 70 | 71 | # Initial convolution block 72 | model = [ nn.ReflectionPad2d(3), 73 | nn.Conv2d(input_nc+1, 64, 7), # + mask 74 | nn.InstanceNorm2d(64), 75 | nn.ReLU(inplace=True) ] 76 | 77 | # Downsampling 78 | in_features = 64 79 | out_features = in_features*2 80 | for _ in range(2): 81 | model += [ nn.Conv2d(in_features, out_features, 3, stride=2, padding=1), 82 | nn.InstanceNorm2d(out_features), 83 | nn.ReLU(inplace=True) ] 84 | in_features = out_features 85 | out_features = in_features*2 86 | 87 | # Residual blocks 88 | for _ in range(n_residual_blocks): 89 | model += [ResidualBlock(in_features)] 90 | 91 | # Upsampling 92 | out_features = in_features//2 93 | for _ in range(2): 94 | model += [ nn.ConvTranspose2d(in_features, out_features, 3, stride=2, padding=1, output_padding=1), 95 | nn.InstanceNorm2d(out_features), 96 | nn.ReLU(inplace=True) ] 97 | in_features = out_features 98 | out_features = in_features//2 99 | 100 | # Output layer 101 | model += [ nn.ReflectionPad2d(3), 102 | nn.Conv2d(64, output_nc, 7) ] 103 | #nn.Tanh() ] 104 | 105 | self.model = nn.Sequential(*model) 106 | 107 | def forward(self, x, mask): 108 | return (self.model(torch.cat((x, mask), 1)) + x).tanh() #(min=-1, max=1) #just learn a residual 109 | 110 | 111 | class Discriminator(nn.Module): 112 | def __init__(self, input_nc): 113 | super(Discriminator, self).__init__() 114 | 115 | # A bunch of convolutions one after another 116 | model = [ nn.Conv2d(input_nc, 64, 4, stride=2, padding=1), 117 | nn.LeakyReLU(0.2, inplace=True) ] 118 | 119 | model += [ nn.Conv2d(64, 128, 4, stride=2, padding=1), 120 | nn.InstanceNorm2d(128), 121 | nn.LeakyReLU(0.2, inplace=True) ] 122 | 123 | model += [ nn.Conv2d(128, 256, 4, stride=2, padding=1), 124 | nn.InstanceNorm2d(256), 125 | nn.LeakyReLU(0.2, inplace=True) ] 126 | 127 | model += [ nn.Conv2d(256, 512, 4, padding=1), 128 | nn.InstanceNorm2d(512), 129 | nn.LeakyReLU(0.2, inplace=True) ] 130 | 131 | # FCN classification layer 132 | model += [nn.Conv2d(512, 1, 4, padding=1)] 133 | 134 | self.model = nn.Sequential(*model) 135 | 136 | def forward(self, x): 137 | x = self.model(x) 138 | # Average pooling and flatten 139 | return F.avg_pool2d(x, x.size()[2:]).view(x.size()[0], -1) #global avg pool 140 | 141 | 142 | # 143 | # net = Generator(3,3).cuda() 144 | # summary(net, input_size=(3, 256, 256)) 145 | 146 | # dtype = torch.float 147 | # #device = torch.deviec("cpu") 148 | # device = torch.device("cuda:0") 149 | # 150 | # x = torch.randn(5, 3, 256, 256, device = device, dtype = dtype) 151 | # out = net(x) 152 | # print(out.shape) -------------------------------------------------------------------------------- /src/models/maskshadowGAN_utils.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | import datetime 4 | import sys 5 | 6 | from torch.autograd import Variable 7 | import torch 8 | # from visdom import Visdom 9 | import torchvision.transforms as transforms 10 | import numpy as np 11 | from skimage.filters import threshold_otsu 12 | 13 | 14 | to_pil = transforms.ToPILImage() 15 | to_gray = transforms.Grayscale(num_output_channels=1) 16 | 17 | class QueueMask(): 18 | def __init__(self, length): 19 | self.max_length = length 20 | self.queue = [] 21 | 22 | def insert(self, mask): 23 | if self.queue.__len__() >= self.max_length: 24 | self.queue.pop(0) 25 | 26 | self.queue.append(mask) 27 | 28 | def rand_item(self): 29 | assert self.queue.__len__() > 0, 'Error! Empty queue!' 30 | return self.queue[np.random.randint(0, self.queue.__len__())] 31 | 32 | def last_item(self): 33 | assert self.queue.__len__() > 0, 'Error! Empty queue!' 34 | return self.queue[self.queue.__len__()-1] 35 | 36 | 37 | 38 | def mask_generator(shadow, shadow_free): 39 | im_f = to_gray(to_pil(((shadow_free.data.squeeze(0) + 1.0) * 0.5).cpu())) 40 | im_s = to_gray(to_pil(((shadow.data.squeeze(0) + 1.0) * 0.5).cpu())) 41 | 42 | diff = (np.asarray(im_f, dtype='float32')- np.asarray(im_s, dtype='float32')) # difference between shadow image and shadow_free image 43 | L = threshold_otsu(diff) 44 | mask = torch.tensor((np.float32(diff >= L)-0.5)/0.5).unsqueeze(0).unsqueeze(0).cuda() #-1.0:non-shadow, 1.0:shadow 45 | mask.requires_grad = False 46 | 47 | return mask 48 | 49 | 50 | 51 | def tensor2image(tensor): 52 | image = 127.5*(tensor[0].cpu().float().numpy() + 1.0) 53 | if image.shape[0] == 1: 54 | image = np.tile(image, (3,1,1)) 55 | return image.astype(np.uint8) 56 | 57 | # class Logger(): 58 | # def __init__(self, n_epochs, batches_epoch, server='http://137.189.90.150', http_proxy_host='http://proxy.cse.cuhk.edu.hk/', env = 'main'): 59 | # self.viz = Visdom(server = server, http_proxy_host = http_proxy_host, env = env)#, http_proxy_port='http://proxy.cse.cuhk.edu.hk:8000/') 60 | # self.n_epochs = n_epochs 61 | # self.batches_epoch = batches_epoch 62 | # self.epoch = 1 63 | # self.batch = 1 64 | # self.prev_time = time.time() 65 | # self.mean_period = 0 66 | # self.losses = {} 67 | # self.loss_windows = {} 68 | # self.image_windows = {} 69 | # 70 | # 71 | # def log(self, losses=None, images=None): 72 | # self.mean_period += (time.time() - self.prev_time) 73 | # self.prev_time = time.time() 74 | # 75 | # sys.stdout.write('\rEpoch %03d/%03d [%04d/%04d] -- ' % (self.epoch, self.n_epochs, self.batch, self.batches_epoch)) 76 | # 77 | # for i, loss_name in enumerate(losses.keys()): 78 | # if loss_name not in self.losses: 79 | # self.losses[loss_name] = losses[loss_name].data.item() 80 | # else: 81 | # self.losses[loss_name] += losses[loss_name].data.item() 82 | # 83 | # if (i+1) == len(losses.keys()): 84 | # sys.stdout.write('%s: %.4f -- ' % (loss_name, self.losses[loss_name]/self.batch)) 85 | # else: 86 | # sys.stdout.write('%s: %.4f | ' % (loss_name, self.losses[loss_name]/self.batch)) 87 | # 88 | # batches_done = self.batches_epoch*(self.epoch - 1) + self.batch 89 | # batches_left = self.batches_epoch*(self.n_epochs - self.epoch) + self.batches_epoch - self.batch 90 | # sys.stdout.write('ETA: %s' % (datetime.timedelta(seconds=batches_left*self.mean_period/batches_done))) 91 | # 92 | # # Draw images 93 | # for image_name, tensor in images.items(): 94 | # if image_name not in self.image_windows: 95 | # self.image_windows[image_name] = self.viz.image(tensor2image(tensor.data), opts={'title':image_name}) 96 | # else: 97 | # self.viz.image(tensor2image(tensor.data), win=self.image_windows[image_name], opts={'title':image_name}) 98 | # 99 | # # End of epoch 100 | # if (self.batch % self.batches_epoch) == 0: 101 | # # Plot losses 102 | # for loss_name, loss in self.losses.items(): 103 | # if loss_name not in self.loss_windows: 104 | # self.loss_windows[loss_name] = self.viz.line(X=np.array([self.epoch]), Y=np.array([loss/self.batch]), 105 | # opts={'xlabel': 'epochs', 'ylabel': loss_name, 'title': loss_name}) 106 | # else: 107 | # self.viz.line(X=np.array([self.epoch]), Y=np.array([loss/self.batch]), win=self.loss_windows[loss_name], update='append') 108 | # # Reset losses for next epoch 109 | # self.losses[loss_name] = 0.0 110 | # 111 | # self.epoch += 1 112 | # self.batch = 1 113 | # sys.stdout.write('\n') 114 | # else: 115 | # self.batch += 1 116 | # 117 | # 118 | 119 | class ReplayBuffer(): 120 | def __init__(self, max_size=50): 121 | assert (max_size > 0), 'Empty buffer or trying to create a black hole. Be careful.' 122 | self.max_size = max_size 123 | self.data = [] 124 | 125 | def push_and_pop(self, data): 126 | to_return = [] 127 | for element in data.data: 128 | element = torch.unsqueeze(element, 0) 129 | if len(self.data) < self.max_size: 130 | self.data.append(element) 131 | to_return.append(element) 132 | else: 133 | if random.uniform(0,1) > 0.5: 134 | i = random.randint(0, self.max_size-1) 135 | to_return.append(self.data[i].clone()) 136 | self.data[i] = element 137 | else: 138 | to_return.append(element) 139 | return Variable(torch.cat(to_return)) 140 | 141 | 142 | class LambdaLR(): 143 | def __init__(self, n_epochs, offset, decay_start_epoch): 144 | assert ((n_epochs - decay_start_epoch) > 0), "Decay must start before the training session ends!" 145 | self.n_epochs = n_epochs 146 | self.offset = offset 147 | self.decay_start_epoch = decay_start_epoch 148 | 149 | def step(self, epoch): 150 | return 1.0 - max(0, epoch + self.offset - self.decay_start_epoch)/(self.n_epochs - self.decay_start_epoch) 151 | 152 | def weights_init_normal(m): 153 | classname = m.__class__.__name__ 154 | if classname.find('Conv') != -1: 155 | torch.nn.init.normal_(m.weight.data, 0.0, 0.02) 156 | elif classname.find('BatchNorm2d') != -1: 157 | torch.nn.init.normal_(m.weight.data, 1.0, 0.02) 158 | torch.nn.init.constant_(m.bias.data, 0.0) 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /src/models/networks.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/models/networks.pyc -------------------------------------------------------------------------------- /src/models/unet_parts.py: -------------------------------------------------------------------------------- 1 | """ Parts of the U-Net model """ 2 | 3 | import torch 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | 7 | 8 | class DoubleConv(nn.Module): 9 | """(convolution => [BN] => ReLU) * 2""" 10 | 11 | def __init__(self, in_channels, out_channels, mid_channels=None): 12 | super().__init__() 13 | if not mid_channels: 14 | mid_channels = out_channels 15 | self.double_conv = nn.Sequential( 16 | nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1), 17 | nn.BatchNorm2d(mid_channels), 18 | nn.ReLU(inplace=True), 19 | nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1), 20 | nn.BatchNorm2d(out_channels), 21 | nn.ReLU(inplace=True) 22 | ) 23 | 24 | def forward(self, x): 25 | return self.double_conv(x) 26 | 27 | 28 | class Down(nn.Module): 29 | """Downscaling with maxpool then double conv""" 30 | 31 | def __init__(self, in_channels, out_channels): 32 | super().__init__() 33 | self.maxpool_conv = nn.Sequential( 34 | nn.MaxPool2d(2), 35 | DoubleConv(in_channels, out_channels) 36 | ) 37 | 38 | def forward(self, x): 39 | return self.maxpool_conv(x) 40 | 41 | 42 | class Up(nn.Module): 43 | """Upscaling then double conv""" 44 | 45 | def __init__(self, in_channels, out_channels, bilinear=True): 46 | super().__init__() 47 | 48 | # if bilinear, use the normal convolutions to reduce the number of channels 49 | if bilinear: 50 | self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) 51 | self.conv = DoubleConv(in_channels, out_channels, in_channels // 2) 52 | else: 53 | self.up = nn.ConvTranspose2d(in_channels , in_channels // 2, kernel_size=2, stride=2) 54 | self.conv = DoubleConv(in_channels, out_channels) 55 | 56 | 57 | def forward(self, x1, x2): 58 | x1 = self.up(x1) 59 | # input is CHW 60 | diffY = x2.size()[2] - x1.size()[2] 61 | diffX = x2.size()[3] - x1.size()[3] 62 | 63 | x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2, 64 | diffY // 2, diffY - diffY // 2]) 65 | # if you have padding issues, see 66 | # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a 67 | # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd 68 | x = torch.cat([x2, x1], dim=1) 69 | return self.conv(x) 70 | 71 | 72 | class OutConv(nn.Module): 73 | def __init__(self, in_channels, out_channels): 74 | super(OutConv, self).__init__() 75 | self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1) 76 | 77 | def forward(self, x): 78 | return self.conv(x) -------------------------------------------------------------------------------- /src/models/vgg.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from __future__ import division 3 | import torch 4 | import torch.nn as nn 5 | import torch.optim as optim 6 | import numpy as np 7 | import torchvision 8 | from torchvision import datasets, models, transforms 9 | import matplotlib.pyplot as plt 10 | import time 11 | import os 12 | import copy 13 | 14 | def set_parameter_requires_grad(model, feature_extracting): 15 | if feature_extracting: 16 | for param in model.parameters(): 17 | param.requires_grad = False 18 | 19 | def create_vgg(num_ic,num_classes,use_pretrained=False,feature_extract=False): 20 | model_ft = models.vgg16(pretrained=use_pretrained) 21 | set_parameter_requires_grad(model_ft, feature_extract) 22 | num_ftrs = model_ft.classifier[6].in_features 23 | 24 | model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes) 25 | modules =[] 26 | for i in model_ft.features: 27 | modules.append(i) 28 | modules[0] = nn.Conv2d(num_ic, 64, kernel_size=3, padding=1) 29 | model_ft.features=nn.Sequential(*modules) 30 | 31 | 32 | modules2=[] 33 | for i in model_ft.classifier: 34 | modules2.append(i) 35 | modules2.append(nn.Tanh()) 36 | model_ft.classifier = nn.Sequential(*modules2) 37 | input_size = 224 38 | return model_ft 39 | if __name__=='__main__': 40 | a = create_vgg(4,6) 41 | print(a) 42 | inp = torch.ones((1,4,128,128)) 43 | print(a(inp).shape) 44 | 45 | -------------------------------------------------------------------------------- /src/options/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/options/test_options.py: -------------------------------------------------------------------------------- 1 | from .base_options import BaseOptions 2 | 3 | class TestOptions(BaseOptions): 4 | def initialize(self, parser): 5 | parser = BaseOptions.initialize(self, parser) 6 | parser.add_argument('--display_freq', type=int, default=40, 7 | help='frequency of showing training results on screen') 8 | parser.add_argument('--display_ncols', type=int, default=4, 9 | help='if positive, display all images in a single visdom web panel with certain number of images per row.') 10 | parser.add_argument('--display_id', type=int, default=-1, help='window id of the web display') 11 | # parser.add_argument('--display_server', type=str, default="http://bigiris.cs.stonybrook.edu", help='visdom server of the web display') 12 | parser.add_argument('--display_server', type=str, default="http://localhost:8097", 13 | help='visdom server of the web display') 14 | 15 | parser.add_argument('--display_env', type=str, default='main', 16 | help='visdom display environment name (default is "main")') 17 | parser.add_argument('--display_port', type=int, default=8097, help='visdom port of the web display') 18 | parser.add_argument('--update_html_freq', type=int, default=10000, 19 | help='frequency of saving training results to html') 20 | parser.add_argument('--print_freq', type=int, default=100, 21 | help='frequency of showing training results on console') 22 | parser.add_argument('--save_latest_freq', type=int, default=5000, help='frequency of saving the latest results') 23 | parser.add_argument('--save_epoch_freq', type=int, default=5, 24 | help='frequency of saving checkpoints at the end of epochs') 25 | parser.add_argument('--continue_train', action='store_true', help='continue training: load the latest model') 26 | parser.add_argument('--epoch_count', type=int, default=1, 27 | help='the starting epoch count, we save the model by , +, ...') 28 | parser.add_argument('--phase', type=str, default='test', help='train, val, test, etc') 29 | parser.add_argument('--niter', type=int, default=100, help='# of iter at starting learning rate') 30 | parser.add_argument('--niter_decay', type=int, default=100, 31 | help='# of iter to linearly decay learning rate to zero') 32 | parser.add_argument('--beta1', type=float, default=0.5, help='momentum term of adam') 33 | parser.add_argument('--lr', type=float, default=0.0002, help='initial learning rate for adam') 34 | parser.add_argument('--no_lsgan', action='store_true', 35 | help='do *not* use least square GAN, if false, use vanilla GAN') 36 | parser.add_argument('--pool_size', type=int, default=50, 37 | help='the size of image buffer that stores previously generated images') 38 | parser.add_argument('--no_html', action='store_true', 39 | help='do not save intermediate training results to [opt.checkpoints_dir]/[opt.name]/web/') 40 | parser.add_argument('--lr_policy', type=str, default='lambda', 41 | help='learning rate policy: lambda|step|plateau|cosine') 42 | parser.add_argument('--lr_decay_iters', type=int, default=50, 43 | help='multiply by a gamma every lr_decay_iters iterations') 44 | parser.add_argument('--eval', action='store_true', help='use eval mode during test time.') 45 | 46 | parser.add_argument('--param_path', type=str) 47 | parser.add_argument('--light_path', type=str) 48 | parser.add_argument('--instance_path', type=str) 49 | parser.add_argument('--shadowimg_path', type=str) 50 | parser.add_argument('--shadowmask_path', type=str) 51 | parser.add_argument('--shadowfree_path', type=str) 52 | parser.add_argument('--light_vis_path', type=str) 53 | parser.add_argument('--bg_instance_path', type=str) 54 | parser.add_argument('--bg_shadow_path', type=str) 55 | parser.add_argument('--new_mask_path', type=str) 56 | parser.add_argument('--redark_path', type=str) 57 | 58 | parser.add_argument('--bosfree', action='store_true') 59 | parser.add_argument('--bos', action='store_true') 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | parser.add_argument('--lambda_P1', type=float, default=1) 68 | parser.add_argument('--lambda_M1', type=float, default=1) 69 | parser.add_argument('--lambda_I1', type=float, default=1) 70 | parser.add_argument('--lambda_STN1', type=float, default=1) 71 | parser.add_argument('--lambda_REF1', type=float, default=1) 72 | parser.add_argument('--lambda_TV1', type=float, default=1) 73 | 74 | 75 | 76 | # parser.add_argument('--resize_or_crop', type=str, default='resize_and_crop', help='scaling and cropping of images at load time [resize_and_crop|crop|scale_width|scale_width_and_crop|none]') 77 | 78 | self.isTrain = False 79 | return parser 80 | -------------------------------------------------------------------------------- /src/options/test_options.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/options/test_options.pyc -------------------------------------------------------------------------------- /src/options/train_options.py: -------------------------------------------------------------------------------- 1 | from .base_options import BaseOptions 2 | 3 | 4 | class TrainOptions(BaseOptions): 5 | def initialize(self, parser): 6 | parser = BaseOptions.initialize(self, parser) 7 | parser.add_argument('--display_freq', type=int, default=4, 8 | help='frequency of showing training results on screen') 9 | parser.add_argument('--display_ncols', type=int, default=4, 10 | help='if positive, display all images in a single visdom web panel with certain number of images per row.') 11 | parser.add_argument('--display_id', type=int, default=1, help='window id of the web display') 12 | # parser.add_argument('--display_server', type=str, default="http://bigiris.cs.stonybrook.edu", help='visdom server of the web display') 13 | parser.add_argument('--display_server', type=str, default="http://localhost:8097", 14 | help='visdom server of the web display') 15 | 16 | parser.add_argument('--display_env', type=str, default='main', 17 | help='visdom display environment name (default is "main")') 18 | parser.add_argument('--display_port', type=int, default=8097, help='visdom port of the web display') 19 | parser.add_argument('--update_html_freq', type=int, default=10000, 20 | help='frequency of saving training results to html') 21 | parser.add_argument('--print_freq', type=int, default=100, 22 | help='frequency of showing training results on console') 23 | parser.add_argument('--save_latest_freq', type=int, default=5000, help='frequency of saving the latest results') 24 | parser.add_argument('--save_epoch_freq', type=int, default=5, 25 | help='frequency of saving checkpoints at the end of epochs') 26 | parser.add_argument('--continue_train', action='store_true', help='continue training: load the latest model') 27 | parser.add_argument('--epoch_count', type=int, default=1, 28 | help='the starting epoch count, we save the model by , +, ...') 29 | parser.add_argument('--phase', type=str, default='train', help='train, val, test, etc') 30 | parser.add_argument('--niter', type=int, default=100, help='# of iter at starting learning rate') 31 | parser.add_argument('--niter_decay', type=int, default=100, 32 | help='# of iter to linearly decay learning rate to zero') 33 | parser.add_argument('--beta1', type=float, default=0.5, help='momentum term of adam') 34 | parser.add_argument('--lr', type=float, default=0.0002, help='initial learning rate for adam') 35 | parser.add_argument('--no_lsgan', action='store_true', 36 | help='do *not* use least square GAN, if false, use vanilla GAN') 37 | parser.add_argument('--pool_size', type=int, default=50, 38 | help='the size of image buffer that stores previously generated images') 39 | parser.add_argument('--no_html', action='store_true', 40 | help='do not save intermediate training results to [opt.checkpoints_dir]/[opt.name]/web/') 41 | parser.add_argument('--lr_policy', type=str, default='lambda', 42 | help='learning rate policy: lambda|step|plateau|cosine') 43 | parser.add_argument('--lr_decay_iters', type=int, default=50, 44 | help='multiply by a gamma every lr_decay_iters iterations') 45 | 46 | parser.add_argument('--param_path', type=str) 47 | parser.add_argument('--light_path', type=str) 48 | parser.add_argument('--instance_path', type=str) 49 | parser.add_argument('--shadowimg_path', type=str) 50 | parser.add_argument('--shadowmask_path', type=str) 51 | parser.add_argument('--shadowfree_path', type=str) 52 | parser.add_argument('--light_vis_path', type=str) 53 | parser.add_argument('--bg_instance_path', type=str) 54 | parser.add_argument('--bg_shadow_path', type=str) 55 | parser.add_argument('--redark_path', type=str) 56 | parser.add_argument('--new_mask_path', type=str) 57 | 58 | 59 | parser.add_argument('--dataroot1', 60 | help='path to images (should have subfolders trainA, trainB, valA, valB, etc)') 61 | parser.add_argument('--param_path1', type=str) 62 | parser.add_argument('--light_path1', type=str) 63 | parser.add_argument('--instance_path1', type=str) 64 | parser.add_argument('--shadowimg_path1', type=str) 65 | parser.add_argument('--shadowmask_path1', type=str) 66 | parser.add_argument('--shadowfree_path1', type=str) 67 | parser.add_argument('--light_vis_path1', type=str) 68 | parser.add_argument('--bg_instance_path1', type=str) 69 | parser.add_argument('--bg_shadow_path1', type=str) 70 | parser.add_argument('--redark_path1', type=str) 71 | parser.add_argument('--new_mask_path1', type=str) 72 | 73 | 74 | 75 | parser.add_argument('--lambda_P1', type=float, default=1) 76 | parser.add_argument('--lambda_M1', type=float, default=1) 77 | parser.add_argument('--lambda_I1', type=float, default=1) 78 | parser.add_argument('--lambda_STN1', type=float, default=1) 79 | parser.add_argument('--lambda_REF1', type=float, default=1) 80 | parser.add_argument('--lambda_TV1', type=float, default=1) 81 | 82 | ####stn network 83 | #### 84 | parser.add_argument('--stn_model_type', type=str, default='unbounded_stn', 85 | help='no_stn, unbounded_stn, bounded_stn') 86 | parser.add_argument('--grid_size', type=int, default=4) 87 | parser.add_argument('--angle', type=int, default=60) 88 | parser.add_argument('--span_range', type=float, default=0.9) 89 | 90 | parser.add_argument('--bg_selfattention', type=int, default=0) 91 | parser.add_argument('--bg_maskattention', type=int, default=0) 92 | parser.add_argument('--adain_mask_generator', type=int, default=0) 93 | 94 | 95 | parser.add_argument('--warp_N', type=int, default=1) 96 | 97 | self.isTrain = True 98 | return parser 99 | -------------------------------------------------------------------------------- /src/options/train_options.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/options/train_options.pyc -------------------------------------------------------------------------------- /src/pytorch_ssim/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.gif 3 | *.png 4 | *.jpg 5 | test* 6 | !einstein.png 7 | !max_ssim.gif 8 | MANIFEST 9 | dist/* 10 | .sync-config.cson 11 | -------------------------------------------------------------------------------- /src/pytorch_ssim/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT 2 | -------------------------------------------------------------------------------- /src/pytorch_ssim/README.md: -------------------------------------------------------------------------------- 1 | # pytorch-ssim 2 | 3 | ### Differentiable structural similarity (SSIM) index. 4 | ![einstein](https://raw.githubusercontent.com/Po-Hsun-Su/pytorch-ssim/master/einstein.png) ![Max_ssim](https://raw.githubusercontent.com/Po-Hsun-Su/pytorch-ssim/master/max_ssim.gif) 5 | 6 | ## Installation 7 | 1. Clone this repo. 8 | 2. Copy "pytorch_ssim" folder in your project. 9 | 10 | ## Example 11 | ### basic usage 12 | ```python 13 | import pytorch_ssim 14 | import torch 15 | from torch.autograd import Variable 16 | 17 | img1 = Variable(torch.rand(1, 1, 256, 256)) 18 | img2 = Variable(torch.rand(1, 1, 256, 256)) 19 | 20 | if torch.cuda.is_available(): 21 | img1 = img1.cuda() 22 | img2 = img2.cuda() 23 | 24 | print(pytorch_ssim.ssim(img1, img2)) 25 | 26 | ssim_loss = pytorch_ssim.SSIM(window_size = 11) 27 | 28 | print(ssim_loss(img1, img2)) 29 | 30 | ``` 31 | ### maximize ssim 32 | ```python 33 | import pytorch_ssim 34 | import torch 35 | from torch.autograd import Variable 36 | from torch import optim 37 | import cv2 38 | import numpy as np 39 | 40 | npImg1 = cv2.imread("einstein.png") 41 | 42 | img1 = torch.from_numpy(np.rollaxis(npImg1, 2)).float().unsqueeze(0)/255.0 43 | img2 = torch.rand(img1.size()) 44 | 45 | if torch.cuda.is_available(): 46 | img1 = img1.cuda() 47 | img2 = img2.cuda() 48 | 49 | 50 | img1 = Variable( img1, requires_grad=False) 51 | img2 = Variable( img2, requires_grad = True) 52 | 53 | 54 | # Functional: pytorch_ssim.ssim(img1, img2, window_size = 11, size_average = True) 55 | ssim_value = pytorch_ssim.ssim(img1, img2).data[0] 56 | print("Initial ssim:", ssim_value) 57 | 58 | # Module: pytorch_ssim.SSIM(window_size = 11, size_average = True) 59 | ssim_loss = pytorch_ssim.SSIM() 60 | 61 | optimizer = optim.Adam([img2], lr=0.01) 62 | 63 | while ssim_value < 0.95: 64 | optimizer.zero_grad() 65 | ssim_out = -ssim_loss(img1, img2) 66 | ssim_value = - ssim_out.data[0] 67 | print(ssim_value) 68 | ssim_out.backward() 69 | optimizer.step() 70 | 71 | ``` 72 | 73 | ## Reference 74 | https://ece.uwaterloo.ca/~z70wang/research/ssim/ 75 | -------------------------------------------------------------------------------- /src/pytorch_ssim/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/pytorch_ssim/einstein.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/pytorch_ssim/einstein.png -------------------------------------------------------------------------------- /src/pytorch_ssim/max_ssim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/pytorch_ssim/max_ssim.gif -------------------------------------------------------------------------------- /src/pytorch_ssim/max_ssim.py: -------------------------------------------------------------------------------- 1 | import pytorch_ssim 2 | import torch 3 | from torch.autograd import Variable 4 | from torch import optim 5 | import cv2 6 | import numpy as np 7 | 8 | npImg1 = cv2.imread("einstein.png") 9 | 10 | img1 = torch.from_numpy(np.rollaxis(npImg1, 2)).float().unsqueeze(0)/255.0 11 | img2 = torch.rand(img1.size()) 12 | 13 | if torch.cuda.is_available(): 14 | img1 = img1.cuda() 15 | img2 = img2.cuda() 16 | 17 | 18 | img1 = Variable( img1, requires_grad=False) 19 | img2 = Variable( img2, requires_grad = True) 20 | 21 | 22 | # Functional: pytorch_ssim.ssim(img1, img2, window_size = 11, size_average = True) 23 | ssim_value = pytorch_ssim.ssim(img1, img2).data[0] 24 | print("Initial ssim:", ssim_value) 25 | 26 | # Module: pytorch_ssim.SSIM(window_size = 11, size_average = True) 27 | ssim_loss = pytorch_ssim.SSIM() 28 | 29 | optimizer = optim.Adam([img2], lr=0.01) 30 | 31 | while ssim_value < 0.95: 32 | optimizer.zero_grad() 33 | ssim_out = -ssim_loss(img1, img2) 34 | ssim_value = - ssim_out.data[0] 35 | print(ssim_value) 36 | ssim_out.backward() 37 | optimizer.step() 38 | -------------------------------------------------------------------------------- /src/pytorch_ssim/pytorch_ssim/__init__.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn.functional as F 3 | from torch.autograd import Variable 4 | import numpy as np 5 | from math import exp 6 | 7 | def gaussian(window_size, sigma): 8 | gauss = torch.Tensor([exp(-(x - window_size//2)**2/float(2*sigma**2)) for x in range(window_size)]) 9 | return gauss/gauss.sum() 10 | 11 | def create_window(window_size, channel): 12 | _1D_window = gaussian(window_size, 1.5).unsqueeze(1) 13 | _2D_window = _1D_window.mm(_1D_window.t()).float().unsqueeze(0).unsqueeze(0) 14 | window = Variable(_2D_window.expand(channel, 1, window_size, window_size).contiguous()) 15 | return window 16 | 17 | def _ssim(img1, img2, window, window_size, channel, size_average = True): 18 | mu1 = F.conv2d(img1, window, padding = window_size//2, groups = channel) 19 | mu2 = F.conv2d(img2, window, padding = window_size//2, groups = channel) 20 | 21 | mu1_sq = mu1.pow(2) 22 | mu2_sq = mu2.pow(2) 23 | mu1_mu2 = mu1*mu2 24 | 25 | sigma1_sq = F.conv2d(img1*img1, window, padding = window_size//2, groups = channel) - mu1_sq 26 | sigma2_sq = F.conv2d(img2*img2, window, padding = window_size//2, groups = channel) - mu2_sq 27 | sigma12 = F.conv2d(img1*img2, window, padding = window_size//2, groups = channel) - mu1_mu2 28 | 29 | C1 = 0.01**2 30 | C2 = 0.03**2 31 | 32 | ssim_map = ((2*mu1_mu2 + C1)*(2*sigma12 + C2))/((mu1_sq + mu2_sq + C1)*(sigma1_sq + sigma2_sq + C2)) 33 | 34 | if size_average: 35 | return ssim_map.mean() 36 | else: 37 | return ssim_map.mean(1).mean(1).mean(1) 38 | 39 | class SSIM(torch.nn.Module): 40 | def __init__(self, window_size = 11, size_average = True): 41 | super(SSIM, self).__init__() 42 | self.window_size = window_size 43 | self.size_average = size_average 44 | self.channel = 1 45 | self.window = create_window(window_size, self.channel) 46 | 47 | def forward(self, img1, img2): 48 | (_, channel, _, _) = img1.size() 49 | 50 | if channel == self.channel and self.window.data.type() == img1.data.type(): 51 | window = self.window 52 | else: 53 | window = create_window(self.window_size, channel) 54 | 55 | if img1.is_cuda: 56 | window = window.cuda(img1.get_device()) 57 | window = window.type_as(img1) 58 | 59 | self.window = window 60 | self.channel = channel 61 | 62 | 63 | return _ssim(img1, img2, window, self.window_size, channel, self.size_average) 64 | 65 | def ssim(img1, img2, window_size = 11, size_average = True): 66 | (_, channel, _, _) = img1.size() 67 | window = create_window(window_size, channel) 68 | 69 | if img1.is_cuda: 70 | window = window.cuda(img1.get_device()) 71 | window = window.type_as(img1) 72 | 73 | return _ssim(img1, img2, window, window_size, channel, size_average) 74 | -------------------------------------------------------------------------------- /src/pytorch_ssim/setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | -------------------------------------------------------------------------------- /src/pytorch_ssim/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | setup( 3 | name = 'pytorch_ssim', 4 | packages = ['pytorch_ssim'], # this must be the same as the name above 5 | version = '0.1', 6 | description = 'Differentiable structural similarity (SSIM) index', 7 | author = 'Po-Hsun (Evan) Su', 8 | author_email = 'evan.pohsun.su@gmail.com', 9 | url = 'https://github.com/Po-Hsun-Su/pytorch-ssim', # use the URL to the github repo 10 | download_url = 'https://github.com/Po-Hsun-Su/pytorch-ssim/archive/0.1.tar.gz', # I'll explain this in a second 11 | keywords = ['pytorch', 'image-processing', 'deep-learning'], # arbitrary keywords 12 | classifiers = [], 13 | ) 14 | -------------------------------------------------------------------------------- /src/script/ARShadowGAN_RealComposite.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=ARShadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | 25 | # model infomation 26 | checkpoint='../../TrainedModels/ARShadowGAN_TrainedModel/' 27 | model_name=ARShadow 28 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 29 | 30 | 31 | #####testing for real composite images 32 | datasetmode=ShadowGenerationDatasetInference2 33 | # dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/OneforegroundObject74/' 34 | dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/TwoforegroundObject26/' 35 | shadowfree_path=${dataroot}'/shadowfree_img' 36 | instance_path=${dataroot}'/foreground_object_mask' 37 | 38 | 39 | 40 | # TESTDATA="--bos" 41 | 42 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 43 | 44 | CMD="python ../generate.py --loadSize ${loadSize} \ 45 | --phase test --eval 46 | --name ${NAME} \ 47 | --checkpoints_dir ${checkpoint} \ 48 | --epoch latest\ 49 | --fineSize $fineSize --model $model\ 50 | --batch_size $batchs --display_port ${DISPLAY_PORT} 51 | --display_server http://localhost 52 | --gpu_ids ${GPU} --lr ${lr} \ 53 | --dataset_mode $datasetmode\ 54 | --norm instance\ 55 | --dataroot ${dataroot}\ 56 | --instance_path $instance_path\ 57 | --shadowfree_path $shadowfree_path\ 58 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 59 | --netG $G\ 60 | --ngf $ngf 61 | --netD $D 62 | --lr_D $lr_D 63 | $OTHER" 64 | 65 | echo $CMD 66 | eval $CMD 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/script/ARShadowGAN_test.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=ARShadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | #####datset selected 25 | datasetmode=shadowparam 26 | 27 | 28 | 29 | 30 | 31 | 32 | checkpoint='../../TrainedModels/ARShadowGAN_TrainedModel/' 33 | 34 | #####testing for desoba dataset 35 | #####testing for desoba dataset 36 | dataroot='../../DESOBA_DATASET/' 37 | shadowimage_path=${dataroot}'/ShadowImage' 38 | shadowfree_path=${dataroot}'/DeshadowedImage' 39 | new_mask_path=${dataroot}'/shadownewmask' 40 | param_path=${dataroot}'/SOBA_params' 41 | bg_shadow_path=${dataroot}'/ShadowMask' 42 | bg_instance_path=${dataroot}'/InstanceMask' 43 | 44 | 45 | model_name=ARShadow 46 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 47 | # TESTDATA="--bos" 48 | TESTDATA="--bosfree" 49 | 50 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 51 | 52 | CMD="python ../test.py --loadSize ${loadSize} \ 53 | --phase test --eval 54 | --name ${NAME} \ 55 | --checkpoints_dir ${checkpoint} \ 56 | --epoch latest\ 57 | --fineSize $fineSize --model $model\ 58 | --batch_size $batchs --display_port ${DISPLAY_PORT} 59 | --display_server http://localhost 60 | --gpu_ids ${GPU} --lr ${lr} \ 61 | --dataset_mode $datasetmode\ 62 | --norm instance\ 63 | --dataroot ${dataroot}\ 64 | --param_path $param_path\ 65 | --shadowimg_path $shadowimage_path\ 66 | --shadowfree_path $shadowfree_path\ 67 | --bg_shadow_path $bg_shadow_path\ 68 | --bg_instance_path $bg_instance_path\ 69 | --new_mask_path $new_mask_path\ 70 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 71 | --netG $G\ 72 | --ngf $ngf 73 | --netD $D 74 | --lr_D $lr_D 75 | 76 | 77 | $TESTDATA 78 | $OTHER" 79 | 80 | echo $CMD 81 | eval $CMD 82 | -------------------------------------------------------------------------------- /src/script/ARShadowGAN_train.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=ARShadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_light=0 15 | L_para=1 16 | L_shadowrecons=10 17 | L_imagerecons=10 18 | L_GAN=0.1 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | 25 | 26 | 27 | 28 | model_name=ARShadowGAN 29 | 30 | 31 | #####datset selected 32 | datasetmode=shadowparam 33 | 34 | 35 | 36 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 37 | FinetuneModel='${NAME}latest' 38 | 39 | 40 | 41 | 42 | #aaai 2021 43 | checkpoint='../../TrainedModels/New_ARShadowGAN_TrainedModel/' 44 | 45 | 46 | 47 | dataroot='../../DESOBA_DATASET/' 48 | shadowimage_path=${dataroot}'/ShadowImage' 49 | shadowfree_path=${dataroot}'/DeshadowedImage' 50 | new_mask_path=${dataroot}'/shadownewmask' 51 | param_path=${dataroot}'/SOBA_params' 52 | bg_shadow_path=${dataroot}'/ShadowMask' 53 | bg_instance_path=${dataroot}'/InstanceMask' 54 | 55 | 56 | 57 | 58 | OTHER="--save_epoch_freq 1 --display_freq 100 --niter 500 --niter_decay 2000 --no_crop --no_flip --no_rotate " 59 | 60 | CMD="python ../train.py --loadSize ${loadSize} \ 61 | --name ${NAME} \ 62 | --checkpoints_dir ${checkpoint} \ 63 | --fineSize $fineSize --model $model\ 64 | --batch_size $batchs --display_port ${DISPLAY_PORT} 65 | --display_server http://localhost 66 | --phase train --gpu_ids ${GPU} --lr ${lr} \ 67 | --dataset_mode $datasetmode\ 68 | 69 | --norm instance\ 70 | --dataroot ${dataroot}\ 71 | --param_path $param_path\ 72 | --shadowimg_path $shadowimage_path\ 73 | --shadowfree_path $shadowfree_path\ 74 | --bg_shadow_path $bg_shadow_path\ 75 | --bg_instance_path $bg_instance_path\ 76 | --new_mask_path $new_mask_path\ 77 | 78 | 79 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 80 | --netG $G\ 81 | --ngf $ngf 82 | --netD $D 83 | --lr_D $lr_D 84 | 85 | 86 | 87 | $OTHER 88 | " 89 | echo $CMD 90 | eval $CMD 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/script/MaskshadowGAN_RealComposite.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=MaskshadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=0.1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | # model infomation 25 | checkpoint='../../TrainedModels/MaskshadowGAN_TrainedModel' 26 | model_name=SelfAttention 27 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 28 | 29 | 30 | #####testing for real composite images 31 | datasetmode=ShadowGenerationDatasetInference2 32 | # dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/OneforegroundObject74/' 33 | dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/TwoforegroundObject26/' 34 | shadowfree_path=${dataroot}'/shadowfree_img' 35 | instance_path=${dataroot}'/foreground_object_mask' 36 | 37 | 38 | 39 | 40 | # TESTDATA="--bos" 41 | 42 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 43 | 44 | CMD="python ../generate.py --loadSize ${loadSize} \ 45 | --phase test --eval 46 | --name ${NAME} \ 47 | --checkpoints_dir ${checkpoint} \ 48 | --epoch latest\ 49 | --fineSize $fineSize --model $model\ 50 | --batch_size $batchs --display_port ${DISPLAY_PORT} 51 | --display_server http://localhost 52 | --gpu_ids ${GPU} --lr ${lr} \ 53 | --dataset_mode $datasetmode\ 54 | --norm instance\ 55 | --dataroot ${dataroot}\ 56 | --instance_path $instance_path\ 57 | --shadowfree_path $shadowfree_path\ 58 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 59 | --netG $G\ 60 | --ngf $ngf 61 | --netD $D 62 | --lr_D $lr_D 63 | 64 | 65 | $OTHER" 66 | 67 | echo $CMD 68 | eval $CMD 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/script/MaskshadowGAN_test.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=MaskshadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=0.1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | #####datset selected 25 | datasetmode=shadowparam 26 | 27 | 28 | 29 | 30 | 31 | 32 | checkpoint='../../TrainedModels/MaskshadowGAN_TrainedModel' 33 | 34 | #####testing for desoba dataset 35 | dataroot='../../DESOBA_DATASET/' 36 | shadowimage_path=${dataroot}'/ShadowImage' 37 | shadowfree_path=${dataroot}'/DeshadowedImage' 38 | new_mask_path=${dataroot}'/shadownewmask' 39 | param_path=${dataroot}'/SOBA_params' 40 | bg_shadow_path=${dataroot}'/ShadowMask' 41 | bg_instance_path=${dataroot}'/InstanceMask' 42 | 43 | model_name=SelfAttention 44 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 45 | # TESTDATA="--bos" 46 | TESTDATA="--bosfree" 47 | 48 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 49 | 50 | CMD="python ../test.py --loadSize ${loadSize} \ 51 | --phase test --eval 52 | --name ${NAME} \ 53 | --checkpoints_dir ${checkpoint} \ 54 | --epoch latest\ 55 | --fineSize $fineSize --model $model\ 56 | --batch_size $batchs --display_port ${DISPLAY_PORT} 57 | --display_server http://localhost 58 | --gpu_ids ${GPU} --lr ${lr} \ 59 | --dataset_mode $datasetmode\ 60 | --norm instance\ 61 | --dataroot ${dataroot}\ 62 | --param_path $param_path\ 63 | --shadowimg_path $shadowimage_path\ 64 | --shadowfree_path $shadowfree_path\ 65 | --bg_shadow_path $bg_shadow_path\ 66 | --bg_instance_path $bg_instance_path\ 67 | --new_mask_path $new_mask_path\ 68 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 69 | --netG $G\ 70 | --ngf $ngf 71 | --netD $D 72 | --lr_D $lr_D 73 | 74 | 75 | $TESTDATA 76 | $OTHER" 77 | 78 | echo $CMD 79 | eval $CMD 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/script/MaskshadowGAN_train.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=MaskshadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_light=0 15 | L_para=1 16 | L_shadowrecons=10 17 | L_imagerecons=10 18 | L_GAN=0.1 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | 25 | 26 | 27 | 28 | model_name=MaskshadowGAN 29 | 30 | 31 | #####datset selected 32 | datasetmode=shadowparam 33 | 34 | 35 | 36 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 37 | FinetuneModel='${NAME}latest' 38 | 39 | 40 | 41 | 42 | #aaai 2021 43 | checkpoint='../../TrainedModels/New_MaskshadowGAN_TrainedModel/' 44 | 45 | dataroot='../../DESOBA_DATASET/' 46 | shadowimage_path=${dataroot}'/ShadowImage' 47 | shadowfree_path=${dataroot}'/DeshadowedImage' 48 | new_mask_path=${dataroot}'/shadownewmask' 49 | param_path=${dataroot}'/SOBA_params' 50 | bg_shadow_path=${dataroot}'/ShadowMask' 51 | bg_instance_path=${dataroot}'/InstanceMask' 52 | 53 | 54 | 55 | OTHER="--save_epoch_freq 1 --display_freq 100 --niter 500 --niter_decay 2000 --no_crop --no_flip --no_rotate " 56 | 57 | CMD="python ../train.py --loadSize ${loadSize} \ 58 | --name ${NAME} \ 59 | --checkpoints_dir ${checkpoint} \ 60 | --fineSize $fineSize --model $model\ 61 | --batch_size $batchs --display_port ${DISPLAY_PORT} 62 | --display_server http://localhost 63 | --phase train --gpu_ids ${GPU} --lr ${lr} \ 64 | --dataset_mode $datasetmode\ 65 | 66 | --norm instance\ 67 | --dataroot ${dataroot}\ 68 | --param_path $param_path\ 69 | --shadowimg_path $shadowimage_path\ 70 | --shadowfree_path $shadowfree_path\ 71 | --bg_shadow_path $bg_shadow_path\ 72 | --bg_instance_path $bg_instance_path\ 73 | --new_mask_path $new_mask_path\ 74 | 75 | 76 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 77 | --netG $G\ 78 | --ngf $ngf 79 | --netD $D 80 | --lr_D $lr_D 81 | 82 | 83 | 84 | $OTHER 85 | " 86 | echo $CMD 87 | eval $CMD 88 | -------------------------------------------------------------------------------- /src/script/Pix2pixRes_test.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=Pix2pix 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | Residual=1 18 | 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | 25 | 26 | #####datset selected 27 | datasetmode=shadowparam 28 | 29 | 30 | 31 | 32 | 33 | 34 | checkpoint='../../TrainedModels/Pix2pixRes_TrainedModel/' 35 | 36 | #####testing for desoba dataset 37 | dataroot='../../DESOBA_DATASET/' 38 | shadowimage_path=${dataroot}'/ShadowImage' 39 | shadowfree_path=${dataroot}'/DeshadowedImage' 40 | new_mask_path=${dataroot}'/shadownewmask' 41 | param_path=${dataroot}'/SOBA_params' 42 | bg_shadow_path=${dataroot}'/ShadowMask' 43 | bg_instance_path=${dataroot}'/InstanceMask' 44 | 45 | model_name=Basic 46 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 47 | # TESTDATA="--bos" 48 | TESTDATA="--bos" 49 | 50 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 51 | 52 | CMD="python ../test.py --loadSize ${loadSize} \ 53 | --phase test --eval 54 | --name ${NAME} \ 55 | --checkpoints_dir ${checkpoint} \ 56 | --epoch latest\ 57 | --fineSize $fineSize --model $model\ 58 | --batch_size $batchs --display_port ${DISPLAY_PORT} 59 | --display_server http://localhost 60 | --gpu_ids ${GPU} --lr ${lr} \ 61 | --dataset_mode $datasetmode\ 62 | --norm instance\ 63 | --dataroot ${dataroot}\ 64 | --param_path $param_path\ 65 | --shadowimg_path $shadowimage_path\ 66 | --shadowfree_path $shadowfree_path\ 67 | --bg_shadow_path $bg_shadow_path\ 68 | --bg_instance_path $bg_instance_path\ 69 | --new_mask_path $new_mask_path\ 70 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 71 | --netG $G\ 72 | --ngf $ngf 73 | --netD $D 74 | --lr_D $lr_D 75 | --residual $Residual 76 | 77 | $TESTDATA 78 | $OTHER" 79 | 80 | echo $CMD 81 | eval $CMD 82 | -------------------------------------------------------------------------------- /src/script/Pix2pixRes_train.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=Pix2pix 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_light=0 15 | L_para=1 16 | L_shadowrecons=10 17 | L_imagerecons=10 18 | L_GAN=1 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | Residual=1 25 | 26 | 27 | 28 | model_name=Pix2pixRes 29 | 30 | 31 | #####datset selected 32 | datasetmode=shadowparam 33 | 34 | 35 | 36 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 37 | FinetuneModel='${NAME}latest' 38 | 39 | 40 | 41 | 42 | #aaai 2021 43 | checkpoint='../../TrainedModels/New_Pix2pixRes_TrainedModel/' 44 | 45 | 46 | 47 | dataroot='../../DESOBA_DATASET/' 48 | shadowimage_path=${dataroot}'/ShadowImage' 49 | shadowfree_path=${dataroot}'/DeshadowedImage' 50 | new_mask_path=${dataroot}'/shadownewmask' 51 | param_path=${dataroot}'/SOBA_params' 52 | bg_shadow_path=${dataroot}'/ShadowMask' 53 | bg_instance_path=${dataroot}'/InstanceMask' 54 | 55 | 56 | 57 | 58 | OTHER="--save_epoch_freq 1 --display_freq 100 --niter 500 --niter_decay 2000 --no_crop --no_flip --no_rotate " 59 | 60 | CMD="python ../train.py --loadSize ${loadSize} \ 61 | --name ${NAME} \ 62 | --checkpoints_dir ${checkpoint} \ 63 | --fineSize $fineSize --model $model\ 64 | --batch_size $batchs --display_port ${DISPLAY_PORT} 65 | --display_server http://localhost 66 | --phase train --gpu_ids ${GPU} --lr ${lr} \ 67 | --dataset_mode $datasetmode\ 68 | 69 | --norm instance\ 70 | --dataroot ${dataroot}\ 71 | --param_path $param_path\ 72 | --shadowimg_path $shadowimage_path\ 73 | --shadowfree_path $shadowfree_path\ 74 | --bg_shadow_path $bg_shadow_path\ 75 | --bg_instance_path $bg_instance_path\ 76 | --new_mask_path $new_mask_path\ 77 | 78 | 79 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 80 | --netG $G\ 81 | --ngf $ngf 82 | --netD $D 83 | --lr_D $lr_D 84 | --residual $Residual 85 | 86 | 87 | 88 | $OTHER 89 | " 90 | echo $CMD 91 | eval $CMD 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/script/Pix2pix_test.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=Pix2pix 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | Residual=0 18 | 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | 25 | 26 | #####datset selected 27 | datasetmode=shadowparam 28 | 29 | 30 | 31 | 32 | 33 | 34 | checkpoint='../../TrainedModels/Pix2pix_TrainedModel/' 35 | 36 | #####testing for desoba dataset 37 | dataroot='../../DESOBA_DATASET/' 38 | shadowimage_path=${dataroot}'/ShadowImage' 39 | shadowfree_path=${dataroot}'/DeshadowedImage' 40 | new_mask_path=${dataroot}'/shadownewmask' 41 | param_path=${dataroot}'/SOBA_params' 42 | bg_shadow_path=${dataroot}'/ShadowMask' 43 | bg_instance_path=${dataroot}'/InstanceMask' 44 | 45 | model_name=Basic 46 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 47 | # TESTDATA="--bos" 48 | TESTDATA="--bos" 49 | 50 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 51 | 52 | CMD="python ../test.py --loadSize ${loadSize} \ 53 | --phase test --eval 54 | --name ${NAME} \ 55 | --checkpoints_dir ${checkpoint} \ 56 | --epoch latest\ 57 | --fineSize $fineSize --model $model\ 58 | --batch_size $batchs --display_port ${DISPLAY_PORT} 59 | --display_server http://localhost 60 | --gpu_ids ${GPU} --lr ${lr} \ 61 | --dataset_mode $datasetmode\ 62 | --norm instance\ 63 | --dataroot ${dataroot}\ 64 | --param_path $param_path\ 65 | --shadowimg_path $shadowimage_path\ 66 | --shadowfree_path $shadowfree_path\ 67 | --bg_shadow_path $bg_shadow_path\ 68 | --bg_instance_path $bg_instance_path\ 69 | --new_mask_path $new_mask_path\ 70 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 71 | --netG $G\ 72 | --ngf $ngf 73 | --netD $D 74 | --lr_D $lr_D 75 | 76 | $TESTDATA 77 | $OTHER" 78 | 79 | echo $CMD 80 | eval $CMD 81 | 82 | -------------------------------------------------------------------------------- /src/script/Pix2pix_train.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=Pix2pix 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_light=0 15 | L_para=1 16 | L_shadowrecons=10 17 | L_imagerecons=10 18 | L_GAN=1 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | Residual=0 25 | 26 | 27 | 28 | model_name=Pix2pix 29 | 30 | 31 | #####datset selected 32 | datasetmode=shadowparam 33 | 34 | 35 | 36 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 37 | FinetuneModel='${NAME}latest' 38 | 39 | 40 | 41 | 42 | #aaai 2021 43 | checkpoint='../../TrainedModels/New_Pix2pix_TrainedModel/' 44 | 45 | 46 | 47 | dataroot='../../DESOBA_DATASET/' 48 | shadowimage_path=${dataroot}'/ShadowImage' 49 | shadowfree_path=${dataroot}'/DeshadowedImage' 50 | new_mask_path=${dataroot}'/shadownewmask' 51 | param_path=${dataroot}'/SOBA_params' 52 | bg_shadow_path=${dataroot}'/ShadowMask' 53 | bg_instance_path=${dataroot}'/InstanceMask' 54 | 55 | 56 | 57 | OTHER="--save_epoch_freq 1 --display_freq 100 --niter 500 --niter_decay 2000 --no_crop --no_flip --no_rotate " 58 | 59 | CMD="python ../train.py --loadSize ${loadSize} \ 60 | --name ${NAME} \ 61 | --checkpoints_dir ${checkpoint} \ 62 | --fineSize $fineSize --model $model\ 63 | --batch_size $batchs --display_port ${DISPLAY_PORT} 64 | --display_server http://localhost 65 | --phase train --gpu_ids ${GPU} --lr ${lr} \ 66 | --dataset_mode $datasetmode\ 67 | 68 | --norm instance\ 69 | --dataroot ${dataroot}\ 70 | --param_path $param_path\ 71 | --shadowimg_path $shadowimage_path\ 72 | --shadowfree_path $shadowfree_path\ 73 | --bg_shadow_path $bg_shadow_path\ 74 | --bg_instance_path $bg_instance_path\ 75 | --new_mask_path $new_mask_path\ 76 | 77 | 78 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 79 | --netG $G\ 80 | --ngf $ngf 81 | --netD $D 82 | --lr_D $lr_D 83 | --residual $Residual 84 | 85 | 86 | 87 | $OTHER 88 | " 89 | echo $CMD 90 | eval $CMD 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/script/SGRNet_RealComposite.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=SGRNet 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=0.1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | #####datset selected 25 | # datasetmode=shadowparam 26 | datasetmode=ShadowGenerationDatasetInference 27 | 28 | 29 | 30 | 31 | 32 | 33 | checkpoint='../../TrainedModels/SGRNet_TrainedModel' 34 | 35 | #####testing for real composite images 36 | # dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/OneforegroundObject74/' 37 | dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/TwoforegroundObject26/' 38 | 39 | 40 | 41 | shadowimage_path=${dataroot}'/shadowfree_img' 42 | shadowfree_path=${dataroot}'/shadowfree_img' 43 | mask_path=${dataroot}'/foreground_object_mask' 44 | instance_path=${dataroot}'/foreground_object_mask' 45 | bg_shadow_path=${dataroot}'/background_shadow_mask' 46 | bg_instance_path=${dataroot}'/background_object_mask' 47 | 48 | 49 | model_name=SelfAttention 50 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 51 | 52 | 53 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 54 | 55 | CMD="python ../generate.py --loadSize ${loadSize} \ 56 | --phase test --eval 57 | --name ${NAME} \ 58 | --checkpoints_dir ${checkpoint} \ 59 | --epoch latest\ 60 | --fineSize $fineSize --model $model\ 61 | --batch_size $batchs --display_port ${DISPLAY_PORT} 62 | --display_server http://localhost 63 | --gpu_ids ${GPU} --lr ${lr} \ 64 | --dataset_mode $datasetmode\ 65 | --mask_train $mask_path\ 66 | --norm instance\ 67 | --dataroot ${dataroot}\ 68 | --instance_path $instance_path\ 69 | --shadowimg_path $shadowimage_path\ 70 | --shadowmask_path $mask_path\ 71 | --shadowfree_path $shadowfree_path\ 72 | --bg_shadow_path $bg_shadow_path\ 73 | --bg_instance_path $bg_instance_path\ 74 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 75 | --netG $G\ 76 | --ngf $ngf 77 | --netD $D 78 | --lr_D $lr_D 79 | 80 | $OTHER" 81 | 82 | echo $CMD 83 | eval $CMD 84 | 85 | -------------------------------------------------------------------------------- /src/script/SGRNet_RealComposite_2.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=SGRNet 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=0.1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | #model infomation 25 | checkpoint='../../TrainedModels/SGRNet_TrainedModel' 26 | model_name=SelfAttention 27 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 28 | 29 | 30 | 31 | #####testing for real composite images 32 | datasetmode=ShadowGenerationDatasetInference2 33 | # dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/OneforegroundObject74/' 34 | dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/TwoforegroundObject26/' 35 | shadowfree_path=${dataroot}'/shadowfree_img' 36 | instance_path=${dataroot}'/foreground_object_mask' 37 | 38 | 39 | 40 | 41 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 42 | 43 | CMD="python ../generate.py --loadSize ${loadSize} \ 44 | --phase test --eval 45 | --name ${NAME} \ 46 | --checkpoints_dir ${checkpoint} \ 47 | --epoch latest\ 48 | --fineSize $fineSize --model $model\ 49 | --batch_size $batchs --display_port ${DISPLAY_PORT} 50 | --display_server http://localhost 51 | --gpu_ids ${GPU} --lr ${lr} \ 52 | --dataset_mode $datasetmode\ 53 | --norm instance\ 54 | --dataroot ${dataroot}\ 55 | --instance_path $instance_path\ 56 | --shadowfree_path $shadowfree_path\ 57 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 58 | --netG $G\ 59 | --ngf $ngf 60 | --netD $D 61 | --lr_D $lr_D 62 | 63 | $OTHER" 64 | 65 | echo $CMD 66 | eval $CMD 67 | 68 | -------------------------------------------------------------------------------- /src/script/SGRNet_test.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=SGRNet 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=0.1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | #####datset selected 25 | datasetmode=shadowparam 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | checkpoint='../../TrainedModels/SGRNet_TrainedModel' 34 | 35 | #####testing for desoba dataset 36 | dataroot='../../DESOBA_DATASET/' 37 | shadowimage_path=${dataroot}'/ShadowImage' 38 | shadowfree_path=${dataroot}'/DeshadowedImage' 39 | new_mask_path=${dataroot}'/shadownewmask' 40 | param_path=${dataroot}'/SOBA_params' 41 | bg_shadow_path=${dataroot}'/ShadowMask' 42 | bg_instance_path=${dataroot}'/InstanceMask' 43 | 44 | model_name=SelfAttention 45 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 46 | 47 | # TESTDATA="--bos" 48 | TESTDATA="--bos" 49 | 50 | OTHER="--no_crop --no_flip --no_rotate --serial_batches --no_dropout" 51 | 52 | CMD="python ../test.py --loadSize ${loadSize} \ 53 | --phase test --eval 54 | --name ${NAME} \ 55 | --checkpoints_dir ${checkpoint} \ 56 | --epoch latest\ 57 | --fineSize $fineSize --model $model\ 58 | --batch_size $batchs --display_port ${DISPLAY_PORT} 59 | --display_server http://localhost 60 | --gpu_ids ${GPU} --lr ${lr} \ 61 | --dataset_mode $datasetmode\ 62 | --norm instance\ 63 | --dataroot ${dataroot}\ 64 | --param_path $param_path\ 65 | --shadowimg_path $shadowimage_path\ 66 | --shadowfree_path $shadowfree_path\ 67 | --bg_shadow_path $bg_shadow_path\ 68 | --bg_instance_path $bg_instance_path\ 69 | --new_mask_path $new_mask_path\ 70 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 71 | --netG $G\ 72 | --ngf $ngf 73 | --netD $D 74 | --lr_D $lr_D 75 | 76 | $TESTDATA 77 | $OTHER" 78 | 79 | echo $CMD 80 | eval $CMD 81 | 82 | -------------------------------------------------------------------------------- /src/script/SGRNet_test_fromTestpairs.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=SGRNet 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=0.1 17 | 18 | #####network design 19 | DISPLAY_PORT=8002 20 | D='pixel' 21 | lr_D=0.0002 22 | 23 | 24 | #####datset selected 25 | # datasetmode=shadowparam 26 | datasetmode=ShadowGenerationDatasetInference 27 | 28 | 29 | 30 | 31 | 32 | checkpoint='/media/user/data/ShadowGeneration/HYShadowGeneration/SGRNet/TrainedModels/SGRNet_TrainedModel' 33 | 34 | #####testing for desoba dataset 35 | dataroot='/media/user/data/ShadowGeneration/HYShadowGeneration/SGRNet/DESOBA_DATASET/TestSplit/bos' 36 | # dataroot='/media/user/data/ShadowGeneration/HYShadowGeneration/SGRNet/DESOBA_DATASET/TestSplit/bosfree' 37 | 38 | shadowimage_path=${dataroot}'/shadow_img' 39 | shadowfree_path=${dataroot}'/shadowfree_img' 40 | mask_path=${dataroot}'/foreground_shadow_mask' 41 | instance_path=${dataroot}'/foreground_object_mask' 42 | bg_shadow_path=${dataroot}'/background_shadow_mask' 43 | bg_instance_path=${dataroot}'/background_object_mask' 44 | 45 | 46 | model_name=SelfAttention 47 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 48 | 49 | 50 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 51 | 52 | CMD="python ../test.py --loadSize ${loadSize} \ 53 | --phase test --eval 54 | --name ${NAME} \ 55 | --checkpoints_dir ${checkpoint} \ 56 | --epoch latest\ 57 | --fineSize $fineSize --model $model\ 58 | --batch_size $batchs --display_port ${DISPLAY_PORT} 59 | --display_server http://localhost 60 | --gpu_ids ${GPU} --lr ${lr} \ 61 | --dataset_mode $datasetmode\ 62 | --mask_train $mask_path\ 63 | --norm instance\ 64 | --dataroot ${dataroot}\ 65 | --instance_path $instance_path\ 66 | --shadowimg_path $shadowimage_path\ 67 | --shadowmask_path $mask_path\ 68 | --shadowfree_path $shadowfree_path\ 69 | --bg_shadow_path $bg_shadow_path\ 70 | --bg_instance_path $bg_instance_path\ 71 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 72 | --netG $G\ 73 | --ngf $ngf 74 | --netD $D 75 | --lr_D $lr_D 76 | --bos 77 | 78 | $OTHER" 79 | 80 | echo $CMD 81 | eval $CMD 82 | 83 | -------------------------------------------------------------------------------- /src/script/SGRNet_train.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=SGRNet 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_light=0 15 | L_para=1 16 | L_shadowrecons=10 17 | L_imagerecons=10 18 | L_GAN=0.1 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | 25 | 26 | 27 | 28 | model_name=SGRNet 29 | 30 | 31 | #####datset selected 32 | datasetmode=shadowparam 33 | 34 | 35 | 36 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 37 | 38 | 39 | 40 | 41 | #aaai 2021 42 | checkpoint='../../TrainedModels/New_SGRNet_TrainedModel/' 43 | 44 | 45 | 46 | dataroot='../../DESOBA_DATASET/' 47 | shadowimage_path=${dataroot}'/ShadowImage' 48 | shadowfree_path=${dataroot}'/DeshadowedImage' 49 | new_mask_path=${dataroot}'/shadownewmask' 50 | param_path=${dataroot}'/SOBA_params' 51 | bg_shadow_path=${dataroot}'/ShadowMask' 52 | bg_instance_path=${dataroot}'/InstanceMask' 53 | 54 | 55 | 56 | OTHER="--save_epoch_freq 1 --display_freq 100 --niter 100 --niter_decay 300 --no_crop --no_flip --no_rotate " 57 | 58 | CMD="python ../train.py --loadSize ${loadSize} \ 59 | --name ${NAME} \ 60 | --phase train 61 | --checkpoints_dir ${checkpoint} \ 62 | --fineSize $fineSize --model $model\ 63 | --batch_size $batchs --display_port ${DISPLAY_PORT} 64 | --display_server http://localhost 65 | --gpu_ids ${GPU} --lr ${lr} \ 66 | --dataset_mode $datasetmode\ 67 | 68 | --norm instance\ 69 | --dataroot ${dataroot}\ 70 | --param_path $param_path\ 71 | --shadowimg_path $shadowimage_path\ 72 | --shadowfree_path $shadowfree_path\ 73 | --bg_shadow_path $bg_shadow_path\ 74 | --bg_instance_path $bg_instance_path\ 75 | --new_mask_path $new_mask_path\ 76 | 77 | 78 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 79 | --netG $G\ 80 | --ngf $ngf 81 | --netD $D 82 | --lr_D $lr_D 83 | 84 | 85 | 86 | $OTHER 87 | " 88 | echo $CMD 89 | eval $CMD 90 | -------------------------------------------------------------------------------- /src/script/ShadowGAN_RealComposite.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=ShadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | 18 | 19 | #####network design 20 | DISPLAY_PORT=8002 21 | D='pixel' 22 | lr_D=0.0002 23 | 24 | 25 | # model infomation 26 | checkpoint='../../TrainedModels/ShadowGAN_TrainedModel/' 27 | model_name=Basic 28 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 29 | 30 | 31 | #####testing for real composite images 32 | datasetmode=ShadowGenerationDatasetInference2 33 | # dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/OneforegroundObject74/' 34 | dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/TwoforegroundObject26/' 35 | shadowfree_path=${dataroot}'/shadowfree_img' 36 | instance_path=${dataroot}'/foreground_object_mask' 37 | 38 | 39 | 40 | 41 | # TESTDATA="--bos" 42 | 43 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 44 | 45 | CMD="python ../generate.py --loadSize ${loadSize} \ 46 | --phase test --eval 47 | --name ${NAME} \ 48 | --checkpoints_dir ${checkpoint} \ 49 | --epoch latest\ 50 | --fineSize $fineSize --model $model\ 51 | --batch_size $batchs --display_port ${DISPLAY_PORT} 52 | --display_server http://localhost 53 | --gpu_ids ${GPU} --lr ${lr} \ 54 | --dataset_mode $datasetmode\ 55 | --norm instance\ 56 | --dataroot ${dataroot}\ 57 | --instance_path $instance_path\ 58 | --shadowfree_path $shadowfree_path\ 59 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 60 | --netG $G\ 61 | --ngf $ngf 62 | --netD $D 63 | --lr_D $lr_D 64 | 65 | $OTHER" 66 | 67 | echo $CMD 68 | eval $CMD 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/script/ShadowGAN_test.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=ShadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | 18 | 19 | #####network design 20 | DISPLAY_PORT=8002 21 | D='pixel' 22 | lr_D=0.0002 23 | 24 | 25 | #####datset selected 26 | datasetmode=shadowparam 27 | 28 | 29 | checkpoint='../../TrainedModels/ShadowGAN_TrainedModel/' 30 | 31 | #####testing for desoba dataset 32 | #####testing for desoba dataset 33 | dataroot='../../DESOBA_DATASET/' 34 | shadowimage_path=${dataroot}'/ShadowImage' 35 | shadowfree_path=${dataroot}'/DeshadowedImage' 36 | new_mask_path=${dataroot}'/shadownewmask' 37 | param_path=${dataroot}'/SOBA_params' 38 | bg_shadow_path=${dataroot}'/ShadowMask' 39 | bg_instance_path=${dataroot}'/InstanceMask' 40 | 41 | model_name=Basic 42 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 43 | # TESTDATA="--bos" 44 | TESTDATA="--bos" 45 | 46 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 47 | 48 | CMD="python ../test.py --loadSize ${loadSize} \ 49 | --phase test --eval 50 | --name ${NAME} \ 51 | --checkpoints_dir ${checkpoint} \ 52 | --epoch latest\ 53 | --fineSize $fineSize --model $model\ 54 | --batch_size $batchs --display_port ${DISPLAY_PORT} 55 | --display_server http://localhost 56 | --gpu_ids ${GPU} --lr ${lr} \ 57 | --dataset_mode $datasetmode\ 58 | --norm instance\ 59 | --dataroot ${dataroot}\ 60 | --param_path $param_path\ 61 | --shadowimg_path $shadowimage_path\ 62 | --shadowfree_path $shadowfree_path\ 63 | --bg_shadow_path $bg_shadow_path\ 64 | --bg_instance_path $bg_instance_path\ 65 | --new_mask_path $new_mask_path\ 66 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 67 | --netG $G\ 68 | --ngf $ngf 69 | --netD $D 70 | --lr_D $lr_D 71 | 72 | 73 | $TESTDATA 74 | $OTHER" 75 | 76 | echo $CMD 77 | eval $CMD 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/script/ShadowGAN_train.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=ShadowGAN 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_light=0 15 | L_para=1 16 | L_shadowrecons=10 17 | L_imagerecons=10 18 | L_GAN=1 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | Residual=0 25 | 26 | 27 | 28 | 29 | 30 | 31 | #####datset selected 32 | datasetmode=shadowparam 33 | 34 | model_name=Basic 35 | NAME="${model_name}_G${G}_C${ngf}_D${D}_lrD${lr_D}" 36 | 37 | 38 | 39 | 40 | #aaai 2021 41 | checkpoint='../../TrainedModels/New_ShadowGAN_TrainedModel/' 42 | 43 | 44 | 45 | dataroot='../../DESOBA_DATASET/' 46 | shadowimage_path=${dataroot}'/ShadowImage' 47 | shadowfree_path=${dataroot}'/DeshadowedImage' 48 | new_mask_path=${dataroot}'/shadownewmask' 49 | param_path=${dataroot}'/SOBA_params' 50 | bg_shadow_path=${dataroot}'/ShadowMask' 51 | bg_instance_path=${dataroot}'/InstanceMask' 52 | 53 | 54 | 55 | 56 | OTHER="--save_epoch_freq 1 --display_freq 100 --niter 500 --niter_decay 2000 --no_crop --no_flip --no_rotate " 57 | 58 | CMD="python ../train.py --loadSize ${loadSize} \ 59 | --name ${NAME} \ 60 | --checkpoints_dir ${checkpoint} \ 61 | --fineSize $fineSize --model $model\ 62 | --batch_size $batchs --display_port ${DISPLAY_PORT} 63 | --display_server http://localhost 64 | --phase train --gpu_ids ${GPU} --lr ${lr} \ 65 | --dataset_mode $datasetmode\ 66 | 67 | --norm instance\ 68 | --dataroot ${dataroot}\ 69 | --param_path $param_path\ 70 | --shadowimg_path $shadowimage_path\ 71 | --shadowfree_path $shadowfree_path\ 72 | --bg_shadow_path $bg_shadow_path\ 73 | --bg_instance_path $bg_instance_path\ 74 | --new_mask_path $new_mask_path\ 75 | 76 | 77 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 78 | --netG $G\ 79 | --ngf $ngf 80 | --netD $D 81 | --lr_D $lr_D 82 | --residual $Residual 83 | 84 | 85 | 86 | $OTHER 87 | " 88 | echo $CMD 89 | eval $CMD 90 | -------------------------------------------------------------------------------- /src/script/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/script/pix2pixRes_RealComposite.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=Pix2pix 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | Residual=1 18 | 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | 25 | 26 | #####datset selected 27 | datasetmode=ShadowGenerationDatasetInference 28 | 29 | 30 | 31 | 32 | 33 | 34 | checkpoint='/media/user/data/ShadowGeneration/HYShadowGeneration/SGRNet/TrainedModels/Pix2pixRes_TrainedModel/' 35 | 36 | #####testing for desoba dataset 37 | # dataroot='/media/user/data/ShadowGeneration/HYShadowGeneration/SGRNet/DESOBA_DATASET/OneForeground_Composite_Images/OneforegroundCompositeSplit_Formal/' 38 | # dataroot='/media/user/data/ShadowGeneration/HYShadowGeneration/SGRNet/DESOBA_DATASET/CompositionShadowGeneration-100/OneforegroundObject74/' 39 | dataroot='/media/user/data/ShadowGeneration/HYShadowGeneration/SGRNet/DESOBA_DATASET/CompositionShadowGeneration-100/TwoforegroundObject26/' 40 | 41 | 42 | 43 | shadowimage_path=${dataroot}'/shadowfree_img' 44 | shadowfree_path=${dataroot}'/shadowfree_img' 45 | mask_path=${dataroot}'/foreground_object_mask' 46 | instance_path=${dataroot}'/foreground_object_mask' 47 | bg_shadow_path=${dataroot}'/background_shadow_mask' 48 | bg_instance_path=${dataroot}'/background_object_mask' 49 | 50 | 51 | model_name=Basic 52 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 53 | 54 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 55 | 56 | CMD="python ../generate.py --loadSize ${loadSize} \ 57 | --phase test --eval 58 | --name ${NAME} \ 59 | --checkpoints_dir ${checkpoint} \ 60 | --epoch latest\ 61 | --fineSize $fineSize --model $model\ 62 | --batch_size $batchs --display_port ${DISPLAY_PORT} 63 | --display_server http://localhost 64 | --gpu_ids ${GPU} --lr ${lr} \ 65 | --dataset_mode $datasetmode\ 66 | --mask_train $mask_path\ 67 | --norm instance\ 68 | --dataroot ${dataroot}\ 69 | --instance_path $instance_path\ 70 | --shadowimg_path $shadowimage_path\ 71 | --shadowmask_path $mask_path\ 72 | --shadowfree_path $shadowfree_path\ 73 | --bg_shadow_path $bg_shadow_path\ 74 | --bg_instance_path $bg_instance_path\ 75 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 76 | --netG $G\ 77 | --ngf $ngf 78 | --netD $D 79 | --lr_D $lr_D 80 | --residual $Residual 81 | 82 | 83 | $OTHER" 84 | 85 | echo $CMD 86 | eval $CMD 87 | 88 | -------------------------------------------------------------------------------- /src/script/pix2pix_RealComposite.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | batchs=1 4 | GPU=0 5 | lr=0.0002 6 | loadSize=256 7 | fineSize=256 8 | L1=100 9 | model=Pix2pix 10 | G='RESNEXT18' 11 | ngf=32 12 | 13 | 14 | L_shadowrecons=10 15 | L_imagerecons=10 16 | L_GAN=1 17 | Residual=0 18 | 19 | 20 | #####network design 21 | DISPLAY_PORT=8002 22 | D='pixel' 23 | lr_D=0.0002 24 | 25 | 26 | 27 | # model infomation 28 | checkpoint='../../TrainedModels/Pix2pix_TrainedModel/' 29 | model_name=Basic 30 | NAME="${model_name}_C${ngf}_D${D}_lrD${lr_D}" 31 | 32 | 33 | #####testing for real composite images 34 | datasetmode=ShadowGenerationDatasetInference2 35 | # dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/OneforegroundObject74/' 36 | dataroot='../../DESOBA_DATASET/CompositionShadowGeneration-100/TwoforegroundObject26/' 37 | shadowfree_path=${dataroot}'/shadowfree_img' 38 | instance_path=${dataroot}'/foreground_object_mask' 39 | 40 | 41 | OTHER="--no_crop --no_flip --no_rotate --serial_batches" 42 | 43 | CMD="python ../generate.py --loadSize ${loadSize} \ 44 | --phase test --eval 45 | --name ${NAME} \ 46 | --checkpoints_dir ${checkpoint} \ 47 | --epoch latest\ 48 | --fineSize $fineSize --model $model\ 49 | --batch_size $batchs --display_port ${DISPLAY_PORT} 50 | --display_server http://localhost 51 | --gpu_ids ${GPU} --lr ${lr} \ 52 | --dataset_mode $datasetmode\ 53 | --norm instance\ 54 | --dataroot ${dataroot}\ 55 | --instance_path $instance_path\ 56 | --shadowfree_path $shadowfree_path\ 57 | --lambda_M1 $L_shadowrecons --lambda_I1 $L_imagerecons --lambda_GAN $L_GAN 58 | --netG $G\ 59 | --ngf $ngf 60 | --netD $D 61 | --lr_D $lr_D 62 | 63 | $OTHER" 64 | 65 | echo $CMD 66 | eval $CMD 67 | 68 | -------------------------------------------------------------------------------- /src/test.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | from options.test_options import TestOptions 3 | from data import CreateDataLoader 4 | from models import create_model 5 | from util.visualizer import Visualizer 6 | from PIL import Image 7 | import visdom 8 | from util.util import sdmkdir 9 | import time 10 | import tqdm 11 | import numpy as np 12 | import math 13 | import torch 14 | 15 | opt = TestOptions().parse() 16 | data_loader = CreateDataLoader(opt) 17 | dataset = data_loader.load_data() 18 | dataset_size = len(data_loader) 19 | model = create_model(opt) 20 | model.setup(opt) 21 | visualizer = Visualizer(opt) 22 | 23 | 24 | RMSES = [] 25 | shadowRMSES = [] 26 | SSIMS = [] 27 | shadowSSIMS = [] 28 | 29 | 30 | for i, data in enumerate(dataset): 31 | model.set_input(data) 32 | model.prediction() 33 | lenght, visual_dict = model.get_current_visuals() 34 | visualizer.display_current_results(visual_dict, i) 35 | RMSE,shadowRMSE, SSIM, shadowSSIM = model.get_current_errors() 36 | RMSES.append(RMSE) 37 | shadowRMSES.append(shadowRMSE) 38 | SSIMS.append(SSIM) 39 | shadowSSIMS.append(shadowSSIM) 40 | 41 | 42 | RMSES_final = np.mean(np.array(RMSES)) 43 | shadowRMSES_final = np.mean(np.array(shadowRMSES)) 44 | SSIMS_final = (torch.mean(torch.tensor(SSIMS))) 45 | shadowSSIMS_final = torch.mean(torch.tensor(shadowSSIMS)) 46 | 47 | if opt.bos: 48 | print('totally {} test bos images'.format(len(RMSES))) 49 | elif opt.bosfree: 50 | print('totally {} test bosfree images'.format(len(RMSES))) 51 | 52 | print('final rmse is', RMSES_final) 53 | print('final shadowrmse is', shadowRMSES_final) 54 | print('final ssim is', SSIMS_final) 55 | print('final shadowssim is', shadowSSIMS_final) 56 | 57 | -------------------------------------------------------------------------------- /src/train.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | from options.train_options import TrainOptions 3 | from data import CreateDataLoader 4 | from models import create_model 5 | from util.visualizer import Visualizer 6 | from PIL import Image 7 | import visdom 8 | from util.util import sdmkdir 9 | import time 10 | import torch 11 | 12 | import random 13 | random.seed(1) 14 | 15 | opt = TrainOptions().parse() 16 | 17 | ### dataset [ShadowParamDataset, WeaklyShadowParamDataset] 18 | data_loader = CreateDataLoader(opt) 19 | dataset = data_loader.load_data() 20 | dataset_size = len(data_loader) 21 | 22 | #### model [vggface, RESNEXT] 23 | model = create_model(opt) 24 | model.setup(opt) 25 | 26 | 27 | ###### visualization 28 | visualizer = Visualizer(opt) 29 | 30 | total_steps = 0 31 | 32 | 33 | 34 | for epoch in range(opt.epoch_count, opt.niter + opt.niter_decay + 1): 35 | epoch_start_time = time.time() 36 | epoch_iter = 0 37 | model.epoch = epoch 38 | 39 | for i, data in enumerate(dataset): 40 | iter_start_time = time.time() 41 | total_steps += opt.batch_size 42 | epoch_iter += opt.batch_size 43 | model.set_input(data) 44 | model.optimize_parameters() 45 | model.cepoch=epoch 46 | 47 | ##############Visualization block 48 | if total_steps % opt.display_freq == 0: 49 | save_result = total_steps % opt.update_html_freq == 0 50 | lenght, visual_dict = model.get_current_visuals() 51 | if lenght>0: 52 | visualizer.display_current_results(visual_dict, epoch) 53 | if total_steps % opt.print_freq == 0: 54 | errors = model.get_current_losses() 55 | t = (time.time() - iter_start_time) / opt.batch_size 56 | # visualizer.print_current_errors(epoch, epoch_iter, errors, t) 57 | if opt.display_id > 0: 58 | visualizer.plot_current_losses(epoch, float(epoch_iter)/dataset_size, opt, errors) 59 | ###################################s 60 | 61 | 62 | if epoch % opt.save_epoch_freq == 0: 63 | print('saving the model at the end of epoch %d, iters %d' % 64 | (epoch, total_steps)) 65 | model.save_networks('latest') 66 | model.save_networks(epoch) 67 | 68 | 69 | print('End of epoch %d / %d \t Time Taken: %d sec' % 70 | (epoch, opt.niter + opt.niter_decay, time.time() - epoch_start_time)) 71 | model.update_learning_rate() 72 | -------------------------------------------------------------------------------- /src/util/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/util/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/util/__init__.pyc -------------------------------------------------------------------------------- /src/util/boundding_box_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Mask R-CNN 3 | Common utility functions and classes. 4 | Copyright (c) 2017 Matterport, Inc. 5 | Licensed under the MIT License (see LICENSE for details) 6 | Written by Waleed Abdulla 7 | """ 8 | 9 | import sys 10 | import os 11 | import logging 12 | import math 13 | import random 14 | import numpy as np 15 | import scipy 16 | import skimage.color 17 | import skimage.io 18 | import skimage.transform 19 | import urllib.request 20 | import shutil 21 | import warnings 22 | from distutils.version import LooseVersion 23 | 24 | 25 | # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. 26 | import math 27 | import torch 28 | class BoxCoder(object): 29 | """ 30 | This class encodes and decodes a set of bounding boxes into 31 | the representation used for training the regressors. 32 | """ 33 | 34 | def __init__(self, weights, bbox_xform_clip=math.log(1000 / 16)): 35 | """ 36 | Arguments: 37 | weights (4-element tuple) 38 | bbox_xform_clip (float) 39 | """ 40 | self.weights = weights 41 | self.bbox_xform_clip = bbox_xform_clip 42 | 43 | def encode(self, reference_boxes, proposals): 44 | ### input gt[x_left, y_bottom, x_right, y_top] 45 | ###computing delta tx, ty, tw, th for calculating loss 46 | ### tx, ty, tw, th are calculated from bbox regression network 47 | """ 48 | Encode a set of proposals with respect to some 49 | reference boxes 50 | Arguments: 51 | reference_boxes (Tensor): reference boxes 52 | proposals (Tensor): boxes to be encoded 53 | """ 54 | 55 | TO_REMOVE = 1 # TODO remove 56 | ex_widths = proposals[:, 2] - proposals[:, 0] + TO_REMOVE 57 | ex_heights = proposals[:, 3] - proposals[:, 1] + TO_REMOVE 58 | ex_ctr_x = proposals[:, 0] + 0.5 * ex_widths 59 | ex_ctr_y = proposals[:, 1] + 0.5 * ex_heights 60 | 61 | gt_widths = reference_boxes[:, 2] - reference_boxes[:, 0] + TO_REMOVE 62 | gt_heights = reference_boxes[:, 3] - reference_boxes[:, 1] + TO_REMOVE 63 | gt_ctr_x = reference_boxes[:, 0] + 0.5 * gt_widths 64 | gt_ctr_y = reference_boxes[:, 1] + 0.5 * gt_heights 65 | 66 | wx, wy, ww, wh = self.weights 67 | targets_dx = wx * (gt_ctr_x - ex_ctr_x) / ex_widths 68 | targets_dy = wy * (gt_ctr_y - ex_ctr_y) / ex_heights 69 | targets_dw = ww * torch.log(gt_widths / ex_widths) 70 | targets_dh = wh * torch.log(gt_heights / ex_heights) 71 | 72 | targets = torch.stack((targets_dx, targets_dy, targets_dw, targets_dh), dim=1) 73 | return targets 74 | 75 | def decode(self, rel_codes, boxes): 76 | ###accoding to the calculated t, ty, tw, th from network and proposals to calculate predict bbox 77 | """ 78 | From a set of original boxes and encoded relative box offsets, 79 | get the decoded boxes. 80 | Arguments: 81 | rel_codes (Tensor): encoded boxes 82 | boxes (Tensor): reference boxes. 83 | """ 84 | 85 | boxes = boxes.to(rel_codes.dtype) 86 | 87 | TO_REMOVE = 1 # TODO remove 88 | widths = boxes[:, 2] - boxes[:, 0] + TO_REMOVE 89 | heights = boxes[:, 3] - boxes[:, 1] + TO_REMOVE 90 | ctr_x = boxes[:, 0] + 0.5 * widths 91 | ctr_y = boxes[:, 1] + 0.5 * heights 92 | 93 | wx, wy, ww, wh = self.weights 94 | dx = rel_codes[:, 0::4] / wx 95 | dy = rel_codes[:, 1::4] / wy 96 | dw = rel_codes[:, 2::4] / ww 97 | dh = rel_codes[:, 3::4] / wh 98 | 99 | # Prevent sending too large values into torch.exp() 100 | dw = torch.clamp(dw, max=self.bbox_xform_clip) 101 | dh = torch.clamp(dh, max=self.bbox_xform_clip) 102 | 103 | pred_ctr_x = dx * widths[:, None] + ctr_x[:, None] 104 | pred_ctr_y = dy * heights[:, None] + ctr_y[:, None] 105 | pred_w = torch.exp(dw) * widths[:, None] 106 | pred_h = torch.exp(dh) * heights[:, None] 107 | 108 | pred_boxes = torch.zeros_like(rel_codes) 109 | # x1 110 | pred_boxes[:, 0::4] = pred_ctr_x - 0.5 * pred_w 111 | # y1 112 | pred_boxes[:, 1::4] = pred_ctr_y - 0.5 * pred_h 113 | # x2 (note: "- 1" is correct; don't be fooled by the asymmetry) 114 | pred_boxes[:, 2::4] = pred_ctr_x + 0.5 * pred_w - 1 115 | # y2 (note: "- 1" is correct; don't be fooled by the asymmetry) 116 | pred_boxes[:, 3::4] = pred_ctr_y + 0.5 * pred_h - 1 117 | 118 | return pred_boxes 119 | 120 | 121 | def smooth_l1_loss(input, target, beta=1. / 9, size_average=True): 122 | """ 123 | very similar to the smooth_l1_loss from pytorch, but with 124 | the extra beta parameter 125 | """ 126 | n = torch.abs(input - target) 127 | cond = n < beta 128 | loss = torch.where(cond, 0.5 * n ** 2 / beta, n - 0.5 * beta) 129 | if size_average: 130 | return loss.mean() 131 | return loss.sum() -------------------------------------------------------------------------------- /src/util/boundding_box_utils.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/util/boundding_box_utils.pyc -------------------------------------------------------------------------------- /src/util/coordconv.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | import torch.nn.modules.conv as conv 4 | 5 | 6 | class AddCoords(nn.Module): 7 | def __init__(self, rank, with_r=False, use_cuda=True): 8 | super(AddCoords, self).__init__() 9 | self.rank = rank 10 | self.with_r = with_r 11 | self.use_cuda = use_cuda 12 | 13 | def forward(self, input_tensor): 14 | """ 15 | :param input_tensor: shape (N, C_in, H, W) 16 | :return: 17 | """ 18 | if self.rank == 1: 19 | batch_size_shape, channel_in_shape, dim_x = input_tensor.shape 20 | xx_range = torch.arange(dim_x, dtype=torch.int32) 21 | xx_channel = xx_range[None, None, :] 22 | 23 | xx_channel = xx_channel.float() / (dim_x - 1) 24 | xx_channel = xx_channel * 2 - 1 25 | xx_channel = xx_channel.repeat(batch_size_shape, 1, 1) 26 | 27 | if torch.cuda.is_available and self.use_cuda: 28 | input_tensor = input_tensor.cuda() 29 | xx_channel = xx_channel.cuda() 30 | out = torch.cat([input_tensor, xx_channel], dim=1) 31 | 32 | if self.with_r: 33 | rr = torch.sqrt(torch.pow(xx_channel - 0.5, 2)) 34 | out = torch.cat([out, rr], dim=1) 35 | 36 | elif self.rank == 2: 37 | batch_size_shape, channel_in_shape, dim_y, dim_x = input_tensor.shape 38 | xx_ones = torch.ones([1, 1, 1, dim_x], dtype=torch.int32) 39 | yy_ones = torch.ones([1, 1, 1, dim_y], dtype=torch.int32) 40 | 41 | xx_range = torch.arange(dim_y, dtype=torch.int32) 42 | yy_range = torch.arange(dim_x, dtype=torch.int32) 43 | xx_range = xx_range[None, None, :, None] 44 | yy_range = yy_range[None, None, :, None] 45 | 46 | xx_channel = torch.matmul(xx_range, xx_ones) 47 | yy_channel = torch.matmul(yy_range, yy_ones) 48 | 49 | # transpose y 50 | yy_channel = yy_channel.permute(0, 1, 3, 2) 51 | 52 | xx_channel = xx_channel.float() / (dim_y - 1) 53 | yy_channel = yy_channel.float() / (dim_x - 1) 54 | 55 | xx_channel = xx_channel * 2 - 1 56 | yy_channel = yy_channel * 2 - 1 57 | 58 | xx_channel = xx_channel.repeat(batch_size_shape, 1, 1, 1) 59 | yy_channel = yy_channel.repeat(batch_size_shape, 1, 1, 1) 60 | 61 | if torch.cuda.is_available and self.use_cuda: 62 | input_tensor = input_tensor.cuda() 63 | xx_channel = xx_channel.cuda() 64 | yy_channel = yy_channel.cuda() 65 | out = torch.cat([input_tensor, xx_channel, yy_channel], dim=1) 66 | 67 | if self.with_r: 68 | rr = torch.sqrt(torch.pow(xx_channel - 0.5, 2) + torch.pow(yy_channel - 0.5, 2)) 69 | out = torch.cat([out, rr], dim=1) 70 | 71 | elif self.rank == 3: 72 | batch_size_shape, channel_in_shape, dim_z, dim_y, dim_x = input_tensor.shape 73 | xx_ones = torch.ones([1, 1, 1, 1, dim_x], dtype=torch.int32) 74 | yy_ones = torch.ones([1, 1, 1, 1, dim_y], dtype=torch.int32) 75 | zz_ones = torch.ones([1, 1, 1, 1, dim_z], dtype=torch.int32) 76 | 77 | xy_range = torch.arange(dim_y, dtype=torch.int32) 78 | xy_range = xy_range[None, None, None, :, None] 79 | 80 | yz_range = torch.arange(dim_z, dtype=torch.int32) 81 | yz_range = yz_range[None, None, None, :, None] 82 | 83 | zx_range = torch.arange(dim_x, dtype=torch.int32) 84 | zx_range = zx_range[None, None, None, :, None] 85 | 86 | xy_channel = torch.matmul(xy_range, xx_ones) 87 | xx_channel = torch.cat([xy_channel + i for i in range(dim_z)], dim=2) 88 | xx_channel = xx_channel.repeat(batch_size_shape, 1, 1, 1, 1) 89 | 90 | yz_channel = torch.matmul(yz_range, yy_ones) 91 | yz_channel = yz_channel.permute(0, 1, 3, 4, 2) 92 | yy_channel = torch.cat([yz_channel + i for i in range(dim_x)], dim=4) 93 | yy_channel = yy_channel.repeat(batch_size_shape, 1, 1, 1, 1) 94 | 95 | zx_channel = torch.matmul(zx_range, zz_ones) 96 | zx_channel = zx_channel.permute(0, 1, 4, 2, 3) 97 | zz_channel = torch.cat([zx_channel + i for i in range(dim_y)], dim=3) 98 | zz_channel = zz_channel.repeat(batch_size_shape, 1, 1, 1, 1) 99 | 100 | if torch.cuda.is_available and self.use_cuda: 101 | input_tensor = input_tensor.cuda() 102 | xx_channel = xx_channel.cuda() 103 | yy_channel = yy_channel.cuda() 104 | zz_channel = zz_channel.cuda() 105 | out = torch.cat([input_tensor, xx_channel, yy_channel, zz_channel], dim=1) 106 | 107 | if self.with_r: 108 | rr = torch.sqrt(torch.pow(xx_channel - 0.5, 2) + 109 | torch.pow(yy_channel - 0.5, 2) + 110 | torch.pow(zz_channel - 0.5, 2)) 111 | out = torch.cat([out, rr], dim=1) 112 | else: 113 | raise NotImplementedError 114 | 115 | return out 116 | 117 | 118 | class CoordConv1d(conv.Conv1d): 119 | def __init__(self, in_channels, out_channels, kernel_size, stride=1, 120 | padding=0, dilation=1, groups=1, bias=True, with_r=False, use_cuda=True): 121 | super(CoordConv1d, self).__init__(in_channels, out_channels, kernel_size, 122 | stride, padding, dilation, groups, bias) 123 | self.rank = 1 124 | self.addcoords = AddCoords(self.rank, with_r, use_cuda=use_cuda) 125 | self.conv = nn.Conv1d(in_channels + self.rank + int(with_r), out_channels, 126 | kernel_size, stride, padding, dilation, groups, bias) 127 | 128 | def forward(self, input_tensor): 129 | """ 130 | input_tensor_shape: (N, C_in,H,W) 131 | output_tensor_shape: N,C_out,H_out,W_out) 132 | :return: CoordConv2d Result 133 | """ 134 | out = self.addcoords(input_tensor) 135 | out = self.conv(out) 136 | 137 | return out 138 | 139 | 140 | class CoordConv2d(conv.Conv2d): 141 | def __init__(self, in_channels, out_channels, kernel_size, stride=1, 142 | padding=0, dilation=1, groups=1, bias=True, with_r=False, use_cuda=True): 143 | super(CoordConv2d, self).__init__(in_channels, out_channels, kernel_size, 144 | stride, padding, dilation, groups, bias) 145 | self.rank = 2 146 | self.addcoords = AddCoords(self.rank, with_r, use_cuda=use_cuda) 147 | self.conv = nn.Conv2d(in_channels + self.rank + int(with_r), out_channels, 148 | kernel_size, stride, padding, dilation, groups, bias) 149 | 150 | def forward(self, input_tensor): 151 | """ 152 | input_tensor_shape: (N, C_in,H,W) 153 | output_tensor_shape: N,C_out,H_out,W_out) 154 | :return: CoordConv2d Result 155 | """ 156 | out = self.addcoords(input_tensor) 157 | out = self.conv(out) 158 | 159 | return out 160 | 161 | 162 | class CoordConv3d(conv.Conv3d): 163 | def __init__(self, in_channels, out_channels, kernel_size, stride=1, 164 | padding=0, dilation=1, groups=1, bias=True, with_r=False, use_cuda=True): 165 | super(CoordConv3d, self).__init__(in_channels, out_channels, kernel_size, 166 | stride, padding, dilation, groups, bias) 167 | self.rank = 3 168 | self.addcoords = AddCoords(self.rank, with_r, use_cuda=use_cuda) 169 | self.conv = nn.Conv3d(in_channels + self.rank + int(with_r), out_channels, 170 | kernel_size, stride, padding, dilation, groups, bias) 171 | 172 | def forward(self, input_tensor): 173 | """ 174 | input_tensor_shape: (N, C_in,H,W) 175 | output_tensor_shape: N,C_out,H_out,W_out) 176 | :return: CoordConv2d Result 177 | """ 178 | out = self.addcoords(input_tensor) 179 | out = self.conv(out) 180 | 181 | return out -------------------------------------------------------------------------------- /src/util/coordconv1.py: -------------------------------------------------------------------------------- 1 | class AddCoordsTh(nn.Module): 2 | def __init__(self, x_dim=64, y_dim=64, with_r=False): 3 | super(AddCoordsTh, self).__init__() 4 | self.x_dim = x_dim 5 | self.y_dim = y_dim 6 | self.with_r = with_r 7 | 8 | def forward(self, input_tensor): 9 | """ 10 | input_tensor: (batch, c, x_dim, y_dim) 11 | """ 12 | batch_size_tensor = input_tensor.shape[0] 13 | 14 | xx_ones = torch.ones([1, self.y_dim], dtype=torch.int32) 15 | xx_ones = xx_ones.unsqueeze(-1) 16 | 17 | xx_range = torch.arange(self.x_dim, dtype=torch.int32).unsqueeze(0) 18 | xx_range = xx_range.unsqueeze(1) 19 | 20 | xx_channel = torch.matmul(xx_ones, xx_range) 21 | xx_channel = xx_channel.unsqueeze(-1) 22 | 23 | yy_ones = torch.ones([1, self.x_dim], dtype=torch.int32) 24 | yy_ones = yy_ones.unsqueeze(1) 25 | 26 | yy_range = torch.arange(self.y_dim, dtype=torch.int32).unsqueeze(0) 27 | yy_range = yy_range.unsqueeze(-1) 28 | 29 | yy_channel = torch.matmul(yy_range, yy_ones) 30 | yy_channel = yy_channel.unsqueeze(-1) 31 | 32 | xx_channel = xx_channel.permute(0, 3, 2, 1) 33 | yy_channel = yy_channel.permute(0, 3, 2, 1) 34 | 35 | xx_channel = xx_channel.float() / (self.x_dim - 1) 36 | yy_channel = yy_channel.float() / (self.y_dim - 1) 37 | 38 | xx_channel = xx_channel * 2 - 1 39 | yy_channel = yy_channel * 2 - 1 40 | 41 | xx_channel = xx_channel.repeat(batch_size_tensor, 1, 1, 1) 42 | yy_channel = yy_channel.repeat(batch_size_tensor, 1, 1, 1) 43 | 44 | ret = torch.cat([input_tensor, xx_channel, yy_channel], dim=1) 45 | 46 | if self.with_r: 47 | rr = torch.sqrt(torch.pow(xx_channel - 0.5, 2) + torch.pow(yy_channel - 0.5, 2)) 48 | ret = torch.cat([ret, rr], dim=1) 49 | 50 | return ret 51 | 52 | 53 | class CoordConvTh(nn.Module): 54 | """CoordConv layer as in the paper.""" 55 | def __init__(self, x_dim, y_dim, with_r, *args, **kwargs): 56 | super(CoordConvTh, self).__init__() 57 | self.addcoords = AddCoordsTh(x_dim=x_dim, y_dim=y_dim, with_r=with_r) 58 | self.conv = nn.Conv2d(*args, **kwargs) 59 | 60 | def forward(self, input_tensor): 61 | ret = self.addcoords(input_tensor) 62 | ret = self.conv(ret) 63 | return ret 64 | 65 | 66 | ''' 67 | An alternative implementation for PyTorch with auto-infering the x-y dimensions. 68 | ''' 69 | class AddCoords(nn.Module): 70 | 71 | def __init__(self, with_r=False): 72 | super().__init__() 73 | self.with_r = with_r 74 | 75 | def forward(self, input_tensor): 76 | """ 77 | Args: 78 | input_tensor: shape(batch, channel, x_dim, y_dim) 79 | """ 80 | batch_size, _, x_dim, y_dim = input_tensor.size() 81 | 82 | xx_channel = torch.arange(x_dim).repeat(1, y_dim, 1) 83 | yy_channel = torch.arange(y_dim).repeat(1, x_dim, 1).transpose(1, 2) 84 | 85 | xx_channel = xx_channel.float() / (x_dim - 1) 86 | yy_channel = yy_channel.float() / (y_dim - 1) 87 | 88 | xx_channel = xx_channel * 2 - 1 89 | yy_channel = yy_channel * 2 - 1 90 | 91 | xx_channel = xx_channel.repeat(batch_size, 1, 1, 1).transpose(2, 3) 92 | yy_channel = yy_channel.repeat(batch_size, 1, 1, 1).transpose(2, 3) 93 | 94 | ret = torch.cat([ 95 | input_tensor, 96 | xx_channel.type_as(input_tensor), 97 | yy_channel.type_as(input_tensor)], dim=1) 98 | 99 | if self.with_r: 100 | rr = torch.sqrt(torch.pow(xx_channel.type_as(input_tensor) - 0.5, 2) + torch.pow(yy_channel.type_as(input_tensor) - 0.5, 2)) 101 | ret = torch.cat([ret, rr], dim=1) 102 | 103 | return ret 104 | 105 | 106 | class CoordConv(nn.Module): 107 | 108 | def __init__(self, in_channels, out_channels, with_r=False, **kwargs): 109 | super().__init__() 110 | self.addcoords = AddCoords(with_r=with_r) 111 | in_size = in_channels+2 112 | if with_r: 113 | in_size += 1 114 | self.conv = nn.Conv2d(in_size, out_channels, **kwargs) 115 | 116 | def forward(self, x): 117 | ret = self.addcoords(x) 118 | ret = self.conv(ret) 119 | return ret -------------------------------------------------------------------------------- /src/util/get_data.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import tarfile 4 | import requests 5 | from warnings import warn 6 | from zipfile import ZipFile 7 | from bs4 import BeautifulSoup 8 | from os.path import abspath, isdir, join, basename 9 | 10 | 11 | class GetData(object): 12 | """ 13 | 14 | Download CycleGAN or Pix2Pix Data. 15 | 16 | Args: 17 | technique : str 18 | One of: 'cyclegan' or 'pix2pix'. 19 | verbose : bool 20 | If True, print additional information. 21 | 22 | Examples: 23 | >>> from util.get_data import GetData 24 | >>> gd = GetData(technique='cyclegan') 25 | >>> new_data_path = gd.get(save_path='./datasets') # options will be displayed. 26 | 27 | """ 28 | 29 | def __init__(self, technique='cyclegan', verbose=True): 30 | url_dict = { 31 | 'pix2pix': 'https://people.eecs.berkeley.edu/~tinghuiz/projects/pix2pix/datasets', 32 | 'cyclegan': 'https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets' 33 | } 34 | self.url = url_dict.get(technique.lower()) 35 | self._verbose = verbose 36 | 37 | def _print(self, text): 38 | if self._verbose: 39 | print(text) 40 | 41 | @staticmethod 42 | def _get_options(r): 43 | soup = BeautifulSoup(r.text, 'lxml') 44 | options = [h.text for h in soup.find_all('a', href=True) 45 | if h.text.endswith(('.zip', 'tar.gz'))] 46 | return options 47 | 48 | def _present_options(self): 49 | r = requests.get(self.url) 50 | options = self._get_options(r) 51 | print('Options:\n') 52 | for i, o in enumerate(options): 53 | print("{0}: {1}".format(i, o)) 54 | choice = input("\nPlease enter the number of the " 55 | "dataset above you wish to download:") 56 | return options[int(choice)] 57 | 58 | def _download_data(self, dataset_url, save_path): 59 | if not isdir(save_path): 60 | os.makedirs(save_path) 61 | 62 | base = basename(dataset_url) 63 | temp_save_path = join(save_path, base) 64 | 65 | with open(temp_save_path, "wb") as f: 66 | r = requests.get(dataset_url) 67 | f.write(r.content) 68 | 69 | if base.endswith('.tar.gz'): 70 | obj = tarfile.open(temp_save_path) 71 | elif base.endswith('.zip'): 72 | obj = ZipFile(temp_save_path, 'r') 73 | else: 74 | raise ValueError("Unknown File Type: {0}.".format(base)) 75 | 76 | self._print("Unpacking Data...") 77 | obj.extractall(save_path) 78 | obj.close() 79 | os.remove(temp_save_path) 80 | 81 | def get(self, save_path, dataset=None): 82 | """ 83 | 84 | Download a dataset. 85 | 86 | Args: 87 | save_path : str 88 | A directory to save the data to. 89 | dataset : str, optional 90 | A specific dataset to download. 91 | Note: this must include the file extension. 92 | If None, options will be presented for you 93 | to choose from. 94 | 95 | Returns: 96 | save_path_full : str 97 | The absolute path to the downloaded data. 98 | 99 | """ 100 | if dataset is None: 101 | selected_dataset = self._present_options() 102 | else: 103 | selected_dataset = dataset 104 | 105 | save_path_full = join(save_path, selected_dataset.split('.')[0]) 106 | 107 | if isdir(save_path_full): 108 | warn("\n'{0}' already exists. Voiding Download.".format( 109 | save_path_full)) 110 | else: 111 | self._print('Downloading Data...') 112 | url = "{0}/{1}".format(self.url, selected_dataset) 113 | self._download_data(url, save_path=save_path) 114 | 115 | return abspath(save_path_full) 116 | -------------------------------------------------------------------------------- /src/util/html.py: -------------------------------------------------------------------------------- 1 | import dominate 2 | from dominate.tags import * 3 | import os 4 | 5 | 6 | class HTML: 7 | def __init__(self, web_dir, title, reflesh=0): 8 | self.title = title 9 | self.web_dir = web_dir 10 | self.img_dir = os.path.join(self.web_dir, 'images') 11 | if not os.path.exists(self.web_dir): 12 | os.makedirs(self.web_dir) 13 | if not os.path.exists(self.img_dir): 14 | os.makedirs(self.img_dir) 15 | # print(self.img_dir) 16 | 17 | self.doc = dominate.document(title=title) 18 | if reflesh > 0: 19 | with self.doc.head: 20 | meta(http_equiv="reflesh", content=str(reflesh)) 21 | 22 | def get_image_dir(self): 23 | return self.img_dir 24 | 25 | def add_header(self, str): 26 | with self.doc: 27 | h3(str) 28 | 29 | def add_table(self, border=1): 30 | self.t = table(border=border, style="table-layout: fixed;") 31 | self.doc.add(self.t) 32 | 33 | def add_images(self, ims, txts, links, width=400): 34 | self.add_table() 35 | with self.t: 36 | with tr(): 37 | for im, txt, link in zip(ims, txts, links): 38 | with td(style="word-wrap: break-word;", halign="center", valign="top"): 39 | with p(): 40 | with a(href=os.path.join('images', link)): 41 | img(style="width:%dpx" % width, src=os.path.join('images', im)) 42 | br() 43 | p(txt) 44 | 45 | def save(self): 46 | html_file = '%s/index.html' % self.web_dir 47 | f = open(html_file, 'wt') 48 | f.write(self.doc.render()) 49 | f.close() 50 | 51 | 52 | if __name__ == '__main__': 53 | html = HTML('web/', 'test_html') 54 | html.add_header('hello world') 55 | 56 | ims = [] 57 | txts = [] 58 | links = [] 59 | for n in range(4): 60 | ims.append('image_%d.png' % n) 61 | txts.append('text_%d' % n) 62 | links.append('image_%d.png' % n) 63 | html.add_images(ims, txts, links) 64 | html.save() 65 | -------------------------------------------------------------------------------- /src/util/html.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/util/html.pyc -------------------------------------------------------------------------------- /src/util/image_pool.py: -------------------------------------------------------------------------------- 1 | import random 2 | import torch 3 | 4 | 5 | class ImagePool(): 6 | def __init__(self, pool_size): 7 | self.pool_size = pool_size 8 | if self.pool_size > 0: 9 | self.num_imgs = 0 10 | self.images = [] 11 | 12 | def query(self, images): 13 | if self.pool_size == 0: 14 | return images 15 | return_images = [] 16 | for image in images: 17 | image = torch.unsqueeze(image.data, 0) 18 | if self.num_imgs < self.pool_size: 19 | self.num_imgs = self.num_imgs + 1 20 | self.images.append(image) 21 | return_images.append(image) 22 | else: 23 | p = random.uniform(0, 1) 24 | if p > 0.5: 25 | random_id = random.randint(0, self.pool_size - 1) # randint is inclusive 26 | tmp = self.images[random_id].clone() 27 | self.images[random_id] = image 28 | return_images.append(tmp) 29 | else: 30 | return_images.append(image) 31 | return_images = torch.cat(return_images, 0) 32 | return return_images 33 | -------------------------------------------------------------------------------- /src/util/ssim.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn.functional as F 3 | from torch.autograd import Variable 4 | import numpy as np 5 | from math import exp 6 | import os 7 | 8 | 9 | def gaussian(window_size, sigma): 10 | gauss = torch.Tensor([exp(-(x - window_size//2)**2/float(2*sigma**2)) for x in range(window_size)]) 11 | return gauss/gauss.sum() 12 | 13 | def create_window(window_size, channel): 14 | _1D_window = gaussian(window_size, 1.5).unsqueeze(1) 15 | _2D_window = _1D_window.mm(_1D_window.t()).float().unsqueeze(0).unsqueeze(0) 16 | window = Variable(_2D_window.expand(channel, 1, window_size, window_size).contiguous()) 17 | return window 18 | 19 | def _ssim(img1, img2, window, window_size, channel, size_average = True, mask=None): 20 | mu1 = F.conv2d(img1, window, padding = window_size//2, groups = channel) 21 | mu2 = F.conv2d(img2, window, padding = window_size//2, groups = channel) 22 | 23 | mu1_sq = mu1.pow(2) 24 | mu2_sq = mu2.pow(2) 25 | mu1_mu2 = mu1*mu2 26 | 27 | sigma1_sq = F.conv2d(img1*img1, window, padding = window_size//2, groups = channel) - mu1_sq 28 | sigma2_sq = F.conv2d(img2*img2, window, padding = window_size//2, groups = channel) - mu2_sq 29 | sigma12 = F.conv2d(img1*img2, window, padding = window_size//2, groups = channel) - mu1_mu2 30 | 31 | C1 = 0.01**2 32 | C2 = 0.03**2 33 | 34 | ssim_map = ((2*mu1_mu2 + C1)*(2*sigma12 + C2))/((mu1_sq + mu2_sq + C1)*(sigma1_sq + sigma2_sq + C2)) 35 | 36 | if mask is not None: 37 | mask_sum = mask.sum() 38 | fg_ssim_map = ssim_map*mask 39 | fg_ssim_map_sum = fg_ssim_map.sum(3).sum(2) 40 | fg_ssim = fg_ssim_map_sum/mask_sum 41 | fg_ssim_mu = fg_ssim.mean() 42 | ssim_mu = ssim_map.mean() 43 | # return ssim_mu.item(), fg_ssim_mu.item() 44 | return fg_ssim_mu.item() 45 | 46 | # if size_average: 47 | # return ssim_map.mean() 48 | # else: 49 | # return ssim_map.mean(1).mean(1).mean(1) 50 | 51 | class SSIM(torch.nn.Module): 52 | def __init__(self, window_size = 11, size_average = True): 53 | super(SSIM, self).__init__() 54 | self.window_size = window_size 55 | self.size_average = size_average 56 | self.channel = 1 57 | self.window = create_window(window_size, self.channel) 58 | 59 | def forward(self, img1, img2): 60 | (_, channel, _, _) = img1.size() 61 | 62 | if channel == self.channel and self.window.data.type() == img1.data.type(): 63 | window = self.window 64 | else: 65 | window = create_window(self.window_size, channel) 66 | 67 | if img1.is_cuda: 68 | window = window.cuda(img1.get_device()) 69 | window = window.type_as(img1) 70 | 71 | self.window = window 72 | self.channel = channel 73 | 74 | 75 | return _ssim(img1, img2, window, self.window_size, channel, self.size_average) 76 | 77 | def ssim(img1, img2, window_size = 11, size_average = True, mask=None): 78 | (_, channel, _, _) = img1.size() 79 | window = create_window(window_size, channel) 80 | 81 | if img1.is_cuda: 82 | window = window.cuda(img1.get_device()) 83 | window = window.type_as(img1) 84 | 85 | return _ssim(img1, img2, window, window_size, channel, size_average, mask) 86 | -------------------------------------------------------------------------------- /src/util/util.py: -------------------------------------------------------------------------------- 1 | # _*_ coding:UTF-8 _*_ 2 | from __future__ import print_function 3 | import torch 4 | import numpy as np 5 | from PIL import Image 6 | import os 7 | 8 | 9 | def sdmkdir(dir_name): 10 | if not os.path.exists(dir_name): 11 | os.mkdir(dir_name) 12 | # Converts a Tensor into an image array (numpy) 13 | # |imtype|: the desired type of the converted numpy array 14 | def tensor2cvim(input_image, imtype=np.uint8,scale=None): 15 | # print('hhhhh',np.shape(input_image)) 16 | 17 | if len(input_image.shape)<3: return None 18 | # if scale>0 and input_image.size()[1]==3: 19 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 20 | 21 | if isinstance(input_image, torch.Tensor): 22 | image_tensor = input_image.data 23 | else: 24 | return input_image 25 | image_numpy = image_tensor.data[0].cpu().float().numpy() 26 | # if image_numpy.shape[0] == 1: 27 | # image_numpy = np.tile(image_numpy, (3, 1, 1)) 28 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 29 | image_numpy[image_numpy<0] = 0 30 | image_numpy[image_numpy>255] = 255 31 | return image_numpy.astype(imtype) 32 | 33 | 34 | def tensor2imonechannel(input_image, imtype=np.uint8, scale=None): 35 | if len(input_image.shape) < 3: return None 36 | # if scale>0 and input_image.size()[1]==3: 37 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 38 | 39 | if isinstance(input_image, torch.Tensor): 40 | image_tensor = input_image.data 41 | else: 42 | return input_image 43 | image_numpy = image_tensor.data[0].cpu().float().numpy() 44 | # if image_numpy.shape[0] == 1: 45 | # image_numpy = np.tile(image_numpy, (3, 1, 1)) 46 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 47 | # image_numpy[image_numpy < 0] = 0 48 | # image_numpy[image_numpy > 255] = 255 49 | # return image_numpy.astype(imtype) 50 | return image_numpy 51 | 52 | 53 | 54 | def tensor2im(input_image, imtype=np.uint8,scale=None): 55 | 56 | if len(input_image.shape)<3: return None 57 | # if scale>0 and input_image.size()[1]==3: 58 | # return tensor2im_logc(input_image, imtype=np.uint8,scale=scale) 59 | 60 | if isinstance(input_image, torch.Tensor): 61 | image_tensor = input_image.data 62 | else: 63 | return input_image 64 | image_numpy = image_tensor.data[0].cpu().float().numpy() 65 | if image_numpy.shape[0] == 1: 66 | image_numpy = np.tile(image_numpy, (3, 1, 1)) 67 | image_numpy = (np.transpose(image_numpy, (1, 2, 0)) + 1) / 2.0 * 255.0 68 | image_numpy[image_numpy<0] = 0 69 | image_numpy[image_numpy>255] = 255 70 | return image_numpy.astype(imtype) 71 | 72 | def tensor2im_logc(image_tensor, imtype=np.uint8,scale=255): 73 | image_numpy = image_tensor.data[0].cpu().double().numpy() 74 | image_numpy = np.transpose(image_numpy,(1,2,0)) 75 | image_numpy = (image_numpy+1) /2.0 76 | image_numpy = image_numpy * (np.log(scale+1)) 77 | image_numpy = np.exp(image_numpy) -1 78 | image_numpy = image_numpy.astype(np.uint8) 79 | 80 | return image_numpy.astype(np.uint8) 81 | 82 | 83 | def diagnose_network(net, name='network'): 84 | mean = 0.0 85 | count = 0 86 | for param in net.parameters(): 87 | if param.grad is not None: 88 | mean += torch.mean(torch.abs(param.grad.data)) 89 | count += 1 90 | if count > 0: 91 | mean = mean / count 92 | print(name) 93 | print(mean) 94 | 95 | 96 | def save_image(image_numpy, image_path): 97 | image_pil = Image.fromarray(image_numpy) 98 | image_pil.save(image_path) 99 | 100 | 101 | def print_numpy(x, val=True, shp=False): 102 | x = x.astype(np.float64) 103 | if shp: 104 | print('shape,', x.shape) 105 | if val: 106 | x = x.flatten() 107 | print('mean = %3.3f, min = %3.3f, max = %3.3f, median = %3.3f, std=%3.3f' % ( 108 | np.mean(x), np.min(x), np.max(x), np.median(x), np.std(x))) 109 | 110 | 111 | def mkdirs(paths): 112 | if isinstance(paths, list) and not isinstance(paths, str): 113 | for path in paths: 114 | mkdir(path) 115 | else: 116 | mkdir(paths) 117 | 118 | 119 | def mkdir(path): 120 | if not os.path.exists(path): 121 | os.makedirs(path) 122 | 123 | 124 | def transparent_png(img,fg_mask): 125 | img = img.convert('RGBA') 126 | W, H = img.size 127 | # fg_mask = np.array(fg_mask) 128 | for h in range(H): ###循环图片的每个像素点 129 | for l in range(W): 130 | if fg_mask.getpixel((l,h)) == 0: 131 | pixels = img.getpixel((l,h)) 132 | if h==0 and l==0: 133 | print('old',pixels) 134 | pixels = pixels[:-1] + (80,) 135 | if h==0 and l==0: 136 | print('new',tuple(pixels)) 137 | img.putpixel((l,h),pixels) 138 | img.save('/media/user/data/ShadowGeneration/HYShadowGeneration/SOBAMixFGAllData/Model_SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/SelfAttention_Illumination1_Residual0_ConditionD1_Llight0_Lpara1_Lshadowrecons10_Limagerecons10_Lgan0.1_Lstn0_Nwarp0_Lref1_Ltv0_Lganmask0/SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/web/images/0.png') 139 | # img = Image.open('/media/user/data/ShadowGeneration/HYShadowGeneration/SOBAMixFGAllData/Model_SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/SelfAttention_Illumination1_Residual0_ConditionD1_Llight0_Lpara1_Lshadowrecons10_Limagerecons10_Lgan0.1_Lstn0_Nwarp0_Lref1_Ltv0_Lganmask0/SelfAttention_GRESNEXT18_C32_Dpixel_lrD0.0002/web/images/0.png') 140 | # print(img.size()) 141 | return img -------------------------------------------------------------------------------- /src/util/util.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/util/util.pyc -------------------------------------------------------------------------------- /src/util/visualizer.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcmi/Object-Shadow-Generation-Dataset-DESOBA/df723bbf20392f9bbd0f42305c4f048e8b616b23/src/util/visualizer.pyc --------------------------------------------------------------------------------