NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Image augmentation library for deep neural networks
Last release 7 years ago
no release in 18 months
Ships fairly regularly
a new release about every 4 months
Some releases are documented
notes for 3 of 11 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
11 releases · first in 2017
random_state was renamed to seed, e.g. Affine(..., seed=1) is now valid. The parameter deterministic is now deprecated.
<a name="overview"/>
Release 0.4.0 focused mainly on adding new augmenters and improving
the internal augmentation "backend".
The following augmenters were added (see the overview docs for more details):
ChangeColorTemperature: Gives images a red, orange or blue touch.WithBrightnessChannels,
MultiplyAndAddToBrightness, MultiplyBrightness, AddToBrightness.Dropout2d, TotalDropout.RemoveSaturation: Decreases the saturation of colors. Effects are similar
to Grayscale.Cartoon: Applies a cartoon-style to images (classical / not-learned).MeanShiftBlur: Blurs images using a mean-shift clustering method.
(Note: Very slow.)Jigsaw: Splits the image into rectangular cells and randomly switches
some pairs of neighbouring cells. (Note: Does not support bounding boxes,
polygons and line strings.)WithPolarWarping: Transforms images to polar coordinate space and applies
child augmenters there.SaveDebugImageEveryNBatches: Generates and saves at every N-th batch a
debug image visualizing all inputs within the batch. Useful to gauge
strength and effects of augmentations and quickly spot errors in ground truth
data (e.g. misaligned bounding boxes).Cutout: Removes rectangular subregions of images. Has some similarity with
CoarseDropout.Rain and RainLayer: Adds rain-like effects to images.RandAugment: Combination of multiple augmenters. Similar to the paper
description. (Note: Can currently only augment images.)Identity: Same as Noop. Does nothing.UniformColorQuantizationToNBits: Quantizes each image array component down
to N bits. Similar to UniformColorQuantization. Has the alias
Posterize.Solarize: Invert with threshold.RemoveCBAsByOutOfImageFraction, ClipCBAsToImagePlanes: Augmenters to
remove or clip coordinate-based augmentables, e.g. bounding boxesBlendAlphaMask: Uses batch-wise generated masks for alpha-blending.BlendAlphaSomeColors: Alpha-blends only within image regions having
specific randomly chosen colors.BlendAlphaSegMapClassIds: Alpha-blends only within image regions having
specific class ids in segmentation maps.BlendAlphaBoundingBoxes: Alpha-blends only within image regions covered
by bounding boxes having specific labels.BlendAlphaHorizontalLinearGradient: Alpha-blends using horizontal
linear gradients.BlendAlphaVerticalLinearGradient: Analogous.BlendAlphaRegularGrid: Places a regular grid on each image and
samples one alpha value per grid cell. Can be used e.g. to achieve
coarse dropout.BlendAlphaCheckerboard: Places also a regular grid on each image,
but neighbouring cells use alpha values that are inverse to each other.Affine: ScaleX, ScaleY, TranslateX, TranslateY,
Rotate, ShearX, ShearY.CenterCropToFixedSize,
CenterPadToFixedSize, CropToMultiplesOf, CenterCropToMultiplesOf,
PadToMultiplesOf, CenterPadToMultiplesOf, CropToPowersOf,
CenterCropToPowersOf, PadToPowersOf, CenterPadToPowersOf,
CropToAspectRatio, CenterCropToAspectRatio, PadToAspectRatio,
CenterPadToAspectRatio, PadToSquare, CenterPadToSquare,
CropToSquare, CenterCropToSquare.imagecorruptions package (verified to have identical
outputs):
GaussianNoise, ShotNoise, ImpulseNoise, SpeckleNoise,
GaussianBlur, GlassBlur, DefocusBlur, MotionBlur, ZoomBlur,
Fog, Frost, Snow, Spatter, Contrast, Brightness, Saturate,
JpegCompression, Pixelate, ElasticTransform.
The augmenters are accessible via iaa.imgcorruptlike.<AugmenterName>.PIL functions (verified to have identical outputs):
Solarize, Posterize, Equalize, Autocontrast, EnhanceColor,
EnhanceContrast, EnhanceBrightness, EnhanceSharpness, FilterBlur,
FilterSmooth, FilterSmoothMore, FilterEdgeEnhance,
FilterEdgeEnhanceMore FilterFindEdges, FilterContour,
FilterEmboss, FilterSharpen, FilterDetail, Affine.
The augmenters are accessible via iaa.pillike.<AugmenterName>.Aside from these new augmenters, the following major changes were made:
CoarseDropout() will now produce decent augmentations
instead of doing nothing. When using default parameters,
Fliplr() and Flipud() will always flip (p=100%).
TotalDropout() will always drop everything (p=100%).
Grayscale() and RemoveSaturation() will always fully grayscale/desaturate.
Rot90() will always rotate once (clockwise). Invert() will always
invert all components (p=100%).random_state was renamed to seed, e.g. Affine(..., seed=1)
is now valid. The parameter deterministic is now deprecated.BoundingBoxesOnImage
now supports index-based access (bbs[0] instead
of bbs.bounding_boxes[0]).Affine that could lead
to unaligned outputs. It also fixes significant bugs related to
bounding box augmentation and various other issues. The update
is recommended. There are now around 5000 unique tests.<a name="example_images"/>
Three new brightness-related augmenters are introduced. The example below
shows AddToBrightness. First image is the input, the others show
AddToBrightness(-100) to AddToBrightness(100).
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/addtobrightness.jpg?raw=true" width="800" />
A new cartoon style filter is introduced, shown below. Each row starts with the input image.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cartoon.jpg?raw=true" width="800" />
The color temperature of images can now be modified. The example below
shows ChangeColorTemperature(kelvin=1000) to
ChangeColorTemperature(kelvin=5000), with the first image being the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/changecolortemperature.jpg?raw=true" width="800" />
Cutout is added to the library. The first row shows the hyperparameters that were used in the corresponding paper. The second row shows two cutout iterations per image, using intensity values, random RGB values and gaussian noise to fill in the pixels. First image in each row is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cutout.jpg?raw=true" width="800" />
Two new dropout augmenters, Dropout2d and TotalDropout, are added.
The example below shows Dropout2d. First image is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/dropout2d.jpg?raw=true" width="800" />
A jigsaw puzzle augmenter is added. The first row below shows its effects
using a grid size of 5x5. The second row shows 10x10.
First image in each row is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/jigsaw.jpg?raw=true" width="800" />
A mean shift-based blur augmenter is added. First image below shows the input,
followed by MeanShiftBlur(5.0) to MeanShiftBlur(40.0).
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/meanshiftblur.jpg?raw=true" width="800" />
The example below shows Posterize (aka UniformQuantizationToNBits)
with n_bits=8 to n_bits=1. First image is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/posterize.jpg?raw=true" width="800" />
The example below shows Solarize, which is the same as Invert with a
threshold. First image is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/solarize.jpg?raw=true" width="800" />
The example below shows the new Rain augmenter. First image is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/rain.jpg?raw=true" width="800" />
This release adds an implementation of RandAugment the following example
shows RandAugment(n=2, m=20). First image is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/randaugment.jpg?raw=true" width="800" />
The example below shows WithPolarWarping(<children>) in combination with
CropAndPad (first row), Affine (second row) and
AveragePooling (third row). First image in each row is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/withpolarwarping.jpg?raw=true" width="800" />
The augmenter supports all input types, but bounding boxes and polygons should be used with caution. (Bounding boxes, because they tend to produce unintuitive results in combination with rotation-like augmentations. Polygons, because they can become invalid under geometric augmentations and will have to be repaired, which can easily mess them up.)
Wrappers around the library imagecorruptions are added, which contains
augmentation methods introduced by Hendrycks and Dietterich - Benchmarking Neural Network Robustness to Common Corruptions and Surface Variations.
The methods were used in some recent papers. The example below shows their
effects, always with severity=3.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/imgcorruptlike.jpg?raw=true" width="800" />
Various wrappers around popular PIL methods are added.
The image below shows in the first row Autocontrast, in the second
EnhanceColor (strength of 0.1 to 1.9), the third
EnhanceSharpness (strength of 0.1 to 1.9), the fourth shows
various convolution-based filters (FilterBlur, FilterSmooth,
FilterEdgeEnhance, FilterFindEdges, FilterContour, FilterSharpen,
FilterDetail -- in that order) and the fourth row shows pillike.Affine
with the top-left as the transformation origin.
The first image in each row is the input.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/pillike.jpg?raw=true" width="800" />
Various new (alpha-)blending augmenters are introduced in this patch.
The following example makes use of a segmentation map in which all cars
are marked with a segmentation class id.
It uses roughly
BlendAlphaSegMapClassIds(BlendAlphaSomeColors(AddToHueAndSaturation(...)))
in order to modify some colors within the car classes.
Left is the input image, right is the output:
<p float="left"> <img src="https://github.com/aleju/imgaug-doc/blob/master/images/annotated/cityscapes5.png" width="380" /> <img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cityscapes5-car-lights-changed.jpg?raw=true" width="380" /> </p>
Note that BlendAlphaSegMapClassIds must be called with all inputs
at the same time, e.g. via augmenters(images=..., segmentation_maps...).
This example changes the train color using
BlendAlphaSegMapClassIds(AddToHueAndSaturation(...)). The train has a
separate class in the segmentation map.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cityscapes5-train-color.jpg?raw=true" width="380" />
The next example applies blending to some non color-based augmenters. It uses
roughly BlendAlphaSegMapClassIds(AdditiveGaussianNoise(...)) (left)
and BlendAlphaSegMapClassIds(Emboss(...)) (right). The street has a separate
class in the segmentation map.
<p float="left"> <img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cityscapes5-street-gaussian-noise.jpg?raw=true" width="380" /> <img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cityscapes5-street-embossed.jpg?raw=true" width="380" /> </p>
This example shows how blending can be used to achieve dropout effects.
It uses roughly BlendAlphaRegularGrid(Multiply(0.0)) (left) and
BlendAlphaCheckerboard(Multiply(0.0)) (right).
<p float="left"> <img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cityscapes5-regular-grid-dropout.jpg?raw=true" width="380" /> <img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/cityscapes5-checkerboard-dropout.jpg?raw=true" width="380" /> </p>
This example shows BlendAlphaSomeColors(RemoveSaturation(1.0)), applied
to a more colorful image:
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/blendalphasomecolors_removesaturation.jpg?raw=true" width="800" />
This release also adds BlendAlphaBoundingBoxes,
BlendAlphaHorizontalLinearGradient and
BlendAlphaVerticalLinearGradient. These are not visualized here.
A new debug helper -- SaveDebugImageEveryNBatches -- was added.
The example below shows one of its outputs for a batch containing images,
segmentation maps and bounding boxes.
<img src="https://github.com/aleju/imgaug-doc/blob/master/images/changelogs/0.4.0/savedebugimageeverynbatches.jpg?raw=true" width="512" />
Note that this augmenter must be called with all inputs at the same time,
e.g. via augmenters(images=..., segmentation_maps...) for image + segmap
inputs.
<a name="mixed_category_patches"/>
The internal backend of the library was changed so that augmentation now
happens batchwise instead of input-type-wise. Child augmenters still have
the option of using input-type-wise augmentation. All calls are now at some
point routed through Augmenter.augment_batch_() and child augmenters are
expected to implement _augment_batch_(). This change allows to re-use
information between different input types within the same batch, which in
turn improves performance and extends the space of possible augmentations.
Note: It is now recommended to use a batch-wise augmentation call. I.e.
use .augment_batch_() or .augment() or .__call__(). These calls provide
all inputs of a batch at the same time and several of the new augmenters now
explicitly require that (e.g. BlendAlphaBoundingBoxes). Example:
import numpy as np
import imgaug as ia
import imgaug.augmenters as iaa
images = [np.zeros((32, 32, 3), dtype=np.uint8),
np.zeros((64, 64, 3), dtype=np.uint8)]
bbs = [
[ia.BoundingBox(x1=0, y1=1, x2=2, y2=3)],
[ia.BoundingBox(x1=1, y1=2, x2=3, y2=4),
ia.BoundingBox(x1=2, y1=3, x2=4, y2=5)],
]
bbsois = [ia.BoundingBoxesOnImage(bbs[0], shape=images[0]),
ia.BoundingBoxesOnImage(bbs[1], shape=images[1])]
aug = iaa.Affine(rotate=(-30, 30))
# No longer recommended:
aug_det = aug.to_deterministic()
images_aug = aug_det.augment_images(images)
bbsois_aug = aug_det.augment_bounding_boxes(bbsois)
# Now recommended:
images_aug, bbs_aug = aug(images=images, bounding_boxes=bbs)
Added methods:
augmentables.batches.Batch.to_normalized_batch().augmentables.batches.Batch.get_augmentables().augmentables.batches.UnnormalizedBatch.get_augmentables().augmentables.batches.Batch.get_augmentable_names().augmentables.batches.UnnormalizedBatch.get_augmentable_names().augmentables.batches.Batch.to_batch_in_augmentation().augmentables.batches.Batch.fill_from_batch_in_augmentation_().augmentables.batches.UnnormalizedBatch.fill_from_augmented_normalized_batch().augmenters.meta.Augmenter.augment_batch_(), ,
similar to augment_batch(), but explicitly works in-place and has a
parent parameter.augmenters.meta.Augmenter._augment_batch_().augmentables.polys.recover_psois_().augmentables.utils.convert_cbaois_to_kpsois().augmentables.utils.invert_convert_cbaois_to_kpsois_().augmentables.utils.deepcopy_fast().augmentables.bbs.BoundingBox.from_point_soup().augmentables.bbs.BoundingBoxesOnImages.from_point_soups().to_xy_array() to:
augmentables.bbs.BoundingBoxesOnImage.augmentables.polys.PolygonsOnImage.augmentables.lines.LineStringsOnImage.to_keypoints_on_image(),
invert_to_keypoints_on_image_() and fill_from_xy_array_() to:
augmentables.kps.KeypointsOnImage.augmentables.bbs.BoundingBoxesOnImage.augmentables.polys.PolygonsOnImage.augmentables.lines.LineStringsOnImage.Added classes:
testutils.TemporaryDirectory (context)Changed:
augment_batch_():
augmenters.meta.Augmenter.augment_images()augmenters.meta.Augmenter.augment_heatmaps().augmenters.meta.Augmenter.augment_segmentation_maps().augmenters.meta.Augmenter.augment_keypoints().augmenters.meta.Augmenter.augment_bounding_boxes().augmenters.meta.Augmenter.augment_polygons().augmenters.meta.Augmenter.augment_line_strings().augment_image(), augment_images(), augment_heatmaps(),
augment_segmentation_maps(), augment_keypoints(),
augment_bounding_boxes(), augment_polygons() and
augment_line_strings() to return None inputs without change.
Previously they resulted in an exception. This is more consistent with
the behaviour in the other augment_* methods.augment_images() to no longer be abstract. It defaults
to not changing the input images.imgaug.augmentables.BoundingBoxesOnImage.from_xyxy_array()
to also accept (N, 2, 2) arrays instead of only (N, 4).Deprecated:
imgaug.augmenters.meta.Augmenter.augment_batch().
Use .augment_batch_() instead.Refactored:
_augment_batch_() method.Other changes:
KeypointsOnImage.from_xy_array().BoundingBoxesOnImage.from_xyxy_array().This patch reworked the quantization routines to also support quantization
to N bits instead of N colors in a way that is similar to posterization
in PIL. The patch added corresponding UniformColorQuantizationToNBits
and Posterize augmenters, as well as a quantize_uniform_to_n_bits()
function.
Added classes:
augmenters.color.UniformColorQuantizationToNBits.augmenters.color.Posterize (alias of UniformColorQuantizationToNBits).Added functions:
augmenters.color.quantize_uniform_(), the in-place
version of quantize_uniform().augmenters.color.quantize_uniform_to_n_bits().augmenters.color.quantize_uniform_to_n_bits_().augmenters.color.posterize(), an alias of
quantize_uniform_to_n_bits() that produces the same outputs as
PIL.ImageOps.posterize().Added parameters:
to_bin_centers=True to quantize_uniform(), controling
whether each bin (a, b) should be quantized to a + (b-a)/2 or a.Deprecated:
imgaug.augmenters.color.quantize_colors_uniform(image, n_colors)
to imgaug.augmenters.color.quantize_uniform(arr, nb_bins). The old name
is now deprecated.imgaug.augmenters.color.quantize_colors_kmeans(image, n_colors)
to imgaug.augmenters.color.quantize_kmeans(arr, nb_clusters). The old
name is now deprecated.Other changes:
quantize_uniform() by roughly 10x (small images
around 64x64) to 100x (large images around 1024x1024). This also affects
UniformColorQuantization.UniformColorQuantization by using more in-place
functions.Fixed:
quantize_uniform() producing wrong outputs for non-contiguous
arrays.Added thresholds to Invert and the corresponding functions. This enables
solarization (inversion with thresholds). The patch also added
a corresponding Solarize augmenter and two solarization functions.
imgaug.augmenters.Solarize, a wrapper around Invert.imgaug.augmenters.arithmetic.solarize(), a wrapper around
solarize_().imgaug.augmenters.arithmetic.solarize_(), a wrapper around
invert_().imgaug.augmenters.arithmetic.invert_(), an in-place version
of imgaug.augmenters.arithmetic.invert().threshold and invert_above_threshold to
imgaug.augmenters.arithmetic.invert()threshold and invert_above_threshold to
imgaug.augmenters.arithmetic.Invert.imgaug.augmenters.arithmetic.invert() and
imgaug.augmenters.arithmetic.Invert for uint8 images.Ensured that all augmenters can be pickled and un-pickled without errors.
imgaug.testutils.runtest_pickleable_uint8_img().imgaug.augmenters.blur.MotionBlur not being pickle-able.imgaug.augmenters.meta.AssertLambda not being pickle-able.imgaug.augmenters.meta.AssertShape not being pickle-able.imgaug.augmenters.color.MultiplyHueAndSaturation not supporting
all standard RNG datatypes for random_state.This patch extended the cropping and padding augmenters. It added
augmenters that crop/pad towards multiples of values (e.g. crop the
width until it is a multiple of 2), towards powers of values (e.g.
crop the width until it is one of 1, 2, 4, 8, 16, ...), towards
an aspect ratio (crop the width or height until width/height = 2.0) or
towards a squared size (e.g. crop the width or height until they are equal).
These augmenters are wrappers around CropToFixedSize and
PadToFixedSize. All *FixedSize augmenters also have now corresponding
Center*ToFixedSize aliases, e.g. CenterCropToPowersOf. These
are equivalent to using position="center", e.g. CenterCropToPowersOf
is equivalent to CropToPowersOf(..., position="center").
The following functions were moved. Their old names are now deprecated.
imgaug.imgaug.pad to imgaug.augmenters.size.padimgaug.imgaug.pad_to_aspect_ratio to
imgaug.augmenters.size.pad_to_aspect_ratio.imgaug.imgaug.pad_to_multiples_of to
imgaug.augmenters.size.pad_to_multiples_of.imgaug.imgaug.compute_paddings_for_aspect_ratio to
imgaug.augmenters.size.compute_paddings_to_reach_aspect_ratio.imgaug.imgaug.compute_paddings_to_reach_multiples_of
to imgaug.augmenters.size.compute_paddings_to_reach_multiples_of.The following augmenters were added:
CenterCropToFixedSize.CenterPadToFixedSize.CropToMultiplesOf.CenterCropToMultiplesOf.PadToMultiplesOf.CenterPadToMultiplesOf.CropToPowersOf.CenterCropToPowersOf.PadToPowersOf.CenterPadToPowersOf.CropToAspectRatio.CenterCropToAspectRatio.PadToAspectRatio.CenterPadToAspectRatio.PadToSquare.CenterPadToSquare.CropToSquare.CenterCropToSquare.All Center<name> augmenters are wrappers around <name> with parameter
position="center".
Added functions:
imgaug.augmenters.size.compute_croppings_to_reach_aspect_ratio().imgaug.augmenters.size.compute_croppings_to_reach_multiples_of().imgaug.augmenters.size.compute_croppings_to_reach_powers_of().imgaug.augmenters.size.compute_paddings_to_reach_powers_of().Other changes:
CropToFixedSize to support height and/or width
parameters to be None, in which case the respective axis is not changed.PadToFixedSize to support height and/or width
parameters to be None, in which case the respective axis is not changed.CropToFixedSize.get_parameters() to also
return the height and width values.PadToFixedSize.get_parameters() to also
return the height and width values.PadToFixedSize.get_parameters() to match the order in
PadToFixedSize.__init__()PadToFixedSize to prefer padding the right side over the left side
and the bottom side over the top side. E.g. if using a center pad and
3 columns have to be padded, it will pad 1 on the left and 2 on the
right. Previously it was the other way round. This was changed to establish
more consistency with the various other pad and crop methods.imgaug.augmenters.size.compute_paddings_for_aspect_ratio() for zero-sized
axes.imgaug.augmenters.size.compute_paddings_for_aspect_ratio()
to also support shape tuples instead of only ndarrays.imgaug.augmenters.size.compute_paddings_to_reach_multiples_of()
to also support shape tuples instead of only ndarrays.Fixes:
compute_paddings_to_reach_multiples_of().The available augmenters for alpha-blending of images were significantly extended. There are now new blending augmenters available to alpha-blend acoording to:
BlendAlphaSomeColors)BlendAlphaHorizontalLinearGradient,
BlendAlphaVerticalLinearGradient)BlendAlphaRegularGrid,
BlendAlphaCheckerboard)BlendAlphaSegMapClassIds)BlendAlphaBoundingBoxes)This allows to e.g. randomly remove some colors while leaving
other colors unchanged (BlendAlphaSomeColors(Grayscale(1.0))),
to change the color of some objects
(BlendAlphaSegMapClassIds(AddToHue((-256, 256)))), to add
cloud-patterns only to the top of images
(BlendAlphaVerticalLinearGradient(Clouds())) or to apply
augmenters in some coarse rectangular areas (e.g.
BlendAlphaRegularGrid(Multiply(0.0)) to achieve a similar
effect to CoarseDropout or
BlendAlphaRegularGrid(AveragePooling(8)) to pool in equally
coarse image sub-regions).
Other mask-based alpha blending techniques can be achieved by
subclassing IBatchwiseMaskGenerator and providing an
instance of such a class to BlendAlphaMask.
This patch also changes the naming of the blending augmenters as follows:
Alpha -> BlendAlphaAlphaElementwise -> BlendAlphaElementwiseSimplexNoiseAlpha -> BlendAlphaSimplexNoiseFrequencyNoiseAlpha -> BlendAlphaFrequencyNoise
The old names are now deprecated.
Furthermore, the parameters first and second, which were
used by all blending augmenters, have now the names foreground
and background.List of changes:
imgaug.augmenters.blend.BlendAlphaMask, which uses
a mask generator instance to generate per batch alpha masks and
then alpha-blends using these masks.imgaug.augmenters.blend.BlendAlphaSomeColors.imgaug.augmenters.blend.BlendAlphaHorizontalLinearGradient.imgaug.augmenters.blend.BlendAlphaVerticalLinearGradient.imgaug.augmenters.blend.BlendAlphaRegularGrid.imgaug.augmenters.blend.BlendAlphaCheckerboard.imgaug.augmenters.blend.BlendAlphaSegMapClassIds.imgaug.augmenters.blend.BlendAlphaBoundingBoxes.imgaug.augmenters.blend.IBatchwiseMaskGenerator,
an interface for classes generating masks on a batch-by-batch
basis.imgaug.augmenters.blend.StochasticParameterMaskGen,
a helper to generate masks from StochasticParameter instances.imgaug.augmenters.blend.SomeColorsMaskGen, a generator
that produces masks marking randomly chosen colors in images.imgaug.augmenters.blend.HorizontalLinearGradientMaskGen,
a linear gradient mask generator.imgaug.augmenters.blend.VerticalLinearGradientMaskGen,
a linear gradient mask generator.imgaug.augmenters.blend.RegularGridMaskGen,
a checkerboard-like mask generator where every grid cell has
a random alpha value.imgaug.augmenters.blend.CheckerboardMaskGen,
a checkerboard-like mask generator where every grid cell has
the opposite alpha value of its 4-neighbours.imgaug.augmenters.blend.SegMapClassIdsMaskGen, a
segmentation map-based mask generator.imgaug.augmenters.blend.BoundingBoxesMaskGen, a bounding
box-based mask generator.imgaug.augmenters.blend.InvertMaskGen, an mask generator
that inverts masks produces by child generators.imgaug.parameters.SimplexNoise and
imgaug.parameters.FrequencyNoise to also accept (H, W, C)
sampling shapes, instead of only (H, W).AlphaElementwise to be a wrapper around
BlendAlphaMask.Alpha to BlendAlpha.
Alpha is now deprecated.AlphaElementwise to BlendAlphaElementwise.
AlphaElementwise is now deprecated.SimplexNoiseAlpha to BlendAlphaSimplexNoise.
SimplexNoiseAlpha is now deprecated.FrequencyNoiseAlpha to BlendAlphaFrequencyNoise.
FrequencyNoiseAlpha is now deprecated.first and second to foreground and background
in BlendAlpha, BlendAlphaElementwise, BlendAlphaSimplexNoise and
BlendAlphaFrequencyNoise.imgaug.parameters.handle_categorical_string_param() to allow
parameter valid_values to be None.imgaug.augmenters.color.change_colorspace_().<a name="added"/>
The bounding box augmentation was previously a wrapper around keypoint augmentation. Bounding Boxes were simply converted to keypoints at the start of the augmentation and then augmented as keypoints by all called augmenters. This was now changed so that all augmenters receive bounding boxes and can then chose how to augment them. This enables augmentations specific to bounding boxes.
coords to BoundingBox. The property returns an (N,2)
numpy array containing the coordinates of the top-left and bottom-right
bounding box corners.BoundingBox.coords_almost_equals(other).BoundingBox.almost_equals(other).Polygon.almost_equals(other) to no longer verify the
datatype. It is assumed now that the input is a Polygon.items to KeypointsOnImage, BoundingBoxesOnImage,
PolygonsOnImage, LineStringsOnImage. The property returns the
keypoints/BBs/polygons/LineStrings contained by that instance.Polygon.coords_almost_equals(other). Alias for
Polygon.exterior_almost_equals(other).Polygon.coords. Alias for Polygon.exterior.Keypoint.coords.Keypoint.coords_almost_equals(other).Keypoint.almost_equals(other).imgaug.testutils.assert_cbaois_equal().imgaug.testutils.shift_cbaoi()._augment_bounding_boxes() methods to various augmenters.
This allows to individually control how bounding boxes are supposed to
be augmented. Previously, the bounding box augmentation was a wrapper around
keypoint augmentation that did not allow such control.parents to
Augmenter.augment_bounding_boxes().
This breaks if hooks was used as a positional argument in connection with
that method.func_bounding_boxes to Lambda.
This breaks if one relied on the order of the augmenter's parameters instead
of their names.func_bounding_boxes to AssertLambda.
This breaks if one relied on the order of the augmenter's parameters instead
of their names.check_bounding_boxes to AssertShape.
This breaks if one relied on the order of the augmenter's parameters instead
of their names.This patch is the same as the bounding box unwrapping above, only applied to line strings.
_augment_line_strings() methods to various augmenters.
This allows to individually control how line strings are supposed to
be augmented. Previously, the line string augmentation was a wrapper around
keypoint augmentation that did not allow such control.func_line_strings to Lambda.
This breaks if one relied on the order of the augmenter's parameters instead
of their names.func_line_strings to AssertLambda.
This breaks if one relied on the order of the augmenter's parameters instead
of their names.check_line_strings to AssertShape.
This breaks if one relied on the order of the augmenter's parameters instead
of their names.This patch added fit_output to PerspectiveTransform.
fit_output parameter,
similar to Affine. This change may break code that relied on the order of
arguments to __init__.PerspectiveTransform was reworked and should now
be faster.ChangeColorTemperature Augmenter #454This patch added an augmenter and corresponding function to change the color temperature of images. This adds e.g. red, orange or blue tints.
imgaug.augmenters.color.ChangeColorTemperature.imgaug.augmenters.color.change_color_temperatures_().imgaug.augmenters.color.change_color_temperature_().This patch added brightness-related augmenters. At the core is
WithBrightnessChannels, which converts images to a choice of
colorspaces that have brightness-related channels, extracts these
channels and applies child augmenters to them. E.g. it might
transform to L*a*b* colorspace and extract L, then apply
a child augmenter and convert the modified L*a*b* back to RGB.
imgaug.augmenters.color.WithBrightnessChannels.imgaug.augmenters.color.MultiplyAndAddToBrightness.imgaug.augmenters.color.MultiplyBrightness.imgaug.augmenters.color.AddToBrightness.imgaug.parameters.handle_categorical_string_param().change_colorspaces_() to accept any iterable of str for
argument to_colorspaces, not just list.This patch added more dropout augmenters. Dropout2d randomly zeros
whole channels, while TotalDropout randomly zeros whole images.
The latter augmenter can sometimes be used in connection with
blending operations. (Note though that in these cases it should not be
used with coordinate-based input data, such as bounding boxes, because
it removes that data from examples affected by total dropout. That
breaks the blending operation, which requires the number of coordinates
to be unchanged.)
Dropout2d, which drops channels in images with
a defineable probability p. Dropped channels will be filled with zeros.
By default, the augmenter keeps at least one channel in each image
unaltered (i.e. not dropped).TotalDropout, which sets all components to zero
for p percent of all images. The augmenter should be used in connection
with e.g. blend augmenters.RemoveSaturation #462RemoveSaturation, a shortcut for MultiplySaturation((0.0, 1.0))
with outputs similar to Grayscale((0.0, 1.0)).Cartoon Augmenter #463This patch added a filter to change the style of images to one that looks more cartoon-ish. The filter used classical methods. As such it works well on some images and badly on others. It seems to work better on images that already have rather saturated colors and pronounced edges.
imgaug.augmenters.artistic.imgaug.augmenters.artistic.stylize_cartoon(image).imgaug.augmenters.artistic.Cartoon.MeanShiftBlur Augmenter #466This patch added a mean shift-based blur filter. Note that it is very slow when using the default parameters (high radius).
imgaug.augmenters.blur.blur_mean_shift_(image).imgaug.augmenters.blur.MeanShiftBlur.DeterministicList Parameter #475Added imgaug.parameters.DeterministicList. Upon a request to generate
samples of shape S, this parameter will create a new array of shape S
and fill it by cycling over its list of values repeatedly.
Jigsaw Augmenter #476 #577This patch added a jigsaw puzzle augmenter and corresponding functions.
The augmenter splits each image into a regular grid of cells, then
randomly picks some cells and switches them with one of their
8-neighbours. The process is repeated for N steps per image.
Note: The augmenter will reject batches containing bounding boxes, polygons or line strings.
imgaug.augmenters.geometric.apply_jigsaw().imgaug.augmenters.geometric.apply_jigsaw_to_coords().imgaug.augmenters.geometric.generate_jigsaw_destinations().PIL #479 #480 #538This patch added wrapper functions and augmenters around popular
PIL functions. The outputs of these functions and augmenters are
tested to be identical with the ones in PIL. They are intended
for research cases where papers have to be re-implemented as
accurately as possible.
imgaug.augmenters.pillike, which contains augmenters and
functions corresponding to commonly used PIL functions. Their outputs
are guaranteed to be identical to the PIL outputs.imgaug.augmenters.pillike.equalizeimgaug.augmenters.pillike.equalize_imgaug.augmenters.pillike.autocontrastimgaug.augmenters.pillike.autocontrast_imgaug.augmenters.pillike.solarizeimgaug.augmenters.pillike.solarize_imgaug.augmenters.pillike.posterizeimgaug.augmenters.pillike.posterize_imgaug.augmenters.pillike.enhance_colorimgaug.augmenters.pillike.enhance_contrastimgaug.augmenters.pillike.enhance_brightnessimgaug.augmenters.pillike.enhance_sharpnessimgaug.augmenters.pillike.filter_blurimgaug.augmenters.pillike.filter_smoothimgaug.augmenters.pillike.filter_smooth_moreimgaug.augmenters.pillike.filter_edge_enhanceimgaug.augmenters.pillike.filter_edge_enhance_moreimgaug.augmenters.pillike.filter_find_edgesimgaug.augmenters.pillike.filter_contourimgaug.augmenters.pillike.filter_embossimgaug.augmenters.pillike.filter_sharpenimgaug.augmenters.pillike.filter_detailimgaug.augmenters.pillike.warp_affineimgaug.augmenters.pillike.Solarizeimgaug.augmenters.pillike.Posterize.
(Currently alias for imgaug.augmenters.color.Posterize.)imgaug.augmenters.pillike.Equalizeimgaug.augmenters.pillike.Autocontrastimgaug.augmenters.pillike.EnhanceColorimgaug.augmenters.pillike.EnhanceContrastimgaug.augmenters.pillike.EnhanceBrightnessimgaug.augmenters.pillike.EnhanceSharpnessimgaug.augmenters.pillike.FilterBlurimgaug.augmenters.pillike.FilterSmoothimgaug.augmenters.pillike.FilterSmoothMoreimgaug.augmenters.pillike.FilterEdgeEnhanceimgaug.augmenters.pillike.FilterEdgeEnhanceMoreimgaug.augmenters.pillike.FilterFindEdgesimgaug.augmenters.pillike.FilterContourimgaug.augmenters.pillike.FilterEmbossimgaug.augmenters.pillike.FilterSharpenimgaug.augmenters.pillike.FilterDetailimgaug.augmenters.pillike.AffineIdentity #481This patch added an identity function augmenter (Identity), which is
the same as Noop and will replace the latter one in the long run.
imgaug.augmenters.meta.Identity, an alias of
Noop. Identity is now the recommended augmenter for identity
transformations. This change can break code that explicitly relied on
exactly Noop being used, e.g. via isinstance checks.noop_if_topmost to identity_if_topmost in
method imgaug.augmenters.meta.Augmenter.remove_augmenters(). The old name
is now deprecated.Affine #482Affine was changed to now also support shearing on the y-axis.
Previously, only the x-axis was supported. Use e.g.
Affine(shear={"y": (-20, 20)) now.
Affine to also support shearing on the
y-axis (previously, only x-axis was possible). This feature can be used
via e.g. Affine(shear={"x": (-30, 30), "y": (-10, 10)}). If instead
a single number is used (e.g. Affine(shear=15)), shearing will be done
only on the x-axis. If a single tuple, list or
StochasticParameter is used, the generated samples will be used
identically for both the x-axis and y-axis (this is consistent with
translation and scaling). To get independent random samples per axis use
the dictionary form.Affine #484This patch added a few convenience wrappers around Affine.
imgaug.augmenters.geometric.ScaleX.imgaug.augmenters.geometric.ScaleY.imgaug.augmenters.geometric.TranslateX.imgaug.augmenters.geometric.TranslateY.imgaug.augmenters.geometric.Rotate.imgaug.augmenters.geometric.ShearX.imgaug.augmenters.geometric.ShearY.This patch extended the methods to handle coordinate-based augmentables,
e.g. bounding boxes, that are partially/fully outside of the image plane.
They can now more easily be dropped if more than p% of their areas is
outside of the image plane.
The patch also adds augmenters to remove and clip coordinate-based augmentables that are outside of the image plane.
Added Keypoint.is_out_of_image().
Added BoundingBox.compute_out_of_image_area().
Added Polygon.compute_out_of_image_area().
Added Keypoint.compute_out_of_image_fraction()
Added BoundingBox.compute_out_of_image_fraction().
Added Polygon.compute_out_of_image_fraction().
Added LineString.compute_out_of_image_fraction().
Added KeypointsOnImage.remove_out_of_image_fraction().
Added BoundingBoxesOnImage.remove_out_of_image_fraction().
Added PolygonsOnImage.remove_out_of_image_fraction().
Added LineStringsOnImage.remove_out_of_image_fraction().
Added KeypointsOnImage.clip_out_of_image().
Added imgaug.augmenters.meta.RemoveCBAsByOutOfImageFraction.
Removes coordinate-based augmentables (e.g. BBs) that have at least a
specified fraction of their area outside of the image plane.
Added imgaug.augmenters.meta.ClipCBAsToImagePlanes.
Clips off all parts from coordinate-based augmentables (e.g. BBs) that are
outside of the corresponding image.
Changed Polygon.area to return 0.0 if the polygon contains less than
three points (previously: exception).
imgaug.augmentables.bbs.BoundingBox.to_polygon().imgaug.augmentables.bbs.BoundingBoxesOnImage.to_polygons_on_image().imgaug.augmentables.polys.Polygon.subdivide(N).
The method increases the polygon's corner point count by interpolating
N points on each edge with regular distance.imgaug.augmentables.polys.PolygonsOnImage.subdivide(N).WithPolarWarping Augmenter #489This patch added an augmenter to transform images to polar coordinates and apply child augmenters within that space. This leads to interesting effects in combination with augmenters that affect pixel locations, such as cropping or affine transformations.
imgaug.augmenters.geometric.WithPolarWarping, an
augmenter that applies child augmenters in a polar representation of the
image.This patch added various magic functions to coordinate-based augmentables that make their usage more convenient. Example:
import imgaug as ia
bb1 = ia.BoundingBox(x1=0, y1=1, x2=2, y2=3)
bb2 = ia.BoundingBox(x1=1, y1=2, x2=3, y2=4)
bbsoi = ia.BoundingBoxesOnImage([bb1, bb2])
print(bbsoi[0]) # prints now str(bb1)
print(len(bbsoi)) # prints now 2
for bb in bbsoi: # looping is now supported
print(bb)
imgaug.augmentables.base.imgaug.augmentables.base.IAugmentable, implemented by
HeatmapsOnImage, SegmentationMapsOnImage, KeypointsOnImage,
BoundingBoxesOnImage, PolygonsOnImage and LineStringsOnImage.*OnImage instances
(keypoints, bounding boxes, polygons, line strings), e.g.
bbsoi = BoundingBoxesOnImage(bbs, shape=...); for bb in bbsoi: ....
would iterate now over bbs.__len__ methods to coordinate-based *OnImage
instances, e.g.
bbsoi = BoundingBoxesOnImage(bbs, shape=...); print(len(bbsoi))
would now print the number of bounding boxes in bbsoi.BoundingBox (top-left,
bottom-right), Polygon and LineString via for xy in obj: ....BoundingBox, Polygon and
LineString using indices or slices, e.g. line_string[1:] to get an
array of all coordinates except the first one.Keypoint.xy.Keypoint.xy_int.SaveDebugImageEveryNBatches Augmenter #502This patch added a debug augmenter SaveDebugImageEveryNBatches that
visualizes a whole batch and saves the corresponding image to a directory.
The visualization happens at every Nth batch. The plot contains
a visualization of all images within the batch, as well as all additional
input data (e.g. segmentation maps or bounding boxes overlayed with
images). The plot also contains various additional information, such as
observed value ranges (min/max values) of images, observed labels of
bounding boxes or observed segmentation classes.
The augmenter can be used during training to evaluate the strength of augmentations, whether all data is still aligned (e.g. bounding box positions match object positions) and whether the data statistics match the expectations (e.g. no segmentation map classes missing).
The augmenter might be useful even if no augmentation is actually performed.
imgaug.augmenters.debug.imgaug.augmenters.debug.draw_debug_image(). The function
draws an image containing debugging information for a provided set of
images and non-image data (e.g. segmentation maps, bounding boxes)
corresponding to a single batch. The debug image visualizes these
informations (e.g. bounding boxes drawn on images) and offers relevant
information (e.g. actual value ranges of images, labels of bounding
boxes and their counts, etc.).imgaug.augmenters.debug.SaveDebugImageEveryNBatches.
Augmenter corresponding to draw_debug_image(). Saves an image at every
n-th batch into a provided folder.pad() #502Improved imgaug.augmenters.size.pad() to support multi-channel values
for the cval parameter (e.g. RGB colors).
imagecorruptions #530Added wrappers around the functions from package
bethgelab/imagecorruptions.
The functions in that package were used in some recent papers and are added
here for convenience.
The wrappers produce arrays containing values identical to the output
arrays from the corresponding imagecorruptions functions when called
via the imagecorruptions.corrupt() (verified via unittests).
The interfaces of the wrapper functions are identical to the
imagecorruptions functions, with the only difference of also supporting
seed parameters.
imgaug.augmenters.imgcorruptlike. The like signals that
the augmentation functions do not have to wrap imagecorruptions
internally. They merely have to produce the same outputs.imgaug.augmenters.imgcorruptlike:
apply_gaussian_noise()apply_shot_noise()apply_impulse_noise()apply_speckle_noise()apply_gaussian_blur()apply_glass_blur() (improved performance over original function)apply_defocus_blur()apply_motion_blur()apply_zoom_blur()apply_fog()apply_snow()apply_spatter()apply_contrast()apply_brightness()apply_saturate()apply_jpeg_compression()apply_pixelate()apply_elastic_transform()imgaug.augmenters.imgcorruptlike.get_corruption_names(subset).
Similar to imagecorruptions.get_corruption_names(subset), but returns a
tuple
(list of corruption method names, list of corruption method functions),
instead of only the names.imgaug.augmenters.imgcorruptlike:
GaussianNoiseShotNoiseImpulseNoiseSpeckleNoiseGaussianBlurGlassBlurDefocusBlurMotionBlurZoomBlurFogFrostSnowSpatterContrastBrightnessSaturateJpegCompressionPixelateElasticTransformimgaug.random.temporary_numpy_seed().Cutout Augmenter #531 #570This patch added Cutout augmentation, similar to the paper proposal.
The augmetner has some similarity with CoarseDropout.
imgaug.augmenters.arithmetic.apply_cutout_(), which replaces
in-place a single rectangular area with a constant intensity value or a
constant color or gaussian noise.
See also the paper about Cutout.imgaug.augmenters.arithmetic.apply_cutout(). Same as
apply_cutout_(), but copies the input images before applying cutout.imgaug.augmenters.arithmetic.Cutout.This patch added for many already existing methods corresponding in-place variations. They are now used throughout the library, improving the performance of augmentation in the case of e.g. bounding boxes.
Keypoint.project_().Keypoint.shift_().KeypointsOnImage.on_().KeypontsOnImage.items.BoundingBoxesOnImage.items.LineStringsOnImage.items.PolygonsOnImage.items.KeypointsOnImage.remove_out_of_image_fraction_().KeypointsOnImage.clip_out_of_image_fraction_().KeypointsOnImage.shift_().BoundingBox.project_().BoundingBox.extend_().BoundingBox.clip_out_of_image_().BoundingBox.shift_().BoundingBoxesOnImage.on_().BoundingBoxesOnImage.clip_out_of_image_().BoundingBoxesOnImage.remove_out_of_image_().BoundingBoxesOnImage.remove_out_of_image_fraction_().BoundingBoxesOnImage.shift_().imgaug.augmentables.utils.project_coords_().LineString.project_().LineString.shift_().LineStringsOnImage.on_().LineStringsOnImage.remove_out_of_image_().LineStringsOnImage.remove_out_of_image_fraction_().LineStringsOnImage.clip_out_of_image_().LineStringsOnImage.shift_().Polygon.project_().Polygon.shift_().Polygon.on_().Polygon.subdivide_().PolygonsOnImage.remove_out_of_image_().PolygonsOnImage.remove_out_of_image_fraction_().PolygonsOnImage.clip_out_of_image_().PolygonsOnImage.shift_().PolygonsOnImage.subdivide_().BoundingBoxesOnImage.copy() to a custom copy operation (away
from module copy module).bounding_boxes and shape to
BoundingBoxesOnImage.copy()`.bounding_boxes and shape to
BoundingBoxesOnImage.deepcopy()`.KeypointsOnImage.copy() to a custom copy operation (away
from module copy module).PolygonsOnImage.copy() to a custom copy operation (away
from module copy module).polygons and shape to
PolygonsOnImage.copy()`.polygons and shape to
PolygonsOnImage.deepcopy()`.This patch standardized the handling of lookup tables throughout the library.
imgaug.imgaug.apply_lut(), which applies a lookup table to an image.imgaug.imgaug.apply_lut_(). In-place version of apply_lut().When drawing bounding boxes on images via BoundingBox.draw_on_image()
or BoundingBoxesOnImage.draw_on_image(), a box containing the label will now
be drawn over each bounding box's rectangle. If the bounding box's label is
set to None, the label box will not be drawn. For more detailed control,
use BoundingBox.draw_label_on_image().
imgaug.augmentables.BoundingBox.draw_label_on_image().imgaug.augmentables.BoundingBox.draw_box_on_image().imgaug.augmentables.BoundingBox.draw_on_image()
to automatically draw a bounding box's label.*OnImage Instances #547Enabled index-based access to coordinate-based *OnImage instances, i.e. to
KeypointsOnImage, BoundingBoxesOnImage, LineStringsOnImage and
PolygonsOnImage. This allows to do things like
bbsoi = BoundingBoxesOnImage(...); bbs = bbsoi[0:2];.
imgaug.augmentables.kps.KeypointsOnImage.__getitem__().imgaug.augmentables.bbs.BoundingBoxesOnImage.__getitem__().imgaug.augmentables.lines.LineStringsOnImage.__getitem__().imgaug.augmentables.polys.PolygonsOnImage.__getitem__().Rain and RainLayer Augmenters #551Added augmenter(s) to create fake rain effects. They currently seem to work best at around medium-sized images (~224px).
imgaug.augmenters.weather.Rain.imgaug.augmenters.weather.RainLayer.round Parameter to Discretize #553Added the parameter round to imgaug.parameters.Discretize. The parameter
defaults to True, i.e. the default behaviour of Discretize did not change.
RandAugment Augmenter #553Added a RandAugment augmenter, similar to the one described in the paper "RandAugment: Practical automated data augmentation with a reduced search space".
Note: This implementation makes a best guess about some hyperparameters that were neither in the paper nor in the code repsitory clearly defined.
Note: This augmenter differs from the paper implementation by applying a fix to their color augmentations. The ones in the paper's implementation seemed to increase in strength as the magnitude was decreased below a threshold.
Note: This augmenter currently only accepts image inputs. Other input types (e.g. bounding boxes) will be rejected.
imgaug.augmenters.collectionsimgaug.augmenters.collections.RandAugment.Improved the errors and warnings on image augmentation calls.
augment_image() will now produce a more self-explanatory error
message when calling it as in augment_image(list of images).
Calls of single-image augmentation functions (e.g.
augment(image=...)) with inputs that look like multiple images
will now produce warnings. This is the case for (H, W, C)
inputs when C>=32 (as that indicates that (N, H, W) was
actually provided).
Calls of multi-image augmentation functions (e.g.
augment(images=...)) with inputs that look like single images
will now produce warnings. This is the case for (N, H, W)
inputs when W=1 or W=3 (as that indicates that (H, W, C)
was actually provided.)
augment_image() to verify that inputs are
arrays.augment_image(), augment_images(), augment() (and its
alias __call__()).imgaug.augmenters.base.imgaug.augmenters.base.SuspiciousMultiImageShapeWarning.imgaug.augmenters.base.SuspiciousSingleImageShapeWarning.imgaug.testutils.assertWarns, similar to unittest's
assertWarns, but available in python <3.2.<a name="changed"/>
Changed Augmenter.augment_polygons() to copy the augmenter's RNG
before starting concave polygon recovery. This is done for cleanliness and
should not have any effects for users.
Also removed RNG copies in _ConcavePolygonRecoverer to improve performance.
Pooling augmenters were previously implemented so that they did not pool
the arrays of maps (i.e. heatmap arrays, segmentation map arrays). Only
the image shape saved within HeatmapsOnImage.shape and
SegmentationMapsOnImage.shape were updated. That was done because the library
can handle map arrays that are larger than the corresponding images and hence
no pooling was necessary for the augmentation to work correctly. This was now
changed and pooling augmenters will also pool map arrays
(if keep_size=False). The motiviation for this change is that the old
behaviour was unintuitive and inconsistent with other augmenters (e.g. Crop).
Removed a rounding operation in Affine translation that would unnecessarily
round floats to integers. This should make coordinate augmentation overall
more accurate.
Affine.get_parameters() and translate_px/translate_percent #508Changed Affine.get_parameters() to always return a tuple (x, y, mode)
for translation, where mode is either px or percent,
and x and y are stochastic parameters. y may be None if the same
parameter (and hence samples) are used for both axes.
The docstring of each module in imgaug.augmenters previously included a
suggestion to not directly import from that module, but instead use
imgaug.augmenters.<AugmenterName>. That was due to the categorization
still being unstable. As the categorization has now been fairly stable
for a long time, the suggestion was removed from all modules. Calling
imgaug.augmenters.<AugmenterName> instead of
imgaug.augmenters.<ModuleName>.<AugmenterName> is however still the
preferred way.
shift() Interfaces of Coordinate-Based Augmentables #548The interfaces for shift operations of all coordinate-based
augmentables (Keypoints, BoundingBoxes, LineStrings, Polygons)
were standardized. All of these augmentables have now the same
interface for shift operations. Previously, Keypoints used
a different interface (using x and y arguments) than the
other augmentables (using top, right, bottom, left
arguments). All augmentables use now the interface of Keypoints
as that is simpler and less ambiguous. Old arguments are still
accepted, but will produce deprecation warnings. Change the
arguments to x and y following x=left-right and
y=top-bottom.
[breaking] This breaks if one relied on calling shift() functions of
BoundingBox, LineString, Polygon, BoundingBoxesOnImage,
LineStringsOnImage or PolygonsOnImage without named arguments.
E.g. bb = BoundingBox(...); bb_shifted = bb.shift(1, 2, 3, 4);
will produce unexpected outputs now (equivalent to
shift(x=1, y=2, top=3, right=4, bottom=0, left=0)),
while bb_shifted = bb.shift(top=1, right=2, bottom=3, left=4) will still
work as expected.
x, y to BoundingBox.shift(), LineString.shift()
and Polygon.shift().x, y to BoundingBoxesOnImage.shift(),
LineStringsOnImage.shift() and PolygonsOnImage.shift().top, right, bottom, left in
BoundingBox.shift(), LineString.shift() and Polygon.shift()
as deprecated. This also affects the corresponding *OnImage
classes.testutils.wrap_shift_deprecation().The patch changed the standard parameters shared by all augmenters to a
reduced and more self-explanatory set. Previously, all augmenters
shared the parameters name, random_state and deterministic.
The new parameters are seed and name.
deterministic was removed as it was hardly ever used and because
it caused frequently confusion with regards to its meaning. The
parameter is still accepted but will now produce a deprecation
warning. Use <augmenter>.to_deterministic() instead.
Reminder: to_deterministic() is necessary if you want to get
the same samples in consecutive augmentation calls. It is not
necessary if you want your generated samples to be dependent on
an initial seed or random state as that is always the case
anyways. To use non-random initial seeds, use either
the seed parameter (augmenter-specific seeding) or
imgaug.random.seed() (global seeding, affects only augmenters
for which the seed parameter was not explicitly provided).
random_state was renamed to seed as providing a seed value
is the more common use case compared to providing a random state.
Many users also seemed to be unaware that random_state accepted
seed values. The new name should make this more clear.
The old parameter random_state is still accepted, but will
likely be deprecated in the future.
[breaking] This patch breaks if one relied on the order of
name, random_state and deterministic. The new order is now
seed=..., name=..., random_state=..., deterministic=... (with the
latter two parameters being outdated or deprecated)
as opposed to previously
name=..., deterministic=..., random_state=....
[breaking] Most augmenters had previously default values that
made them equivalent to identity functions. Users had to explicitly
change the defaults to proper values in order to "activate"
augmentations. To simplify the usage of the library, the default
values of most augmenters were changed to medium-strength
augmentations. E.g.
Sequential([Affine(), UniformVoronoi(), CoarseDropout()])
should now produce decent augmentations.
A few augmenters were set to always-on, maximum-strength augmentations. This is the case for:
Grayscale (always fully grayscales images, use
Grayscale((0.0, 1.0)) for random strengths)RemoveSaturation (same as Grayscale)Fliplr (always flips images, use Fliplr(0.5) for 50%
probability)Flipud (same as Fliplr)TotalDropout (always drops everything, use
TotalDropout(0.1) to drop everything for 10% of all images)Invert (always inverts images, use Invert(0.1) to invert
10% of all images)Rot90 (always rotates exactly once clockwise by 90 degrees,
use Rot90((0, 3)) for any rotation)These settings seemed to better match user-expectations.
Such maximum-strength settings however were not chosen for all
augmenters where one might expect them. The defaults are set to
varying strengths for, e.g. Superpixels (replaces only some
superpixels with cellwise average colors), UniformVoronoi (also
only replaces some cells), Sharpen (alpha-blends with variable
strength, the same is the case for Emboss, EdgeDetect and
DirectedEdgeDetect) and CLAHE (variable clip limits).
Note: Some of the new default values will cause issues with
non-uint8 inputs.
Note: The defaults for per_channel and keep_size were not
adjusted. It is currently still the default behaviour of all
augmenters to affect all channels in the same way and to resize
their outputs back to the input sizes.
The exact changes to default values are listed below.
imgaug.arithmetic
Add
value: 0 -> (-20, 20)AddElementwise
value: 0 -> (-20, 20)AdditiveGaussianNoise
scale: 0 -> (0, 15)AdditiveLaplaceNoise
scale: 0 -> (0, 15)AdditivePoissonNoise
scale: 0 -> (0, 15)Multiply
mul: 1.0 -> (0.8, 1.2)MultiplyElementwise:
mul: 1.0 -> (0.8, 1.2)Dropout:
p: 0.0 -> (0.0, 0.05)CoarseDropout:
p: 0.0 -> (0.02, 0.1)size_px: None -> (3, 8)min_size: 4 -> 3size_px is only used if neither size_percent
nor size_px is provided by the user.CoarseSaltAndPepper:
p: 0.0 -> (0.02, 0.1)size_px: None -> (3, 8)min_size: 4 -> 3size_px is only used if neither size_percent
nor size_px is provided by the user.CoarseSalt:
p: 0.0 -> (0.02, 0.1)size_px: None -> (3, 8)min_size: 4 -> 3size_px is only used if neither size_percent
nor size_px is provided by the user.CoarsePepper:
p: 0.0 -> (0.02, 0.1)size_px: None -> (3, 8)min_size: 4 -> 3size_px is only used if neither size_percent
nor size_px is provided by the user.SaltAndPepper:
p: 0.0 -> (0.0, 0.03)Salt:
p: 0.0 -> (0.0, 0.03)Pepper:
p: 0.0 -> (0.0, 0.05)ImpulseNoise:
p: 0.0 -> (0.0, 0.03)Invert:
p: 0 -> 1JpegCompression:
compression: 50 -> (0, 100)imgaug.blend
BlendAlpha
factor: 0 -> (0.0, 1.0)BlendAlphaElementwise
factor: 0 -> (0.0, 1.0)imgaug.blur
GaussianBlur:
sigma: 0 -> (0.0, 3.0)AverageBlur:
k: 1 -> (1, 7)MedianBlur:
k: 1 -> (1, 7)BilateralBlur:
d: 1 -> (1, 9)MotionBlur:
k: 5 -> (3, 7)imgaug.color
MultiplyHueAndSaturation:
mul_hue: None -> (0.5, 1.5)mul_saturation: None -> (0.0, 1.7)mul nor mul_hue nor mul_saturation.MultiplyHue:
mul: (-1.0, 1.0) -> (-3.0, 3.0)AddToHueAndSaturation:
value_hue: None -> (-40, 40)value_saturation: None -> (-40, 40)value nor value_hue nor value_saturation.Grayscale:
alpha: 0 -> 1imgaug.contrast
GammaContrast:
gamma: 1 -> (0.7, 1.7)SigmoidContrast:
gain: 10 -> (5, 6)cutoff: 0.5 -> (0.3, 0.6)LogContrast:
gain: 1 -> (0.4, 1.6)LinearContrast:
alpha: 1 -> (0.6, 1.4)AllChannelsCLAHE:
clip_limit: 40 -> (0.1, 8)tile_grid_size_px: 8 -> (3, 12)CLAHE:
clip_limit: 40 -> (0.1, 8)tile_grid_size_px: 8 -> (3, 12)convolutional
Sharpen:
alpha: 0 -> (0.0, 0.2)lightness: 1 -> (0.8, 1.2)Emboss:
alpha: 0 -> (0.0, 1.0)strength: 1 -> (0.25, 1.0)EdgeDetect:
alpha: 0 -> (0.0, 0.75)DirectedEdgeDetect:
alpha: 0 -> (0.0, 0.75)imgaug.flip
Fliplr:
p: 0 -> 1Flipud:
p: 0 -> 1imgaug.geometric
Affine:
scale: 1 -> {"x": (0.9, 1.1), "y": (0.9, 1.1)}translate_percent: None -> {"x": (-0.1, 0.1), "y": (-0.1, 0.1)}rotate: 0 -> (-15, 15)shear: 0 -> shear={"x": (-10, 10), "y": (-10, 10)}PiecewiseAffine:
scale: 0 -> (0.0, 0.04)nb_rows: 4 -> (2, 4)nb_cols: 4 -> (2, 4)PerspectiveTransform:
scale: 0 -> (0.0, 0.06)ElasticTransformation:
alpha: 0 -> (0.0, 40.0)sigma: 0 -> (4.0, 8.0)Rot90:
k: (no default) -> k=1imgaug.pooling
AveragePooling:
k: (no default) -> (1, 5)MaxPooling:
k: (no default) -> (1, 5)MinPooling:
k: (no default) -> (1, 5)MedianPooling:
k: (no default) -> (1, 5)imgaug.segmentation
Superpixels:
p_replace: 0.0 -> (0.5, 1.0)n_segments: 100 -> (50, 120)UniformVoronoi:
n_points: (no default) -> (50, 500)p_replace: 1.0 -> (0.5, 1.0).RegularGridVoronoi:
n_rows: (no default) -> (10, 30)n_cols: (no default) -> (10, 30)p_drop_points: 0.4 -> (0.0, 0.5)p_replace: 1.0 -> (0.5, 1.0)RelativeRegularGridVoronoi: Changed defaults from
n_rows_frac: (no default) -> (0.05, 0.15)n_cols_frac: (no default) -> (0.05, 0.15)p_drop_points: 0.4 -> (0.0, 0.5)p_replace: 1.0 -> (0.5, 1.0)imgaug.size
CropAndPad:
percent: None -> (-0.1, 0.1)px nor percent.Pad:
percent: None -> (0.0, 0.1)px nor percent.Crop:
percent: None -> (0.0, 0.1)px nor percent.setup.py Now Accepts any opencv-* Installation #586setup.py was changed so that it now accepts opencv-python,
opencv-python-headless, opencv-contrib-python and
opencv-contrib-python-headless as valid OpenCV installations.
Previously, only opencv-python-headless was accepted, which
could easily cause conflicts when another one of the mentioned
libraries was already installed.
If none of the mentioned libraries is installed, setup.py
will default to adding opencv-python as a requirement.
Note that this may still cause issues if a single installation
call installs multiple libraries and the order is random.
imgaug will then currently request opencv-python-headless
to be installed, which may differ from what a later installed
library requests. Try to ensure that the other library is installed
first in these cases.
Changed various augmenters to use the same normalization for OpenCV inputs. This probably fixes some previously undiscovered bugs.
Augmenter.reseed() to Augmenter.seed_(). The old name is
now deprecated.Augmenter.remove_augmenters_inplace() to
Augmenter.remove_augmenters_(). The old name is now deprecated.AffineCv2 #540Deprecated imgaug.augmenters.geometric.AffineCv2.
Use imgaug.augmenters.geometric.Affine instead. #540
<a name="refactored"/>
imgaug.augmenters.size.KeepSizeByResize.get_shapes() to _get_shapes().<a name="fixed"/>
Resize always returning an uint8 array during image augmentation
if the input was a single numpy array and all augmented images had the
same shape. #442 #443Affine coordinate-based augmentation applying wrong offset
when shifting images to/from top-left corner. This would lead to an error
of around 0.5 to 1.0 pixels. #446PiecewiseAffine potentially being
unaligned if a KeypointsOnImage instance contained no keypoints. #446Note truncated.
One column per quarter.
This improvement leads to some breaking changes. To adapt to the new version, the following steps should be sufficient for most users:
The segmentation map augmentation was previously previously a wrapper around heatmap augmentation. This patch introduces independent methods for segmentation map augmentation. This makes the augmentation of such inputs faster and more memory efficient. The internal representation (int instead of floats) also becomes more intuitive.
This improvement leads to some breaking changes. To adapt to the new version, the following steps should be sufficient for most users:
SegmentationMapOnImage to SegmentationMapsOnImage
(Map -> Maps).SegmentationMapsOnImage.get_arr_int() to
SegmentationMapsOnImage.get_arr().nb_classes from all calls of SegmentationMapsOnImage.background_threshold from all
calls as it is no longer supported.draw_foreground_mask from all calls of
SegmentationMapsOnImage.draw_on_image() as it is no longer supported.SegmentationMapsOnImage is always an
int-like (int, uint or bool). Float arrays are now deprecated.SegmentationMapsOnImage.draw() and
SegmentationMapsOnImage.draw_on_image(), as both of these now return a
list of drawn images instead of a single array. (For a segmentation map
array of shape (H,W,C) they return C drawn images. In most cases C=1,
so simply call draw()[0] or draw_on_image()[0].)SegmentationMapsOnImage.arr is accessed anywhere, the
respective code can handle the new int32 (H,W,#maps) array form.
Previously, it was float32 and the channel-axis had the same size as the
max class id (+1) that could appear in the map.<augmenter>.augment() or <augmenter>() that
provide segmentation maps as numpy arrays (i.e. bypassing
SegmentationMapsOnImage) use the shape (N,H,W,#maps) as
(N,H,W) is no longer supported.numpy 1.17 introduces a new API for random number generation. This patch
adapts imgaug to automatically use the new API if it is available and
fall back to the old one otherwise. To achieve that, the module
imgaug.random is introduced, containing the new standard random number
generator imgaug.random.RNG. You can create a new RNG using a seed value
via RNG(seed) and it will take care of the rest. It supports all sampling
functions that numpy.random.RandomState and numpy.random.Generator
support. This new random number generator is now supposed to be used
wherever previously numpy.random.RandomState would have been used.
(For most users, this shouldn't change anything. Integer seeds are
still supported. If you used RandomState anywhere, that is also still
supported.)
Breaking changes related to this patch:
imgaug.random.seed() to set a custom seed.)imgaug.SEED_MIN_VALUE and imgaug.SEED_MAX_VALUE were
removed. They are now in imgaug.random.imgaug.CURRENT_RANDOM_STATE was removed.
Use imgaug.random.get_global_rng() instead.numpy 1.17 uses a new implementation of clip(), which turns int64 values
into float64 values. As a result, it is no longer safe to use int64 in
many augmenters and other functions/methods and hence these inputs are now
rejected. This affects at least ReplaceElementwise and thereby Dropout,
CoarseDropout, Salt, Pepper, SaltAndPepper, CoarseSalt,
CoarsePepper and CoarseSaltAndPepper. See the ReadTheDocs documentation
page about dtype support for more details.
In relation to this change, parameters in imgaug.parameters that previously
returned int64 were modified to now return int32 instead. Analogously,
float64 results were changed to float32.
The following new augmenters were added to the library:
Canny edge detection (#316):
imgaug.augmenters.edges.Canny. Performs canny edge detection and colorizes
the resulting binary image in random ways.Pooling (#317):
imgaug.augmenters.edges.AveragePooling. Performs average pooling using a
given kernel size. Very similar to AverageBlur.imgaug.augmenters.edges.MaxPooling. Performs maximum pooling using a
given kernel size.imgaug.augmenters.edges.MinPooling. Analogous.imgaug.augmenters.edges.MedianPooling. Analogous.Hue and Saturation (#210, #319):
imgaug.augmenters.color.WithHueAndSaturation. Apply child augmenters to
images in HSV colorspace. Automatically accounts for the hue being in
angular representation.imgaug.augmenters.color.AddToHue. Adds a defined value to the hue of each
pixel in input images.imgaug.augmenters.color.AddToSaturation. Adds a defined value to the
saturation of each pixel in input images.imgaug.augmenters.color.MultiplyHueAndSaturation. Multiplies the hue and/or
saturation of all pixels in input images.imgaug.augmenters.color.MultiplyHue. Analogous, affects always only the hue.imgaug.augmenters.color.MultiplySaturation. Analogous, affects always only
the saturation.Color Quantization (#347):
imgaug.augmenters.color.UniformColorQuantization. Uniformly splits all
possible colors into N different ones, then finds for each pixel in an
image among the N colors the most similar one and replaces that pixel's
color with the quantized color.imgaug.augmenters.color.KMeansColorQuantization. Groups all colors in an
each into N different ones using k-Means clustering. Then replaces each
pixel'S color, analogously to UniformColorQuantization.Voronoi (#348):
imgaug.augmenters.segmentation.Voronoi. Queries a point sampler to
generate a large number of (x,y) coordinates on an image. Each such
coordinate becomes a voronoi cell. All pixels within the voronoi cell
are replaced by their average color. (Similar to Superpixels, this
augmenter also supports to only replace p% of all cells with their
average color.)imgaug.augmenters.segmentation.UniformVoronoi. Shortcut to call Voronoi
with a uniform points sampler. That sampler places N points on an image
using uniform distributions (i.e. they are randomly spread over the image.)imgaug.augmenters.segmentation.RegularGridVoronoi. Shortcut to call
Voronoi with a regular grid points sampler. That points sampler generates
coordinate on a regular grid with H rows and W cols. Some of these points
can be randomly dropped to generate a less regular pattern.imgaug.augmenters.segmentation.RelativeRegularGridVoronoi. Same as
RegularGridVoronoi, but instead of using absolute numbers for H and W,
they are defined as relative amounts w.r.t. image shapes, leading to more
rows/cols on larger images.One of the long term goals of the library is to move as much augmentation
logic as possible out of Augmenter instances and into functions. This
patch therefore adds several new augmentation functions:
imgaug.min_pool(). #369imgaug.median_pool(). #369augmenters.segmentation.segment_voronoi(). #348augmenters.flip.fliplr(). #385augmenters.flip.flipud(). #385augmenters.color.change_colorspace_(). #409augmenters.color.change_colorspace_batch_(). #409augmenters.arithmetic.add_scalar(). #411augmenters.arithmetic.add_elementwise(). #411augmenters.arithmetic.replace_elementwise_(). #411augmenters.arithmetic.compress_jpg(). #411The color space naming within the library had become rather messy in the past as there were many colorspace-related augmenters, with some of them not using constants for colorspace names/IDs and others defining their own ones. This patch introduces a unified colorspace naming system for which the following constants were added:
imgaug.CSPACE_RGBimgaug.CSPACE_BGRimgaug.CSPACE_GRAYimgaug.CSPACE_CIEimgaug.CSPACE_YCrCbimgaug.CSPACE_HSVimgaug.CSPACE_HLSimgaug.CSPACE_Labimgaug.CSPACE_Luvimgaug.CSPACE_YUVimgaug.CSPACE_ALLAll colorspace-related augmenters should now support these constants.
Additionally, support for rarely used colorspaces -- mainly CIE, YCrCb,
Luv and YUV -- was previously unverified or non-existent. These colorspaces
are now tested for the underlying transformation functions and should be
supported by most colorspace-related augmenters. (Some augmenters may still
define their own subset of actually sensible colorspaces and only accept
these.)
The methods imap_batches() and imap_batches_unordered() of
imgaug.multicore.Pool have now the new argument output_buffer_size.
The argument set the maximum number of batches that may be handled anywhere
in the augmentation pipeline at a given time (i.e. in the steps "loaded and
waiting", "in augmentation" or "augmented and waiting"). It denotes the
total number of batches over all processes. Setting this argument to
an integer value avoids situations where Pool eats up all the available
memory due to the data loading and augmentation running faster than the
training.
Augmenter.augment_batches() now uses a default value of 10*C
for output_buffer_size, where C is the number of available logical CPU
cores.
The algorithms for Fliplr and Flipud were reworked to be as fast as
possible. In practice this should have no noticeable effects as both augmenters
were already very fast. (#385)
Furthermore, all assert statements within the library were changed from
do_assert() to standard assert statements. This is a bit less secure
(as assert statements can be optimized away), but should have a small
positive impact on the performance. (#387)
Large parts of the library were also refactored to reduce code duplication
and decrease the complexity of many functions. This should make future
improvements easier, but is expected to have a very small negative impact on
the performance due to an increased number of function calls.
It is also expected that numpy 1.17 can make some operations slower. This
is because (a) creating and copying random number generaters has become slower
and (b) clip() overall seems to be slower.
imgaug uses quite many assert statements and other checks on input data
to fail early instead of late. This is supposed to improve usability, but that
goal was not always reached as many errors had no associated error
messages. This patch changes that. Now, all assert statements and other
checks have an associated error message. This should protect users from having
to wade through the library's code in order to understand the root cause of
errors.
Some augmenters were previously defined as functions returning other
augmenters with appropriate settings. This could lead to confusing effects,
where seemingly instantiating an augmenters would lead to the instantiation
of a completely different augmenter. Hence, most of these augmenters were
switched from functions to classes. (The classes are now inheriting from the
previously returned augmenters, i.e. instanceof checks should still work.)
This affects: AdditiveGaussianNoise, AdditiveLaplaceNoise,
AdditivePoissonNoise, Dropout, CoarseDropout, ImpulseNoise,
SaltAndPepper, CoarseSaltAndPepper, Salt, CoarseSalt, Pepper,
CoarsePepper, SimplexNoiseAlpha, FrequencyNoiseAlpha, MotionBlur,
MultiplyHueAndSaturation, MultiplyHue, MultiplySaturation, AddToHue,
AddToSaturation, Grayscale, GammaContrast, SigmoidContrast,
LogContrast, LinearContrast, Sharpen, Emboss, EdgeDetect,
DirectedEdgeDetect, OneOf, AssertLambda, AssertShape, Pad, Crop,
Clouds, Fog and Snowflakes.
Not yet switched are: InColorspace (deprecated),
ContrastNormalization (deprecated), HorizontalFlip (pure alias
for Fliplr), VerticalFlip (pure alias for Flipud)
and Scale (deprecated).
Feeding images with height and/or width of 0 or a channel axis of size 0
into augmenters would previously often result in crashes. This was also the
case for input arrays with more than 512 channels. Some of these errors
also included segmentation faults or endlessly hanging programs. Most
augmenters and helper functions were modified to be more robust towards
such unusual inputs and will no longer crash.
It is still good practice to avoid such inputs. Note e.g. that some helper functions -- like drawing routines -- may still crash. The unittests corresponding to this change also only cover image data. Using other inputs, e.g. segmentation maps, might still induce problems.
The following (public) functions were added to the library (not listing functions that were already mentioned above):
imgaug.is_np_scalar(). #366dtypes.normalize_dtypes(). #366dtypes.normalize_dtype(). #366dtypes.change_dtypes_(). #366dtypes.change_dtype_(). #366dtypes.increase_itemsize_of_dtype(). #366imgaug.warn() function. #367imgaug.compute_paddings_to_reach_multiples_of(). #369imgaug.pad_to_multiples_of(). #369augmentables.utils.copy_augmentables. #410validation.convert_iterable_to_string_of_types(). #413validation.is_iterable_of(). #413validation.assert_is_iterable_of(). #413random.supports_new_rng_style(). #375random.get_global_rng(). #375random.seed(). #375random.normalize_generator(). #375random.normalize_generator_(). #375random.convert_seed_to_generator(). #375random.convert_seed_sequence_to_generator(). #375random.create_pseudo_random_generator_(). #375random.create_fully_random_generator(). #375random.generate_seed_(). #375random.generate_seeds_(). #375random.copy_generator(). #375random.copy_generator_unless_global_generator(). #375random.reset_generator_cache_(). #375random.derive_generator_(). #375random.derive_generators_(). #375random.get_generator_state(). #375random.set_generator_state_(). #375random.is_generator_equal_to(). #375random.advance_generator_(). #375random.polyfill_integers(). #375random.polyfill_random(). #375The following (public) classes were added (not listing classes that were already mentioned above):
augmenters.edges.IBinaryImageColorizer. #316augmenters.edges.RandomColorsBinaryImageColorizer. #316augmenters.segmentation.IPointsSampler. #348augmenters.segmentation.RegularGridPointsSampler. #348augmenters.segmentation.RelativeRegularGridPointsSampler. #348augmenters.segmentation.DropoutPointsSampler. #348augmenters.segmentation.UniformPointsSampler. #348augmenters.segmentation.SubsamplingPointsSampler. #348testutils.ArgCopyingMagicMock. #413The image colorization is used for Canny to turn binary images into color
images.
The points samplers are currently used within Voronoi.
Due to fast growth of the library in the past, a significant amount of messy code had accumulated. To fix that, a lot of time was spend to refactor the code throughout the whole library to reduce code duplication and improve the general quality. This also included a rewrite of many outdated docstrings. There is still quite some mess remaining, but the current state should make it somewhat easier to add future improvements.
As part of the refactorings, a few humongously large unittests were also split up into many smaller tests. The library has now around 3000 unique unittests (i.e. each unittest function is counted once, even it is called many times with different parameters).
Related PRs:
The following functions/classes/arguments are now deprecated:
imgaug.augmenters.meta.clip_augmented_image_.
Use imgaug.dtypes.clip_() or numpy.clip() instead. #398imgaug.augmenters.meta.clip_augmented_image.
Use imgaug.dtypes.clip_() or numpy.clip() instead. #398imgaug.augmenters.meta.clip_augmented_images_.
Use imgaug.dtypes.clip_() or numpy.clip() instead. #398imgaug.augmenters.meta.clip_augmented_images.
Use imgaug.dtypes.clip_() or numpy.clip() instead. #398imgaug.normalize_random_state.
Use imgaug.random.normalize_generator instead. #375imgaug.current_random_state.
Use imgaug.random.get_global_rng instead. #375imgaug.new_random_state.
Use class imgaug.random.RNG instead. #375imgaug.dummy_random_state.
Use imgaug.random.RNG(1) instead. #375imgaug.copy_random_state.
Use imgaug.random.copy_generator instead.imgaug.derive_random_state.
Use imgaug.random.derive_generator_ instead. #375imgaug.normalize_random_states.
Use imgaug.random.derive_generators_ instead. #375imgaug.forward_random_state.
Use imgaug.random.advance_generator_ instead. #375imgaug.augmenters.arithmetic.ContrastNormalization.
Use imgaug.augmenters.contrast.LinearContrast instead. #396X in imgaug.augmentables.kps.compute_geometric_median().
Use argument points instead. #402cval in imgaug.pool(), imgaug.avg_pool() and
imgaug.max_pool(). Use pad_cval instead. #369The following changes were made to the dependencies of the library:
scikit-image to
0.14.2. #377, #399opencv-python to opencv-python-headless.
This should improve support for some system without GUIs. #324pytest-subtests for the library's unittests. #366The library was added to conda-forge so that it can now be installed via
conda install imgaug. (The conda-forge channel must be added first,
see installation docs or README.) #320 #339
Polygon.clip_out_of_image(),
which would lead to exceptions if a polygon had overlap with an image,
but not a single one of its points was inside that image plane.multicore methods falsely not accepting
augmentables.batches.UnnormalizedBatch.Rot90 now uses subpixel-based coordinate remapping.
I.e. any coordinate (x, y) will be mapped to (H-y, x) for a rotation by
90deg.
Previously, an integer-based remapping to (H-y-1, x) was used.
Coordinates are e.g. used by keypoints, bounding boxes or polygons.augmenters.arithmetic.Invert
min_value and/or max_value arguments were
set, uint64 is no longer a valid input array dtype for Invert.
This is due to a conversion to float64 resulting in loss of resolution.Invert in rare cases restoring dtypes improperly.dtypes.gate_dtypes() crashing if the input was one or more numpy
scalars instead of numpy arrays or dtypes.augmenters.geometric.PerspectiveTransform producing invalid
polygons (more often with higher scale values). #338external/poly_point_isect_py2py3.py related to
floating point inaccuracies (changed an epsilon from 1e-10 to 1e-4,
rounded some floats). #338Superpixels breaking when a sampled n_segments was <=0.
n_segments is now treated as 1 in these cases.ReplaceElementwise both allowing and disallowing dtype int64. #346BoundingBox.deepcopy() creating only shallow copies of labels. #356dtypes.change_dtypes_() #366
round being ignored if input images were a list.dtypes.get_minimal_dtype() failing if argument arrays contained
not exactly two items. #366CloudLayer.get_parameters() resulting in errors. #309SimplexNoiseAlpha and FrequencyNoiseAlpha not handling
sigmoid argument correctly. #343SnowflakesLayer crashing for grayscale images. #345Affine heatmap augmentation crashing for arrays with more than
four channels and order!=0. #381Affine. #381Polygon.clip_out_of_image() crashing if the intersection between
polygon and image plane was an edge or point. #382Polygon.clip_out_of_image() potentially failing for polygons
containing two or fewer points. #382Polygon.is_out_of_image() returning wrong values if the image plane
was fully contained inside the polygon with no intersection between the
image plane and the polygon edge. #382Fliplr and Flipud using for coordinate-based inputs and image-like
inputs slightly different conditions for when to actually apply
augmentations. #385Convolve using an overly restrictive check when validating inputs
for matrix w.r.t. whether they are callables. The check should now also
support class methods (and possibly various other callables). #407CropAndPad, Pad and PadToFixedSize still clipping cval samples
to the uint8. They now clip to the input array's dtype's value range. #407WithColorspace not propagating polygons to child augmenters. #409WithHueAndSaturation not propagating segmentation maps and polygons
to child augmenters. #409AlphaElementwise to blend coordinates (for keypoints, polygons,
line strings) on a point-by-point basis following the image's average
alpha value in the sampled alpha mask of the point's coordinate.
Previously, the average over the whole mask was used and then either all
points of the first branch or all of the second branch were used as the
augmentation output. This also affects SimplexNoiseAlpha and
FrequencyNoiseAlpha. #4100 or the channels
were >512. See further above for more details. #433Rot90 not supporting imgaug.ALL. #434PiecewiseAffine possibly generating samples for non-image data
when using absolute_scale=True that were not well aligned with the
corresponding images. #437Marked support for non-Batch (and non-UnnormalizedBatch) inputs to augment_batches() as deprecated.
This update mainly covers the following topics:
For the Polygon and Line String augmentation, new classes and methods had to be added. The previous file for that was imgaug/imgaug.py, which however was already fairly large. Therefore, all classes and methods related to augmentable data were split off and moved to imgaug/augmentables/<type>.py. The new modules and their main contents are:
imgaug.augmentables.batches: Contains Batch, UnnormalizedBatch.imgaug.augmentables.utils: Contains utility functions.imgaug.augmentables.bbs: Contains BoundingBox, BoundingBoxesOnImage.imgaug.augmentables.kps: Contains Keypoint, KeypointsOnImage.imgaug.augmentables.polys: Contains Polygon, PolygonsOnImage.imgaug.augmentables.lines: Contains LineString, LineStringsOnImage.imgaug.augmentables.heatmaps: Contains HeatmapsOnImage.imgaug.augmentables.segmaps: Contains SegmentationMapOnImage.Currently, all augmentable classes can still be created via imgaug.<type>, e.g. imgaug.BoundingBox still works.
Changes related to the new modules:
Keypoint, KeypointsOnImage and imgaug.imgaug.compute_geometric_median to augmentables/kps.py.BoundingBox, BoundingBoxesOnImage to augmentables/bbs.py.Polygon, PolygonsOnImage and related classes/functions to augmentables/polys.py.HeatmapsOnImage to augmentables/heatmaps.py.SegmentationMapOnImage to augmentables/segmaps.py.Batch to augmentables/batches.py.imgaug.augmentables.utils.
normalize_shape().project_coords()._interpolate_points(), _interpolate_point_pair() and _interpolate_points_by_max_distance() to imgaug.augmentables.utils and made them public functions.__init__() of PolygonsOnImage, BoundingBoxesOnImage, KeypointsOnImage to make use of imgaug.augmentables.utils.normalize_shape().KeypointsOnImage.on() to use imgaug.augmentables.utils.normalize_shape().Keypoint.project() to use imgaug.augmentables.utils.project_coords().Polygons were already part of imgaug for quite a while, but couldn't be augmented yet. This version adds methods to perform such augmentations. It also makes some changes to the Polygon class, see the list of changes below.
Example for polygon augmentation:
import imgaug as ia
import imgaug.augmenters as iaa
from imgaug.augmentables.polys import Polygon, PolygonsOnImage
image = ia.quokka(size=0.2)
psoi = PolygonsOnImage([
Polygon([(0, 0), (20, 0), (20, 20)])
], shape=image.shape)
image_aug, psoi_aug = iaa.Affine(rotate=45).augment(
images=[image],
polygons=[psoi]
)
See imgaug-doc/notebooks for a jupyter notebook with many more examples.
Changes related to polygon augmentation:
_ConcavePolygonRecoverer to imgaug.augmentables.polys.PolygonsOnImage to imgaug.augmentables.polys.augment_polygons() to Augmenter._augment_polygons() to Augmenter._augment_polygons_as_keypoints() to Augmenter.polygons to imgaug.augmentables.batches.Batch.polygons_aug and polygons_unaug to imgaug.augmentables.batches.Batch.Augmenter.augment_batches().Polygon.height.Polygon.width.Polygon.to_keypoints().Polygon.draw_on_image() and PolygonsOnImage.draw_on_image().raise_if_too_far_away=True to Polygon.change_first_point_by_coords().imgaug.quokka_polygons() function to generate example polygon data.Polygon.draw_on_image(), PolygonsOnImage.draw_on_image()
LineString methods.size and size_perimeter to control polygon line thickness.alpha_perimeter to alpha_line, color_perimeter to color_line to align with LineStrings.alpha_fill to alpha_face and color_fill to color_face.Polygon.clip_out_of_image() from MultiPolygon to list of Polygon.
This breaks for anybody who has already used Polygon.clip_out_of_image().Polygon.exterior_almost_equals() to accept lists of tuples as argument other_polygon.color and alpha in Polygon.draw_on_image() and PolygonsOnImage.draw_on_image() to represent
the general color and alpha of the polygon. The colors/alphas of the inner area, perimeter and points are derived from
color and alpha (unless color_inner, color_perimeter or color_points are set (analogous for alpha)).Polygon.project() to use LineString.project().Polygon.shift() to use LineString.shift().Polygon.exterior_almost_equals(), Polygon.almost_equals()
LineString.coords_almost_equals().interpolate to points_per_edge.other_polygon to other.color_line to color_lines, alpha_line to alpha_lines in Polygon.draw_on_image() and PolygonsOnImage.draw_on_image().Polygon.clip_out_of_image(image) not handling image being a tuple.Polygon.is_out_of_image() falsely only checking the corner points of the polygon.This version adds Line String augmentation. Line Strings are simply lines made up of consecutive corner points that are connected by straight lines. Line strings have similarity with polygons, but do not have a filled inner area and are not closed (i.e. first and last coordinate differ).
Similar to other augmentables, line string are represented with the classes LineString(<iterable of xy-coords>) and LineStringsOnImage(<iterable of LineString>, <shape of image>). They are augmented e.g. via Augmenter.augment_line_strings(<iterable of LineStringsOnImage>) or Augmenter.augment(images=..., line_strings=...).
Example:
import imgaug as ia
import imgaug.augmenters as iaa
from imgaug.augmentables.lines import LineString, LineStringsOnImage
image = ia.quokka(size=0.2)
lsoi = LineStringsOnImage([
LineString([(0, 0), (20, 0), (20, 20)])
], shape=image.shape)
image_aug, lsoi_aug = iaa.Affine(rotate=45).augment(
images=[image],
line_strings=[lsoi]
)
See imgaug-doc/notebooks for a jupyter notebook with many more examples.
Augmentation of different data corresponding to the same image(s) has been a bit convoluted in the past, as each data type had to be augmented on its own. E.g. to augment an image and its bounding boxes, one had to first switch the augmenters to deterministic mode, then augment the images, then the bounding boxes. This version adds methods that perform these steps in one call. Specifically, Augmenter.augment(...) is used for that, which has the alias Augmenter.__call__(...). One argument can be used for each augmentable, e.g. bounding_boxes=<bounding box data>.
Example:
import imgaug as ia
import imgaug.augmenters as iaa
from imgaug.augmentables.kps import Keypoint, KeypointsOnImage
image = ia.quokka(size=0.2)
kpsoi = KeypointsOnImage([Keypoint(x=0, y=10), Keypoint(x=10, y=5)],
shape=image.shape)
image_aug, kpsoi_aug = iaa.Affine(rotate=(-45, 45)).augment(
image=image,
keypoints=kpsoi
)
This will automatically make sure that image and keypoints are rotated by corresponding amounts.
Normalization methods have been added to that class, which allow it to process many more different inputs than just variations of *OnImage.
Example:
import imgaug as ia
import imgaug.augmenters as iaa
image = ia.quokka(size=0.2)
kps = [(0, 10), (10, 5)]
image_aug, kps_aug = iaa.Affine(rotate=(-45, 45)).augment(
image=image, keypoints=kps)
Examples for other inputs that are automatically handled by augment():
list([N,4] ndarray) for bounding boxes. (One list for images,
then N bounding boxes in (x1,y1,x2,y2) form.)list(list(list(tuple))) for line strings. (One list for images,
one list for line strings on the image, one list for coordinates within
the line string. Each tuple must contain two values for xy-coordinates.)list(list(imgaug.augmentables.polys.Polygon)) for polygons.
Note that this "skips" imgaug.augmentables.polys.PolygonsOnImage.In python <3.6, augment() is limited to a maximum of two inputs/outputs and if two inputs/outputs are used, then one of them must be image data and such (augmented) image data will always be returned first,
independent of the argument's order. E.g. augment(line_strings=<data>, polygons=<data>) would be invalid due to not containing image data. augment(polygons=<data>, images=<data>) would still return the images first, even though they are the second argument.
In python >=3.6, augment() may be called with more than two arguments and will respect their order.
Example:
import numpy as np
import imgaug as ia
import imgaug.augmenters as iaa
image = ia.quokka(size=0.2)
kps = [(0, 10), (10, 5)]
heatmap = np.zeros((image.shape[0], image.shape[1]), dtype=np.float32)
rotate = iaa.Affine(rotate=(-45, 45))
heatmaps_aug, images_aug, kps_aug = rotate(
heatmaps=[heatmap],
images=[image],
keypoints=[kps]
)
To use more than two inputs/outputs in python <3.6, add the argument return_batch=True, which will return an instance of imgaug.augmentables.batches.UnnormalizedBatch.
Changes related to the augmentation interface:
Augmenter.augment() method.Augmenter.augment_batch() method.
Augmenter.augment_batches() and multicore routines.imgaug.augmentables.batches.UnnormalizedBatch.imgaug.augmentables.normalization for data normalization routines.augment_batches():
UnnormalizedBatch as input. It is automatically normalized before augmentation and unnormalized afterwards.
This allows to use Batch instances with non-standard datatypes.Batch (and UnnormalizedBatch).Batch (and non-UnnormalizedBatch) inputs to augment_batches() as deprecated.Batch.deepcopy()
batch.deepcopy(images_aug=...).Keypoint augmentation
Keypoint.draw_on_image().alpha argument to KeypointsOnImage.draw_on_image(). This can break code that relied on the order of arguments of the method (though will usually only have visual consequences).KeypointsOnImage and Keypoint copying:
keypoints and shape to KeypointsOnImage.deepcopy().keypoints and shape to KeypointsOnImage.copy().Keypoint.copy().Keypoint.deepcopy().
Keypoint to use deepcopy() to create copies of itself (instead of instantiating new instances via Keypoint(...)).KeypointsOnImage.deepcopy() now uses Keypoint.deepcopy() to create Keypoint copies, making it more flexible.KeypointsOnImage to use KeypointsOnImage.deepcopy() in as many methods as possible to create copies of itself.Affine, AffineCv2, PiecewiseAffine, PerspectiveTransform, ElasticTransformation, Rot90 to use KeypointsOnImage.deepcopy() and Keypoint.deepcopy() during keypoint augmentation.Keypoint.draw_on_image() to draw a rectangle for the keypoint so long as any part of that rectangle is within the image plane. (Previously, the rectangle was only drawn if the integer xy-coordinate of the point was inside the image plane.)KeypointsOnImage.draw_on_image() to raise an error if an input image has shape (H,W).KeypointsOnImage.draw_on_image() to handle single-number inputs for color.KeypointsOnImage.from_coords_array()
from_xy_array().coords to xy.staticmethod to classmethod.KeypointsOnImage.get_coords_array()
to_xy_array().KeypointsOnImage.draw_on_image() to use Keypoint.draw_on_image().Heatmap augmentation
Affine, PiecewiseAffine, ElasticTransformation to always use order=3 for heatmap augmentation.HeatmapsOnImage that validates whether the input array is within the desired value range [min_value, max_value] from a hard exception to a soft warning (with clipping). Also improved the error message a bit.Deprecation warnings:
imgaug.imgaug.DeprecationWarning. The builtin python DeprecationWarning is silent since 2.7, which is why now a separate deprecation warning is used.imgaug.imgaug.warn_deprecated().
imgaug.imgaug.deprecated decorator.
Bounding Boxes:
BoundingBox.extract_from_image() the arguments pad and pad_max.BoundingBox.contains() to also accept Keypoint.BoundingBox.project(from, to) to also accept images instead of shapes.thickness in BoundingBox.draw_on_image() to size in order to match the name used for keypoints, polygons and line strings. The argument thickness will still be accepted, but raises a deprecation warning.thickness in BoundingBoxesOnImage.draw_on_image() to size in order to match the name used for keypoints, polygons and line strings. The argument thickness will still be accepted, but raises a deprecation warning.BoundingBox to reduce code repetition.BoundingBox.extract_from_image(). Improved some code fragments that looked wrong.BoundingBoxesOnImage.draw_on_image() to improve efficiency by evading unnecessary array copies.Other:
cval and mode to PerspectiveTransform (PR #301). This breaks code that relied on the order of the arguments and used keep_size, name, deterministic or random_state as positional arguments.dtypes.clip_() function.imgaug.imgaug.flatten() that flattens nested lists/tuples.PerspectiveTransform to ensure minimum height and width of output images (by default 2x2). This prevents errors in polygon augmentation (possibly also in keypoint augmentation).imgaug.augmenters.blend.blend_alpha() to no longer enforce a channel axis for foreground and background image.imgaug/parameters.py to reorder classes within the file.requirements.txt.blend.blend_alpha() if dtype numpy.float128 does not exist.ChangeColorspace when cv2.COLOR_Lab2RGB was actually called cv2.COLOR_LAB2RGB in the local OpenCV installation (analogous for BGR). (PR #263)ReplaceElementwise always sampling replacement per channel.draw_text() due to arrays that could not be set to writeable after drawing the text via PIL.parameters.Subtract.angle_between_vectors().KeypointsOnImage instances
Rot90 not changing KeypointsOnImage.shape if .keypoints was empty.Affine not changing KeypointsOnImage.shape if .keypoints was empty.PerspectiveTransform not changing KeypointsOnImage.shape if .keypoints was empty.Resize not changing KeypointsOnImage.shape if .keypoints was empty.CropAndPad not changing KeypointsOnImage.shape if .keypoints was empty. (Same for Crop, Pad.)PadToFixedSize not changing KeypointsOnImage.shape if .keypoints was empty.CropToFixedSize not changing KeypointsOnImage.shape if .keypoints was empty.KeepSizeByResize not changing KeypointsOnImage.shape if .keypoints was empty.Affine heatmap augmentation producing arrays with values outside the range [0.0, 1.0] when order was set to 3.PiecewiseAffine heatmap augmentation producing arrays with values outside the range [0.0, 1.0] when order was set to 3.SegmentationMapOnImage falsely checking if max class index is <= nb_classes instead of < nb_classes.dtypes.clip_to_value_range_() and dtypes.restore_dtypes_() causing errors when clip value range exceeded array dtype's value range.dtypes.clip_to_value_range_() and dtypes.restore_dtypes_() when the input array was scalar, i.e. had shape ().JpegCompression on windows (possibly also affected other systems). #297Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →