def landmarks_for_face(detector, predictor, image): """ Detects and corrects landmarks for faces :param detector: Face detector :param predictor: landmarks detector :param image: Image with face to detect :return: landmarks of face """ angle = 0 faces = [] result = [] while len(faces) == 0 and angle < 1: rotated = rotate_image(image, angle) faces = detector(rotated) for face in faces: landmarks = predictor(image, face) image_center = tuple(np.array(image.shape[1::-1]) / 2) rot_mat = cv2.getRotationMatrix2D(image_center, -angle, 1.0) for n in range(0, 68): landmark = np.array([landmarks.part(n).x, landmarks.part(n).y, 1], dtype=np.float) transformed = np.dot(rot_mat, landmark.T) result.append(transformed) angle += 10 return result
def augmentation_function(images, labels, **kwargs): ''' Function for augmentation of minibatches. It will transform a set of images and corresponding labels by a number of optional transformations. Each image/mask pair in the minibatch will be seperately transformed with random parameters. :param images: A numpy array of shape [minibatch, X, Y, (Z), nchannels] :param labels: A numpy array containing a corresponding label mask :param do_rotations: Rotate the input images by a random angle between -15 and 15 degrees. :param do_scaleaug: Do scale augmentation by sampling one length of a square, then cropping and upsampling the image back to the original size. :param do_fliplr: Perform random flips with a 50% chance in the left right direction. :return: A mini batch of the same size but with transformed images and masks. ''' if images.ndim > 4: raise AssertionError('Augmentation will only work with 2D images') do_rotations = kwargs.get('do_rotations', False) do_scaleaug = kwargs.get('do_scaleaug', False) do_fliplr = kwargs.get('do_fliplr', False) new_images = [] new_labels = [] num_images = images.shape[0] for ii in range(num_images): img = np.squeeze(images[ii, ...]) lbl = np.squeeze(labels[ii, ...]) # ROTATE if do_rotations: angles = kwargs.get('angles', (-15, 15)) random_angle = np.random.uniform(angles[0], angles[1]) img = image_utils.rotate_image(img, random_angle) lbl = image_utils.rotate_image(lbl, random_angle, interp=cv2.INTER_NEAREST) # RANDOM CROP SCALE if do_scaleaug: offset = kwargs.get('offset', 30) n_x, n_y = img.shape r_y = np.random.random_integers(n_y - offset, n_y) p_x = np.random.random_integers(0, n_x - r_y) p_y = np.random.random_integers(0, n_y - r_y) img = image_utils.resize_image( img[p_y:(p_y + r_y), p_x:(p_x + r_y)], (n_x, n_y)) lbl = image_utils.resize_image(lbl[p_y:(p_y + r_y), p_x:(p_x + r_y)], (n_x, n_y), interp=cv2.INTER_NEAREST) # RANDOM FLIP if do_fliplr: coin_flip = np.random.randint(2) if coin_flip == 0: img = np.fliplr(img) lbl = np.fliplr(lbl) new_images.append(img[..., np.newaxis]) new_labels.append(lbl[...]) sampled_image_batch = np.asarray(new_images) sampled_label_batch = np.asarray(new_labels) return sampled_image_batch, sampled_label_batch
def augmentation_function(images, labels): ''' :param images: A numpy array of shape [batch, X, Y], normalized between 0-1 :param labels: A numpy array containing a corresponding label mask ''' # Define in configuration.py which operations to perform do_rotation_range = config.do_rotation_range do_fliplr = config.do_fliplr do_flipud = config.do_flipud crop = config.crop # Probability to perform a generic operation prob = config.prob if 0.0 <= prob <= 1.0: new_images = [] new_labels = [] num_images = images.shape[0] for i in range(num_images): #extract the single image img = np.squeeze(images[i, ...]) lbl = np.squeeze(labels[i, ...]) for jj in range(8): imgg = img lbll = lbl # RANDOM ROTATION if do_rotation_range: angle = config.rg random_angle = np.random.uniform(angle[0], angle[1]) imgg = image_utils.rotate_image(imgg, random_angle) lbll = image_utils.rotate_image(lbll, random_angle, interp=cv2.INTER_NEAREST) # FLIP Lelf/Right if do_fliplr: coin_flip = np.random.randint(2) if coin_flip == 0: imgg = np.fliplr(imgg) lbll = np.fliplr(lbll) # FLIP up/down if do_flipud: coin_flip = np.random.randint(2) if coin_flip == 0: imgg = np.flipud(imgg) lbll = np.flipud(lbll) # RANDOM TRANSLATION 5% if (random.randint(0, 1)): x = random.randint(-11, 11) y = random.randint(-11, 11) M = np.float32([[1, 0, x], [0, 1, y]]) imgg = cv2.warpAffine( imgg, M, (config.image_size[0], config.image_size[1])) lbll = cv2.warpAffine( lbll, M, (config.image_size[0], config.image_size[1])) # RANDOM CROP 5% if crop: coin_flip = np.random.randint(2) if coin_flip == 0: zfactor = round(random.uniform(1, 1.05), 2) imgg = zoom(imgg, zfactor) lbll = zoom(lbll, zfactor) new_images.append(imgg[..., np.newaxis]) new_labels.append(lbll[...]) sampled_image_batch = np.asarray(new_images) sampled_label_batch = np.asarray(new_labels) return sampled_image_batch, sampled_label_batch else: logging.warning('Probability must be in range [0.0,1.0]!!')
def augmentation_function(images, labels): ''' :param images: A numpy array of shape [batch, X, Y], normalized between 0-1 :param labels: A numpy array containing a corresponding label mask ''' # Define in configuration.py which operations to perform do_rotation_range = config.do_rotation_range do_fliplr = config.do_fliplr do_flipud = config.do_flipud crop = config.crop do_gamma = config.gamma do_blurr = config.blurr # Probability to perform a generic operation prob = config.prob if 0.0 <= prob <= 1.0: new_images = [] new_labels = [] num_images = images.shape[0] for i in range(num_images): #extract the single image img = np.squeeze(images[i, ...]) lbl = np.squeeze(labels[i, ...]) # RANDOM ROTATION if do_rotation_range: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: angle = config.rg random_angle = np.random.uniform(angle[0], angle[1]) img = image_utils.rotate_image(img, random_angle) lbl = image_utils.rotate_image(lbl, random_angle, interp=cv2.INTER_NEAREST) # FLIP Lelf/Right if do_fliplr: coin_flip = np.random.randint(2) if coin_flip == 0: img = np.fliplr(img) lbl = np.fliplr(lbl) # FLIP up/down if do_flipud: coin_flip = np.random.randint(2) if coin_flip == 0: img = np.flipud(img) lbl = np.flipud(lbl) # RANDOM TRANSLATION 5% # if (random.randint(0,1)): # x = random.randint(-11,11) # y = random.randint(-11,11) # M = np.float32([[1,0,x],[0,1,y]]) # img = cv2.warpAffine(img,M,(config.image_size[0],config.image_size[1])) # lbl = cv2.warpAffine(lbl,M,(config.image_size[0],config.image_size[1])) # RANDOM CROP 5% if crop: coin_flip = np.random.randint(2) if coin_flip == 0: zfactor = round(random.uniform(1, 1.05), 2) img = zoom(img, zfactor) lbl = zoom(lbl, zfactor) # RANDOM GAMMA CORRECTION if do_gamma: coin_flip = np.random.randint(2) if coin_flip == 0: gamma = random.randrange(8, 13, 1) img = exposure.adjust_gamma(img, gamma / 10) # RANDOM BLURR if do_blurr: coin_flip = np.random.randint(2) if coin_flip == 0: sigma = random.randrange(6, 16, 2) img = scipy.ndimage.gaussian_filter(img, sigma / 10) new_images.append(img[..., np.newaxis]) new_labels.append(lbl[...]) sampled_image_batch = np.asarray(new_images) sampled_label_batch = np.asarray(new_labels) return sampled_image_batch, sampled_label_batch else: logging.warning('Probability must be in range [0.0,1.0]!!')
def augmentation_function(images, labels): ''' :param images: A numpy array of shape [batch, X, Y], normalized between 0-1 :param labels: A numpy array containing a corresponding label mask ''' # Define in configuration.py which operations to perform do_rotation_range = config.do_rotation_range do_rotation_90 = config.do_rotation_90 do_rotation_180 = config.do_rotation_180 do_rotation_270 = config.do_rotation_270 do_rotation_reshape = config.do_rotation_reshape do_rotation = config.do_rotation crop = config.crop do_fliplr = config.do_fliplr do_flipud = config.do_flipud RandomContrast = config.RandomContrast blurr = config.blurr SaltAndPepper = config.SaltAndPepper Multiply = config.Multiply ElasticTransformation = config.ElasticTransformation Pad = config.Pad # Probability to perform a generic operation prob = config.prob if 0.0 <= prob <= 1.0: new_images = [] new_labels = [] num_images = images.shape[0] for i in range(num_images): #extract the single image img = np.squeeze(images[i, ...]) lbl = np.squeeze(labels[i, ...]) # ROTATE (Min,Max) # The operation will rotate an image by a random amount, within a range # specified if do_rotation_range: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: angles = config.rg random_angle = np.random.uniform(angles[0], angles[1]) imgg = img.copy() lbll = lbl.copy() imgg = image_utils.rotate_image(img, random_angle) lbll = image_utils.rotate_image(lbl, random_angle, interp=cv2.INTER_NEAREST) new_images.append(imgg[...]) new_labels.append(lbll[...]) # ROTATE 90° if do_rotation_90: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: angle = 90 imgg = img.copy() lbll = lbl.copy() imgg = image_utils.rotate_image(img, angle) lbll = image_utils.rotate_image(lbl, angle, interp=cv2.INTER_NEAREST) new_images.append(imgg[...]) new_labels.append(lbll[...]) # ROTATE 180° if do_rotation_180: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: angle = 180 imgg = img.copy() lbll = lbl.copy() imgg = image_utils.rotate_image(img, angle) lbll = image_utils.rotate_image(lbl, angle, interp=cv2.INTER_NEAREST) new_images.append(imgg[...]) new_labels.append(lbll[...]) # ROTATE 270° if do_rotation_270: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: angle = 270 imgg = img.copy() lbll = lbl.copy() imgg = image_utils.rotate_image(img, angle) lbll = image_utils.rotate_image(lbl, angle, interp=cv2.INTER_NEAREST) new_images.append(imgg[...]) new_labels.append(lbll[...]) # ROTATE (generic angle with reshape) if do_rotation_reshape: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: angle = config.angle imgg = img.copy() lbll = lbl.copy() imgg = scipy.ndimage.rotate(img, angle) lbll = scipy.ndimage.rotate(lbl, angle) new_images.append(imgg[...]) new_labels.append(lbll[...]) # ROTATE (generic angle) if do_rotation: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: angle = config.angle imgg = img.copy() lbll = lbl.copy() imgg = scipy.ndimage.rotate(img, angle, reshape=False) lbll = scipy.ndimage.rotate(lbl, angle, reshape=False) new_images.append(imgg[...]) new_labels.append(lbll[...]) # RANDOM CROP SCALE if crop: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: augmenters = [iaa.Crop(px=config.offset)] seq = iaa.Sequential(augmenters, random_order=True) imgg = img.copy() lbll = lbl.copy() imgg = seq.augment_image(img) lbll = seq.augment_image(lbl) new_images.append(imgg[...]) new_labels.append(lbll[...]) # RANDOM FLIP Lelf/Right if do_fliplr: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: imgg = img.copy() lbll = lbl.copy() imgg = np.fliplr(img) lbll = np.fliplr(lbl) new_images.append(imgg[...]) new_labels.append(lbll[...]) # RANDOM FLIP up/down if do_flipud: coin_flip = np.random.uniform(low=0.0, high=1.0) if coin_flip < prob: imgg = img.copy() lbll = lbl.copy() imgg = np.flipud(img) lbll = np.flipud(lbl) new_images.append(imgg[...]) new_labels.append(lbll[...]) # RANDOM CONTRAST # Random change the passed image contrast ''' min_factor: The value between 0.0 and max_factor that define the minimum adjustment of image contrast. The value 0.0 gives s solid grey image, value 1.0 gives the original image. max_factor: A value should be bigger than min_factor. that define the maximum adjustment of image contrast. The value 0.0 gives s solid grey image, value 1.0 gives the original image. ''' if RandomContrast: coin_flip = np.random.uniform(low=0, high=1.0) if coin_flip < prob: factor = np.random.uniform(config.min_factor, config.max_factor) img = ImageEnhance.Contrast(img).enhance(factor) # write the code (img should not be an array) # BLURRING # only on image not label if blurr: coin_flip = np.random.uniform(low=0, high=1.0) if coin_flip < prob: inter = config.sigma sigma = np.random.uniform(inter[0], inter[1]) imgg = img.copy() lbll = lbl.copy() imgg = scipy.ndimage.gaussian_filter(img, sigma) new_images.append(imgg[...]) new_labels.append(lbll[...]) # SaltAndPepper (image should be normalized between 0 and 1) if SaltAndPepper: coin_flip = np.random.uniform(low=0, high=1.0) if coin_flip < prob: dens = config.density imgg = img.copy() lbll = lbl.copy() if (dens > 1.00) | (dens < 0.00): dens = 0.05 coords = [ np.random.randint(0, d - 1, int(np.ceil(dens * img.size * 0.5))) for d in img.shape ] imgg[coords] = 1 coords = [ np.random.randint(0, d - 1, int(np.ceil(dens * img.size * 0.5))) for d in img.shape ] imgg[coords] = 0 new_images.append(imgg[...]) new_labels.append(lbll[...]) # Multiply if Multiply: coin_flip = np.random.uniform(low=0, high=1.0) if coin_flip < prob: augmenters = [iaa.Multiply(config.m)] seq = iaa.Sequential(augmenters, random_order=True) imgg = img.copy() lbll = lbl.copy() imgg = seq.augment_image(img) new_images.append(imgg[...]) new_labels.append(lbll[...]) # ElasticTransformation ''' The augmenter has the parameters ``alpha`` and ``sigma``. ``alpha`` controls the strength of the displacement: higher values mean that pixels are moved further. ``sigma`` controls the smoothness of the displacement: higher values lead to smoother patterns -- as if the image was below water -- while low values will cause indivdual pixels to be moved very differently from their neighbours, leading to noisy and pixelated images. A relation of 10:1 seems to be good for ``alpha`` and ``sigma` ''' if ElasticTransformation: coin_flip = np.random.uniform(low=0, high=1.0) if coin_flip < prob: augmenters = [ iaa.ElasticTransformation(alpha=config.alpha, sigma=config.sigma) ] seq = iaa.Sequential(augmenters, random_order=True) imgg = img.copy() lbll = lbl.copy() imgg = seq.augment_image(img) lbll = seq.augment_image(lbl) new_images.append(imgg[...]) new_labels.append(lbll[...]) if Pad: coin_flip = np.random.uniform(low=0, high=1.0) if coin_flip < prob: augmenters = [iaa.Pad(px=config.offset2)] seq = iaa.Sequential(augmenters, random_order=True) imgg = img.copy() lbll = lbl.copy() imgg = seq.augment_image(img) lbll = seq.augment_image(lbl) new_images.append(imgg[...]) new_labels.append(lbll[...]) sampled_image_batch = np.asarray(new_images) sampled_label_batch = np.asarray(new_labels) return sampled_image_batch, sampled_label_batch else: logging.warning('Probability must be in range [0.0,1.0]!!')