def get(): def sometimes(aug): return iaa.Sometimes(0.5, aug) return iaa.SomeOf( 3, [ # iaa.PiecewiseAffine(scale=(0.01, 0.025)), iaa.AverageBlur((1, 3)), iaa.Grayscale((0.6, 1.0)), # iaa.PerspectiveTransform(scale=(0.01, 0.05), keep_size=True), # iaa.Flipud(1.0), # iaa.Fliplr(1.0), iaa.OneOf([ iaa.Rot90(0, keep_size=True), iaa.Rot90(1, keep_size=True), iaa.Rot90(2, keep_size=True), iaa.Rot90(3, keep_size=True) ]), iaa.OneOf([ iaa.AdditiveGaussianNoise(scale=(0, 0.1 * 255)), iaa.AdditiveGaussianNoise(scale=(0, 0.1 * 255), per_channel=True) ]), iaa.Multiply((0.8, 1.2)), iaa.SaltAndPepper(0.03), iaa.OneOf([ iaa.GaussianBlur(sigma=(0.25, 0.7)), iaa.MotionBlur(k=(3, 7), angle=[-45, 45]) ]) ], random_order=False)
def chapter_augmenters_rot90(): fn_start = "geometric/rot90" image = ia.quokka(size=(128, 128)) image = image[:, :-40] save( "overview_of_augmenters", fn_start + "_base_image.jpg", image, quality=90 ) aug = iaa.Rot90(1) run_and_save_augseq( fn_start + "_k_is_1.jpg", aug, [image for _ in range(4*1)], cols=4, rows=1) aug = iaa.Rot90([1, 3]) run_and_save_augseq( fn_start + "_k_is_1_or_3.jpg", aug, [image for _ in range(4*2)], cols=4, rows=2) aug = iaa.Rot90((1, 3)) run_and_save_augseq( fn_start + "_k_is_1_or_2_or_3.jpg", aug, [image for _ in range(4*2)], cols=4, rows=2) aug = iaa.Rot90((1, 3), keep_size=False) run_and_save_augseq( fn_start + "_keep_size_false.jpg", aug, [image for _ in range(4*2)], cols=4, rows=2)
def build_reference_augmenter(self): augmenter = iaa.Sometimes( 0.7, iaa.Sequential([ iaa.Sequential([ iaa.Resize( { 'longer-side': (144, 48), 'shorter-side': 'keep-aspect-ratio' }, interpolation=ia.ALL), iaa.Resize( { 'longer-side': self.config.image_size, 'shorter-side': 'keep-aspect-ratio' }, interpolation=ia.ALL) ]), iaa.Affine( scale=(0.7, 1.1), translate_percent={ "x": (-0.2, 0.2), "y": (-0.2, 0.2) }, rotate=(-15, 15), order=[0, 1], mode=ia.ALL, ), iaa.Sometimes(0.3, iaa.Rot90([1, 2, 3], keep_size=False)), iaa.OneOf([ iaa.Multiply((0.2, 1.2)), iaa.GammaContrast((1.0, 1.7)), ]), iaa.OneOf([ iaa.Noop(), iaa.JpegCompression(compression=(85, 95)), iaa.GaussianBlur(sigma=(0.75, 2.25)), iaa.MotionBlur(k=(10, 15)) ]), iaa.OneOf([ iaa.Noop(), iaa.OneOf([ iaa.Crop(percent=((0.2, 0.5), 0, 0, 0), keep_size=False), iaa.Crop(percent=(0, (0.2, 0.5), 0, 0), keep_size=False), iaa.Crop(percent=(0, 0, (0.2, 0.5), 0), keep_size=False), iaa.Crop(percent=(0, 0, 0, (0.2, 0.5)), keep_size=False), iaa.Crop(percent=((0.1, 0.3), 0, (0.1, 0.3), 0), keep_size=False), iaa.Crop(percent=(0, (0.1, 0.3), 0, (0.1, 0.3)), keep_size=False) ]), iaa.PerspectiveTransform(0.1) ]) ])) return augmenter
def _aug(self, image, mask): mask = ia.SegmentationMapsOnImage(mask, image.shape[:2]) seq = iaa.Sequential( [ iaa.Fliplr(0.5), iaa.Rot90([0, 3]), iaa.SomeOf( 1, [ iaa.Affine(scale={"x": (0.7, 1.5), "y": (1.6, 1.5)}), iaa.Affine(rotate=(-30, 30)), # iaa.Add((-110, 111)), # iaa.GaussianBlur(sigma=1.8 * np.random.rand()), # iaa.Emboss(alpha=(0.0, 1.0), strength=(0.5, 1.5)), # iaa.AdditiveGaussianNoise(scale=0.05*255), # iaa.Multiply((0.5, 1.5)), # iaa.Affine(shear=(-20, 20)), # iaa.PiecewiseAffine(scale=(0.01, 0.02)), iaa.PerspectiveTransform(scale=(0.01, 0.1)), ], ), ], random_order=True, ) image, mask = seq(image=image, segmentation_maps=mask) mask = mask.get_arr_int().astype(np.uint8) return image, mask
def main(): json_file_name_in = sys.argv[1] json_file_name_out = sys.argv[2] input_dir = sys.argv[3] with open(json_file_name_in) as f: d = json.load(f) aug1 = iaa.Affine(rotate=(20,70)) aug2 = iaa.Rot90(1) aug3 = iaa.Fliplr() aug4 = iaa.Flipud() aug_dict = {aug1:'rot20_70', aug2:'rot90_', aug3:'flipx_', aug4:'flipy_'} current_ann_id = -1 current_img_id = -1 for a in d['images']: if(a['id']>=current_img_id): current_img_id = a['id'] + 1 for a in d['annotations']: if(a['id']>=current_ann_id): current_ann_id = a['id'] + 1 print(current_img_id, current_ann_id) #applying augmentation: d = AugmentData(d, input_dir, aug_dict, current_img_id, current_ann_id) with open(json_file_name_out, 'w') as f: json.dump(d, f) print('File Saved. Job done.')
def __init__(self, p=1.0, seed=None, name=None, trainPath=None, labels=None, random_state="deprecated", deterministic="deprecated"): super(randomMerge, self).__init__(seed=seed, name=name) self.p = iap.handle_probability_param(p, "p") self.seed = seed self.random_state = None self.deterministic = None self.trainPath = trainPath self.labels = labels self.randomCenterX = 0 self.randomCenterY = 0 self.cropTopLeft = None self.cropTopRight = None self.cropBottomLeft = None self.cropBottomRight = None self.imageSize = (1024, 1024) self.boxes = [] self.seq = iaa.Sequential( [ iaa.Fliplr(0.5), # horizontally flip 50% of all images iaa.Flipud(0.5), # vertically flip 20% of all images sometimes_p5(iaa.Rot90(k=ia.ALL)), ], random_order=False)
def getAuger_p_p(rot_angle): seq = iaa.Sequential([ #iaa.Fliplr(0.5), iaa.Rot90(rot_angle), ], random_order=False) return seq
def get_augmentation(augment=True, full=False): """ Returns the imgaug augmentation pipeline. :param augment: Returns None iff True :param full: Don't full mammograms by 90 degrees, as that changes the aspect ratio """ if not augment: return None augs = [ iaa.Fliplr(0.5), iaa.Affine(scale={ "x": (0.8, 1.2), "y": (0.8, 1.2) }, rotate=(-22.5, 22.5), shear=(-16, 16), mode='reflect') ] if not full: augs.append(iaa.Rot90(imgaug.ALL, keep_size=False)) return iaa.Sequential(augs)
def getAuger_online(contrast_range,Perspective_range): roate=random.randint(0,4) seq = iaa.Sequential([ iaa.Rot90(roate), iaa.ContrastNormalization(contrast_range), iaa.PerspectiveTransform(scale=Perspective_range), ], random_order=False) return seq
def randomImageAugment(imageFolder, maskFolder, des): #read image images, name = load_images_from_folder(imageFolder) masks, _ = load_images_from_folder(maskFolder) rand = random.randint(1, 3) if rand == 1: aug = iaa.Fliplr(1) elif rand == 2: aug = iaa.Rot90(1) else: aug = iaa.Rot90(2) for i in range(images.__len__()): print(i) print(name[i]) images_aug = aug(image=images[i]) masks_aug = aug(image=masks[i]) saveImage(images_aug, masks_aug, des + name[i])
def __init__(self, data_path, transform=None): # Flatten grid grid = [] # path for per patch slideIDX = [] slidenames = [] targets = [] slideLen = [0] idx = 0 for each_file in data_path: slidenames.append(each_file.split('/')[-1]) if 'pos' in each_file: targets.append(1) else: targets.append(0) slideLen.append(slideLen[-1] + len(os.listdir(each_file))) for each_patch in os.listdir(each_file): img_path = os.path.join(each_file, each_patch) grid.append(img_path) slideIDX.append(idx) idx += 1 cp('(#g)index: {}(#)\t(#r)name: {}(#)\t(#y)len: {}(#)'.format( idx, each_file.split('/')[-1], len(os.listdir(each_file)))) cp('(#g)total: {}(#)'.format(len(grid))) assert len(targets) == len(slidenames), print( "targets and names not match") assert len(slideIDX) == len(grid), print("idx and mask not match") seq = iaa.Sequential( [ iaa.Fliplr(0.5), iaa.Flipud(0.5), iaa.Crop(percent=(0.1, 0.3)), # iaa.Sometimes(0.4, iaa.GaussianBlur(sigma=(0, 0.5))), # iaa.Sometimes(0.6, iaa.ContrastNormalization((0.75, 1.5))), # iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05 * 255), per_channel=0.5), iaa.Rot90((1, 3)) ], random_order=True) self.slidenames = slidenames self.targets = targets self.grid = grid self.slideIDX = slideIDX self.transform = transform self.mode = None self.slideLen = slideLen # patches for each slide self.size = config.DATASET.PATCHSIZE self.seq = seq self.multi_scale = config.DATASET.MULTISCALE self.unit = self.size self.overlap = config.DATASET.OVERLAP self.step = self.unit self.blocks_per_slide = 1 self.ms_slideLen = self.slideLen #for multi_scale self.ms_slideIDX = self.slideIDX
def __init__(self, target_size=(120,160), batch_size=128): self.train_gen = data_gen.flow_from_dataframe(train, "../images", x_col="image_name", y_col=['x1', 'x2', 'y1', 'y2'], target_size=target_size, class_mode='other', batch_size=batch_size//8) self.n = self.train_gen.n self.batch_size = batch_size//8 self._rot90 = iaa.Rot90(k=3)
def augment(): """ Function used for augmentation of patches. Defines the pipeline of augmentation that will be used on each patch. """ seq = iaa.Sequential([ iaa.Fliplr(0.5), # vertically flip 50% of the images iaa.Flipud(0.5), # horizontally flip 50% of the images iaa.Sometimes(0.5, iaa.Rot90((1, 3))) # Rotate by 90, 180 or 270 degrees 50% of the images ]) return seq
def aug_sequencer(images, seed): return iaa.Sequential( [ iaa.Rot90((0, 3), keep_size=False, seed=seed), iaa.Fliplr(0.5, seed=seed), iaa.Flipud(0.5, seed=seed), # iaa.GaussianBlur(), ], random_order=True, seed=seed)(images=images)
def get_imgaug_seq(self): ia.seed(1) sometimes = lambda aug: iaa.Sometimes(0.5, aug) seq = iaa.Sequential([ iaa.Fliplr(0.5), iaa.Flipud(0.5), iaa.Rot90([0, 1, 2, 3]), ], random_order=True) return seq
def getAuger_p(rot_angle,contrast_range): if rot_angle==0: seq = iaa.Sequential([ iaa.ContrastNormalization(contrast_range), ], random_order=False) else: seq = iaa.Sequential([ #iaa.Fliplr(0.5), iaa.Rot90(rot_angle), iaa.ContrastNormalization(contrast_range), ], random_order=False) return seq
def __init__(self, images): w, h, _ = images[0].shape self.seq = iaa.Sequential([ # iaa.ElasticTransformation(sigma=5.0,alpha = 20,cval = 0), iaa.PiecewiseAffine(scale=(0.01, 0.05), mode="symmetric"), iaa.Fliplr(0.5), # horizontally flip 50% of the images iaa.Flipud(0.5), iaa.Rot90(k=(0, 3)), # iaa.CropToFixedSize(w - 2,w - 2,position = 'uniform') ]) self.name = 'Elastic'
def get_Augmentation_Transf(): # 'images' should be either a 4D numpy array of shape (N, height, width, channels) # or a list of 3D numpy arrays, each having shape (height, width, channels). # Grayscale images must have shape (height, width, 1) each. # All images must have numpy's dtype uint8. Values are expected to be in # range 0-255. sometimes = lambda aug: iaa.Sometimes(0.5, aug, name="Random1") sometimes2 = lambda aug: iaa.Sometimes(0.2, aug, name="Random2") sometimes3 = lambda aug: iaa.Sometimes(0.9, aug, name="Random3") sometimes4 = lambda aug: iaa.Sometimes(0.9, aug, name="Random4") sometimes5 = lambda aug: iaa.Sometimes(0.9, aug, name="Random5") # specify DATA AUGMENTATION TRANSFORMATION seq_img = iaa.Sequential([ iaa.AddToHueAndSaturation(value=(-13, 13), name="MyHSV"), sometimes2(iaa.GammaContrast(gamma=(0.85, 1.15), name="MyGamma")), iaa.Fliplr(0.5, name="MyFlipLR"), iaa.Flipud(0.5, name="MyFlipUD"), sometimes(iaa.Rot90(k=1, keep_size=True, name="MyRot90")), iaa.OneOf([ sometimes3(iaa.PiecewiseAffine(scale=(0.015, 0.02), cval=0, name="MyPiece")), sometimes4(iaa.ElasticTransformation(alpha=(100, 200), sigma=20, cval=0, name="MyElastic")), sometimes5(iaa.Affine(scale={"x": (0.95, 1.05), "y": (0.95, 1.05)}, rotate=(-45, 45), shear=(-4, 4), cval=0, name="MyAffine")) ], name="MyOneOf") ], name="MyAug") seq_lbl = iaa.Sequential([ iaa.Fliplr(0.5, name="MyFlipLR"), iaa.Flipud(0.5, name="MyFlipUD"), sometimes(iaa.Rot90(k=1, keep_size=True, name="MyRot90")), iaa.OneOf([ sometimes3(iaa.PiecewiseAffine(scale=(0.015, 0.02), cval=8, order=0, name="MyPiece")), sometimes4(iaa.ElasticTransformation(alpha=(100, 200), sigma=20, cval=8, order=0, name="MyElastic")), sometimes5(iaa.Affine(scale={"x": (0.95, 1.05), "y": (0.95, 1.05)}, rotate=(-45, 45), shear=(-4, 4), cval=8, order=0, name="MyAffine")) ], name="MyOneOf") ], name="MyAug") return seq_img, seq_lbl
def __init__(self, dir_path, batch_size, img_set, shuffle=True): self.dir_path = dir_path self.batch_size = batch_size self.img_set = img_set self.shuffle = shuffle self.seq = iaa.Sequential([ iaa.Fliplr(0.5), iaa.Flipud(0.5), iaa.Rot90(k=[0, 1, 2, 3]), # iaa.CropAndPad(percent=(-0.2, 0.2)) iaa.AllChannelsHistogramEqualization() ]) if self.shuffle == True: np.random.shuffle(self.img_set)
def getAuger(rot_angle,contrast_range,Perspective_range): if rot_angle==0: seq = iaa.Sequential([ iaa.ContrastNormalization(contrast_range), iaa.PerspectiveTransform(scale=Perspective_range), ], random_order=False) else: seq = iaa.Sequential([ #iaa.Fliplr(0.5), iaa.Rot90(rot_angle), iaa.ContrastNormalization(contrast_range), iaa.PerspectiveTransform(scale=Perspective_range), ], random_order=False) return seq
def __init__(self, augmentation_ratio=1.0, flip_probability=0.5, contrast_probability=0.2, defocus_probability=0.1, motion_blur_probability=0.2, cutout_probability=0.2, scale_probability=0.1, shift_probability=0.2, fog_probability=0.1): rot = iaa.Rot90(ia.ALL) shift = iaa.Affine(translate_percent=(-0.2, 0.2)) flip = iaa.OneOf([iaa.Fliplr(1), iaa.Flipud(1)]) scale = iaa.Affine(scale=(0.75, 1.25)) motion_blur = iaa.MotionBlur() cutout = iaa.Cutout( nb_iterations=(1, 3), size=(0.01, 0.1), squared=False) fog = iaa.imgcorruptlike.Fog(severity=1) defocus = iaa.imgcorruptlike.DefocusBlur(severity=1) contrast = iaa.imgcorruptlike.Contrast(severity=1) aug_weather = iaa.Sequential([ iaa.Sometimes(augmentation_ratio * fog_probability, fog), ], random_order=True) aug_initial = iaa.Sequential([ rot, iaa.Sometimes(flip_probability, flip), iaa.Sometimes(augmentation_ratio * contrast_probability, contrast) ], random_order=True) aug_camera = iaa.Sequential([ iaa.Sometimes(augmentation_ratio * defocus_probability, defocus), iaa.Sometimes(augmentation_ratio * motion_blur_probability, motion_blur), ], random_order=False) aug_obstacles = iaa.Sequential([ iaa.Sometimes(augmentation_ratio * cutout_probability, cutout), iaa.Sometimes(augmentation_ratio * scale_probability, scale), iaa.Sometimes(shift_probability, shift) ], random_order=False) self.augmentation_pipeline = iaa.Sequential( [aug_weather, aug_initial, aug_camera, aug_obstacles], random_order=False)
def build_augmenter(self): augmenter = iaa.Sometimes( 0.5, iaa.Sequential([ iaa.Affine(scale={ "x": (0.95, 1.05), "y": (0.95, 1.05) }, translate_percent={ "x": (-0.1, 0.1), "y": (-0.1, 0.1) }, order=[0, 1]), iaa.Sometimes(0.3, iaa.Rot90(k=[1, 2, 3], keep_size=False)) ])) return augmenter
def get_augmenter(self): seq = iaa.Sequential([ iaa.SomeOf((2, 6), [ iaa.Flipud(0.5), iaa.Rot90(k=(0, 3)), iaa.GaussianBlur(sigma=(0.0, 3.0)), iaa.MotionBlur(angle=(0, 360), k=(3, 8)), iaa.Add((-50, 5)), iaa.AddElementwise((-20, 2)), iaa.AdditiveGaussianNoise(scale=0.05 * 255), iaa.Multiply((0.3, 1.05)), iaa.SaltAndPepper(p=(0.1, 0.3)), iaa.JpegCompression(compression=(20, 90)), iaa.Affine(shear=(-15, 15)), iaa.Affine(rotate=(-10, 10)), ]) ]) return seq
def apply_augmentation(img): ''' apply augmentation for TFRecords Parameters ---------- img : numpy array N dimensional an MxNxD array that contains the image Returns ------- img : numpy array an MxNxD array that contains the augmented image ''' sometimes = lambda aug: iaa.Sometimes(0.5, aug) # channel invariant augmentations seq = iaa.Sequential([ iaa.Fliplr(0.5), # horizontally flip 50% of the images iaa.Flipud(0.5), sometimes(iaa.Rot90((1, 3))) ], random_order=True) # RGB dependent augmentations seq2 = sometimes( iaa.SomeOf((1,4),[ iaa.AddToHue((-8,8)), iaa.AddToSaturation((-10,10)), iaa.Multiply((0.90, 1.25)), iaa.LinearContrast((0.90, 1.3)) ], random_order=True) ) img = seq(image=img) img2 = np.array(img[:,:,0:3] * 255, dtype=np.uint8) img2 = seq2(image=img2) img2 = np.array(img2/255, dtype=np.float32) img[:,:,0:3] = img2 #print(img) return img
def __init__(self): self.augmenter = iaa.OneOf([ iaa.Identity(), iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.03 * 255)), iaa.Fliplr(1), iaa.Flipud(1), iaa.Rot90(k=1), iaa.Rot90(k=2), iaa.Rot90(k=3), iaa.Sequential([ iaa.Flipud(1), iaa.Rot90(k=1), ]), iaa.Sequential([ iaa.Flipud(1), iaa.Rot90(k=2), ]), iaa.Sequential([ iaa.Flipud(1), iaa.Rot90(k=3), ]) ])
def __init__(self, X, Y, random_subvolumes_in_DA=False, subvol_shape=None, seed=42, shuffle_each_epoch=False, batch_size=32, da=True, da_prob=0.5, rotation90=False, rand_rot=False, rnd_rot_range=(-180, 180), shear=False, shear_range=(-20, 20), zoom=False, zoom_range=(0.8, 1.2), shift=False, shift_range=(0.1, 0.2), flip=False, elastic=False, e_alpha=(240, 250), e_sigma=25, e_mode='constant', g_blur=False, g_sigma=(1.0, 2.0), median_blur=False, mb_kernel=(3, 7), motion_blur=False, motb_k_range=(3, 8), gamma_contrast=False, gc_gamma=(1.25, 1.75), dropout=False, drop_range=(0, 0.2), cutout=False, cout_nb_iterations=(1, 3), cout_size=0.2, cout_fill_mode='constant', cutblur=False, cblur_size=0.4, cblur_down_range=(2, 8), cblur_inside=True, cutmix=False, cmix_size=0.4, n_classes=1, out_number=1, val=False, prob_map=None, extra_data_factor=1): """ImageDataGenerator constructor. Based on transformations from `imgaug <https://github.com/aleju/imgaug>`_ library. Here a brief description of each transformation parameter is made. Find a complete explanation of the library `documentation <https://imgaug.readthedocs.io/en/latest/index.html>`_. Parameters ---------- X : Numpy 5D array Data. E.g. ``(num_of_images, x, y, z, channels)``. Y : Numpy 5D array Mask data. E.g. ``(num_of_images, x, y, z, channels)``. random_subvolumes_in_DA : bool, optional To extract random subvolumes from the given data. If not, the data must be 5D and is assumed that the subvolumes are prepared. subvol_shape : 4D tuple of ints, optional Shape of the subvolume to be extracted randomly from the data. E. g. ``(x, y, z, channels)``. seed : int, optional Seed for random functions. shuffle_each_epoch : bool, optional To shuffle data after each epoch. batch_size : int, optional Size of the batches. da : bool, optional To activate the data augmentation. da_prob : float, optional Probability of doing each transformation. rotation90 : bool, optional To make square (90, 180,270) degree rotations. rand_rot : bool, optional To make random degree range rotations. rnd_rot_range : tuple of float, optional Range of random rotations. E. g. ``(-180, 180)``. shear : bool, optional To make shear transformations. shear_range : tuple of int, optional Degree range to make shear. E. g. ``(-20, 20)``. zoom : bool, optional To make zoom on images. zoom_range : tuple of floats, optional Zoom range to apply. E. g. ``(0.8, 1.2)``. shift : float, optional To make shifts. shift_range : tuple of float, optional Range to make a shift. E. g. ``(0.1, 0.2)``. flip : bool, optional To activate flips (both horizontal and vertical). elastic : bool, optional To make elastic deformations. e_alpha : tuple of ints, optional Strength of the distortion field. E. g. ``(240, 250)``. e_sigma : int, optional Standard deviation of the gaussian kernel used to smooth the distortion fields. e_mode : str, optional Parameter that defines the handling of newly created pixels with the elastic transformation. g_blur : bool, optional To insert gaussian blur on the images. g_sigma : tuple of floats, optional Standard deviation of the gaussian kernel. E. g. ``(1.0, 2.0)``. median_blur : bool, optional To blur an image by computing median values over neighbourhoods. mb_kernel : tuple of ints, optional Median blur kernel size. E. g. ``(3, 7)``. motion_blur : bool, optional Blur images in a way that fakes camera or object movements. motb_k_range : int, optional Kernel size to use in motion blur. gamma_contrast : bool, optional To insert gamma constrast changes on images. gc_gamma : tuple of floats, optional Exponent for the contrast adjustment. Higher values darken the image. E. g. ``(1.25, 1.75)``. dropout : bool, optional To set a certain fraction of pixels in images to zero. drop_range : tuple of floats, optional Range to take a probability ``p`` to drop pixels. E.g. ``(0, 0.2)`` will take a ``p`` folowing ``0<=p<=0.2`` and then drop ``p`` percent of all pixels in the image (i.e. convert them to black pixels). cutout : bool, optional To fill one or more rectangular areas in an image using a fill mode. cout_nb_iterations : tuple of ints, optional Range of number of areas to fill the image with. E. g. ``(1, 3)``. cout_size : float, optional Size of the areas in % of the corresponding image size. Value between ``0`` and ``1``. cout_fill_mode : str, optional Parameter that defines the handling of newly created pixels with cutout. cutblur : boolean, optional Blur a rectangular area of the image by downsampling and upsampling it again. cblur_size : float, optional Size of the area to apply cutblur on. cblur_inside : boolean, optional If ``True`` only the region inside will be modified (cut LR into HR image). If ``False`` the ``50%`` of the times the region inside will be modified (cut LR into HR image) and the other ``50%`` the inverse will be done (cut HR into LR image). See Figure 1 of the official `paper <https://arxiv.org/pdf/2004.00448.pdf>`_. cutmix : boolean, optional Combine two images pasting a region of one image to another. cmix_size : float, optional Size of the area to paste one image into another. n_classes : int, optional Number of classes. If ``> 1`` one-hot encoding will be done on the ground truth. out_number : int, optional Number of output returned by the network. Used to produce same number of ground truth data on each batch. val : bool, optional Advice the generator that the volumes will be used to validate the model to not make random crops (as the validation data must be the same on each epoch). Valid when ``random_subvolumes_in_DA`` is set. prob_map : 5D Numpy array, optional Probability map used to make random crops when ``random_subvolumes_in_DA`` is set. extra_data_factor : int, optional Factor to multiply the batches yielded in a epoch. It acts as if ``X`` and ``Y``` where concatenated ``extra_data_factor`` times. """ if X.ndim != 5 or Y.ndim != 5: raise ValueError("X and Y must be a 5D Numpy array") if X.shape[:4] != Y.shape[:4]: raise ValueError( "The shape of X and Y must be the same. {} != {}".format( X.shape[:4], Y.shape[:4])) if random_subvolumes_in_DA: if subvol_shape is None: raise ValueError("'subvol_shape' must be provided when " "'random_subvolumes_in_DA is enabled") if subvol_shape[0] > X.shape[1] or subvol_shape[1] > X.shape[2] or \ subvol_shape[2] > X.shape[3]: raise ValueError( "Given 'subvol_shape' is bigger than the data " "provided") if rotation90 and rand_rot: print( "Warning: you selected double rotation type. Maybe you should" " set only 'rand_rot'?") self.X = (X / 255).astype(np.float32) if np.max(X) > 100 else X.astype( np.float32) self.X_c = self.X.shape[-1] self.X_z = self.X.shape[-2] self.Y = (Y / 255).astype(np.uint8) if np.max(Y) > 100 else Y.astype( np.uint8) self.Y_c = self.Y.shape[-1] self.Y_z = self.Y.shape[-2] self.n_classes = n_classes self.out_number = out_number self.channels = Y.shape[-1] self.random_subvolumes_in_DA = random_subvolumes_in_DA self.seed = seed self.shuffle_each_epoch = shuffle_each_epoch self.da = da self.da_prob = da_prob self.flip = flip self.cutblur = cutblur self.cblur_size = cblur_size self.cblur_down_range = cblur_down_range self.cblur_inside = cblur_inside self.cutmix = cutmix self.cmix_size = cmix_size self.val = val self.batch_size = batch_size self.o_indexes = np.arange(len(self.X)) if extra_data_factor > 1: self.extra_data_factor = extra_data_factor self.o_indexes = np.concatenate([self.o_indexes] * extra_data_factor) else: self.extra_data_factor = 1 self.prob_map = prob_map if random_subvolumes_in_DA: self.shape = subvol_shape else: self.shape = X.shape[1:] self.total_batches_seen = 0 self.da_options = [] self.trans_made = '' if rotation90: self.da_options.append(iaa.Sometimes(da_prob, iaa.Rot90((1, 3)))) self.trans_made += '_rot[90,180,270]' if rand_rot: self.da_options.append( iaa.Sometimes(da_prob, iaa.Affine(rotate=rnd_rot_range))) self.trans_made += '_rrot' + str(rnd_rot_range) if shear: self.da_options.append( iaa.Sometimes(da_prob, iaa.Affine(rotate=shear_range))) self.trans_made += '_shear' + str(shear_range) if zoom: self.da_options.append( iaa.Sometimes( da_prob, iaa.Affine(scale={ "x": zoom_range, "y": zoom_range }))) self.trans_made += '_zoom' + str(zoom_range) if shift: self.da_options.append( iaa.Sometimes(da_prob, iaa.Affine(translate_percent=shift_range))) self.trans_made += '_shift' + str(shift_range) if flip: self.da_options.append(iaa.Flipud(0.5)) self.da_options.append(iaa.Fliplr(0.5)) self.trans_made += '_flip' if elastic: self.da_options.append( iaa.Sometimes( da_prob, iaa.ElasticTransformation(alpha=e_alpha, sigma=e_sigma, mode=e_mode))) self.trans_made += '_elastic' + str(e_alpha) + '+' + str( e_sigma) + '+' + str(e_mode) if g_blur: self.da_options.append( iaa.Sometimes(da_prob, iaa.GaussianBlur(g_sigma))) self.trans_made += '_gblur' + str(g_sigma) if median_blur: self.da_options.append( iaa.Sometimes(da_prob, iaa.MedianBlur(k=mb_kernel))) self.trans_made += '_mblur' + str(mb_kernel) if motion_blur: self.da_options.append( iaa.Sometimes(da_prob, iaa.MotionBlur(k=motb_k_range))) self.trans_made += '_motb' + str(motb_k_range) if gamma_contrast: self.da_options.append( iaa.Sometimes(da_prob, iaa.GammaContrast(gc_gamma))) self.trans_made += '_gcontrast' + str(gc_gamma) if dropout: self.da_options.append( iaa.Sometimes(da_prob, iaa.Dropout(p=drop_range))) self.trans_made += '_drop' + str(drop_range) if cutout: self.da_options.append( iaa.Sometimes( da_prob, iaa.Cutout(nb_iterations=cout_nb_iterations, size=cout_size, fill_mode=cout_fill_mode, squared=False))) self.trans_made += '_cout' + str(cout_nb_iterations) + '+' + str( cout_size) + '+' + str(cout_fill_mode) if cutblur: self.trans_made += '_cblur' + str(cblur_size) + '+' + str( cblur_down_range) + '+' + str(cblur_inside) if cutmix: self.trans_made += '_cmix' + str(cmix_size) self.trans_made = self.trans_made.replace(" ", "") self.seq = iaa.Sequential(self.da_options) ia.seed(seed) self.on_epoch_end()
def train_on_tiles(data_dir, model_id, max_epochs=25, learning_rate=1e-3, batch_size=32, threshold=0.5, n_classes=None, class_weights=None, batch_norm=True, augmentation=False, input_channels=None, depth=4, wf=4, padding=True, scheduler=None): print('Building U-Net model and training') exports_dir = './figures/{}/'.format(model_id) os.makedirs(exports_dir, exist_ok=True) # Define augmentation transforms aug = iaa.Sequential([ # iaa.MultiplyHueAndSaturation((0.5, 1.5)), # iaa.AddToHueAndSaturation((-45, 45)), # iaa.Grayscale((0.0, 1.0)), # iaa.AllChannelsHistogramEqualization(), # iaa.GammaContrast((0.0, 1.75), per_channel=True), # iaa.LinearContrast((0.0, 1.75), per_channel=True), iaa.Crop(px=(0, 32)), # randomly crop between 0 and 32 pixels iaa.Fliplr(0.50), # horizontally flip 50% of the images iaa.Flipud(0.50), # horizontally flip 50% of the images iaa.Rot90([0, 1, 2, 3]), # apply any of the 90 deg rotations # iaa.PerspectiveTransform((0.025, 0.1)), # randomly scale between 0.025 and 0.1 # iaa.Affine(scale=(0.5, 1.5), translate_percent=(0, 0.25), # random affine transforms with symmetric padding # rotate=(0, 360), shear=(0, 360), mode='symmetric'), ]) if class_weights is None: class_weights = [1, 1, 1] if augmentation: tfms = ImgAugTransform(aug) else: tfms = None datasets = {} datasets['train'] = OrthoData(os.path.join(data_dir, 'train_tiles.h5'), transform=None, channels=input_channels) datasets['val'] = OrthoData(os.path.join(data_dir, 'test_tiles.h5'), transform=None, channels=input_channels) if input_channels is None: n_channels = datasets['train'].input_shape[1] else: n_channels = len(input_channels) if n_classes is None: n_classes = datasets['train'].n_classes print('Input channels:', input_channels) # DataLoader parameters dataloader_params = { 'batch_size': batch_size, 'num_workers': 0, 'shuffle': True } # Make the DataLoaders data_loaders = { name: DataLoader(datasets[name], **dataloader_params) for name in ['train', 'val'] } # Define model print('CUDA:', torch.cuda.is_available()) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') unet_params = { 'n_classes': n_classes, 'in_channels': n_channels, 'depth': depth, 'padding': padding, 'wf': wf, 'up_mode': 'upconv', 'batch_norm': batch_norm } model = UNet(**unet_params).to(device) n_parameters = count_parameters(model) print(f'Number of model parameters: {n_parameters}') # Define optimizer and loss function optim = torch.optim.Adam(model.parameters(), lr=learning_rate) class_weights = torch.Tensor(class_weights).to(device) criterion = nn.CrossEntropyLoss(class_weights) if scheduler: scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optim, verbose=True, patience=2) scheduler = GradualWarmupScheduler( optim, multiplier=10, total_epoch=10, after_scheduler=scheduler, ) # Train model, history = train_model(model, data_loaders, max_epochs, criterion, optim, scheduler=scheduler, return_history=True, transform=tfms) os.makedirs('./saved_weights/', exist_ok=True) model_filename = '{}.pt'.format(model_id) torch.save(model.state_dict(), './saved_weights/{}'.format(model_filename)) print('Saved model as: ./saved_weights/{}'.format(model_filename)) n_examples = len(datasets['val']) # //10 sampler = RandomSampler(datasets['val'], replacement=True, num_samples=n_examples) inputs = DataLoader(datasets['val'], sampler=sampler) print('Predicting over the validation dataset') inputs, preds, probs, targets = predict(model, data_loaders['val'], th=threshold) plot_results(inputs=inputs.astype(np.uint8), classes=np.expand_dims(targets, 1), prob=probs, n_plot=5, save_path=exports_dir + 'example_tiles.png') learning_curve(history=history, name='loss', outfile=exports_dir + 'loss_learning_curves.png') compare_learning_curve(history=history, name='accuracy', outfile=exports_dir + 'accuracy_learning_curves.png')
from PIL import Image import numpy as np import imgaug as ia from imgaug import augmenters as iaa # set up the file paths from_path = 'art/cropped/' to_path = 'art/resized/' # set up some parameters size = 1024 num_augmentations = 6 # set up the image augmenter seq = iaa.Sequential([ iaa.Rot90((0, 3)), # iaa.Fliplr(0.5), iaa.PerspectiveTransform(scale=(0.0, 0.05), mode='replicate'), iaa.AddToHueAndSaturation((-20, 20)) ]) # loop through the images, resizing and augementing path, dirs, files = next(os.walk(from_path)) for file in sorted(files): print(file) image = Image.open(path + "/" + file) image.save(to_path + "/" + file) image_resized = image.resize((size, size), resample=Image.BILINEAR) image_np = np.array(image_resized) images = [image_np] * num_augmentations images_aug = seq(images=images)
#criterion = criterion.to(device) #TODO: IS THIS NEEDED? # Enable Multi-GPU training if torch.cuda.device_count() > 1: print("Let's use", torch.cuda.device_count(), "GPUs!") # dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs net = nn.DataParallel(net) augs_train = iaa.Sequential([ # Geometric Augs iaa.Scale((imsize, imsize), 0), iaa.Fliplr(0.5), iaa.Flipud(0.5), iaa.Rot90((0, 4)), # Blur and Noise #iaa.Sometimes(0.2, iaa.GaussianBlur(sigma=(0, 1.5), name="gaus-blur")), #iaa.Sometimes(0.1, iaa.Grayscale(alpha=(0.0, 1.0), from_colorspace="RGB", name="grayscale")), # iaa.Sometimes(0.2, iaa.AdditiveLaplaceNoise(scale=(0, 0.1*255), per_channel=True, name="gaus-noise")), # Color, Contrast, etc. iaa.Sometimes(0.2, iaa.Multiply((0.75, 1.25), per_channel=0.1, name="brightness")), iaa.Sometimes(0.2, iaa.GammaContrast((0.7, 1.3), per_channel=0.1, name="contrast")), iaa.Sometimes(0.2, iaa.AddToHueAndSaturation((-20, 20), name="hue-sat")), iaa.Sometimes(0.3, iaa.Add((-20, 20), per_channel=0.5, name="color-jitter")), ]) augs_test = iaa.Sequential([ # Geometric Augs iaa.Scale((imsize, imsize), 0), ])
# Get the images images_list = os.listdir(in_pics) # should be the same as annotations for img in images_list: print(img) name = img.split(".")[0] xml_file = name + '.xml' # Load imge for augment i = cv2.imread(in_pics + img) # Get bbs. Won't apply the transorms unless it's a spacial augment bbs_og = get_bbs(in_annotations + xml_file) # Rotating all images_list seq = iaa.Rot90(1) rot90, bbs = seq(image=i, bounding_boxes=bbs_og) write_new_files(name, 'rot90', rot90, bbs, True) seq = iaa.Rot90(2) rot180, bbs = seq(image=i, bounding_boxes=bbs_og) write_new_files(name, 'rot180', rot180, bbs, True) seq = iaa.Rot90(3) rot270, bbs = seq(image=i, bounding_boxes=bbs_og) write_new_files(name, 'rot270', rot270, bbs, True) # DARKENING IMAGE seq = iaa.Multiply((0.4, 0.5)) darkened, _ = seq(image=i, bounding_boxes=bbs_og) write_new_files(name, 'darkened', darkened, _, False)