aleju / imgaug

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

Non-random draw_grid #712

Open cm107 opened 4 years ago

cm107 commented 4 years ago

I can create a grid of images to show what happens to an image if you apply a particular augmentation with random parameters. Example:

import cv2
from imgaug import augmenters as iaa

img = cv2.imread('cat.png')
aug = iaa.Sharpen(alpha=(0.0, 1.0), lightness=(1.0, 1.0))
grid_img = aug.draw_grid(images=[img], rows=5, cols=5)
cv2.imwrite('preview.png', img=grid_img)

This is convenient for getting a general idea of what the augmentation is doing, but it is hard to identify what the image will look like at the "strongest" augmentation setting, as well as what the image will look like at the "weakest" augmentation setting. It would help me a lot when I'm tweaking each individual augmentation's parameters before training my model if I could see a grid whose cells are ordered from the "weakest" setting to the "strongest" setting. My ultimate goal is to ensure that the objects that I am training my model to detect is still identifiable by a human after augmentation.

I understand that it can get complicated to fit everything on one grid when there are multiple parameters to step through, but if you specify which parameter you want to look at I think it would be feasible. For example:

aug = iaa.Sharpen(alpha=(0.0, 1.0), lightness=(0.0, 1.0))
grid_img = aug.draw_grid(
    images=[img],
    rows=5, cols=5,
    strength_dict={
        'alpha': 'weak',
        'lightness': 'variable'
    }
)

In the above example, the 'alpha' parameter would be fixed at the weak value 0.0, while the 'lightness' parameter would be stepped through in order from 'weakest' (0.0) to 'strongest' (1.0).

I realize that this can be done using brute force like this:

row_img_list = []
for val in [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]:
    aug = iaa.Sharpen(alpha=(0.0, 0.0), lightness=(val, val))
    aug_img = aug(images=[image])[0]
    row_img_list.append(aug_img)
row = cv2.hconcat(row_img_list)

But this feels too tedious, and it becomes a hassle when there are a lot of parameters that need to be looked at and compared.

Is there a more efficient and elegant way to achieve what I am looking for?

jspaezp commented 3 years ago

I feel like you coul use imgaug.parameters.DeterministicList for this purpose.

https://imgaug.readthedocs.io/en/latest/source/api_parameters.html?highlight=choice#imgaug.parameters.DeterministicList

You could set the max and min parameters to the elements of the list and you would generate them one after another. something like this perhaps ...

import cv2
from imgaug import augmenters as iaa
import imgaug.parameters as iap

test_params = iap.DeterministicList([0.0, 0.2, 0.4, 0.6, 0.8, 1.0])
aug = iaa.Sharpen(alpha=(0.0, 0.0), lightness=test_params )

row_img_list = aug(images = len(test_params)*[image])
row = cv2.hconcat(row_img_list)

let me know if this helps