Beispiel #1
0
 def test_random_transforms(self):
     x = np.random.random((2, 28, 28))
     assert image.random_rotation(x, 45).shape == (2, 28, 28)
     assert image.random_shift(x, 1, 1).shape == (2, 28, 28)
     assert image.random_shear(x, 20).shape == (2, 28, 28)
     assert image.random_zoom(x, (5, 5)).shape == (2, 28, 28)
     assert image.random_channel_shift(x, 20).shape == (2, 28, 28)
Beispiel #2
0
 def test_random_transforms(self):
     x = np.random.random((2, 28, 28))
     assert image.random_rotation(x, 45).shape == (2, 28, 28)
     assert image.random_shift(x, 1, 1).shape == (2, 28, 28)
     assert image.random_shear(x, 20).shape == (2, 28, 28)
     assert image.random_zoom(x, (5, 5)).shape == (2, 28, 28)
     assert image.random_channel_shift(x, 20).shape == (2, 28, 28)
Beispiel #3
0
def do_tta(x, tta_types):
    if 'hflip' in tta_types:
        x = flip_axis(x, 1)
    if 'vflip' in tta_types:
        x = flip_axis(x, 0)
    if 'channel_shift' in tta_types:
        x = random_channel_shift(x, 0.2, 2)
    return x
Beispiel #4
0
 def test_img_transforms(self):
     x = np.random.random((3, 200, 200))
     _ = preprocessing_image.random_rotation(x, 20)
     _ = preprocessing_image.random_shift(x, 0.2, 0.2)
     _ = preprocessing_image.random_shear(x, 2.)
     _ = preprocessing_image.random_zoom(x, (0.5, 0.5))
     _ = preprocessing_image.apply_channel_shift(x, 2, 2)
     _ = preprocessing_image.apply_affine_transform(x, 2)
     with self.assertRaises(ValueError):
         preprocessing_image.random_zoom(x, (0, 0, 0))
     _ = preprocessing_image.random_channel_shift(x, 2.)
    def test_random_transforms(self):
        x = np.random.random((2, 28, 28))
        assert image.random_rotation(x, 45).shape == (2, 28, 28)
        assert image.random_shift(x, 1, 1).shape == (2, 28, 28)
        assert image.random_shear(x, 20).shape == (2, 28, 28)
        assert image.random_zoom(x, (5, 5)).shape == (2, 28, 28)
        assert image.random_channel_shift(x, 20).shape == (2, 28, 28)

        # Test get_random_transform with predefined seed
        seed = 1
        generator = image.ImageDataGenerator(
            rotation_range=90.,
            width_shift_range=0.1,
            height_shift_range=0.1,
            shear_range=0.5,
            zoom_range=0.2,
            channel_shift_range=0.1,
            brightness_range=(1, 5),
            horizontal_flip=True,
            vertical_flip=True)
        transform_dict = generator.get_random_transform(x.shape, seed)
        transform_dict2 = generator.get_random_transform(x.shape, seed * 2)
        assert transform_dict['theta'] != 0
        assert transform_dict['theta'] != transform_dict2['theta']
        assert transform_dict['tx'] != 0
        assert transform_dict['tx'] != transform_dict2['tx']
        assert transform_dict['ty'] != 0
        assert transform_dict['ty'] != transform_dict2['ty']
        assert transform_dict['shear'] != 0
        assert transform_dict['shear'] != transform_dict2['shear']
        assert transform_dict['zx'] != 0
        assert transform_dict['zx'] != transform_dict2['zx']
        assert transform_dict['zy'] != 0
        assert transform_dict['zy'] != transform_dict2['zy']
        assert transform_dict['channel_shift_intensity'] != 0
        assert (transform_dict['channel_shift_intensity'] !=
                transform_dict2['channel_shift_intensity'])
        assert transform_dict['brightness'] != 0
        assert transform_dict['brightness'] != transform_dict2['brightness']

        # Test get_random_transform without any randomness
        generator = image.ImageDataGenerator()
        transform_dict = generator.get_random_transform(x.shape, seed)
        assert transform_dict['theta'] == 0
        assert transform_dict['tx'] == 0
        assert transform_dict['ty'] == 0
        assert transform_dict['shear'] == 0
        assert transform_dict['zx'] == 1
        assert transform_dict['zy'] == 1
        assert transform_dict['channel_shift_intensity'] is None
        assert transform_dict['brightness'] is None
Beispiel #6
0
    def test_random_transforms(self):
        x = np.random.random((2, 28, 28))
        assert image.random_rotation(x, 45).shape == (2, 28, 28)
        assert image.random_shift(x, 1, 1).shape == (2, 28, 28)
        assert image.random_shear(x, 20).shape == (2, 28, 28)
        assert image.random_zoom(x, (5, 5)).shape == (2, 28, 28)
        assert image.random_channel_shift(x, 20).shape == (2, 28, 28)

        # Test get_random_transform with predefined seed
        seed = 1
        generator = image.ImageDataGenerator(
            rotation_range=90.,
            width_shift_range=0.1,
            height_shift_range=0.1,
            shear_range=0.5,
            zoom_range=0.2,
            channel_shift_range=0.1,
            brightness_range=(1, 5),
            horizontal_flip=True,
            vertical_flip=True)
        transform_dict = generator.get_random_transform(x.shape, seed)
        transform_dict2 = generator.get_random_transform(x.shape, seed * 2)
        assert transform_dict['theta'] != 0
        assert transform_dict['theta'] != transform_dict2['theta']
        assert transform_dict['tx'] != 0
        assert transform_dict['tx'] != transform_dict2['tx']
        assert transform_dict['ty'] != 0
        assert transform_dict['ty'] != transform_dict2['ty']
        assert transform_dict['shear'] != 0
        assert transform_dict['shear'] != transform_dict2['shear']
        assert transform_dict['zx'] != 0
        assert transform_dict['zx'] != transform_dict2['zx']
        assert transform_dict['zy'] != 0
        assert transform_dict['zy'] != transform_dict2['zy']
        assert transform_dict['channel_shift_intensity'] != 0
        assert (transform_dict['channel_shift_intensity'] !=
                transform_dict2['channel_shift_intensity'])
        assert transform_dict['brightness'] != 0
        assert transform_dict['brightness'] != transform_dict2['brightness']

        # Test get_random_transform without any randomness
        generator = image.ImageDataGenerator()
        transform_dict = generator.get_random_transform(x.shape, seed)
        assert transform_dict['theta'] == 0
        assert transform_dict['tx'] == 0
        assert transform_dict['ty'] == 0
        assert transform_dict['shear'] == 0
        assert transform_dict['zx'] == 1
        assert transform_dict['zy'] == 1
        assert transform_dict['channel_shift_intensity'] is None
        assert transform_dict['brightness'] is None
    def augmentation(self, X, Y):
        print('Augmentation model...')
        total = len(X)
        x_train, y_train = [], []

        for i in range(total):
            if i % 100 == 0:
                print('Aug', i)
            x, y = X[i], Y[i]
            #standart
            x_train.append(x)
            y_train.append(y)

            for _ in range(2):
                _x, _y = elastic_transform(x[0], y[0], 100, 20)
                x_train.append(_x.reshape((1, ) + _x.shape))
                y_train.append(_y.reshape((1, ) + _y.shape))

            #flip x
            x_train.append(flip_axis(x, 2))
            y_train.append(flip_axis(y, 2))
            #flip y
            x_train.append(flip_axis(x, 1))
            y_train.append(flip_axis(y, 1))
            continue
            #zoom
            for _ in range(1):
                _x, _y = random_zoom(x, y, (0.9, 1.1))
                x_train.append(_x)
                y_train.append(_y)
            #intentsity
            for _ in range(1):
                _x = random_channel_shift(x, 5.0)
                x_train.append(_x)
                y_train.append(y)


#        for j in range(5):
#            xs, ys = load_aug(j)
#            ys = self.norm_mask(ys)
#            (xn, yn), _ = self.split_train_and_valid_by_patient(xs, ys, validation_split=self.validation_split, shuffle=False)
#            for i in range(len(xn)):
#                x_train.append(xn[i])
#                y_train.append(yn[i])

        x_train = np.array(x_train)
        y_train = np.array(y_train)
        return x_train, y_train
Beispiel #8
0
    def augmentation(self, X, Y):
        print('Augmentation model...')
        total = len(X)
        x_train, y_train = [], []

        for i in xrange(total):
            x, y = X[i], Y[i]
            #standart
            x_train.append(x)
            y_train.append(y)

            #            for _ in xrange(1):
            #                _x, _y = elastic_transform(x[0], y[0], 100, 20)
            #                x_train.append(_x.reshape((1,) + _x.shape))
            #                y_train.append(_y.reshape((1,) + _y.shape))

            #flip x
            x_train.append(flip_axis(x, 2))
            y_train.append(flip_axis(y, 2))
            #flip y
            x_train.append(flip_axis(x, 1))
            y_train.append(flip_axis(y, 1))
            #continue
            #zoom
            for _ in xrange(1):
                _x, _y = random_zoom(x, y, (0.9, 1.1))
                x_train.append(_x)
                y_train.append(_y)
            for _ in xrange(0):
                _x, _y = random_rotation(x, y, 5)
                x_train.append(_x)
                y_train.append(_y)
            #intentsity
            for _ in xrange(1):
                _x = random_channel_shift(x, 5.0)
                x_train.append(_x)
                y_train.append(y)

        x_train = np.array(x_train)
        y_train = np.array(y_train)

        print('x_trian: ', x_train.shape)

        return x_train, y_train
Beispiel #9
0
    def random_transform(self, *args):
        """
        Override original `random_transform`

        Randomly augment list of single image tensors.
        # Arguments
            *args: list of 3D ndarrays of same shape
        # Returns
            A randomly transformed inputs (same shape).
        """
        assert len(args) > 0, "List of arguments should not be empty"
        output_args = list(args)
        img_channel_axis = self.channel_axis - 1
        img_row_axis = self.row_axis - 1
        img_col_axis = self.col_axis - 1
        transform_matrix = self._get_random_transform_matrix(
            output_args[0].shape)

        if transform_matrix is not None:
            for i, arg in enumerate(output_args):
                output_args[i] = apply_transform(arg,
                                                 transform_matrix,
                                                 img_channel_axis,
                                                 fill_mode=self.fill_mode,
                                                 cval=self.cval)
        if self.channel_shift_range != 0:
            for i, arg in enumerate(output_args):
                output_args[i] = random_channel_shift(arg,
                                                      self.channel_shift_range,
                                                      img_channel_axis)
        if self.horizontal_flip:
            if np.random.random() < 0.5:
                for i, arg in enumerate(output_args):
                    output_args[i] = flip_axis(arg, img_col_axis)
        if self.vertical_flip:
            if np.random.random() < 0.5:
                for i, arg in enumerate(output_args):
                    output_args[i] = flip_axis(arg, img_row_axis)
        return output_args[0] if len(output_args) == 1 else output_args
    def random_transform(self, x, y):
        x_shape = None
        for x_sub in x:
            if x_sub[1]:
                x_shape = x_sub.shape

        img_channel_index, img_col_index, img_row_index, transform_matrix = self.build_transform(
            x_shape)
        flip_horiz_choice, flip_vert_choice = np.random.random(2) < 0.5
        for x_i in range(len(x)):
            if x[x_i][1]:
                to_transform = x[x_i][0]
                to_transform = self.spatial_transforms(
                    flip_horiz_choice, flip_vert_choice, img_channel_index,
                    img_col_index, img_row_index, to_transform,
                    transform_matrix)

                if self.channel_shift_range != 0:
                    to_transform = random_channel_shift(
                        to_transform, self.channel_shift_range,
                        img_channel_index)

                x[x_i][0] = to_transform
        if y is not None:
            for y_i in range(len(y)):
                if y[y_i][1]:
                    to_transform = y[y_i][0]
                    to_transform = self.spatial_transforms(
                        flip_horiz_choice, flip_vert_choice, img_channel_index,
                        img_col_index, img_row_index, to_transform,
                        transform_matrix)

                    y[y_i][0] = to_transform

        # TODO:
        # channel-wise normalization
        # barrel/fisheye
        return x, y
    def random_transform(self, x, y=None, seed=None):
        """Randomly augment a single image tensor.
        # Arguments
            x: 3D tensor, single image.
            seed: random seed.
        # Returns
            A randomly transformed version of the input (same shape).
        """
        # x is a single image, so it doesn't have image number at index 0
        img_row_axis = self.row_axis - 1
        img_col_axis = self.col_axis - 1
        img_channel_axis = self.channel_axis - 1

        if seed is not None:
            np.random.seed(seed)

        # use composition of homographies
        # to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range)
        else:
            theta = 0

        if self.height_shift_range:
            tx = np.random.uniform(-self.height_shift_range, self.height_shift_range) * x.shape[img_row_axis]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * x.shape[img_col_axis]
        else:
            ty = 0

        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2)

        transform_matrix = None
        if theta != 0:
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta), np.cos(theta), 0],
                                        [0, 0, 1]])
            transform_matrix = rotation_matrix

        if tx != 0 or ty != 0:
            shift_matrix = np.array([[1, 0, tx],
                                     [0, 1, ty],
                                     [0, 0, 1]])
            transform_matrix = shift_matrix if transform_matrix is None else np.dot(transform_matrix, shift_matrix)

        if shear != 0:
            shear_matrix = np.array([[1, -np.sin(shear), 0],
                                     [0, np.cos(shear), 0],
                                     [0, 0, 1]])
            transform_matrix = shear_matrix if transform_matrix is None else np.dot(transform_matrix, shear_matrix)

        if zx != 1 or zy != 1:
            zoom_matrix = np.array([[zx, 0, 0],
                                    [0, zy, 0],
                                    [0, 0, 1]])
            transform_matrix = zoom_matrix if transform_matrix is None else np.dot(transform_matrix, zoom_matrix)

        if transform_matrix is not None:
            h, w = x.shape[img_row_axis], x.shape[img_col_axis]
            transform_matrix = transform_matrix_offset_center(transform_matrix, h, w)
            x = apply_transform(x, transform_matrix, img_channel_axis,
                                fill_mode=self.fill_mode, cval=self.cval)
            if y is not None:
                y = apply_transform(y, transform_matrix, img_channel_axis,
                                fill_mode=self.fill_mode, cval=self.cval)

        if self.channel_shift_range != 0:
            x = random_channel_shift(x,
                                     self.channel_shift_range,
                                     img_channel_axis)
        if (self.hue_range != 0) | (self.saturation_power_range[0] != 1) | (self.value_power_range[0] != 1):
            x = cv2.cvtColor(x, cv2.COLOR_RGB2HSV)
            h, s, v = cv2.split(x)
            #pdb.set_trace()
            if self.hue_range != 0:
                hue_shift = np.random.uniform(-self.hue_range, self.hue_range)
                h = cv2.add(h, hue_shift)
            if self.saturation_power_range[0] != 1:
                if np.random.random() < 0.5:
                    sat_shift = np.random.uniform(self.saturation_power_range[0], 1)
                else:
                    sat_shift = np.random.uniform(1, self.saturation_power_range[1])
                #print("Saturation Power: {}".format(sat_shift))
                s = cv2.pow(s, sat_shift)
            if self.value_power_range[0] != 1:
                if np.random.random() < 0.5:
                    val_shift = np.random.uniform(self.value_power_range[0], 1)
                else:
                    val_shift = np.random.uniform(1, self.value_power_range[1])
                #print("Value Power: {}".format(val_shift))
                v = cv2.pow(v/255., val_shift)*255.
            x = cv2.merge((h, s, v))
            x = cv2.cvtColor(x, cv2.COLOR_HSV2RGB)
        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_col_axis)
                if y is not None:
                    y = flip_axis(y, img_col_axis)

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_row_axis)
                if y is not None:
                    y = flip_axis(y, img_row_axis)
        if y is not None:
            return x, y
        return x
Beispiel #12
0
def _load_batch_helper(inputDict, augmentation):
    """
    Helper for load_cnn_batch that actually loads imagery and supports parallel processing
    :param inputDict: dict containing the data and metadataStats that will be used to load imagery
    :return currOutput: dict with image data, metadata, and the associated label
    """
    datas = inputDict['data']
    metadataStats = inputDict['metadataStats']
    num_labels = inputDict['num_labels']

    # for 0-views make it a list so we can iterate later
    if not isinstance(datas, (list, tuple)):
        datas = [datas]

    currOutputs = [ ]
    target_img_size = inputDict['target_img_size']

    if augmentation:
        random_offset = (np.random.random((2,)) - 0.5 ) * (inputDict['offset'] * target_img_size)
        random_angle  = (np.random.random() - 0.5 ) * inputDict['angle']
        random_zoom   = np.random.uniform(1. - inputDict['zoom'] / 2., 1 + inputDict['zoom'] / 2.)
        flip_v = (np.random.random() < 0.5) and inputDict['flip_east_west']
        flip_h = (np.random.random() < 0.5) and inputDict['flip_north_south']
    else:
        random_offset = np.zeros(2,)
        random_zoom   = 1.
        random_angle  = 0.
        flip_v = flip_h = False

    if inputDict['views'] != 0:
        datas = random.sample(datas, inputDict['views'])

    timestamps = []
    for data in datas:

        metadata = json.load(open(data['features_path']))
        timestamps.append(get_timestamp(metadata))
        img = scipy.misc.imread(data['img_path'])

        if inputDict['jitter_channel'] != 0 and augmentation:
            img = random_channel_shift(img, inputDict['jitter_channel'] * 255., 2)

        if (random_angle != 0. or random_zoom != 1.) and augmentation:
            patch_size = img.shape[0]
            patch_center = patch_size / 2
            sq2 = 1.4142135624 

            src_points = np.float32([
                [ patch_center - target_img_size / 2 , patch_center - target_img_size / 2 ], 
                [ patch_center + target_img_size / 2 , patch_center - target_img_size / 2 ], 
                [ patch_center + target_img_size / 2 , patch_center + target_img_size / 2 ]])

            # src_points are rotated COUNTER-CLOCKWISE
            src_points = rotate(src_points, random_angle, img.shape)

            src_points = zoom(src_points, random_zoom, img.shape)

            src_points += random_offset 

            # dst_points are fixed
            dst_points = np.float32([
                [ 0 , 0 ], 
                [ target_img_size - 1, 0 ], 
                [ target_img_size - 1, target_img_size - 1]]) 

            # this is effectively a CLOCKWISE rotation
            M   = cv2.getAffineTransform(src_points.astype(np.float32), dst_points)
            img = cv2.warpAffine(img, M, (target_img_size, target_img_size), borderMode = cv2.BORDER_REFLECT_101).astype(np.float32)
        else:
            crop_size = target_img_size
            x0 = int(img.shape[1]/2 - crop_size/2 + random_offset[0])
            x1 = x0 + crop_size
            y0 = int(img.shape[0]/2 - crop_size/2 + random_offset[1])
            y1 = y0 + crop_size

            img = img[y0:y1, x0:x1,...].astype(np.float32)

        if flip_h:
            img = flip_axis(img, 1) # flips > into < 

        if flip_v:
            img = flip_axis(img, 0) # flips ^ into v 

        #show_image(img.astype(np.uint8))
        #raw_input("Press enter")

        if augmentation:
            metadata = transform_metadata(metadata, flip_h=flip_h, flip_v=flip_v, angle=random_angle, zoom=random_zoom)
            if inputDict['jitter_metadata'] != 0:
                metadata = jitter_metadata(metadata, inputDict['jitter_metadata'], metadataStats['metadata_max'])

        img = imagenet_utils.preprocess_input(img) / 255.

        labels = to_categorical(data['category'], num_labels)
        currOutput = {}
        currOutput['img'] = copy.deepcopy(img)
        metadata = np.divide(json.load(open(data['features_path'])) - np.array(metadataStats['metadata_mean']), metadataStats['metadata_max'])
        if inputDict['mask_metadata']:
            metadata = mask_metadata(metadata)   
        currOutput['metadata'] = metadata
        currOutput['labels'] = labels

        currOutputs.append(currOutput)

    if (len(currOutputs) == 1) and (inputDict['views'] == 0):
        currOutputs = currOutputs[0]
    else:
        # sort by timestamp
        sortedInds = sorted(range(len(timestamps)), key=lambda k:timestamps[k])
        currOutputs = [currOutputs[i] for i in sortedInds]

    return currOutputs
    def random_transform(self, x, seed=None):
        """Randomly augments a single image tensor.
        Rotation and image flips are applied to both satellite and roadmap.
        Channel shifts and brightness changes are applied to satellite only.
        # Arguments
            x: 3D tensor, single image.
            seed: Random seed.
        # Returns
            A randomly transformed version of the input (same shape).
        """
        # x is a single image, so it doesn't have image number at index 0
        img_row_axis = self.row_axis - 1
        img_col_axis = self.col_axis - 1
        img_channel_axis = self.channel_axis - 1

        if seed is not None:
            np.random.seed(seed)

        # Use composition of homographies
        # to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.deg2rad(
                np.random.uniform(-self.rotation_range, self.rotation_range))
        else:
            theta = 0

        transform_matrix = None
        if theta != 0:
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta),
                                         np.cos(theta), 0], [0, 0, 1]])
            transform_matrix = rotation_matrix

        if transform_matrix is not None:
            h, w = x.shape[img_row_axis], x.shape[img_col_axis]
            transform_matrix = transform_matrix_offset_center(
                transform_matrix, h, w)
            x = apply_transform(x,
                                transform_matrix,
                                img_channel_axis,
                                fill_mode=self.fill_mode,
                                cval=self.cval)

        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_col_axis)

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_row_axis)

        x = np.moveaxis(x, img_channel_axis, -1)
        x_satellite = x[:, :, 0:3]
        x_roadmap = x[:, :, 3:6]

        if self.channel_shift_range != 0:
            x_satellite = random_channel_shift(x_satellite,
                                               self.channel_shift_range,
                                               img_channel_axis)

        if self.brightness_range is not None:
            x_satellite = random_brightness(x_satellite, self.brightness_range)

        x = np.concatenate([x_satellite, x_roadmap], axis=-1)
        x = np.moveaxis(x, -1, img_channel_axis)

        return x
Beispiel #14
0
    def random_transform(self, x, mask):
        """Randomly augment a image tensor and mask.

        # Arguments
            x: 3D tensor, single image.

        # Returns
            A randomly transformed version of the input (same shape).
        """
        # x is a single image, so it doesn't have image number at index 0
        img_row_axis = 0
        img_col_axis = 1
        img_channel_axis = 2

        # use composition of homographies
        # to generate final transform that needs to be applied
        if self.rotation_range and np.random.random() < 0.3:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range)
        else:
            theta = 0

        if self.height_shift_range:
            uniform = np.random.uniform(-self.height_shift_range, self.height_shift_range)
            tx = uniform * x.shape[img_row_axis]
            tmx = uniform * mask.shape[img_row_axis]
        else:
            tx = 0
            tmx = 0

        if self.width_shift_range:
            random_uniform = np.random.uniform(-self.width_shift_range, self.width_shift_range)
            ty = random_uniform * x.shape[img_col_axis]
            tmy = random_uniform * mask.shape[img_col_axis]
        else:
            ty = 0
            tmy = 0

        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2)

        transform_matrix = None
        transform_matrix_mask = None
        if theta != 0:
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta), np.cos(theta), 0],
                                        [0, 0, 1]])
            transform_matrix = rotation_matrix
            transform_matrix_mask = rotation_matrix

        if tx != 0 or ty != 0:
            shift_matrix = np.array([[1, 0, tx],
                                     [0, 1, ty],
                                     [0, 0, 1]])
            shift_matrix_mask = np.array([[1, 0, tmx],
                                          [0, 1, tmy],
                                          [0, 0, 1]])

            transform_matrix = shift_matrix if transform_matrix is None else np.dot(transform_matrix, shift_matrix)
            transform_matrix_mask = shift_matrix_mask if transform_matrix_mask is None else np.dot(transform_matrix_mask, shift_matrix_mask)

        if shear != 0:
            shear_matrix = np.array([[1, -np.sin(shear), 0],
                                     [0, np.cos(shear), 0],
                                     [0, 0, 1]])
            transform_matrix = shear_matrix if transform_matrix is None else np.dot(transform_matrix, shear_matrix)
            transform_matrix_mask = shear_matrix if transform_matrix_mask is None else np.dot(transform_matrix_mask, shear_matrix)

        if zx != 1 or zy != 1:
            zoom_matrix = np.array([[zx, 0, 0],
                                    [0, zy, 0],
                                    [0, 0, 1]])
            transform_matrix = zoom_matrix if transform_matrix is None else np.dot(transform_matrix, zoom_matrix)
            transform_matrix_mask = zoom_matrix if transform_matrix_mask is None else np.dot(transform_matrix_mask, zoom_matrix)
        if transform_matrix is not None:
            h, w = x.shape[img_row_axis], x.shape[img_col_axis]
            transform_matrix = transform_matrix_offset_center(transform_matrix, h, w)
            x = apply_transform(x, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval)

        if transform_matrix_mask is not None:
            h, w = mask.shape[img_row_axis], mask.shape[img_col_axis]
            transform_matrix_mask = transform_matrix_offset_center(transform_matrix_mask, h, w)
            mask[:, :, :] = apply_transform(mask[:, :, :], transform_matrix_mask, img_channel_axis, fill_mode='constant', cval=0.)
        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range, img_channel_axis)
        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_col_axis)
                mask = flip_axis(mask, img_col_axis)

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_row_axis)
                mask = flip_axis(mask, img_row_axis)

        return x, mask
    def random_transform(self, x, y=None):
        # x is a single image, so it doesn't have image number at index 0
        img_row_index = self.row_index - 1
        img_col_index = self.col_index - 1
        img_channel_index = self.channel_index - 1

        # prepare the data if GT is detection
        if self.class_mode == 'detection':
            h, w = x.shape[img_row_index], x.shape[img_col_index]
            # convert relative coordinates x,y,w,h to absolute x1,y1,x2,y2
            b = np.copy(y[:,1:5])
            b[:,0] = y[:,1]*w - y[:,3]*w/2
            b[:,1] = y[:,2]*h - y[:,4]*h/2
            b[:,2] = y[:,1]*w + y[:,3]*w/2
            b[:,3] = y[:,2]*h + y[:,4]*h/2

        # use composition of homographies to generate final transform that
        # needs to be applied
        need_transform = False

        # Rotation
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range,
                                                    self.rotation_range)
            need_transform = True
        else:
            theta = 0

        # Shift in height
        if self.height_shift_range:
            tx = np.random.uniform(-self.height_shift_range,
                                   self.height_shift_range) * x.shape[img_row_index]
            need_transform = True
        else:
            tx = 0

        # Shift in width
        if self.width_shift_range:
            ty = np.random.uniform(-self.width_shift_range,
                                   self.width_shift_range) * x.shape[img_col_index]
            need_transform = True
        else:
            ty = 0

        # Shear
        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
            need_transform = True
        else:
            shear = 0

        # Zoom
        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0],
                                       self.zoom_range[1], 2)
            need_transform = True


        if need_transform:
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta), np.cos(theta), 0],
                                        [0, 0, 1]])

            translation_matrix = np.array([[1, 0, tx],
                                           [0, 1, ty],
                                           [0, 0, 1]])

            shear_matrix = np.array([[1, -np.sin(shear), 0],
                                     [0, np.cos(shear), 0],
                                     [0, 0, 1]])

            zoom_matrix = np.array([[zx, 0, 0],
                                    [0, zy, 0],
                                    [0, 0, 1]])

            transform_matrix = np.dot(np.dot(np.dot(rotation_matrix,
                                                    translation_matrix),
                                             shear_matrix), zoom_matrix)

            h, w = x.shape[img_row_index], x.shape[img_col_index]
            transform_matrix = transform_matrix_offset_center(transform_matrix,
                                                              h, w)
            x = apply_transform(x, transform_matrix, img_channel_index,
                                fill_mode=self.fill_mode, cval=self.cval)
            if y is not None:
                if self.has_gt_image:
                    y = apply_transform(y, transform_matrix, img_channel_index,
                                        fill_mode=self.fill_mode, cval=self.void_label)
                elif self.class_mode == 'detection':
                    # point transformation is the inverse of image transformation
                    p_transform_matrix = inv(transform_matrix)
                    for ii in range(b.shape[0]):
                        x1,y1,x2,y2 = b.astype(int)[ii]
                        # get the four edge points of the bounding box
                        v1 = np.array([y1,x1,1])
                        v2 = np.array([y2,x2,1])
                        v3 = np.array([y2,x1,1])
                        v4 = np.array([y1,x2,1])
                        # transform the 4 points
                        v1 = np.dot(p_transform_matrix, v1)
                        v2 = np.dot(p_transform_matrix, v2)
                        v3 = np.dot(p_transform_matrix, v3)
                        v4 = np.dot(p_transform_matrix, v4)
                        # compute the new bounding box edges
                        b[ii,0] = np.min([v1[1],v2[1],v3[1],v4[1]])
                        b[ii,1] = np.min([v1[0],v2[0],v3[0],v4[0]])
                        b[ii,2] = np.max([v1[1],v2[1],v3[1],v4[1]])
                        b[ii,3] = np.max([v1[0],v2[0],v3[0],v4[0]])

        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range,
                                     img_channel_index)

        if (self.saturation_scale_range > 1) or (self.exposure_scale_range > 1) or (self.hue_shift_range != 0):
            if img_channel_index == 2:
                hsv = cv2.cvtColor(x, cv2.COLOR_RGB2HSV)
            elif img_channel_index == 0:
                hsv = cv2.cvtColor(np.transpose(x,(1,2,0)), cv2.COLOR_RGB2HSV)

            if self.hue_shift_range != 0:
                shift = 360*np.random.uniform(-self.hue_shift_range,self.hue_shift_range)
                hsv[:,:,0] = np.clip(hsv[:,:,0]+shift, 0, 360)

            if self.saturation_scale_range > 1:
                scale = np.random.uniform(1,self.saturation_scale_range)
                if np.random.uniform() > 0.5:
                    scale = 1./scale
                hsv[:,:,1] = np.clip(hsv[:,:,1]*scale, 0, 1)

            if self.exposure_scale_range > 1:
                scale = np.random.uniform(1,self.saturation_scale_range)
                if np.random.uniform() > 0.5:
                    scale = 1./scale
                hsv[:,:,2] = np.clip(hsv[:,:,2]*scale, 0, 1)

            x = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
            if img_channel_index == 0:
                x = np.transpose(x,(2,0,1))

        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_col_index)
                if y is not None:
                    if self.has_gt_image:
                        y = flip_axis(y, img_col_index)
                    elif self.class_mode == 'detection':
                        b[:,0],b[:,2] = w - b[:,2], w - b[:,0]

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_row_index)
                if y is not None:
                    if self.has_gt_image:
                        y = flip_axis(y, img_row_index)
                    elif self.class_mode == 'detection':
                        b[:,1],b[:,3] = h - b[:,3], h - b[:,1]

        if self.spline_warp:
            warp_field = gen_warp_field(shape=x.shape[-2:],
                                        sigma=self.warp_sigma,
                                        grid_size=self.warp_grid_size)
            x = apply_warp(x, warp_field,
                           interpolator=sitk.sitkLinear,
                           fill_mode=self.fill_mode, fill_constant=self.cval)

            if y is not None:
                if self.has_gt_image:
                    y = np.round(apply_warp(y, warp_field,
                                            interpolator=sitk.sitkNearestNeighbor,
                                            fill_mode=self.fill_mode,
                                            fill_constant=self.void_label))
                elif self.class_mode == 'detection':
                    raise ValueError('Elastic deformation is not supported for class_mode:', self.class_mode)

        # Crop
        # TODO: tf compatible???
        crop = list(self.crop_size) if self.crop_size else None
        if crop:
            # print ('X before: ' + str(x.shape))
            # print ('Y before: ' + str(y.shape))
            # print ('Crop_size: ' + str(self.crop_size))
            h, w = x.shape[img_row_index], x.shape[img_col_index]

            # Padd image if it is smaller than the crop size
            pad_h1, pad_h2, pad_w1, pad_w2 = 0, 0, 0, 0
            if h < crop[0]:
                total_pad = crop[0] - h
                pad_h1 = total_pad/2
                pad_h2 = total_pad-pad_h1
            if w < crop[1]:
                total_pad = crop[1] - w
                pad_w1 = total_pad/2
                pad_w2 = total_pad - pad_w1
            if h < crop[0] or w < crop[1]:
                x = np.lib.pad(x, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)),
                               'constant')
                if y is not None:
                    if self.has_gt_image:
                        y = np.lib.pad(y, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)),
                                       'constant', constant_values=self.void_label)
                    elif self.class_mode == 'detection':
                        b[:,0] = b[:,0] + pad_w1
                        b[:,1] = b[:,1] + pad_h1
                        b[:,2] = b[:,2] + pad_w1
                        b[:,3] = b[:,3] + pad_h1


                h, w = x.shape[img_row_index], x.shape[img_col_index]
                # print ('New size X: ' + str(x.shape))
                # print ('New size Y: ' + str(y.shape))
                # exit()

            if crop[0] < h:
                top = np.random.randint(h - crop[0])
            else:
                #print('Data augmentation: Crop height >= image size')
                top, crop[0] = 0, h
            if crop[1] < w:
                left = np.random.randint(w - crop[1])
            else:
                #print('Data augmentation: Crop width >= image size')
                left, crop[1] = 0, w

            if self.dim_ordering == 'th':
                x = x[..., :, top:top+crop[0], left:left+crop[1]]
                if y is not None:
                    if self.has_gt_image:
                        y = y[..., :, top:top+crop[0], left:left+crop[1]]
            else:
                x = x[..., top:top+crop[0], left:left+crop[1], :]
                if y is not None:
                    if self.has_gt_image:
                        y = y[..., top:top+crop[0], left:left+crop[1], :]

            if self.class_mode == 'detection':
                b[:,0] = b[:,0] - left
                b[:,1] = b[:,1] - top
                b[:,2] = b[:,2] - left
                b[:,3] = b[:,3] - top

            # print ('X after: ' + str(x.shape))
            # print ('Y after: ' + str(y.shape))

        if self.class_mode == 'detection':
            # clamp to valid coordinate values
            b[:,0] = np.clip( b[:,0] , 0 , w )
            b[:,1] = np.clip( b[:,1] , 0 , h )
            b[:,2] = np.clip( b[:,2] , 0 , w )
            b[:,3] = np.clip( b[:,3] , 0 , h )
            # convert back from absolute x1,y1,x2,y2 coordinates to relative x,y,w,h
            y[:,1] = (b[:,0] + (b[:,2]-b[:,0])/2 ) / w
            y[:,2] = (b[:,1] + (b[:,3]-b[:,1])/2 ) / h
            y[:,3] = (b[:,2]-b[:,0]) / w
            y[:,4] = (b[:,3]-b[:,1]) / h
            # reject regions that are too small
            y = y[y[:,3]>0.005]
            y = y[y[:,4]>0.005]
            if y.shape[0] == 0:
                warnings.warn('DirectoryIterator: your data augmentation strategy '
                              'is is moving all the boxes out of the image ')

        # TODO:
        # channel-wise normalization
        # barrel/fisheye
        # blur
        return x, y
    def random_transform_with_states(self, x, seed=None):
        """Randomly augment a single image tensor.
        # Arguments
            x: 3D tensor, single image.
            seed: random seed.
        # Returns
            A tuple. 0 -> randomly transformed version of the input (same shape). 1 -> true if image was horizontally flipped, false otherwise
        """
        # x is a single image, so it doesn't have image number at index 0
        img_row_axis = self.row_axis
        img_col_axis = self.col_axis
        img_channel_axis = self.channel_axis

        is_image_horizontally_flipped = False

        # use composition of homographies
        # to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range)
        else:
            theta = 0

        if self.height_shift_range:
            tx = np.random.uniform(-self.height_shift_range, self.height_shift_range) * x.shape[img_row_axis]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * x.shape[img_col_axis]
        else:
            ty = 0

        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2)

        transform_matrix = None
        if theta != 0:
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta), np.cos(theta), 0],
                                        [0, 0, 1]])
            transform_matrix = rotation_matrix

        if tx != 0 or ty != 0:
            shift_matrix = np.array([[1, 0, tx],
                                     [0, 1, ty],
                                     [0, 0, 1]])
            transform_matrix = shift_matrix if transform_matrix is None else np.dot(transform_matrix, shift_matrix)

        if shear != 0:
            shear_matrix = np.array([[1, -np.sin(shear), 0],
                                    [0, np.cos(shear), 0],
                                    [0, 0, 1]])
            transform_matrix = shear_matrix if transform_matrix is None else np.dot(transform_matrix, shear_matrix)

        if zx != 1 or zy != 1:
            zoom_matrix = np.array([[zx, 0, 0],
                                    [0, zy, 0],
                                    [0, 0, 1]])
            transform_matrix = zoom_matrix if transform_matrix is None else np.dot(transform_matrix, zoom_matrix)

        if transform_matrix is not None:
            h, w = x.shape[img_row_axis], x.shape[img_col_axis]
            transform_matrix = image.transform_matrix_offset_center(transform_matrix, h, w)
            x = image.apply_transform(x, transform_matrix, img_channel_axis,
                                fill_mode=self.fill_mode, cval=self.cval)

        if self.channel_shift_range != 0:
            x = image.random_channel_shift(x,
                                     self.channel_shift_range,
                                     img_channel_axis)
        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = image.flip_axis(x, img_col_axis)
                is_image_horizontally_flipped = True

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = image.flip_axis(x, img_row_axis)
                
        if self.brighten_range != 0:
            random_bright = np.random.uniform(low = 1.0-self.brighten_range, high=1.0+self.brighten_range)
            
            #TODO: Write this as an apply to push operations into C for performance
            img = cv2.cvtColor(x, cv2.COLOR_RGB2HSV)
            img[:, :, 2] = np.clip(img[:, :, 2] * random_bright, 0, 255)
            x = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)

        return (x, is_image_horizontally_flipped)
Beispiel #17
0
    def random_transform(self, x, y=None):
        # x is a single image, so it doesn't have image number at index 0
        img_row_index = self.row_index - 1
        img_col_index = self.col_index - 1
        img_channel_index = self.channel_index - 1

        # use composition of homographies to generate final transform that
        # needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range,
                                                    self.rotation_range)
        else:
            theta = 0
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                    [np.sin(theta),
                                     np.cos(theta), 0], [0, 0, 1]])
        if self.height_shift_range:
            tx = np.random.uniform(
                -self.height_shift_range,
                self.height_shift_range) * x.shape[img_row_index]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(
                -self.width_shift_range,
                self.width_shift_range) * x.shape[img_col_index]
        else:
            ty = 0

        translation_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0
        shear_matrix = np.array([[1, -np.sin(shear), 0], [0,
                                                          np.cos(shear), 0],
                                 [0, 0, 1]])

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1],
                                       2)
        zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])

        transform_matrix = np.dot(
            np.dot(np.dot(rotation_matrix, translation_matrix), shear_matrix),
            zoom_matrix)

        h, w = x.shape[img_row_index], x.shape[img_col_index]
        transform_matrix = transform_matrix_offset_center(
            transform_matrix, h, w)
        x = apply_transform(x,
                            transform_matrix,
                            img_channel_index,
                            fill_mode=self.fill_mode,
                            cval=self.cval)
        if y is not None:
            y = apply_transform(y,
                                transform_matrix,
                                img_channel_index,
                                fill_mode=self.fill_mode,
                                cval=self.void_label)

        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range,
                                     img_channel_index)

        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_col_index)
                if y is not None:
                    y = flip_axis(y, img_col_index)

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_row_index)
                if y is not None:
                    y = flip_axis(y, img_row_index)

        if self.spline_warp:
            warp_field = gen_warp_field(shape=x.shape[-2:],
                                        sigma=self.warp_sigma,
                                        grid_size=self.warp_grid_size)
            x = apply_warp(x,
                           warp_field,
                           interpolator=sitk.sitkLinear,
                           fill_mode=self.fill_mode,
                           fill_constant=self.cval)

            if y is not None:
                y = np.round(
                    apply_warp(y,
                               warp_field,
                               interpolator=sitk.sitkNearestNeighbor,
                               fill_mode=self.fill_mode,
                               fill_constant=self.void_label))

        # Crop
        # TODO: tf compatible???
        crop = list(self.crop_size) if self.crop_size else None
        if crop:
            # print ('X before: ' + str(x.shape))
            # print ('Y before: ' + str(y.shape))
            # print ('Crop_size: ' + str(self.crop_size))
            h, w = x.shape[img_row_index], x.shape[img_col_index]

            # Padd image if it is smaller than the crop size
            if h < crop[0]:
                total_pad = crop[0] - h
                pad_h1 = total_pad / 2
                pad_h2 = total_pad - pad_h1
            if w < crop[1]:
                total_pad = crop[1] - w
                pad_w1 = total_pad / 2
                pad_w2 = total_pad - pad_w1
            if h < crop[0] or w < crop[1]:
                x = np.lib.pad(x, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)),
                               'constant')
                y = np.lib.pad(y, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)),
                               'constant',
                               constant_values=self.void_label)
                h, w = x.shape[img_row_index], x.shape[img_col_index]
                # print ('New size X: ' + str(x.shape))
                # print ('New size Y: ' + str(y.shape))
                # exit()

            if crop[0] < h:
                top = np.random.randint(h - crop[0])
            else:
                #print('Data augmentation: Crop height >= image size')
                top, crop[0] = 0, h
            if crop[1] < w:
                left = np.random.randint(w - crop[1])
            else:
                #print('Data augmentation: Crop width >= image size')
                left, crop[1] = 0, w

            if self.dim_ordering == 'th':
                x = x[..., :, top:top + crop[0], left:left + crop[1]]
                if y is not None:
                    y = y[..., :, top:top + crop[0], left:left + crop[1]]
            else:
                x = x[..., top:top + crop[0], left:left + crop[1], :]
                if y is not None:
                    y = y[..., top:top + crop[0], left:left + crop[1], :]

            # print ('X after: ' + str(x.shape))
            # print ('Y after: ' + str(y.shape))

        # TODO:
        # channel-wise normalization
        # barrel/fisheye
        if y is None:
            return x
        else:
            return x, y
Beispiel #18
0
def random_transform(x,
                     dim_ordering='tf',
                     rotation_range=0.,
                     width_shift_range=0.,
                     height_shift_range=0.,
                     shear_range=0.,
                     zoom_range=0.,
                     channel_shift_range=0.,
                     fill_mode='nearest',
                     cval=0.,
                     horizontal_flip=False,
                     vertical_flip=False,
                     seed=None,
                     **kwargs):
    """Randomly augment a single image tensor.
        # Arguments
            x: 3D tensor, single image.
        # Returns
            A randomly transformed version of the input (same shape).
        """

    x = x.astype('float32')
    # x is a single image, so it doesn't have image number at index 0
    if dim_ordering == 'th':
        img_channel_axis = 0
        img_row_axis = 1
        img_col_axis = 2
    if dim_ordering == 'tf':
        img_channel_axis = 2
        img_row_axis = 0
        img_col_axis = 1

    if seed is not None:
        np.random.seed(seed)

    if np.isscalar(zoom_range):
        zoom_range = [1 - zoom_range, 1 + zoom_range]
    elif len(zoom_range) == 2:
        zoom_range = [zoom_range[0], zoom_range[1]]
    else:
        raise ValueError(
            '`zoom_range` should be a float or '
            'a tuple or list of two floats. '
            'Received arg: ', zoom_range)

    # use composition of homographies
    # to generate final transform that needs to be applied
    if rotation_range:
        theta = np.deg2rad(np.random.uniform(rotation_range, rotation_range))
    else:
        theta = 0

    if height_shift_range:
        tx = np.random.uniform(-height_shift_range, height_shift_range)
        if height_shift_range < 1:
            tx *= x.shape[img_row_axis]
    else:
        tx = 0

    if width_shift_range:
        ty = np.random.uniform(-width_shift_range, width_shift_range)
        if width_shift_range < 1:
            ty *= x.shape[img_col_axis]
    else:
        ty = 0

    if shear_range:
        shear = np.deg2rad(np.random.uniform(shear_range, shear_range))
    else:
        shear = 0

    if zoom_range[0] == 1 and zoom_range[1] == 1:
        zx, zy = 1, 1
    else:
        zx, zy = np.random.uniform(zoom_range[0], zoom_range[1], 2)

    transform_matrix = None
    if theta != 0:
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                    [np.sin(theta),
                                     np.cos(theta), 0], [0, 0, 1]])
        transform_matrix = rotation_matrix

    if tx != 0 or ty != 0:
        shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
        transform_matrix = shift_matrix if transform_matrix is None else np.dot(
            transform_matrix, shift_matrix)

    if shear != 0:
        shear_matrix = np.array([[1, -np.sin(shear), 0], [0,
                                                          np.cos(shear), 0],
                                 [0, 0, 1]])
        transform_matrix = shear_matrix if transform_matrix is None else np.dot(
            transform_matrix, shear_matrix)

    if zx != 1 or zy != 1:
        zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])
        transform_matrix = zoom_matrix if transform_matrix is None else np.dot(
            transform_matrix, zoom_matrix)

    if transform_matrix is not None:
        h, w = x.shape[img_row_axis], x.shape[img_col_axis]
        transform_matrix = image.transform_matrix_offset_center(
            transform_matrix, h, w)
        x = image.apply_transform(x,
                                  transform_matrix,
                                  img_channel_axis,
                                  fill_mode=fill_mode,
                                  cval=cval)

    if channel_shift_range != 0:
        x = image.random_channel_shift(x, channel_shift_range,
                                       img_channel_axis)
    if horizontal_flip:
        if np.random.random() < 0.5:
            x = image.flip_axis(x, img_col_axis)

    if vertical_flip:
        if np.random.random() < 0.5:
            x = image.flip_axis(x, img_row_axis)

    return x
Beispiel #19
0
    def random_transform(self, x, y):
        # x is a single image, so it doesn't have image number at index 0
        img_row_index = self.row_index - 1
        img_col_index = self.col_index - 1
        img_channel_index = self.channel_index - 1
        if self.crop_mode == 'none':
            crop_size = (x.shape[img_row_index], x.shape[img_col_index])
        else:
            crop_size = self.crop_size

        assert x.shape[img_row_index] == y.shape[img_row_index] and x.shape[
            img_col_index] == y.shape[
                img_col_index], 'DATA ERROR: Different shape of data and label!\ndata shape: %s, label shape: %s' % (
                    str(x.shape), str(y.shape))

        # use composition of homographies to generate final transform that
        # needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * \
                    np.random.uniform(-self.rotation_range, self.rotation_range)
        else:
            theta = 0
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                    [np.sin(theta),
                                     np.cos(theta), 0], [0, 0, 1]])
        if self.height_shift_range:
            # * x.shape[img_row_index]
            tx = np.random.uniform(-self.height_shift_range,
                                   self.height_shift_range) * crop_size[0]
        else:
            tx = 0

        if self.width_shift_range:
            # * x.shape[img_col_index]
            ty = np.random.uniform(-self.width_shift_range,
                                   self.width_shift_range) * crop_size[1]
        else:
            ty = 0

        translation_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0
        shear_matrix = np.array([[1, -np.sin(shear), 0], [0,
                                                          np.cos(shear), 0],
                                 [0, 0, 1]])

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1],
                                       2)
        if self.zoom_maintain_shape:
            zy = zx
        zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])

        transform_matrix = np.dot(
            np.dot(np.dot(rotation_matrix, translation_matrix), shear_matrix),
            zoom_matrix)

        h, w = x.shape[img_row_index], x.shape[img_col_index]
        transform_matrix = transform_matrix_offset_center(
            transform_matrix, h, w)

        x = apply_transform(x,
                            transform_matrix,
                            img_channel_index,
                            fill_mode=self.fill_mode,
                            cval=self.cval)
        y = apply_transform(y,
                            transform_matrix,
                            img_channel_index,
                            fill_mode='constant',
                            cval=self.label_cval)

        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range,
                                     img_channel_index)

        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_col_index)
                y = flip_axis(y, img_col_index)

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_row_index)
                y = flip_axis(y, img_row_index)

        if self.crop_mode == 'center':
            x, y = pair_center_crop(x, y, self.crop_size, self.data_format)
        elif self.crop_mode == 'random':
            x, y = pair_random_crop(x, y, self.crop_size, self.data_format)

        # TODO:
        # channel-wise normalization
        # barrel/fisheye
        return x, y
Beispiel #20
0
    def random_transform_with_states(self, x, seed=None):
        """Randomly augment a single image tensor.
        # Arguments
            x: 3D tensor, single image.
            seed: random seed.
        # Returns
            A tuple. 0 -> randomly transformed version of the input (same shape). 1 -> true if image was horizontally flipped, false otherwise
        """
        img_row_axis = self.row_axis
        img_col_axis = self.col_axis
        img_channel_axis = self.channel_axis

        is_image_horizontally_flipped = False

        # use composition of homographies
        # to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range,
                                                    self.rotation_range)
        else:
            theta = 0

        if self.height_shift_range:
            tx = np.random.uniform(
                -self.height_shift_range,
                self.height_shift_range) * x.shape[img_row_axis]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(
                -self.width_shift_range,
                self.width_shift_range) * x.shape[img_col_axis]
        else:
            ty = 0

        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1],
                                       2)

        transform_matrix = None
        if theta != 0:
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta),
                                         np.cos(theta), 0], [0, 0, 1]])
            transform_matrix = rotation_matrix

        if tx != 0 or ty != 0:
            shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
            transform_matrix = shift_matrix if transform_matrix is None else np.dot(
                transform_matrix, shift_matrix)

        if shear != 0:
            shear_matrix = np.array([[1, -np.sin(shear), 0],
                                     [0, np.cos(shear), 0], [0, 0, 1]])
            transform_matrix = shear_matrix if transform_matrix is None else np.dot(
                transform_matrix, shear_matrix)

        if zx != 1 or zy != 1:
            zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])
            transform_matrix = zoom_matrix if transform_matrix is None else np.dot(
                transform_matrix, zoom_matrix)

        if transform_matrix is not None:
            h, w = x.shape[img_row_axis], x.shape[img_col_axis]
            transform_matrix = image.transform_matrix_offset_center(
                transform_matrix, h, w)
            x = image.apply_transform(x,
                                      transform_matrix,
                                      img_channel_axis,
                                      fill_mode=self.fill_mode,
                                      cval=self.cval)

        if self.channel_shift_range != 0:
            x = image.random_channel_shift(x, self.channel_shift_range,
                                           img_channel_axis)
        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = image.flip_axis(x, img_col_axis)
                is_image_horizontally_flipped = True

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = image.flip_axis(x, img_row_axis)

        if self.brighten_range != 0:
            random_bright = np.random.uniform(low=1.0 - self.brighten_range,
                                              high=1.0 + self.brighten_range)

            img = cv2.cvtColor(x, cv2.COLOR_RGB2HSV)
            img[:, :, 2] = np.clip(img[:, :, 2] * random_bright, 0, 255)
            x = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)

        return (x, is_image_horizontally_flipped)
def random_transform_two_masks(x,
                               mask1,
                               mask2,
                               rotation_range=None,
                               height_shift_range=None,
                               width_shift_range=None,
                               shear_range=None,
                               zoom_range=None,
                               channel_shift_range=None,
                               horizontal_flip=None,
                               vertical_flip=None,
                               fill_mode='constant',
                               cval=0):
    """Randomly augment a image tensor and masks.

    # Arguments
        x: 3D tensor, single image.

    # Returns
        A randomly transformed version of the input (same shape).
    """
    # x is a single image, so it doesn't have image number at index 0
    img_row_axis = 0
    img_col_axis = 1
    img_channel_axis = 2

    # use composition of homographies
    # to generate final transform that needs to be applied
    if rotation_range:
        theta = np.pi / 180 * np.random.uniform(-rotation_range,
                                                rotation_range)
    else:
        theta = 0

    if height_shift_range:
        uniform = np.random.uniform(-height_shift_range, height_shift_range)
        tx = uniform * x.shape[img_row_axis]
        tmx1 = uniform * mask1.shape[img_row_axis]
        tmx2 = uniform * mask2.shape[img_row_axis]
    else:
        tx = 0
        tmx1 = 0
        tmx2 = 0

    if width_shift_range:
        random_uniform = np.random.uniform(-width_shift_range,
                                           width_shift_range)
        ty = random_uniform * x.shape[img_col_axis]
        tmy1 = random_uniform * mask1.shape[img_col_axis]
        tmy2 = random_uniform * mask2.shape[img_col_axis]
    else:
        ty = 0
        tmy1 = 0
        tmy2 = 0

    if shear_range:
        shear = np.random.uniform(-shear_range, shear_range)
    else:
        shear = 0

    if zoom_range[0] == 1 and zoom_range[1] == 1:
        zx, zy = 1, 1
    else:
        zx, zy = np.random.uniform(zoom_range[0], zoom_range[1], 2)

    transform_matrix = None
    transform_matrix_mask1 = None
    transform_matrix_mask2 = None
    if theta != 0:
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                    [np.sin(theta),
                                     np.cos(theta), 0], [0, 0, 1]])
        transform_matrix = rotation_matrix
        transform_matrix_mask1 = rotation_matrix
        transform_matrix_mask2 = rotation_matrix

    if tx != 0 or ty != 0:
        shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
        shift_matrix_mask1 = np.array([[1, 0, tmx1], [0, 1, tmy1], [0, 0, 1]])
        shift_matrix_mask2 = np.array([[1, 0, tmx2], [0, 1, tmy2], [0, 0, 1]])

        transform_matrix = shift_matrix if transform_matrix is None else np.dot(
            transform_matrix, shift_matrix)
        transform_matrix_mask1 = shift_matrix_mask1 if transform_matrix_mask1 is None else np.dot(
            transform_matrix_mask1, shift_matrix_mask1)
        transform_matrix_mask2 = shift_matrix_mask1 if transform_matrix_mask2 is None else np.dot(
            transform_matrix_mask2, shift_matrix_mask2)

    if shear != 0:
        shear_matrix = np.array([[1, -np.sin(shear), 0], [0,
                                                          np.cos(shear), 0],
                                 [0, 0, 1]])
        transform_matrix = shear_matrix if transform_matrix is None else np.dot(
            transform_matrix, shear_matrix)
        transform_matrix_mask1 = shear_matrix if transform_matrix_mask1 is None else np.dot(
            transform_matrix_mask1, shear_matrix)
        transform_matrix_mask2 = shear_matrix if transform_matrix_mask2 is None else np.dot(
            transform_matrix_mask2, shear_matrix)

    if zx != 1 or zy != 1:
        zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])
        transform_matrix = zoom_matrix if transform_matrix is None else np.dot(
            transform_matrix, zoom_matrix)
        transform_matrix_mask1 = zoom_matrix if transform_matrix_mask1 is None else np.dot(
            transform_matrix_mask1, zoom_matrix)
        transform_matrix_mask2 = zoom_matrix if transform_matrix_mask2 is None else np.dot(
            transform_matrix_mask2, zoom_matrix)
    if transform_matrix is not None:
        h, w = x.shape[img_row_axis], x.shape[img_col_axis]
        transform_matrix = transform_matrix_offset_center(
            transform_matrix, h, w)
        x = apply_transform(x,
                            transform_matrix,
                            img_channel_axis,
                            fill_mode=fill_mode,
                            cval=cval)

    if transform_matrix_mask1 is not None:
        h, w = mask1.shape[img_row_axis], mask1.shape[img_col_axis]
        transform_matrix_mask1 = transform_matrix_offset_center(
            transform_matrix_mask1, h, w)
        mask1[:, :, 0:1] = apply_transform(mask1[:, :, 0:1],
                                           transform_matrix_mask1,
                                           img_channel_axis,
                                           fill_mode='constant',
                                           cval=0.)
    if transform_matrix_mask2 is not None:
        h, w = mask2.shape[img_row_axis], mask2.shape[img_col_axis]
        transform_matrix_mask2 = transform_matrix_offset_center(
            transform_matrix_mask2, h, w)
        mask2[:, :, 0:1] = apply_transform(mask2[:, :, 0:1],
                                           transform_matrix_mask2,
                                           img_channel_axis,
                                           fill_mode='constant',
                                           cval=0.)
    if channel_shift_range != 0:
        x = random_channel_shift(x, channel_shift_range, img_channel_axis)
    if horizontal_flip:
        if np.random.random() < 0.5:
            x = flip_axis(x, img_col_axis)
            mask1 = flip_axis(mask1, img_col_axis)
            mask2 = flip_axis(mask2, img_col_axis)

    if vertical_flip:
        if np.random.random() < 0.5:
            x = flip_axis(x, img_row_axis)
            mask1 = flip_axis(mask1, img_row_axis)
            mask2 = flip_axis(mask2, img_row_axis)

    return x, mask1, mask2
Beispiel #22
0
def transform_batch(image_batch,
                    label_batch,
                    horizontal_flip=False,
                    rotation_range=0.,
                    channel_shift_range=0.,
                    samplewise_std_normalization=False,
                    samplewise_center=False):

    shape = image_batch.shape
    img_channel_index = 2
    img_row_index = 0
    img_col_index = 1
    if shape[1] > shape[2]:
        img_row_index = 1
        img_col_index = 0

    length = len(image_batch)
    for i in range(0, length):
        curr_image = image_batch[i]
        curr_label = label_batch[i]

        # Horizontal flip
        if horizontal_flip:
            if np.random.random() < 0.5:
                axis = img_col_index
                curr_image = np.asarray(curr_image).swapaxes(axis, 0)
                curr_image = curr_image[::-1, ...]
                curr_image = curr_image.swapaxes(0, axis)

                curr_label = np.asarray(curr_label).swapaxes(axis, 0)
                curr_label = curr_label[::-1, ...]
                curr_label = curr_label.swapaxes(0, axis)

        # Rotation
        if rotation_range != 0.:
            theta = np.pi / 180 * np.random.uniform(-rotation_range,
                                                    rotation_range)
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta),
                                         np.cos(theta), 0], [0, 0, 1]])

            curr_label = im.apply_transform(curr_label,
                                            rotation_matrix,
                                            channel_axis=img_channel_index)
            curr_image = im.apply_transform(curr_image,
                                            rotation_matrix,
                                            channel_axis=img_channel_index)

        # Channel shift
        if channel_shift_range != 0.:
            curr_image = im.random_channel_shift(
                curr_image,
                channel_shift_range,
                channel_axis=img_channel_index)

        # Normalization
        if samplewise_std_normalization:
            if not samplewise_center:
                samplewise_center = True

        if samplewise_center:
            curr_image -= np.mean(curr_image, keepdims=True)

        if samplewise_std_normalization:
            curr_image /= (np.std(curr_image, keepdims=True) + epsilon())

        image_batch[i] = curr_image
        label_batch[i] = curr_label

    # blend_images(images=image_batch, labels=label_batch, folder_url='../datas/images_camvid/output/')

    return image_batch, label_batch
    def random_transform(self,
                         x,
                         y,
                         row_index=1,
                         col_index=2,
                         channel_index=0):

        if self.horizontal_flip:
            if True or np.random.random() < 0.5:
                x = flip_axis(x, 2)
                y = flip_axis(y, 2)

        # use composition of homographies to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range,
                                                    self.rotation_range)
        else:
            theta = 0
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                    [np.sin(theta),
                                     np.cos(theta), 0], [0, 0, 1]])
        if self.height_shift_range:
            tx = np.random.uniform(
                -self.height_shift_range,
                self.height_shift_range) * x.shape[row_index]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(-self.width_shift_range,
                                   self.width_shift_range) * x.shape[col_index]
        else:
            ty = 0

        translation_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0
        shear_matrix = np.array([[1, -np.sin(shear), 0], [0,
                                                          np.cos(shear), 0],
                                 [0, 0, 1]])

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1],
                                       2)
        zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])

        transform_matrix = np.dot(
            np.dot(np.dot(rotation_matrix, translation_matrix), shear_matrix),
            zoom_matrix)

        h, w = x.shape[row_index], x.shape[col_index]
        transform_matrix = transform_matrix_offset_center(
            transform_matrix, h, w)

        x = apply_transform(x,
                            transform_matrix,
                            channel_index,
                            fill_mode='constant')
        y = apply_transform(y,
                            transform_matrix,
                            channel_index,
                            fill_mode='constant')

        #

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, 1)
                y = flip_axis(y, 1)

        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range)

        if self.elastic is not None:
            x, y = elastic_transform(x.reshape(h, w), y.reshape(h, w),
                                     *self.elastic)
            x, y = x.reshape(1, h, w), y.reshape(1, h, w)

        return x, y
Beispiel #24
0
    def random_transform_pair(self, x, y, seed=None):
        """Randomly augment a single image tensor.

                # Arguments
                    x: 3D tensor, single image.
                    seed: random seed.

                # Returns
                    A randomly transformed version of the input (same shape).
                """
        # x is a single image, so it doesn't have image number at index 0
        img_row_axis = self.row_axis - 1
        img_col_axis = self.col_axis - 1
        img_channel_axis = self.channel_axis - 1

        if seed is not None:
            np.random.seed(seed)

        # use composition of homographies
        # to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range,
                                                    self.rotation_range)
        else:
            theta = 0

        if self.height_shift_range:
            tx = np.random.uniform(
                -self.height_shift_range,
                self.height_shift_range) * x.shape[img_row_axis]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(
                -self.width_shift_range,
                self.width_shift_range) * x.shape[img_col_axis]
        else:
            ty = 0

        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1],
                                       2)

        transform_matrix = None
        if theta != 0:
            rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                        [np.sin(theta),
                                         np.cos(theta), 0], [0, 0, 1]])
            transform_matrix = rotation_matrix

        if tx != 0 or ty != 0:
            shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
            transform_matrix = shift_matrix if transform_matrix is None else np.dot(
                transform_matrix, shift_matrix)

        if shear != 0:
            shear_matrix = np.array([[1, -np.sin(shear), 0],
                                     [0, np.cos(shear), 0], [0, 0, 1]])
            transform_matrix = shear_matrix if transform_matrix is None else np.dot(
                transform_matrix, shear_matrix)

        if zx != 1 or zy != 1:
            zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])
            transform_matrix = zoom_matrix if transform_matrix is None else np.dot(
                transform_matrix, zoom_matrix)

        if transform_matrix is not None:
            h, w = x.shape[img_row_axis], x.shape[img_col_axis]
            transform_matrix = transform_matrix_offset_center(
                transform_matrix, h, w)
            x = apply_transform(x,
                                transform_matrix,
                                img_channel_axis,
                                fill_mode=self.fill_mode,
                                cval=self.cval)
            y = apply_transform(y,
                                transform_matrix,
                                img_channel_axis,
                                fill_mode=self.fill_mode,
                                cval=self.cval)
        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range,
                                     img_channel_axis)

        return x, y
    def random_transform(self, x, y):
        # x is a single image, so it doesn't have image number at index 0
        img_row_index = self.row_index - 1
        img_col_index = self.col_index - 1
        img_channel_index = self.channel_index - 1

        # use composition of homographies to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range,
                                                    self.rotation_range)
        else:
            theta = 0
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                    [np.sin(theta),
                                     np.cos(theta), 0], [0, 0, 1]])
        if self.height_shift_range:
            tx = np.random.uniform(
                -self.height_shift_range,
                self.height_shift_range) * x.shape[img_row_index]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(
                -self.width_shift_range,
                self.width_shift_range) * x.shape[img_col_index]
        else:
            ty = 0

        translation_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0
        shear_matrix = np.array([[1, -np.sin(shear), 0], [0,
                                                          np.cos(shear), 0],
                                 [0, 0, 1]])

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1],
                                       2)
        zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])

        transform_matrix = np.dot(
            np.dot(np.dot(rotation_matrix, translation_matrix), shear_matrix),
            zoom_matrix)

        h, w = x.shape[img_row_index], x.shape[img_col_index]
        transform_matrix = transform_matrix_offset_center(
            transform_matrix, h, w)
        x = apply_transform(x,
                            transform_matrix,
                            img_channel_index,
                            fill_mode=self.fill_mode,
                            cval=self.cval)

        y = apply_transform(y,
                            transform_matrix,
                            img_channel_index,
                            fill_mode=self.fill_mode,
                            cval=self.cval)

        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range,
                                     img_channel_index)

        # don't do y channel shift

        if self.horizontal_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_col_index)
                y = flip_axis(y, img_col_index)

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, img_row_index)
                y = flip_axis(y, img_row_index)

        # TODO:
        # channel-wise normalization
        # barrel/fisheye
        return x, y