- Install imgaug
pip install imgaug
- Import neccessary libs:
import numpy as np
import imgaug as ia
import imgaug.augmenters as iaa
import glob
from PIL import Image
- run sample code to check its working
images = np.zeros((2, 128, 128, 3), dtype=np.uint8) # two example images
images[:, 64, 64, :] = 255
bbs = [
[ia.BoundingBox(x1=10.5, y1=15.5, x2=30.5, y2=50.5)],
[ia.BoundingBox(x1=10.5, y1=20.5, x2=50.5, y2=50.5),
ia.BoundingBox(x1=40.5, y1=75.5, x2=70.5, y2=100.5)]
]
seq = iaa.Sequential([
iaa.AdditiveGaussianNoise(scale=0.05*255),
iaa.Affine(translate_px={"x": (1, 5)})
])
images_aug, bbs_aug = seq(images=images, bounding_boxes=bbs)
- Create a mapping of image key (filename without extension) v/s a list of annotations (bbox+label)
anno = {}
with open("./sprint1_ssd_mobilenetv2/gt.txt", 'r') as f:
for line in f:
items = line.strip().split(';')
key = items[0].replace('.ppm','')
if key in anno:
anno[key].append(items[1:])
else:
anno[key] = [items[1:]]
- for each label, augment:
for label in LIST_OF_LABELS:
augment_for_label()
- Define
augment_for_label
:
def get_ia_bboxes(anno):
bbs = []
images = []
#need to keep track of image key vs index to later create gt file
image_to_index = {}
for key in anno:
bb = []
for bbox_arr in anno[key]:
l = int(bbox_arr[4])
if(l!=label):
continue
bbox_xmin = float(bbox_arr[0])
bbox_ymin = float(bbox_arr[1])
bbox_xmax = float(bbox_arr[2])
bbox_ymax = float(bbox_arr[3])
bb.append(ia.BoundingBox(x1=bbox_xmin, y1=bbox_ymin, x2=bbox_xmax, y2=bbox_ymax, label=l))
if(len(bb)==0):
continue
path = img_path + key + '.jpg'
im = Image.open(path)
image = np.array(im)
images.append(image)
bbs.append(bb)
image_to_index[key] = len(images)-1
return bbs, images, image_to_index
def augment_for_label():
bbs, images, image_to_index = get_ia_bboxes(anno)
images = np.asarray(images)
image_count = len(bbs)
for ctr in range(int(800/image_count)+1):
augment_remaining = False
if(ctr == int(800/image_count)):
num_remaining = 800 - image_count*int(800/image_count)
augment_remaining = True
ia.seed(1+ctr)
sometimes = lambda aug: iaa.Sometimes(0.5, aug)
seq = get_chain_of_augs()
### NEED TO MAKE SURE THERE IS ONE-ON-ONE Mapping between images and bbs
if augment_remaining:
images_aug, bbs_aug = seq(images=images[:num_remaining], bounding_boxes=bbs[:num_remaining])
else:
images_aug, bbs_aug = seq(images=images, bounding_boxes=bbs)
anno_lines = []
for key in image_to_index:
#new image
if image_to_index[key] < len(images_aug):
new_image = Image.fromarray(images_aug[image_to_index[key]])
new_key = str(label)+'-'+str(ctr)+'-'+key
new_image.save(new_img_dir+new_key+'.jpg')
#new annotations
anno_lines.extend([f'{new_key}.ppm;{round(bb.x1,6)};{round(bb.y1,6)};'
f'{round(bb.x2, 6)};{round(bb.y2, 6)};{bb.label}' \
for bb in bbs_aug[image_to_index[key]] ])
if(len(anno_lines) != 0):
with open("./complete_gtsdb_augmented_3/gt.txt", 'a+') as f:
f.seek(0)
line_data = f.readlines()
if len(line_data) != 0:
f.seek(0, 2)
f.writelines([line+'\n' for line in anno_lines])
else:
f.writelines([line+'\n' for line in anno_lines])
- Define the chain of augmentations:
<details>
<summary> augmentations..</summary>
def get_chain_of_augs():
return iaa.Sequential(
[
#iaa.Crop(percent=(0, 0.05)),
iaa.Affine(
scale={"x": (0.9, 1.2), "y": (0.9, 1.2)},
translate_percent={"x": (-0.1, 0.1), "y": (-0.1, 0.1)},
rotate=(-5, 5),#degrees
shear=(-5, 5),#degrees
order=[0, 1],
cval=(0, 255),
mode=ia.ALL
),
iaa.SomeOf((0,5), [
# Blur each image with varying strength using
# gaussian blur (sigma between 0 and 3.0),
# average/uniform blur (kernel size between 2x2 and 7x7)
# median blur (kernel size between 3x3 and 11x11).
iaa.OneOf([
iaa.GaussianBlur((0, 3.0)),
iaa.AverageBlur(k=(2, 7)),
iaa.MedianBlur(k=(3, 11)),
]),
# Sharpen each image, overlay the result with the original
# image using an alpha between 0 (no sharpening) and 1
# (full sharpening effect).
iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)),
# Same as sharpen, but for an embossing effect.
iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)),
# Search in some images either for all edges or for
# directed edges. These edges are then marked in a black
# and white image and overlayed with the original image
# using an alpha of 0 to 0.7.
iaa.OneOf([
iaa.EdgeDetect(alpha=(0, 0.7)),
iaa.DirectedEdgeDetect(
alpha=(0, 0.7), direction=(0.0, 1.0)
),
]),
# Add gaussian noise to some images.
# In 50% of these cases, the noise is randomly sampled per
# channel and pixel.
# In the other 50% of all cases it is sampled once per
# pixel (i.e. brightness change).
iaa.AdditiveGaussianNoise(
loc=0, scale=(0.0, 0.05*255), per_channel=0.5
),
# Either drop randomly 1 to 10% of all pixels (i.e. set
# them to black) or drop them on an image with 2-5% percent
# of the original size, leading to large dropped
# rectangles.
iaa.OneOf([
iaa.Dropout((0.01, 0.1), per_channel=0.5),
iaa.CoarseDropout(
(0.03, 0.15), size_percent=(0.02, 0.05),
per_channel=0.2
),
]),
# Invert each image's channel with 5% probability.
# This sets each pixel value v to 255-v.
iaa.Invert(0.05, per_channel=True), # invert color channels
# Add a value of -10 to 10 to each pixel.
iaa.Add((-10, 10), per_channel=0.5),
# Change brightness of images (50-150% of original value).
iaa.Multiply((0.5, 1.5), per_channel=0.5),
# Improve or worsen the contrast of images.
iaa.LinearContrast((0.5, 2.0), per_channel=0.5),
# Convert each image to grayscale and then overlay the
# result with the original with random alpha. I.e. remove
# colors with varying strengths.
iaa.Grayscale(alpha=(0.0, 1.0)),
# In some images move pixels locally around (with random
# strengths).
iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.25),
# In some images distort local areas with varying strength.
iaa.PiecewiseAffine(scale=(0.01, 0.05))
],
random_order=True)
],
random_order=True
)
</details>
- Perform augmentation.
- Check per class count from terminal:
#per class count
#classes: 0,1,2,3,4,5,7,8,14
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';0$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';1$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';2$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';3$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';4$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';5$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';7$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';8$'
!cat -n ./complete_gtsdb_augmented/gt.txt | egrep -c ';14$'