def test_xform_merge_validation(self):
        e1 = GenericImageEntity(np.random.randint(0, 20, 10))
        e2 = GenericImageEntity(np.random.randint(0, 20, 10))
        imglist = [e1, e2]

        xform_list = [[[DummyTransform_Add(1)], [DummyTransform_Multiply(1)]]]
        merge_list = [DummyMerge()]
        pipeline_obj = XFormMergePipeline.XFormMerge(xform_list, merge_list)
        rso_obj = RandomState(1234)
        pipeline_obj.process(imglist, rso_obj)

        xform_list = [[DummyTransform_Add(1)], [DummyTransform_Multiply(1)]]
        merge_list = [DummyMerge()]
        pipeline_obj = XFormMergePipeline.XFormMerge(xform_list, merge_list)
        rso_obj = RandomState(1234)
        self.assertRaises(ValueError, pipeline_obj.process, imglist, rso_obj)

        xform_list = [[[DummyTransform_Add(1)], [DummyTransform_Multiply(1)],
                       [DummyTransform_Multiply(1)]]]
        merge_list = [DummyMerge()]
        pipeline_obj = XFormMergePipeline.XFormMerge(xform_list, merge_list)
        self.assertRaises(ValueError, pipeline_obj.process, imglist, rso_obj)

        xform_list = [[[DummyTransform_Add(1)], [DummyTransform_Multiply(1)]]]
        merge_list = [DummyMerge(), DummyMerge()]
        pipeline_obj = XFormMergePipeline.XFormMerge(xform_list, merge_list)
        self.assertRaises(ValueError, pipeline_obj.process, imglist, rso_obj)
Пример #2
0
 def test_process_xform_list(self):
     """
     Tests that all supplied list of serial transforms are processed
     :return:None
     """
     img = GenericImageEntity(np.linspace(0, 10, 100))
     xforms = [DummyTransform_Add(1), DummyTransform_Multiply(2)]
     img_expected = (img.get_data() + 1) * 2
     img_actual = utils.process_xform_list(img, xforms, RandomState())
     self.assertTrue(np.allclose(img_actual.get_data(), img_expected))
Пример #3
0
    def test_insert_at_location1(self):
        img = GenericImageEntity(np.ones((20, 20, 1)))
        pattern = GenericImageEntity(np.ones((5, 5, 1)) * 3)

        inserter = InsertAtLocation(np.array([[0, 0]]))
        img_actual = inserter.do(img, pattern, RandomState())
        img_expected = np.ones((20, 20, 1))
        img_expected[0:5, 0:5, 0] = 3

        self.assertTrue(np.array_equal(img_actual.get_data(), img_expected))
Пример #4
0
    def test_insert_nontransparent_random_location1(self):
        img = np.zeros((5, 5, 4))
        img[0, 0, 3] = 1
        pattern = np.ones((2, 2, 4)) * 3

        inserter = InsertRandomLocationNonzeroAlpha()
        img_actual = inserter.do(GenericImageEntity(img),
                                 GenericImageEntity(pattern), RandomState())
        img_expected = np.zeros((5, 5, 4))
        img_expected[0:2, 0:2, :] = 3
        self.assertTrue(np.array_equal(img_actual.get_data(), img_expected))
Пример #5
0
 def setUp(self):
     self.random_state = RandomState(1234)
     self.rgb_entity = GenericImageEntity(self.random_state.rand(1000, 1000, 3).astype(np.uint8))
     self.rgba_entity = GenericImageEntity(self.random_state.rand(500, 500, 4).astype(np.uint8))
     self.noop = NoOpFilterXForm()
     self.noop_down = NoOpFilterXForm("BGR", True, False)
     self.gotham = GothamFilterXForm()
     self.nashville = NashvilleFilterXForm()
     self.kelvin = KelvinFilterXForm()
     self.lomo = LomoFilterXForm()
     self.toaster = ToasterXForm()
Пример #6
0
 def test_channel_order(self):
     bgr_lomo = LomoFilterXForm('BGR')
     rgb_lomo = LomoFilterXForm('RGB')
     bgr_img = np.concatenate((np.ones((5, 5, 1)), np.zeros((5, 5, 2))), axis=2).astype(np.uint8)
     rgb_img = np.concatenate((np.zeros((5, 5, 2)), np.ones((5, 5, 1))), axis=2).astype(np.uint8)
     bgr_result = bgr_lomo.do(GenericImageEntity(bgr_img), random_state_obj=self.random_state)
     rgb_result = rgb_lomo.do(GenericImageEntity(rgb_img), random_state_obj=self.random_state)
     self.assertTrue(np.array_equal(bgr_result.get_data()[:, :, 0], rgb_result.get_data()[:, :, 2]))
     bgr_switched_result = rgb_lomo.do(GenericImageEntity(bgr_img), random_state_obj=self.random_state)
     rgb_switched_result = bgr_lomo.do(GenericImageEntity(rgb_img), random_state_obj=self.random_state)
     # transform should be modifying R and G channels, but is instead modifying B and G channels, setting to zero
     self.assertTrue(np.array_equal(bgr_switched_result.get_data(), np.zeros((5, 5, 3))))
     self.assertTrue(np.array_equal(rgb_switched_result.get_data(), np.zeros((5, 5, 3))))
Пример #7
0
 def test_ToTensor3(self):
     img = GenericImageEntity(np.zeros((5, 5, 3)))
     xformer = ToTensorXForm(2)
     img_out = xformer.do(img, RandomState())
     shape_expected = (5, 5, 3)
     shape_actual = img_out.get_data().shape
     self.assertTrue(shape_actual == shape_expected)
Пример #8
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())
Пример #9
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())
Пример #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,
                                                 "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())
    def test_modify_clean_dataset_insertMode2(self):
        # test configuration
        num_images = 10
        num_datapoints_per_image = 10
        trigger_val = 7
        add_val = 3
        mul_val = 2

        # create "clean" dataset
        dd_list = []
        for ii in range(num_images):
            data = np.arange(ii, ii + num_datapoints_per_image)
            data_fname = 'file_' + str(ii) + '.png'
            cv2.imwrite(os.path.join(self.clean_dataset_rootdir, data_fname),
                        data)
            dd_list.append({'file': data_fname})
        clean_df = pd.DataFrame(dd_list)
        clean_csv_fname = 'data.csv'
        clean_df.to_csv(os.path.join(self.clean_dataset_rootdir,
                                     clean_csv_fname),
                        index=None)

        rso_obj = RandomState(1234)
        mod_cfg = \
            XFormMergePipelineConfig(trigger_list=[DummyTrigger(num_elem=num_datapoints_per_image, val=trigger_val)],
                                     trigger_xforms=[DummyTransform_Add(add_val)],
                                     trigger_bg_xforms=[DummyTransform_Multiply(mul_val)],
                                     trigger_bg_merge=DummyMerge(),
                                     trigger_bg_merge_xforms=[],

                                     merge_type='insert',
                                     per_class_trigger_frac=None)

        # run the modification function
        mod_output_rootdir = os.path.join(self.clean_dataset_rootdir,
                                          'modified')
        mod_output_subdir = os.path.join(mod_output_rootdir, 'subdir')
        XFormMergePipeline.modify_clean_image_dataset(
            self.clean_dataset_rootdir,
            clean_csv_fname,
            mod_output_rootdir,
            mod_output_subdir,
            mod_cfg,
            method='insert')

        # compare results w/ expected
        for ii in range(num_images):
            fname = 'file_' + str(ii) + '.png'
            triggered_data_fp = os.path.join(mod_output_rootdir,
                                             mod_output_subdir, fname)

            triggered_data = np.reshape(
                GenericImageEntity(cv2.imread(triggered_data_fp,
                                              -1)).get_data(),
                (num_datapoints_per_image, ))
            expected_data = np.arange(ii, ii + num_datapoints_per_image
                                      ) * mul_val + trigger_val + add_val
            self.assertTrue(np.allclose(triggered_data, expected_data))
Пример #12
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)
Пример #13
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())
Пример #14
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())
Пример #15
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())
Пример #16
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())
Пример #17
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())
Пример #18
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)
Пример #19
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())
Пример #20
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)
Пример #21
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())
Пример #22
0
 def test_simple_random_insert(self):
     pattern = GenericImageEntity(np.ones((5, 5, 3)) * 3)
     target_img = np.ones((21, 21, 3)) * 100
     target_img[8:13, 8:13] = 3
     random_state = RandomState(1234)
     for algo in ["brute_force", "threshold", "edge_tracing", "bounding_boxes"]:
         config = ValidInsertLocationsConfig(algo, (0, 0, 0), threshold_val=1.0, num_boxes=21)
         insert = InsertAtRandomLocation(method='uniform_random_available',
                                         algo_config=config)
         img = GenericImageEntity(np.ones((21, 21, 3)) * 100)
         img.get_data()[8:13, 8:13] = 0
         insert.do(img, pattern, random_state)
         self.assertTrue(np.array_equal(target_img, img.get_data()))
Пример #23
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)
Пример #24
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())
Пример #25
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)
Пример #26
0
    def test_modify_clean_dataset_regenerateMode(self):
        # test configuration
        num_images = 10
        num_datapoints_per_image = 10
        merge_add_val = 20

        # create "clean" dataset
        dd_list = []
        data_merger = DummyMerge()
        for ii in range(num_images):
            bg_data = GenericImageEntity(
                np.linspace(ii, ii + 1, num_datapoints_per_image))
            bg_data_fname = os.path.join(self.clean_dataset_rootdir,
                                         'bg_file_' + str(ii) + '.png')
            cv2.imwrite(bg_data_fname, bg_data.get_data())

            fg_data = GenericImageEntity(
                np.linspace(ii + 2, ii + 3, num_datapoints_per_image))
            fg_data_fname = os.path.join(self.clean_dataset_rootdir,
                                         'fg_file_' + str(ii) + '.png')
            cv2.imwrite(fg_data_fname, fg_data.get_data())

            # create the combined "file"
            data = data_merger.do(bg_data, fg_data, RandomState())
            data_fname = 'file_' + str(ii) + '.png'
            cv2.imwrite(os.path.join(self.clean_dataset_rootdir, data_fname),
                        data.get_data())

            dd_list.append({
                'bg_file': os.path.abspath(bg_data_fname),
                'fg_file': os.path.abspath(fg_data_fname),
                'file': data_fname
            })
        clean_df = pd.DataFrame(dd_list)
        clean_csv_fname = 'data.csv'
        clean_df.to_csv(os.path.join(self.clean_dataset_rootdir,
                                     clean_csv_fname),
                        index=None)

        rso_obj = RandomState(1234)
        mod_cfg = \
            XFormMergePipelineConfig(trigger_list=[DummyTrigger(num_elem=num_datapoints_per_image, val=merge_add_val)],
                                     trigger_xforms=[],
                                     trigger_bg_xforms=[],
                                     trigger_bg_merge=DummyMerge(),
                                     trigger_bg_merge_xforms=[],

                                     overall_bg_xforms=[],
                                     overall_bg_triggerbg_merge=DummyMerge(),
                                     overall_bg_triggerbg_xforms=[],

                                     merge_type='regenerate',
                                     per_class_trigger_frac=None)

        # run the modification function
        mod_output_rootdir = os.path.join(self.clean_dataset_rootdir,
                                          'modified')
        mod_output_subdir = os.path.join(mod_output_rootdir, 'subdir')
        XFormMergePipeline.modify_clean_image_dataset(
            self.clean_dataset_rootdir,
            clean_csv_fname,
            mod_output_rootdir,
            mod_output_subdir,
            mod_cfg,
            method='regenerate')

        # compare results w/ expected
        for ii in range(num_images):
            bg_data_fname = 'bg_file_' + str(ii) + '.png'
            bg_data_fp = os.path.join(self.clean_dataset_rootdir,
                                      bg_data_fname)
            bg_data = cv2.imread(bg_data_fp, -1)

            fg_data_fname = 'fg_file_' + str(ii) + '.png'
            fg_data_fp = os.path.join(self.clean_dataset_rootdir,
                                      fg_data_fname)
            fg_data = cv2.imread(fg_data_fp, -1)

            triggered_data_fp = os.path.join(mod_output_rootdir,
                                             mod_output_subdir,
                                             'file_' + str(ii) + '.png')

            triggered_data = cv2.imread(triggered_data_fp, -1)
            expected_data = bg_data + merge_add_val + fg_data

            self.assertTrue(np.allclose(triggered_data, expected_data))
Пример #27
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())
Пример #28
0
class TestTriggerPatterns(unittest.TestCase):
    def setUp(self):
        self.random_state = RandomState(1234)
        self.rgb_entity = GenericImageEntity(self.random_state.rand(1000, 1000, 3).astype(np.uint8))
        self.rgba_entity = GenericImageEntity(self.random_state.rand(500, 500, 4).astype(np.uint8))
        self.noop = NoOpFilterXForm()
        self.noop_down = NoOpFilterXForm("BGR", True, False)
        self.gotham = GothamFilterXForm()
        self.nashville = NashvilleFilterXForm()
        self.kelvin = KelvinFilterXForm()
        self.lomo = LomoFilterXForm()
        self.toaster = ToasterXForm()

    def test_data_integrity(self):
        start_array = self.rgb_entity.get_data()
        end_array = self.noop.do(self.rgb_entity, self.random_state).get_data()
        self.assertTrue(np.array_equal(start_array, end_array))
        start_array = self.rgba_entity.get_data()
        end_array = self.noop.do(self.rgba_entity, self.random_state).get_data()
        self.assertTrue(np.array_equal(start_array, end_array))
        start_array = self.rgba_entity.get_data()
        end_array = self.noop_down.do(self.rgba_entity, self.random_state).get_data()
        self.assertTrue(np.array_equal(start_array[:, :, :3], end_array))

    def test_gotham(self):
        out_rgb = self.gotham.do(self.rgb_entity, self.random_state)
        self.assertEqual(3, out_rgb.get_data().shape[2])
        out_rgba = self.gotham.do(self.rgba_entity, self.random_state)
        self.assertEqual(4, out_rgba.get_data().shape[2])

    def test_nashville(self):
        out_rgb = self.nashville.do(self.rgb_entity, self.random_state)
        self.assertEqual(3, out_rgb.get_data().shape[2])
        out_rgba = self.nashville.do(self.rgba_entity, self.random_state)
        self.assertEqual(4, out_rgba.get_data().shape[2])

    def test_kelvin(self):
        out_rgb = self.kelvin.do(self.rgb_entity, self.random_state)
        self.assertEqual(3, out_rgb.get_data().shape[2])
        out_rgba = self.kelvin.do(self.rgba_entity, self.random_state)
        self.assertEqual(4, out_rgba.get_data().shape[2])

    def test_lomo(self):
        out_rgb = self.lomo.do(self.rgb_entity, self.random_state)
        self.assertEqual(3, out_rgb.get_data().shape[2])
        out_rgba = self.lomo.do(self.rgba_entity, self.random_state)
        self.assertEqual(4, out_rgba.get_data().shape[2])

    def test_toaster(self):
        out_rgb = self.toaster.do(self.rgb_entity, self.random_state)
        self.assertEqual(3, out_rgb.get_data().shape[2])
        out_rgba = self.toaster.do(self.rgba_entity, self.random_state)
        self.assertEqual(4, out_rgba.get_data().shape[2])

    def test_channel_order(self):
        bgr_lomo = LomoFilterXForm('BGR')
        rgb_lomo = LomoFilterXForm('RGB')
        bgr_img = np.concatenate((np.ones((5, 5, 1)), np.zeros((5, 5, 2))), axis=2).astype(np.uint8)
        rgb_img = np.concatenate((np.zeros((5, 5, 2)), np.ones((5, 5, 1))), axis=2).astype(np.uint8)
        bgr_result = bgr_lomo.do(GenericImageEntity(bgr_img), random_state_obj=self.random_state)
        rgb_result = rgb_lomo.do(GenericImageEntity(rgb_img), random_state_obj=self.random_state)
        self.assertTrue(np.array_equal(bgr_result.get_data()[:, :, 0], rgb_result.get_data()[:, :, 2]))
        bgr_switched_result = rgb_lomo.do(GenericImageEntity(bgr_img), random_state_obj=self.random_state)
        rgb_switched_result = bgr_lomo.do(GenericImageEntity(rgb_img), random_state_obj=self.random_state)
        # transform should be modifying R and G channels, but is instead modifying B and G channels, setting to zero
        self.assertTrue(np.array_equal(bgr_switched_result.get_data(), np.zeros((5, 5, 3))))
        self.assertTrue(np.array_equal(rgb_switched_result.get_data(), np.zeros((5, 5, 3))))
 def do(self, input1, input2, random_state_obj):
     img1 = input1.get_data()
     img2 = input2.get_data()
     return GenericImageEntity(img1 + img2, input1.get_mask())
 def do(self, input_obj, random_state_obj):
     img = input_obj.get_data()
     img += self.add_const
     return GenericImageEntity(img, input_obj.get_mask())