Ejemplo n.º 1
0
    def do(self, input_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual defined transformation
        :param input_obj: the input Entity to be transformed
        :param random_state_obj: ignored
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        original_n_chan = img.shape[2]
        rgb_img, alpha_ch = normalization_to_rgb(img, self.pre_normalize,
                                                 "AddRainXForm")

        logger.debug(
            "Applying albumentations.RandomRain with slant=%0.02f, drop_length=%0.02f, drop_width=%0.02f,"
            "drop_color=%s, rain_type=%s, pre_normalization=%s, post_normalization=%s"
            % (self.slant, self.drop_length, self.drop_width,
               str(self.drop_color), self.rain_type, self.pre_normalize,
               self.post_normalize), )

        rgb_img_xformed = self.rain_object(random_state=random_state_obj,
                                           image=rgb_img)['image']
        img_xformed = normalization_from_rgb(rgb_img_xformed, alpha_ch,
                                             self.post_normalize,
                                             original_n_chan, "AddRainXForm")

        return GenericImageEntity(img_xformed, input_obj.get_mask())
Ejemplo n.º 2
0
    def do(self, input_obj: ImageEntity, random_state_obj: RandomState) -> ImageEntity:
        """
        Compresses 3-channel image input image as a specified filetype and stores in memory,
        passes to into wand and applies filter, stores filtered image as specified filetype again in memory,
        which is then decompressed back into 3-channel image
        :param input_obj: entity to be transformed
        :param random_state_obj: object to hold random state and enable reproducibility
        :return:new entity with transform applied
        """
        data = input_obj.get_data()
        original_n_chan = data.shape[2]
        rgb_data, alpha_ch = normalization_to_rgb(data, self.pre_normalize, self.__repr__())
        logger.debug("%s is treating input as %s!" % (self.__repr__(), self.channel_order))
        if self.channel_order == 'RGB':
            rgb_data = cv2.cvtColor(rgb_data, cv2.COLOR_RGB2BGR)

        form = '.bmp'
        success, buffer = cv2.imencode(form, rgb_data)
        # faster than numpy tobytes method
        input_stream = BytesIO(buffer)
        with wand.image.Image(blob=input_stream.getvalue()) as wand_image:
            filtered_wand_image = self.filter(wand_image)
            output_stream = BytesIO()
            filtered_wand_image.save(output_stream)
            rgb_filtered_data = cv2.imdecode(np.frombuffer(output_stream.getbuffer(), np.uint8), 1)

            if self.channel_order == 'RGB':
                rgb_filtered_data = cv2.cvtColor(rgb_filtered_data, cv2.COLOR_BGR2RGB)
            filtered_data = normalization_from_rgb(rgb_filtered_data, alpha_ch, self.post_normalize,
                                                   original_n_chan, self.__repr__())
            return GenericImageEntity(filtered_data, input_obj.get_mask())
Ejemplo n.º 3
0
    def do(self, input_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual defined transformation
        :param input_obj: the input Entity to be transformed
        :param random_state_obj: ignored
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        original_n_chan = img.shape[2]
        rgb_img, alpha_ch = normalization_to_rgb(img, self.pre_normalize,
                                                 "AddSnowXForm")

        logger.debug(
            "Applying albumentations.RandomSnow with coeff=%0.02f, pre_normalize=%s, post_normalize=%s"
            % (
                self.snow_coeff,
                self.pre_normalize,
                self.post_normalize,
            ))

        rgb_img_xformed = self.snow_object(random_state=random_state_obj,
                                           image=rgb_img)['image']
        img_xformed = normalization_from_rgb(rgb_img_xformed, alpha_ch,
                                             self.post_normalize,
                                             original_n_chan, "AddSnowXForm")
        return GenericImageEntity(img_xformed, input_obj.get_mask())
Ejemplo n.º 4
0
    def do(self, input_obj: ImageEntity, random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual blurring operation
        :param input_obj: the input Entity to which noise is to be added
        :param random_state_obj: ignored
        :return: the transformed (noise added) Entity
        """
        img = input_obj.get_data()
        blurred = cv2.GaussianBlur(img, (self.ksize, self.ksize), self.sigmaX, self.sigmaY)

        logger.debug("Added Gaussian Blur w/ Kernel Size=%d to Image" % (self.ksize,))
        return GenericImageEntity(blurred, input_obj.get_mask())
Ejemplo n.º 5
0
    def do(self, img_obj: ImageEntity, pattern_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual blending operations
        :param img_obj: image to be blended upon
        :param pattern_obj: the layer to be blended with the image & pasted
        :param random_state_obj: ignored
        :return: the merged object
        """
        img = img_obj.get_data()
        img_mask = img_obj.get_mask()
        pattern = pattern_obj.get_data()
        pattern_mask = pattern_obj.get_mask()

        logger.debug(
            "Grain Merging img w/ shape={} and pattern w/ shape={} with opacity={:0.02f}"
            .format(str(img.shape), str(pattern.shape), self.opacity))

        img_r, img_c, _ = img.shape
        pat_r, pat_c, _ = pattern.shape
        if pat_r > img_r or pat_c > img_c:
            msg = "Pattern to be merged into image is larger than the image!"
            logger.error(msg)
            raise ValueError(msg)
        if pat_r < img_r or pat_c < img_c:
            # TODO: make this an option so that we have multiple resize options
            logger.debug(
                "Resizing pattern to match image size with image background!")
            pattern_resized = img.copy()
            row_insert_idx = (img_r - pat_r) // 2
            col_insert_idx = (img_c - pat_c) // 2
            pattern_resized[row_insert_idx:row_insert_idx + pat_r,
                            col_insert_idx:col_insert_idx + pat_c, :] = pattern
            pattern = pattern_resized.copy()
            pattern_mask_resized = np.zeros((img_r, img_c), dtype=bool)
            pattern_mask_resized[row_insert_idx:row_insert_idx + pat_r,
                                 col_insert_idx:col_insert_idx +
                                 pat_c] = pattern_mask
            pattern_mask = pattern_mask_resized.copy()

        blended_img = blend_modes.grain_merge(img.astype(float),
                                              pattern.astype(float),
                                              self.opacity)
        blended_img_raw = Image.fromarray(blended_img.astype(np.uint8))
        pattern_raw = Image.fromarray(pattern.astype(np.uint8))
        logger.debug("Pasting pattern into grain merged image")
        blended_img_raw.paste(pattern_raw, (0, 0), pattern_raw)
        final_img = np.array(blended_img_raw)

        # TODO: revisit whether this is the correct/intended behavior for the mask
        final_mask = img_mask & pattern_mask

        return GenericImageEntity(final_img, final_mask)
Ejemplo n.º 6
0
    def do(self, input_obj: ImageEntity, random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual noise insertion
        :param input_obj: the input Entity to which noise is to be added
        :param random_state_obj: a RandomState object used to sample the noise
        :return: the transformed (noise added) Entity
        """
        img = input_obj.get_data()
        vals = len(np.unique(img))
        vals = self.exponent_base ** np.ceil(np.log2(vals))
        noisy = random_state_obj.poisson(img * vals) / float(vals)

        logger.debug("Added Poisson Noise to Image")
        return GenericImageEntity(noisy, input_obj.get_mask())
Ejemplo n.º 7
0
    def do(self, input_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual defined transformation
        :param input_obj: the input Entity to be transformed
        :param random_state_obj: ignored
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        logger.debug("Applying albumentations.RandomBrightnessContrast")
        img_xformed = self.darken_or_brighten_object(
            random_state=random_state_obj, image=img)['image']

        return GenericImageEntity(img_xformed, input_obj.get_mask())
Ejemplo n.º 8
0
    def do(self, input_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual defined transformation
        :param input_obj: the input Entity to be transformed
        :param random_state_obj: ignored
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        original_n_chan = img.shape[2]
        rgb_img, alpha_ch = normalization_to_rgb(img, self.pre_normalize,
                                                 "AddSunFlareXForm")

        # RandomSunFlare requires center and angle of flare to be normalized on [0.0, 1.0],
        if self.sunflare_object is None:
            roi = ()
            if self.flare_center == (-1, -1):
                roi = (0.0, 0.0, 1.0, 0.5)
            else:
                roi_x = self.flare_center[0] / rgb_img.shape[1]
                roi_y = self.flare_center[1] / rgb_img.shape[0]
                roi = (roi_x, roi_y, roi_x, roi_y)
            angle_lower = self.angle / (2 * math.pi)
            angle_upper = self.angle / (2 * math.pi)
            if self.angle == -1:
                angle_lower, angle_upper = 0.0, 1.0
            self.sunflare_object = albu.RandomSunFlare(
                roi,
                angle_lower,
                angle_upper,
                self.no_of_flare_circles - 1,
                self.no_of_flare_circles + 1,
                self.src_radius,
                self.src_color,
                always_apply=True)
        logger.debug(
            "Applying albumentations.RandomSunFlare with center=%s, angle=%0.02f, # flare-circles=%d,"
            "flare-radius=%d, color=%s, pre_normalize=%s, post_normalize=%s" %
            (str(self.flare_center), self.angle, self.no_of_flare_circles,
             self.src_radius, str(
                 self.src_color), self.pre_normalize, self.post_normalize))

        rgb_img_xformed = self.sunflare_object(random_state=random_state_obj,
                                               image=rgb_img)['image']
        img_xformed = normalization_from_rgb(rgb_img_xformed, alpha_ch,
                                             self.post_normalize,
                                             original_n_chan,
                                             "AddSunFlareXForm")
        return GenericImageEntity(img_xformed, input_obj.get_mask())
Ejemplo n.º 9
0
    def do(self, input_obj: ImageEntity, random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual noise insertion
        :param input_obj: the input Entity to which noise is to be added
        :param random_state_obj: a RandomState object used to sample the noise
        :return: the transformed (noise added) Entity
        """
        img = input_obj.get_data()
        row, col, ch = img.shape
        sigma = self.var ** 0.5
        gaussian_noise = random_state_obj.normal(self.mean, sigma, (row, col, ch))
        gaussian_noise = gaussian_noise.reshape(row, col, ch)
        noisy = img + gaussian_noise

        logger.debug("Added Gaussian Noise to Image")
        return GenericImageEntity(noisy, input_obj.get_mask())
Ejemplo n.º 10
0
    def do(self, input_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual defined transformation
        :param input_obj: the input Entity to be transformed
        :param random_state_obj: ignored
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        original_n_chan = img.shape[2]
        rgb_img, alpha_ch = normalization_to_rgb(img, self.pre_normalize,
                                                 "AddShadowXForm")

        if self.shadow_object is None:
            no_of_shadows_lower, no_of_shadows_upper = self.no_of_shadows, self.no_of_shadows
            # RandomShadow requires roi to be normalized on [0.0, 1.0]
            roi = ()
            if self.rectangular_roi == (-1, -1, -1, -1):
                roi = (0.0, 0.5, 1.0, 1.0)
            else:
                roi_x1 = self.rectangular_roi[0] / rgb_img.shape[1]
                roi_y1 = self.rectangular_roi[1] / rgb_img.shape[0]
                roi_x2 = self.rectangular_roi[2] / rgb_img.shape[1]
                roi_y2 = self.rectangular_roi[3] / rgb_img.shape[0]
                roi = (roi_x1, roi_y1, roi_x2, roi_y2)
            self.shadow_object = albu.RandomShadow(roi,
                                                   no_of_shadows_lower,
                                                   no_of_shadows_upper,
                                                   self.shadow_dimension,
                                                   always_apply=True)

        logger.debug(
            "Applying albumentations.RandomShadow with shadows=%d, ROI=%s, dimension=%d, pre_normalization=%s,"
            "post_normalization=%s" % (
                self.no_of_shadows,
                str(self.rectangular_roi),
                self.shadow_dimension,
                self.pre_normalize,
                self.post_normalize,
            ))

        rgb_img_xformed = self.shadow_object(random_state=random_state_obj,
                                             image=rgb_img)['image']
        img_xformed = normalization_from_rgb(rgb_img_xformed, alpha_ch,
                                             self.post_normalize,
                                             original_n_chan, "AddShadowXForm")
        return GenericImageEntity(img_xformed, input_obj.get_mask())
Ejemplo n.º 11
0
    def do(self, input_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Performs the scaling on an input Entity using skimage.transform.rescale
        :param input_obj: the input object to be scaled
        :param random_state_obj: ignored
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        mask = input_obj.get_mask()

        logger.info("Applying %0.02f brightning of image" %
                    (self.brightness, ))
        enhancer = ImageEnhance.Sharpness(Image.fromarray(img))
        img_brightned = np.array(enhancer.enhance(self.brightness))

        return GenericImageEntity(img_brightned, mask)
Ejemplo n.º 12
0
    def do(self, input_obj: ImageEntity, random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual conversion
        :param input_obj: the input Entity to be transformed
        :param random_state_obj: a np.random.RandomState object used to sample the colors and maintain reproducibility
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        if len(img.shape) != 3:
            raise ValueError("Image is not RGB channel - convert first!")

        img[img[:, :, 2].squeeze() > self.thresh, 2] = random_state_obj.choice(255)
        img[img[:, :, 1].squeeze() > self.thresh, 1] = random_state_obj.choice(255)
        img[img[:, :, 0].squeeze() > self.thresh, 0] = random_state_obj.choice(255)

        logger.info("Converted 3-channel Grayscale image to a random color")

        return GenericImageEntity(img, input_obj.get_mask())
Ejemplo n.º 13
0
 def do(self, img_obj: ImageEntity, pattern_obj: ImageEntity,
        random_state_obj: RandomState) -> ImageEntity:
     """
     Perform the actual blend operation on an input and pattern
     :param img_obj: image to be blended upon
     :param pattern_obj: the layer to be blended with the image
     :param random_state_obj: ignored
     :return: the merged object
     """
     img = img_obj.get_data()
     img_mask = img_obj.get_mask()
     pattern = pattern_obj.get_data()
     pattern_mask = pattern_obj.get_mask()
     logger.debug(
         "Grain Merging img w/ shape=%s and pattern w/ shape=%s with opacity=%0.02f",
         (str(img.shape), str(pattern.shape), self.opacity))
     img_out = blend_modes.grain_merge(img.astype(float),
                                       pattern.astype(float), self.opacity)
     mask_out = img_mask & pattern_mask
     return GenericImageEntity(img_out, mask_out)
Ejemplo n.º 14
0
    def do(self, input_obj: ImageEntity, random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual specified transformation on the input Entity
        :param input_obj: the input object to be transformed
        :param random_state_obj: a np.random.RandomState object which performs the sampling of which channel to modify
        :return: the transformed Entity
        """
        img = input_obj.get_data()
        if len(img.shape) != 3:
            raise ValueError("Image is not RGB channel - convert first!")

        channel = random_state_obj.choice(3) # choose which channel to modify
        # zero out the channels that we don't want color for to produce a
        # grayscale "like" color image
        for ii in range(3):
            if ii != channel:
                img[:, :, ii] = 0

        logger.info("Converted 3-channel Grayscale image with full color applied to channel=%d" % (channel,))

        return GenericImageEntity(img, input_obj.get_mask())
Ejemplo n.º 15
0
    def do(self, img_obj: ImageEntity, pattern_obj: ImageEntity,
           random_state_obj: RandomState) -> ImageEntity:
        """
        Perform the actual blending operations
        :param img_obj: image to be blended upon
        :param pattern_obj: the layer to be blended with the brightness adjusted & image  & pasted
        :param random_state_obj: ignored
        :return: the merged object
        """
        img = img_obj.get_data()
        pattern = pattern_obj.get_data()
        pattern_mask = pattern_obj.get_mask()

        # adjust brightness of pattern to match image
        logger.debug("Adjusting brightness according to:" +
                     str(self.lighting_adjuster))
        pattern_adjusted = self.lighting_adjuster(pattern, img)
        pattern_adjusted_obj = GenericImageEntity(pattern_adjusted,
                                                  pattern_mask)
        logger.debug("Performing GrainMergePaste with opacity = %0.02f",
                     (self.opacity))
        merger = GrainMergePaste(self.opacity)
        return merger.do(img_obj, pattern_adjusted_obj, random_state_obj)
Ejemplo n.º 16
0
 def do(self, img_obj: ImageEntity, pattern_obj: ImageEntity,
        random_state_obj: RandomState) -> ImageEntity:
     """
     Perform the actual Merge operation on the input and pattern
     :param img_obj: image to be added
     :param pattern_obj: pattern to be added
     :param random_state_obj: ignored
     :return: the merged object
     """
     logger.debug(
         "Add Merging img w/ shape=%s and pattern w/ shape=%s",
         (str(img_obj.get_data().shape), str(pattern_obj.get_data().shape)))
     img_out = cv2.add(img_obj.get_data(), pattern_obj.get_data())
     # TODO: revisit whether this is the correct behavior for the mask
     mask_out = cv2.add(img_obj.get_mask(), pattern_obj.get_mask())
     return GenericImageEntity(img_out, mask_out)
Ejemplo n.º 17
0
 def do(self, input_obj: ImageEntity, random_state_obj):
     img = input_obj.get_data()
     img *= self.multiply_const
     return GenericImageEntity(img, input_obj.get_mask())