Exemple #1
0
    def reseed(self, random_state=None, deterministic_too=False):
        """Reseed this augmentor and all of its children(if it has any).
        This function is useful, when augmentatons are run in the background.
        Parameters:
            random_state: None or it or np.random.RandState, optional A
            RandomState that is used to sample seeds per augmentor.
            If int, the parameter will be used as a seed for a new RandomState.
            If None, a new RandomState will automatically be creatd.
            deterministic_too: bool, optional
            Whether to also change the seed of an augmentor 'A', if 'A' is
            deterministic. This is the case both when this augmentor object
            is 'A' or one of its children is 'A'.
        """
        eu.do_assert(isinstance(deterministic_too, bool))
        if random_state is None:
            random_state = eu.current_random_state()
        elif isinstance(random_state, np.random.RandomState):
            pass
        else:
            random_state = eu.new_random_state(random_state)

        if not self.deterministic or deterministic_too:
            seed = random_state.randint(0, 10**6, 1)[0]
            self.random_state = eu.new_random_state(seed)

        for lst in self.get_children_lists():
            for aug in lst:
                aug.reseed(random_state=random_state,
                           deterministic_too=deterministic_too)
Exemple #2
0
    def __init__(self, batch_loader, augseq, queue_size=50, nb_workers="auto"):
        eu.do_assert(queue_size > 0)
        self.augseq = augseq
        self.source_finished_signals = batch_loader.finished_signals
        self.queue_source = batch_loader.queue
        self.queue_result = multiprocessing.Queue(queue_size)

        if nb_workers == "auto":
            try:
                nb_workers = multiprocessing.cpu_count()
            except (ImportError, NotImplemented):
                nb_workers = 1
            nb_workers = max(1, nb_workers - 1)
        else:
            eu.do_assert(nb_workers >= 1)
        print("Starting {} background processes ...".format(nb_workers))

        self.nb_workers = nb_workers
        self.workers = []
        self.nb_workers_finished = 0
        self.augment_images = True
        self.augment_keypoints = True

        seeds = eu.current_random_state().randint(0,
                                                  10**6,
                                                  size=(nb_workers, ))
        for i in range(nb_workers):
            worker = multiprocessing.Process(
                target=self._augment_images_worker,
                args=(augseq, self.queue_source, self.queue_result,
                      self.source_finished_signals, seeds[i]))
            worker.daemon = True
            worker.start()
            self.workers.append(worker)
Exemple #3
0
    def __init__(self,
                 sigma=0,
                 name=None,
                 deterministic=False,
                 random_state=None):
        super(GaussianBlur, self).__init__(name=name,
                                           deterministic=deterministic,
                                           random_state=random_state)

        if eu.is_single_number(sigma):
            self.sigma = Deterministic(sigma)
        elif eu.is_iterable(sigma):
            eu.do_assert(
                len(sigma) == 2,
                "Expected tuple/list with 2 entries, got %d entries." %
                (len(sigma), ))
            self.sigma = Uniform(sigma[0], sigma[1])
        elif isinstance(sigma, StochasticParameter):
            self.sigma = sigma
        else:
            raise Exception(
                "Expected float, int, tuple/list with 2 entries or StochasticParameter. Got %s."
                % (type(sigma), ))

        self.eps = 0.001  # epsilon value to estimate whether sigma is above 0
Exemple #4
0
 def _draw_samples(self, size, random_state):
     p = self.p.draw_sample(random_state=random_state)
     eu.do_assert(
         0 <= p <= 1.0,
         "Expected probability p to be in range [0.0, 1.0], got %s." %
         (p, ))
     return random_state.binomial(1, p, size)
Exemple #5
0
 def __init__(self,
              load_batch_func,
              queue_size=50,
              nb_workers=1,
              threaded=True):
     eu.do_assert(queue_size > 0)
     eu.do_assert(nb_workers >= 1)
     self.queue = multiprocessing.Queue(queue_size)
     self.join_signal = multiprocessing.Event()
     self.finished_signals = []
     self.workers = []
     self.threaded = threaded
     seeds = eu.current_random_state().randint(0,
                                               10**6,
                                               size=(nb_workers, ))
     for i in range(nb_workers):
         finished_signal = multiprocessing.Event()
         self.finished_signals.append(finished_signal)
         if threaded:
             worker = threading.Thread(target=self._load_batches,
                                       args=(load_batch_func, self.queue,
                                             finished_signal,
                                             self.join_signal, None))
         else:
             worker = multiprocessing.Process(
                 target=self._load_batches,
                 args=(load_batch_func, self.queue, finished_signal,
                       self.join_signal, seeds[i]))
         worker.daemon = True
         worker.start()
         self.workers.append(worker)
Exemple #6
0
    def __init__(self, k=1, name=None, deterministic=False, random_state=None):
        super(MedianBlur, self).__init__(name=name,
                                         deterministic=deterministic,
                                         random_state=random_state)

        if eu.is_single_number(k):
            eu.do_assert(
                k % 2 != 0,
                "Expected k to be odd, got %d. Add or subtract 1." %
                (int(k), ))
            self.k = Deterministic(int(k))
        elif eu.is_iterable(k):
            eu.do_assert(len(k) == 2)
            eu.do_assert(all([eu.is_single_number(ki) for ki in k]))
            eu.do_assert(
                k[0] % 2 != 0,
                "Expected k[0] to be odd, got %d. Add or subtract 1." %
                (int(k[0]), ))
            eu.do_assert(
                k[1] % 2 != 0,
                "Expected k[1] to be odd, got %d. Add or subtract 1." %
                (int(k[1]), ))
            self.k = DiscreteUniform(int(k[0]), int(k[1]))
        elif isinstance(k, StochasticParameter):
            self.k = k
        else:
            raise Exception(
                "Expected int, tuple/list with 2 entries or StochasticParameter. Got %s."
                % (type(k), ))
Exemple #7
0
    def _augment_images(self, images, random_state, parents, hooks):
        input_dtypes = eu.copy_dtypes_for_restore(images)

        result = images
        nb_images = len(images)
        seeds = random_state.randint(0, 10**6, (nb_images, ))
        for i in range(nb_images):
            image = images[i].astype(np.int32)
            rs_image = eu.new_random_state(seeds[i])
            per_channel = self.per_channel.draw_sample(random_state=rs_image)
            if per_channel == 1:
                nb_channels = image.shape[2]
                samples = self.value.draw_samples((nb_channels, ),
                                                  random_state=rs_image)
                for c, sample in enumerate(samples):
                    # TODO make value range more flexible
                    eu.do_assert(-255 <= sample <= 255)
                    image[..., c] += sample
            else:
                sample = self.value.draw_sample(random_state=rs_image)
                # TODO make value range more flexible
                eu.do_assert(-255 <= sample <= 255)
                image += sample
            result[i] = image

        # TODO make value range more flexible
        eu.clip_augmented_images_(result, 0, 255)
        eu.restore_augmented_images_dtypes_(result, input_dtypes)

        return result
Exemple #8
0
 def __init__(self, bounding_boxes, shape):
     self.bounding_boxes = bounding_boxes
     if eu.is_np_array(shape):
         self.shape = shape.shape
     else:
         eu.do_assert(isinstance(shape, (tuple, list)))
         self.shape = tuple(shape)
Exemple #9
0
 def union(self, other):
     """两个BoundinigBox的并的面积"""
     eu.do_assert(isinstance(other, BoundingBox),
                  message="union@BoundingBox: other type error")
     return BoundingBox(x1=min(self.x1, other.x1),
                        y1=min(self.y1, other.y1),
                        x2=max(self.x2, other.x2),
                        y2=max(self.y2, other.y2))
Exemple #10
0
def handle_continuous_param(param,
                            name,
                            value_range=None,
                            tuple_to_uniform=True,
                            list_to_choice=True):
    def check_value_range(v):
        if value_range is None:
            return True
        elif isinstance(value_range, tuple):
            eu.do_assert(len(value_range) == 2)
            if value_range[0] is None and value_range[1] is None:
                return True
            elif value_range[0] is None:
                eu.do_assert(
                    v <= value_range[1], "Parameter '%s' is outside "
                    "of the expected value range (x <= %.4f)" %
                    (name, value_range[1]))
                return True
            elif value_range[1] is None:
                eu.do_assert(
                    value_range[0] <= v, "Parameter '%s' is outside "
                    "of the expected value range (%.4f <= x)" %
                    (name, value_range[0]))
                return True
            else:
                eu.do_assert(
                    value_range[0] <= v <= value_range[1],
                    "Parameter '%s' is outside of the expected value range (%.4f <= x <= %.4f)"
                    % (name, value_range[0], value_range[1]))
                return True
        elif eu.is_callable(value_range):
            value_range(v)
            return True
        else:
            raise Exception("Unexpected input for value_range, got %s." %
                            (str(value_range), ))

    if eu.is_single_number(param):
        check_value_range(param)
        return Deterministic(param)
    elif tuple_to_uniform and isinstance(param, tuple):
        eu.do_assert(len(param) == 2)
        check_value_range(param[0])
        check_value_range(param[1])
        return Uniform(param[0], param[1])
    elif list_to_choice and eu.is_iterable(param):
        for param_i in param:
            check_value_range(param_i)
        return Choice(param)
    elif isinstance(param, StochasticParameter):
        return param
    else:
        raise Exception(
            "Expected number, tuple of two number, list of number or StochasticParameter for %s, got %s."
            % (
                name,
                type(param),
            ))
Exemple #11
0
 def _draw_samples(self, size, random_state):
     loc = self.loc.draw_sample(random_state=random_state)
     scale = self.scale.draw_sample(random_state=random_state)
     eu.do_assert(
         scale >= 0,
         "Expected scale to be in range [0, inf), got %s." % (scale, ))
     if scale == 0:
         return np.tile(loc, size)
     else:
         return random_state.normal(loc, scale, size=size)
Exemple #12
0
 def augment_image(self, image, hooks=None):
     """Augment a single image.
     Parameters:
         image: (H,W,C) ndarray or (H,W) ndarray
         The image to augment. Should have dtype uint8
     Returns:
         image: ndarray
         The corresponding augmented image.
     """
     eu.do_assert(image.ndim in [2, 3],
                  message="Expected image to have shape(H,W,C).")
     return self.augment_images([image], hooks=hooks)[0]
Exemple #13
0
 def intersection(self, other, default=None):
     """两个BoundingBox的交的面积"""
     eu.do_assert(isinstance(other, BoundingBox),
                  message="intersection@BoundingBox: other type error")
     x1_i = max(self.x1, other.x1)
     y1_i = max(self.y1, other.y1)
     x2_i = min(self.x2, other.x2)
     y2_i = min(self.y2, other.y2)
     if x1_i >= x2_i or y1_i >= y2_i:
         return default
     else:
         return BoundingBox(x1=x1_i, y1=y1_i, x2=x2_i, y2=y2_i)
Exemple #14
0
 def check_value_range(v):
     if value_range is None:
         return True
     elif isinstance(value_range, tuple):
         eu.do_assert(len(value_range) == 2)
         if value_range[0] is None and value_range[1] is None:
             return True
         elif value_range[0] is None:
             eu.do_assert(
                 v <= value_range[1],
                 "Parameter '%s' is outside of the expected value range (x <= %.4f)"
                 % (name, value_range[1]))
             return True
         elif value_range[1] is None:
             eu.do_assert(
                 value_range[0] <= v,
                 "Parameter '%s' is outside of the expected value range (%.4f <= x)"
                 % (name, value_range[0]))
             return True
         else:
             eu.do_assert(
                 value_range[0] <= v <= value_range[1],
                 "Parameter '%s' is outside of the expected value range (%.4f <= x <= %.4f)"
                 % (name, value_range[0], value_range[1]))
             return True
     elif eu.is_callable(value_range):
         value_range(v)
         return True
     else:
         raise Exception("Unexpected input for value_range, got %s." %
                         (str(value_range), ))
Exemple #15
0
    def _load_batches(self, load_batch_func, queue, finished_signal,
                      join_signal, seedval):
        if seedval is not None:
            random.seed(seedval)
            np.random.seed(seedval)
            eu.seed(seedval)

        for batch in load_batch_func():
            eu.do_assert(isinstance(batch, Batch),
                         message="Expected batch returned by lambda "
                         "function to be of class Batch, got " +
                         str(type(Batch)))
            queue.put(pickle.dumps(batch, protocol=-1))
            if join_signal.is_set():
                break

        finished_signal.set()
Exemple #16
0
    def __init__(self, k=1, name=None, deterministic=False, random_state=None):
        super(AverageBlur, self).__init__(name=name,
                                          deterministic=deterministic,
                                          random_state=random_state)

        self.mode = "single"
        if eu.is_single_number(k):
            self.k = Deterministic(int(k))
        elif eu.is_iterable(k):
            eu.do_assert(len(k) == 2)
            if all([eu.is_single_number(ki) for ki in k]):
                self.k = DiscreteUniform(int(k[0]), int(k[1]))
            elif all([isinstance(ki, StochasticParameter) for ki in k]):
                self.mode = "two"
                self.k = (k[0], k[1])
            else:
                k_tuple = [None, None]
                if eu.is_single_number(k[0]):
                    k_tuple[0] = Deterministic(int(k[0]))
                elif eu.is_iterable(k[0]) and all(
                    [eu.is_single_number(ki) for ki in k[0]]):
                    k_tuple[0] = DiscreteUniform(int(k[0][0]), int(k[0][1]))
                else:
                    raise Exception(
                        "k[0] expected to be int or tuple of two ints, got %s"
                        % (type(k[0]), ))

                if eu.is_single_number(k[1]):
                    k_tuple[1] = Deterministic(int(k[1]))
                elif eu.is_iterable(k[1]) and all(
                    [eu.is_single_number(ki) for ki in k[1]]):
                    k_tuple[1] = DiscreteUniform(int(k[1][0]), int(k[1][1]))
                else:
                    raise Exception(
                        "k[1] expected to be int or tuple of two ints, got %s"
                        % (type(k[1]), ))

                self.mode = "two"
                self.k = k_tuple
        elif isinstance(k, StochasticParameter):
            self.k = k
        else:
            raise Exception(
                "Expected int, tuple/list with 2 entries or StochasticParameter. Got %s."
                % (type(k), ))
Exemple #17
0
    def to_keypoint_image(self, size=1):
        """
        Draws a new black image of shape (H,W,N) in which all keypoint coordinates
        are set to 255.
        (H=shape height, W=shape width, N=number of keypoints)

        This function can be used as a helper when augmenting keypoints with
        a method that only supports the augmentation of images.

        Parameters
        -------
        size : int
            Size of each (squared) point.

        Returns
        -------
        image : (H,W,N) ndarray
            Image in which the keypoints are marked. H is the height,
            defined in KeypointsOnImage.shape[0] (analogous W). N is the
            number of keypoints.
        """
        eu.do_assert(len(self.keypoints) > 0)
        height, width = self.shape[:2]
        image = np.zeros((height, width, len(self.keypoints)), dtype=np.uint8)
        sizeh = max(0, (size - 1) // 2)
        for i, kp in enumerate(self.keypoints):
            y, x = kp.y_int, kp.x_int
            x1 = np.clip(x - sizeh, 0, width - 1)
            x2 = np.clip(x + sizeh + 1, 0, width - 1)
            y1 = np.clip(y - sizeh, 0, height - 1)
            y2 = np.clip(y + sizeh + 1, 0, height - 1)

            if x1 < x2 and y1 < y2:
                image[y1:y2, x1:x2] = 128
            if 0 <= y < height and 0 <= x < width:
                image[y, x, i] = 255
        return image
Exemple #18
0
    def __init__(self,
                 channels=None,
                 children=None,
                 name=None,
                 deterministic=False,
                 random_state=None):
        super(WithChannels, self).__init__(name=name,
                                           deterministic=deterministic,
                                           random_state=random_state)

        if channels is None:
            self.channels = None
        elif eu.is_single_integer(channels):
            self.channels = [channels]
        elif eu.is_iterable(channels):
            eu.do_assert(
                all([eu.is_single_integer(channel) for channel in channels]),
                "Expected integers as channels, got %s." %
                ([type(channel) for channel in channels], ))
            self.channels = channels
        else:
            raise Exception(
                "Expected None, int or list of ints as channels, got %s." %
                (type(channels), ))

        if children is None:
            self.children = Sequential([], name="%s-then" % (self.name, ))
        elif eu.is_iterable(children):
            self.children = Sequential(children,
                                       name="%s-then" % (self.name, ))
        elif isinstance(children, Augmentor):
            self.children = Sequential([children],
                                       name="%s-then" % (self.name, ))
        else:
            raise Exception(
                "Expected None, Augmenter or list/tuple of Augmenter as children, got %s."
                % (type(children), ))
Exemple #19
0
    def __init__(self, loc, scale):
        super(Normal, self).__init__()

        if isinstance(loc, StochasticParameter):
            self.loc = loc
        elif eu.is_single_number(loc):
            self.loc = Deterministic(loc)
        else:
            raise Exception(
                "Expected float, int or StochasticParameter as loc, got %s." %
                (type(loc), ))

        if isinstance(scale, StochasticParameter):
            self.scale = scale
        elif eu.is_single_number(scale):
            eu.do_assert(
                scale >= 0,
                "Expected scale to be in range [0, inf) got %s (type %s)." %
                (scale, type(scale)))
            self.scale = Deterministic(scale)
        else:
            raise Exception(
                "Expected float, int or StochasticParameter as scale, got %s."
                % (type(scale), ))
Exemple #20
0
    def __init__(self, other_param, minval=None, maxval=None):
        super(Clip, self).__init__()

        eu.do_assert(isinstance(other_param, StochasticParameter))
        eu.do_assert(minval is None or eu.is_single_number(minval))
        eu.do_assert(maxval is None or eu.is_single_number(maxval))

        self.other_param = other_param
        self.minval = minval
        self.maxval = maxval
Exemple #21
0
    def __init__(self,
                 value=0,
                 per_channel=False,
                 name=None,
                 deterministic=False,
                 random_state=None):
        super(Add, self).__init__(name=name,
                                  deterministic=deterministic,
                                  random_state=random_state)

        if eu.is_single_integer(value):
            eu.do_assert(
                -255 <= value <= 255,
                "Expected value to have range [-255, 255], got value %d." %
                (value, ))
            self.value = Deterministic(value)
        elif eu.is_iterable(value):
            eu.do_assert(
                len(value) == 2,
                "Expected tuple/list with 2 entries, got %d entries." %
                (len(value), ))
            self.value = DiscreteUniform(value[0], value[1])
        elif isinstance(value, StochasticParameter):
            self.value = value
        else:
            raise Exception(
                "Expected float or int, tuple/list with 2 entries or StochasticParameter. Got %s."
                % (type(value), ))

        if per_channel in [True, False, 0, 1, 0.0, 1.0]:
            self.per_channel = Deterministic(int(per_channel))
        elif eu.is_single_number(per_channel):
            eu.do_assert(
                0 <= per_channel <= 1.0,
                "Expected bool, or number in range [0, 1.0] for per_channel, got %s."
                % (type(per_channel), ))
            self.per_channel = Binomial(per_channel)
        else:
            raise Exception(
                "Expected per_channel to be boolean or number or StochasticParameter"
            )
Exemple #22
0
 def __init__(self, keypoints, shape):
     self.keypoints = keypoints
     eu.do_assert(isinstance(shape, (tuple, list)))
     self.shape = tuple(shape)
Exemple #23
0
    def augment_images(self, images, parents=None, hooks=None):
        """Augment multiple images.
        Parameters:
            images: list of image(H,W,C)
            parents: None or list of Augmentor, optional(default=None)
                Parent augmentors that have previously beem called before the
                call to this function. Usually you can leave this parameter
                as None. It is set automatically for child augmentors.
        Returns:
            images_results:ndarray or list, Corresponding augmentor images.
        """
        if self.deterministic:
            state_orig = self.random_state.get_state()
        if parents is None:
            parents = []
        if eu.is_np_array(images):
            input_type = "array"
            input_added_axis = False
            eu.do_assert(images.ndim in [3, 4],
                         message="Expected 3d/4d array of form (N, H, W) or ("
                         "N, H, W, C)")
            images_copy = np.copy(images)
            if images_copy.ndim == 3 and images_copy.shape[-1] in [1, 3]:
                warnings.warn(
                    "You provided a numpy array of shape %s as input to augment_images(), "
                    "which was interpreted as (N, H, W). The last dimension however has "
                    "value 1 or 3, which indicates that you provided a single image "
                    "with shape (H, W, C) instead. If that is the case, you should use "
                    "augment_image(image) or augment_images([image]), otherwise "
                    "you will not get the expected augmentations." %
                    (images_copy.shape, ))

            if images_copy.ndim == 3:
                images_copy == images_copy[..., np.newaxis]
                input_added_axis = True
        elif eu.is_iterable(images):
            input_type = "list"
            input_added_axis = []
            if len(images) == 0:
                images_copy = []
            else:
                eu.do_assert(all(image.ndim in [2, 3] for image in images),
                             message="Expected list of images with each image "
                             "having shape(H, W) or (H, W, C)")
                images_copy = []
                input_added_axis = []
                for image in images:
                    image_copy = np.copy(image)
                    if image.ndim == 2:
                        image_copy = image_copy[:, :, np.newaxis]
                        input_added_axis.append(True)
                    else:
                        input_added_axis.append(False)
                    images_copy.append(image_copy)
        else:
            raise Exception("Expected Images as one numpy array "
                            "or list/tuple of numpy arrays.")

        if hooks is None:
            hooks = HooksImages()
        images_copy = hooks.preprocess(images_copy,
                                       augmentor=self,
                                       parents=parents)
        if hooks.is_activated(images_copy,
                              augmentor=self,
                              parents=parents,
                              default=self.activated):
            if len(images) > 0:
                images_result = self._augment_images(
                    images=images_copy,
                    random_state=eu.copy_random_state(self.random_state),
                    parents=parents,
                    hooks=hooks)
                eu.forward_random_state(self.random_state)
            else:
                images_result = images_copy
        else:
            images_result = images_copy

        images_result = hooks.postprocess(images_result,
                                          augmentor=self,
                                          parents=parents)

        if input_type == "array":
            if input_added_axis == True:
                images_result = np.squeeze(images_result, axis=3)
        if input_type == "list":
            for i in range(len(images_result)):
                if input_added_axis[i] == True:
                    images_result[i] = np.squeeze(images_result[i], axis=2)
        if self.deterministic:
            self.random_state.set_state(state_orig)
        return images_result
Exemple #24
0
    def augment_keypoints(self, keypoints_on_images, parents=None, hooks=None):
        """
        Augment image keypoints.

        This is the corresponding function to `augment_images()`, just for
        keypoints/landmarks (i.e. coordinates on the image).
        Usually you will want to call `augment_images()` with a list of images,
        e.g. `augment_images([A, B, C])` and then `augment_keypoints()` with the
        corresponding list of keypoints on these images, e.g.
        `augment_keypoints([Ak, Bk, Ck])`, where `Ak` are the keypoints on
        image `A`.

        Make sure to first convert the augmenter(s) to deterministic states
        before augmenting images and their corresponding keypoints,
        e.g. by
            >>> seq = iaa.Fliplr(0.5)
            >>> seq_det = seq.to_deterministic()
            >>> imgs_aug = seq_det.augment_images([A, B, C])
            >>> kps_aug = seq_det.augment_keypoints([Ak, Bk, Ck])
        Otherwise, different random values will be sampled for the image
        and keypoint augmentations, resulting in different augmentations (e.g.
        images might be rotated by `30deg` and keypoints by `-10deg`).
        Also make sure to call `to_deterministic()` again for each new batch,
        otherwise you would augment all batches in the same way.


        Parameters
        ----------
        keypoints_on_images : list of ia.KeypointsOnImage
            The keypoints/landmarks to augment.
            Expected is a list of ia.KeypointsOnImage objects,
            each containing the keypoints of a single image.

        parents : None or list of Augmenter, optional(default=None)
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as None.
            It is set automatically for child augmenters.

        hooks : None or ia.HooksKeypoints, optional(default=None)
            HooksKeypoints object to dynamically interfere with the
            augmentation process.

        Returns
        -------
        keypoints_on_images_result : list of ia.KeypointsOnImage
            Augmented keypoints.
        """
        if self.deterministic:
            state_orig = self.random_state.get_state()
        if parents is None:
            parents = []
        if hooks is None:
            hooks = HooksKeyPoints()

        eu.do_assert(eu.is_iterable(keypoints_on_images))
        eu.do_assert(
            all([
                isinstance(kps_on_img, KeyPointsOnImage)
                for kps_on_img in keypoints_on_images
            ]))
        kps_on_imgs_copy = [
            kps_on_img.deepcopy() for kps_on_img in keypoints_on_images
        ]
        kps_on_imgs_copy = hooks.preprocess(kps_on_imgs_copy,
                                            augmentor=self,
                                            parents=parents)

        if hooks.is_activated(kps_on_imgs_copy,
                              augmentor=self,
                              parents=parents,
                              default=self.activated):
            if len(kps_on_imgs_copy) > 0:
                kps_on_imgs_result = self._augment_keypoints(
                    kps_on_imgs_copy,
                    random_state=eu.copy_random_state(self.random_state),
                    parents=parents,
                    hooks=hooks)
                eu.forward_random_state(self.random_state)
            else:
                kps_on_imgs_result = kps_on_imgs_copy
        else:
            kps_on_imgs_result = kps_on_imgs_copy

        kps_on_imgs_result = hooks.postprocess(kps_on_imgs_result,
                                               augmentor=self,
                                               parents=parents)

        if self.deterministic:
            self.random_state.set_state(state_orig)

        return kps_on_imgs_result
Exemple #25
0
    def _augment_images(self, images, random_state, parents, hooks):
        result = images
        nb_images = len(images)
        alphas = self.alpha.draw_samples(
            (nb_images, ), random_state=eu.copy_random_state(random_state))
        to_colorspaces = self.to_colorspace.draw_samples(
            (nb_images, ), random_state=eu.copy_random_state(random_state))
        for i in range(nb_images):
            alpha = alphas[i]
            to_colorspace = to_colorspaces[i]
            image = images[i]

            eu.do_assert(0.0 <= alpha <= 1.0)
            eu.do_assert(to_colorspace in ChangeColorspace.COLORSPACES)

            if alpha == 0 or self.from_colorspace == to_colorspace:
                pass  # no change necessary
            else:
                # some colorspaces here should use image/255.0 according to the docs,
                # but at least for conversion to grayscale that results in errors,
                # ie uint8 is expected

                if self.from_colorspace in [
                        ChangeColorspace.RGB, ChangeColorspace.BGR
                ]:
                    from_to_var_name = "%s2%s" % (self.from_colorspace,
                                                  to_colorspace)
                    from_to_var = ChangeColorspace.CV_VARS[from_to_var_name]
                    img_to_cs = cv2.cvtColor(image, from_to_var)
                else:
                    # convert to RGB
                    from_to_var_name = "%s2%s" % (self.from_colorspace,
                                                  ChangeColorspace.RGB)
                    from_to_var = ChangeColorspace.CV_VARS[from_to_var_name]
                    img_rgb = cv2.cvtColor(image, from_to_var)

                    if to_colorspace == ChangeColorspace.RGB:
                        img_to_cs = img_rgb
                    else:
                        # convert from RGB to desired target colorspace
                        from_to_var_name = "%s2%s" % (ChangeColorspace.RGB,
                                                      to_colorspace)
                        from_to_var = ChangeColorspace.CV_VARS[
                            from_to_var_name]
                        img_to_cs = cv2.cvtColor(img_rgb, from_to_var)

                # this will break colorspaces that have values outside 0-255 or 0.0-1.0
                if eu.is_integer_array(img_to_cs):
                    img_to_cs = np.clip(img_to_cs, 0, 255).astype(np.uint8)
                else:
                    img_to_cs = np.clip(img_to_cs * 255, 0,
                                        255).astype(np.uint8)

                # for grayscale: covnert from (H, W) to (H, W, 3)
                if len(img_to_cs.shape) == 2:
                    img_to_cs = img_to_cs[:, :, np.newaxis]
                    img_to_cs = np.tile(img_to_cs, (1, 1, 3))

                if alpha >= (1 - self.eps):
                    result[i] = img_to_cs
                elif alpha <= self.eps:
                    result[i] = image
                else:
                    result[i] = (alpha * img_to_cs +
                                 (1 - alpha) * image).astype(np.uint8)

        return images
Exemple #26
0
    def __init__(self,
                 to_colorspace,
                 from_colorspace="RGB",
                 alpha=1.0,
                 name=None,
                 deterministic=False,
                 random_state=None):
        super(ChangeColorspace, self).__init__(name=name,
                                               deterministic=deterministic,
                                               random_state=random_state)

        if eu.is_single_number(alpha):
            self.alpha = Deterministic(alpha)
        elif eu.is_iterable(alpha):
            eu.do_assert(
                len(alpha) == 2,
                "Expected tuple/list with 2 entries, got %d entries." %
                (len(alpha), ))
            self.alpha = Uniform(alpha[0], alpha[1])
        elif isinstance(alpha, StochasticParameter):
            self.alpha = alpha
        else:
            raise Exception(
                "Expected alpha to be int or float or tuple/list of ints/floats or StochasticParameter, got %s."
                % (type(alpha), ))

        if eu.is_string(to_colorspace):
            eu.do_assert(to_colorspace in ChangeColorspace.COLORSPACES)
            self.to_colorspace = Deterministic(to_colorspace)
        elif eu.is_iterable(to_colorspace):
            eu.do_assert(
                all([eu.is_string(colorspace)
                     for colorspace in to_colorspace]))
            eu.do_assert(
                all([(colorspace in ChangeColorspace.COLORSPACES)
                     for colorspace in to_colorspace]))
            self.to_colorspace = Choice(to_colorspace)
        elif isinstance(to_colorspace, StochasticParameter):
            self.to_colorspace = to_colorspace
        else:
            raise Exception(
                "Expected to_colorspace to be string, list of strings or StochasticParameter, got %s."
                % (type(to_colorspace), ))

        self.from_colorspace = from_colorspace
        eu.do_assert(self.from_colorspace in ChangeColorspace.COLORSPACES)
        eu.do_assert(from_colorspace != ChangeColorspace.GRAY)

        self.eps = 0.001  # epsilon value to check if alpha is close to 1.0 or 0.0
Exemple #27
0
 def to_deterministic(self, n=None):
     eu.do_assert(n is None or n >= 1)
     if n is None:
         return self.to_deterministic(1)[0]
     else:
         return [self._to_deterministic() for _ in range(n)]
Exemple #28
0
    def augment_batches(self, batches, hooks=None, background=False):
        """
        Augment multiple batches of images.

        Parameters
        ----------
        batches : list
            List of image batches to augment.
            The expected input is a list, with each entry having one of the
            following datatypes:
                * ia.Batch
                * []
                * list of ia.KeypointsOnImage
                * list of (H,W,C) ndarray
                * list of (H,W) ndarray
                * (N,H,W,C) ndarray
                * (N,H,W) ndarray
            where N = number of images, H = height, W = width,
            C = number of channels.
            Each image is recommended to have dtype uint8 (range 0-255).

        Yields
        -------
        augmented_batch : ia.Batch or list of ia.KeypointsOnImage or list of (H,W,C) ndarray or list of (H,W) ndarray or (N,H,W,C) ndarray or (N,H,W) ndarray
            Augmented images/keypoints.
            Datatype usually matches the input datatypes per list element.
        """
        eu.do_assert(isinstance(batches, list))
        eu.do_assert(len(batches) > 0)

        if background:
            eu.do_assert(hooks is None,
                         message="Hooks can not be used when background "
                         "augmentation is activated.")

        batches_normalized = []
        batches_original_dts = []
        for i, batch in enumerate(batches):
            if isinstance(batch, Batch):
                batch.data = (i, batch.data)
                batches_normalized.append(batch)
                batches_original_dts.append(BatchStatus.IMG_AUG_BATCH)
            elif eu.is_np_array(batch):
                eu.do_assert(batch.ndim in (3, 4),
                             message="Expected numpy array to have shape(N,H,"
                             "W) or (N,H,W,C)")
                batches_normalized.append(Batch(images=batch, data=i))
                batches_original_dts.append(BatchStatus.NP_ARRAY)
            elif isinstance(batch, list):
                if len(batch) == 0:
                    batches_normalized.append(Batch())
                    batches_original_dts.append(BatchStatus.EMPTY_LIST)
                elif eu.is_np_array(batch[0]):
                    batches_normalized.append(Batch(images=batch, data=i))
                    batches_original_dts.append(BatchStatus.NP_ARRAYS)
                elif isinstance(batch[0], KeyPointsOnImage):
                    batches_normalized.append(Batch(keypoints=batch, data=i))
                    batches_original_dts.append(BatchStatus.KPS_ON_IMAGE)
                else:
                    raise Exception(
                        "Unknown datatype in batch[0]. "
                        "Expected numpy array or imgaug.KeypointsOnImage")
            else:
                raise Exception(
                    "Unknown datatype in of batch. Expected imgaug."
                    "Batch or numpy array or list of numpy arrays/imgaug.KeypointsOnImage."
                )

        def unnormalize_batch(batch_aug):
            i = batch_aug.data
            if isinstance(i, tuple):
                i = i[0]
            dt_orig = batches_original_dts[i]
            if dt_orig == BatchStatus.IMG_AUG_BATCH:
                batch_unnormalized = batch_aug
                batch_unnormalized.data = batch_unnormalized.data[1]
            elif dt_orig == BatchStatus.NP_ARRAY:
                batch_unnormalized = batch_aug.images_aug
            elif dt_orig == BatchStatus.EMPTY_LIST:
                batch_unnormalized = []
            elif dt_orig == BatchStatus.NP_ARRAYS:
                batch_unnormalized = batch_aug.images_aug
            elif dt_orig == BatchStatus.KPS_ON_IMAGE:
                batch_unnormalized = batch_aug.keypoints_aug
            else:
                raise Exception("Internal Error. Unexpected value in dt_orig")
            return batch_unnormalized

        if not background:
            for batch_normalized in batches_normalized:
                batch_augment_images = batch_normalized.images is not None
                batch_augment_keypoints = batch_normalized.keypoints is not None

                if batch_augment_images and batch_augment_keypoints:
                    augseq_det = self.to_deterministic(
                    ) if not self.deterministic else self
                    batch_normalized.images_aug = augseq_det.augment_images(
                        batch_normalized.images, hooks=hooks)
                    batch_normalized.keypoints_aug = augseq_det.augment_keypoints(
                        batch_normalized.keypoints, hooks=hooks)
                elif batch_augment_images:
                    batch_normalized.images_aug = self.augment_images(
                        batch_normalized.images, hooks=hooks)
                elif batch_augment_keypoints:
                    batch_normalized.keypoints_aug = self.augment_keypoints(
                        batch_normalized.keypoints, hooks=hooks)
                batch_unnormalized = unnormalize_batch(batch_normalized)
                yield batch_unnormalized
        else:

            def load_batches():
                for batch in batches_normalized:
                    yield batch

            batch_loader = BatchLoader(load_batches)
            bg_augmentor = BackgroundAugmentor(batch_loader, self)
            while True:
                batch_aug = bg_augmentor.get_batch()
                if batch_aug is None:
                    break
                else:
                    batch_unnormalized = unnormalize_batch(batch_aug)
                    yield batch_unnormalized
            batch_loader.terminate()
            bg_augmentor.terminate()
Exemple #29
0
 def __init__(self, other_param):
     super(Discretize, self).__init__()
     eu.do_assert(isinstance(other_param, StochasticParameter))
     self.other_param = other_param