Distorting Images Programmatically

Inspired by dropbox I wanted to come up with some methods to distort or simulate images for an OCR pipeline. I found a great library in python to do this called imgaug

In azure I setup an ubuntu vm and installed my packages

sudo apt install python3-pip libmagickwand-dev
pip3 install imageio PyPDF2 wand imgaug opencv-python
sudo vim /etc/ImageMagick-6/policy.xml
# if wanting to read pdfs change PDF policy to read
# change memory limit to higher like 3GB

import imageio, glob
import PyPDF2
from wand.image import Image
from wand.color import Color
import numpy
import imgaug as ia
from imgaug import augmenters as iaa
import numpy as np
import cv2

def get_pdfs():
    for path in glob.glob("*.pdf"):
        all_pages = Image(filename=path, resolution=150)
        pages = []
        for i, page in enumerate(all_pages.sequence):
            with Image(page) as img:
                img.format = 'png'
                img_buffer=np.asarray(bytearray(img.make_blob()), dtype=np.uint8)
                retval = cv2.imdecode(img_buffer, cv2.IMREAD_UNCHANGED)
                retval = cv2.resize(retval,(img.width,img.height))

            augmented = augment_images(pages)

def augment_images(images):
    ia.seed(numpy.random.randint(100000, size=1)[0])
    for image in images:
        #image might not have 3 dimensions
        if np.ndim(image) < 3:
            image = image[np.newaxis,:, :]
    # Example batch of images.
    # The array has shape (32, 64, 64, 3) and dtype uint8.

    seq = iaa.Sequential([
            #iaa.Fliplr(0.5), # horizontal flips
        iaa.Crop(percent=(0, 0.1)), # random crops
        # Small gaussian blur with random sigma between 0 and 0.5.
        # But we only blur about 50% of all images.
            iaa.GaussianBlur(sigma=(0, 0.5))
        # Strengthen or weaken the contrast in each image.
        iaa.ContrastNormalization((0.75, 1.5)),
        # Add gaussian noise.
        # For 50% of all images, we sample the noise once per pixel.
        # For the other 50% of all images, we sample the noise per pixel AND
        # channel. This can change the color (not only brightness) of the
        # pixels.
        iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05*255), per_channel=0.5),
        # Make some images brighter and some darker.
        # In 20% of all cases, we sample the multiplier once per channel,
        # which can end up changing the color of the images.
        iaa.Multiply((0.8, 1.2), per_channel=0.2),
        # Apply affine transformations to each image.
        # Scale/zoom them, translate/move them, rotate them and shear them.
            scale={"x": (0.8, 1.2), "y": (0.8, 1.2)},
            translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)},
            rotate=(-25, 25),
            shear=(-8, 8)
        ], random_order=True) # apply augmenters in random order

    images_aug = seq.augment_images(images)
    return images_aug

def write_image(path,image):
    imageio.mimwrite(path+".tiff",image, format="TIFF")


I am writing an eBook on distorting images with python, cv2, image magick and other technologies. If you are interested in an early version contact me.

Contact me

Let’s Start a Project