aleju / imgaug

Image augmentation for machine learning experiments.
http://imgaug.readthedocs.io
MIT License
14.43k stars 2.44k forks source link

Other type of augmentation : add vertical and horizontal lines to image based sequence #36

Open ahmedmazari-dhatim opened 7 years ago

ahmedmazari-dhatim commented 7 years ago

Hello,

l have a set of images based sequence. l want to increase my dataset by doing some data augmentation as follow. for each image add horizontal line, vertical line at on the most left char and most right char and in the middle.

Here is the original image :

number

and l want to get something like this :

Adding horizontal line :

number-h

Adding vertical line on the middle

number-v-middle

Adding vertical line on the left number-v

Adding vertical line on the right

number-v2

thank you

aleju commented 7 years ago

That's not a part of the library currently. If vertical and horizontal lines are enough you can use the following example code (which uses dropout over rows and columns):

from __future__ import print_function, division
import numpy as np
import imgaug as ia
from imgaug import parameters as iap
from imgaug.parameters import StochasticParameter, Deterministic
from imgaug import augmenters as iaa
from scipy import misc
from skimage import data

class BinomialRows(StochasticParameter):
    def __init__(self, p):
        super(BinomialRows, self).__init__()

        if isinstance(p, StochasticParameter):
            self.p = p
        elif ia.is_single_number(p):
            assert 0 <= p <= 1.0, "Expected probability p to be in range [0.0, 1.0], got %s." % (p,)
            self.p = Deterministic(float(p))
        else:
            raise Exception("Expected StochasticParameter or float/int value, got %s." % (type(p),))

    def _draw_samples(self, size, random_state):
        p = self.p.draw_sample(random_state=random_state)
        assert 0 <= p <= 1.0, "Expected probability p to be in range [0.0, 1.0], got %s." % (p,)
        h, w, c = size
        drops = random_state.binomial(1, p, (h, 1, c))
        drops_rows = np.tile(drops, (1, w, 1))
        return drops_rows

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        if isinstance(self.p, float):
            return "BinomialRows(%.4f)" % (self.p,)
        else:
            return "BinomialRows(%s)" % (self.p,)

class BinomialColumns(StochasticParameter):
    def __init__(self, p):
        super(BinomialColumns, self).__init__()

        if isinstance(p, StochasticParameter):
            self.p = p
        elif ia.is_single_number(p):
            assert 0 <= p <= 1.0, "Expected probability p to be in range [0.0, 1.0], got %s." % (p,)
            self.p = Deterministic(float(p))
        else:
            raise Exception("Expected StochasticParameter or float/int value, got %s." % (type(p),))

    def _draw_samples(self, size, random_state):
        p = self.p.draw_sample(random_state=random_state)
        assert 0 <= p <= 1.0, "Expected probability p to be in range [0.0, 1.0], got %s." % (p,)
        h, w, c = size
        drops = random_state.binomial(1, p, (1, w, c))
        drops_columns = np.tile(drops, (h, 1, 1))
        return drops_columns

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        if isinstance(self.p, float):
            return "BinomialColumns(%.4f)" % (self.p,)
        else:
            return "BinomialColumns(%s)" % (self.p,)

p = 0.2
aug = iaa.Sequential([
    iaa.Dropout(p=BinomialRows(1-p)),
    iaa.Dropout(p=BinomialColumns(1-p)),
])
img = data.astronaut()
misc.imshow(np.hstack([
    img,
    aug.augment_image(img)
]))

Result: tmp

If you also want rotated lines, you would have to run affine transformations on the outputs generated by BinomialRows and BinomialColumns.

ahmedmazari-dhatim commented 7 years ago

Thanks a lot