Recent Releases of imgaug

imgaug - 0.4.0

Table of Contents

  1. Overview
  2. Example Images
  3. Mixed-Category Patches
  4. Added
  5. Changed
  6. Refactored
  7. Fixed

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. * New Brightness augmenters: WithBrightnessChannels, MultiplyAndAddToBrightness, MultiplyBrightness, AddToBrightness. * New Dropout augmenters: 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 boxes * More blend augmenters: * BlendAlphaMask: 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. * Shortcuts for Affine: ScaleX, ScaleY, TranslateX, TranslateY, Rotate, ShearX, ShearY. * Several new crop and pad augmenters: CenterCropToFixedSize, CenterPadToFixedSize, CropToMultiplesOf, CenterCropToMultiplesOf, PadToMultiplesOf, CenterPadToMultiplesOf, CropToPowersOf, CenterCropToPowersOf, PadToPowersOf, CenterPadToPowersOf, CropToAspectRatio, CenterCropToAspectRatio, PadToAspectRatio, CenterPadToAspectRatio, PadToSquare, CenterPadToSquare, CropToSquare, CenterCropToSquare. * Wrappers around 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>. * Wrappers around 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: * Bounding boxes and line strings have now native augmentation methods. Previously, they were converted to keypoints at the start of the augmentation, which meant that child augmenters were unable to use augmentation routines geared towards these two input types as they would merely see a bunch of keypoints. * Augmentation happens now batchwise. Previously it was done input type-wise. This change should improve performance for batches with different types of inputs by re-using computation results for multiple inputs. It also makes the library more flexible. * Improved the default parameters of augmenters. Most of them will now produce medium-strength augmentations when instantiated without and parameters. E.g. 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%). * Reworked the standard parameters shared by all augmenters. random_state was renamed to seed, e.g. Affine(..., seed=1) is now valid. The parameter deterministic is now deprecated. * Many methods were added to augmentables, e.g. BoundingBoxesOnImage now supports index-based access (bbs[0] instead of bbs.bounding_boxes[0]). * The bounding box drawing methods now also draw each BB's label. * All augmenters are now tested to be pickle-able without errors. * The library is now compatible with numpy 1.18 and python 3.8. * This release fixes two significant bugs in 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.

Example Images

Brightness

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).

Cartoon

A new cartoon style filter is introduced, shown below. Each row starts with the input image.

ChangeColorTemperature

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.

Cutout

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.

Dropout2d and TotalDropout

Two new dropout augmenters, Dropout2d and TotalDropout, are added. The example below shows Dropout2d. First image is the input.

Jigsaw

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.

MeanShiftBlur

A mean shift-based blur augmenter is added. First image below shows the input, followed by MeanShiftBlur(5.0) to MeanShiftBlur(40.0).

Posterize

The example below shows Posterize (aka UniformQuantizationToNBits) with n_bits=8 to n_bits=1. First image is the input.

Solarize

The example below shows Solarize, which is the same as Invert with a threshold. First image is the input.

Rain

The example below shows the new Rain augmenter. First image is the input.

RandAugment

This release adds an implementation of RandAugment the following example shows RandAugment(n=2, m=20). First image is the input.

WithPolarWarping

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.

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.)

imagecorruptions wrappers

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.

PIL wrappers

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.

More Blending Augmenters

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:

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.

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.

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).

This example shows BlendAlphaSomeColors(RemoveSaturation(1.0)), applied to a more colorful image:

This release also adds BlendAlphaBoundingBoxes, BlendAlphaHorizontalLinearGradient and BlendAlphaVerticalLinearGradient. These are not visualized here.

SaveDebugImageEveryNBatches

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.

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.

Mixed-Category Patches

Reworked Augmentation Methods #451 #566

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: ```python 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:

augdet = aug.todeterministic() imagesaug = augdet.augmentimages(images) bbsoisaug = augdet.augmentbounding_boxes(bbsois)

Now recommended:

imagesaug, bbsaug = 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().
    • Added method to_xy_array() to:
    • augmentables.bbs.BoundingBoxesOnImage.
    • augmentables.polys.PolygonsOnImage.
    • augmentables.lines.LineStringsOnImage.
    • Added methods 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:

    • Changed the following methods to be thin wrappers around 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().
    • Changed 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.
    • Changed augment_images() to no longer be abstract. It defaults to not changing the input images.
    • Changed imgaug.augmentables.BoundingBoxesOnImage.from_xyxy_array() to also accept (N, 2, 2) arrays instead of only (N, 4).

Deprecated: * Deprecated imgaug.augmenters.meta.Augmenter.augment_batch(). Use .augment_batch_() instead.

Refactored: * Refactored most augmenters to use single _augment_batch_() method.

Other changes: * Added validation of input arguments to KeypointsOnImage.from_xy_array(). * Improved validation of input arguments to BoundingBoxesOnImage.from_xyxy_array().

Reworked Quantization #467

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:

    • Added to_bin_centers=True to quantize_uniform(), controling whether each bin (a, b) should be quantized to a + (b-a)/2 or a.
  • Deprecated:

    • Renamed imgaug.augmenters.color.quantize_colors_uniform(image, n_colors) to imgaug.augmenters.color.quantize_uniform(arr, nb_bins). The old name is now deprecated.
    • Renamed 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:

    • Improved performance of quantize_uniform() by roughly 10x (small images around 64x64) to 100x (large images around 1024x1024). This also affects UniformColorQuantization.
    • Improved performance of UniformColorQuantization by using more in-place functions.
  • Fixed:

    • Fixed quantize_uniform() producing wrong outputs for non-contiguous arrays.

Improved Invert #469

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.

  • Added augmenter imgaug.augmenters.Solarize, a wrapper around Invert.
  • Added function imgaug.augmenters.arithmetic.solarize(), a wrapper around solarize_().
  • Added function imgaug.augmenters.arithmetic.solarize_(), a wrapper around invert_().
  • Added function imgaug.augmenters.arithmetic.invert_(), an in-place version of imgaug.augmenters.arithmetic.invert().
  • Added parameters threshold and invert_above_threshold to imgaug.augmenters.arithmetic.invert()
  • Added parameters threshold and invert_above_threshold to imgaug.augmenters.arithmetic.Invert.
  • Improved performance of imgaug.augmenters.arithmetic.invert() and imgaug.augmenters.arithmetic.Invert for uint8 images.

All Augmenters are now Pickle-able #493 #575

Ensured that all augmenters can be pickled and un-pickled without errors.

  • Added function imgaug.testutils.runtest_pickleable_uint8_img().
  • Fixed imgaug.augmenters.blur.MotionBlur not being pickle-able.
  • Fixed imgaug.augmenters.meta.AssertLambda not being pickle-able.
  • Fixed imgaug.augmenters.meta.AssertShape not being pickle-able.
  • Fixed imgaug.augmenters.color.MultiplyHueAndSaturation not supporting all standard RNG datatypes for random_state.

Extended Cropping and Padding Augmenters #459

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. * Moved imgaug.imgaug.pad to imgaug.augmenters.size.pad * Moved imgaug.imgaug.pad_to_aspect_ratio to imgaug.augmenters.size.pad_to_aspect_ratio. * Moved imgaug.imgaug.pad_to_multiples_of to imgaug.augmenters.size.pad_to_multiples_of. * Moved imgaug.imgaug.compute_paddings_for_aspect_ratio to imgaug.augmenters.size.compute_paddings_to_reach_aspect_ratio. * Moved imgaug.imgaug.compute_paddings_to_reach_multiples_of to imgaug.augmenters.size.compute_paddings_to_reach_multiples_of.

The following augmenters were added: * Added augmenter CenterCropToFixedSize. * Added augmenter CenterPadToFixedSize. * Added augmenter CropToMultiplesOf. * Added augmenter CenterCropToMultiplesOf. * Added augmenter PadToMultiplesOf. * Added augmenter CenterPadToMultiplesOf. * Added augmenter CropToPowersOf. * Added augmenter CenterCropToPowersOf. * Added augmenter PadToPowersOf. * Added augmenter CenterPadToPowersOf. * Added augmenter CropToAspectRatio. * Added augmenter CenterCropToAspectRatio. * Added augmenter PadToAspectRatio. * Added augmenter CenterPadToAspectRatio. * Added augmenter PadToSquare. * Added augmenter CenterPadToSquare. * Added augmenter CropToSquare. * Added augmenter CenterCropToSquare.

All Center<name> augmenters are wrappers around <name> with parameter position="center".

Added functions: * Added function imgaug.augmenters.size.compute_croppings_to_reach_aspect_ratio(). * Added function imgaug.augmenters.size.compute_croppings_to_reach_multiples_of(). * Added function imgaug.augmenters.size.compute_croppings_to_reach_powers_of(). * Added function imgaug.augmenters.size.compute_paddings_to_reach_powers_of().

Other changes: * Extended augmenter CropToFixedSize to support height and/or width parameters to be None, in which case the respective axis is not changed. * Extended augmenter PadToFixedSize to support height and/or width parameters to be None, in which case the respective axis is not changed. * [rarely breaking] Changed CropToFixedSize.get_parameters() to also return the height and width values. * [rarely breaking] Changed PadToFixedSize.get_parameters() to also return the height and width values. * [rarely breaking] Changed the order of parameters returned by PadToFixedSize.get_parameters() to match the order in PadToFixedSize.__init__() * Changed 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. * Changed the projection of pad/crop values between images and non-images to make the behaviour slightly more accurate in fringe cases. * Improved behaviour of function imgaug.augmenters.size.compute_paddings_for_aspect_ratio() for zero-sized axes. * Changed function imgaug.augmenters.size.compute_paddings_for_aspect_ratio() to also support shape tuples instead of only ndarrays. * Changed function imgaug.augmenters.size.compute_paddings_to_reach_multiples_of() to also support shape tuples instead of only ndarrays.

Fixes: * Fixed a formatting error in an error message of compute_paddings_to_reach_multiples_of().

More Choices for Image Blending #462 #556

The available augmenters for alpha-blending of images were significantly extended. There are now new blending augmenters available to alpha-blend acoording to: * Some randomly chosen colors. (BlendAlphaSomeColors) * Linear gradients. (BlendAlphaHorizontalLinearGradient, BlendAlphaVerticalLinearGradient) * Regular grids and checkerboard patterns. (BlendAlphaRegularGrid, BlendAlphaCheckerboard) * Only at locations that overlap with specific segmentation class IDs (or the inverse of that). (BlendAlphaSegMapClassIds) * Only within bounding boxes with specific labels (or the inverse of that). (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 -> BlendAlpha * AlphaElementwise -> BlendAlphaElementwise * SimplexNoiseAlpha -> BlendAlphaSimplexNoise * FrequencyNoiseAlpha -> 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: * Added imgaug.augmenters.blend.BlendAlphaMask, which uses a mask generator instance to generate per batch alpha masks and then alpha-blends using these masks. * Added imgaug.augmenters.blend.BlendAlphaSomeColors. * Added imgaug.augmenters.blend.BlendAlphaHorizontalLinearGradient. * Added imgaug.augmenters.blend.BlendAlphaVerticalLinearGradient. * Added imgaug.augmenters.blend.BlendAlphaRegularGrid. * Added imgaug.augmenters.blend.BlendAlphaCheckerboard. * Added imgaug.augmenters.blend.BlendAlphaSegMapClassIds. * Added imgaug.augmenters.blend.BlendAlphaBoundingBoxes. * Added imgaug.augmenters.blend.IBatchwiseMaskGenerator, an interface for classes generating masks on a batch-by-batch basis. * Added imgaug.augmenters.blend.StochasticParameterMaskGen, a helper to generate masks from StochasticParameter instances. * Added imgaug.augmenters.blend.SomeColorsMaskGen, a generator that produces masks marking randomly chosen colors in images. * Added imgaug.augmenters.blend.HorizontalLinearGradientMaskGen, a linear gradient mask generator. * Added imgaug.augmenters.blend.VerticalLinearGradientMaskGen, a linear gradient mask generator. * Added imgaug.augmenters.blend.RegularGridMaskGen, a checkerboard-like mask generator where every grid cell has a random alpha value. * Added imgaug.augmenters.blend.CheckerboardMaskGen, a checkerboard-like mask generator where every grid cell has the opposite alpha value of its 4-neighbours. * Added imgaug.augmenters.blend.SegMapClassIdsMaskGen, a segmentation map-based mask generator. * Added imgaug.augmenters.blend.BoundingBoxesMaskGen, a bounding box-based mask generator. * Added imgaug.augmenters.blend.InvertMaskGen, an mask generator that inverts masks produces by child generators. * Changed imgaug.parameters.SimplexNoise and imgaug.parameters.FrequencyNoise to also accept (H, W, C) sampling shapes, instead of only (H, W). * Refactored AlphaElementwise to be a wrapper around BlendAlphaMask. * Renamed Alpha to BlendAlpha. Alpha is now deprecated. * Renamed AlphaElementwise to BlendAlphaElementwise. AlphaElementwise is now deprecated. * Renamed SimplexNoiseAlpha to BlendAlphaSimplexNoise. SimplexNoiseAlpha is now deprecated. * Renamed FrequencyNoiseAlpha to BlendAlphaFrequencyNoise. FrequencyNoiseAlpha is now deprecated. * Renamed arguments first and second to foreground and background in BlendAlpha, BlendAlphaElementwise, BlendAlphaSimplexNoise and BlendAlphaFrequencyNoise. * Changed imgaug.parameters.handle_categorical_string_param() to allow parameter valid_values to be None. * Fixed a wrong error message in imgaug.augmenters.color.change_colorspace_().

Added

Unwrapped Bounding Box Augmentation #446

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.

  • Added property coords to BoundingBox. The property returns an (N,2) numpy array containing the coordinates of the top-left and bottom-right bounding box corners.
  • Added method BoundingBox.coords_almost_equals(other).
  • Added method BoundingBox.almost_equals(other).
  • Changed method Polygon.almost_equals(other) to no longer verify the datatype. It is assumed now that the input is a Polygon.
  • Added property items to KeypointsOnImage, BoundingBoxesOnImage, PolygonsOnImage, LineStringsOnImage. The property returns the keypoints/BBs/polygons/LineStrings contained by that instance.
  • Added method Polygon.coords_almost_equals(other). Alias for Polygon.exterior_almost_equals(other).
  • Added property Polygon.coords. Alias for Polygon.exterior.
  • Added property Keypoint.coords.
  • Added method Keypoint.coords_almost_equals(other).
  • Added method Keypoint.almost_equals(other).
  • Added method imgaug.testutils.assert_cbaois_equal().
  • Added method imgaug.testutils.shift_cbaoi().
  • Added internal _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.
  • [breaking] Added parameter parents to Augmenter.augment_bounding_boxes(). This breaks if hooks was used as a positional argument in connection with that method.
  • [rarely breaking] Added parameter func_bounding_boxes to Lambda. This breaks if one relied on the order of the augmenter's parameters instead of their names.
  • [rarely breaking] Added parameter func_bounding_boxes to AssertLambda. This breaks if one relied on the order of the augmenter's parameters instead of their names.
  • [rarely breaking] Added parameter check_bounding_boxes to AssertShape. This breaks if one relied on the order of the augmenter's parameters instead of their names.

Unwrapped Line String Augmentation #450

This patch is the same as the bounding box unwrapping above, only applied to line strings.

  • Added internal _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.
  • [rarely breaking] Added parameter func_line_strings to Lambda. This breaks if one relied on the order of the augmenter's parameters instead of their names.
  • [rarely breaking] Added parameter func_line_strings to AssertLambda. This breaks if one relied on the order of the augmenter's parameters instead of their names.
  • [rarely breaking] Added parameter check_line_strings to AssertShape. This breaks if one relied on the order of the augmenter's parameters instead of their names.

Added fit_output to PerspectiveTransform #452 #456

This patch added fit_output to PerspectiveTransform.

  • [rarely breaking] PerspectiveTransform has now a fit_output parameter, similar to Affine. This change may break code that relied on the order of arguments to __init__.
  • The sampling code of PerspectiveTransform was reworked and should now be faster.

Added ChangeColorTemperature Augmenter #454

This patch added an augmenter and corresponding function to change the color temperature of images. This adds e.g. red, orange or blue tints.

  • Added augmenter imgaug.augmenters.color.ChangeColorTemperature.
  • Added function imgaug.augmenters.color.change_color_temperatures_().
  • Added function imgaug.augmenters.color.change_color_temperature_().

Added Brightness Augmenters #455

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.

  • Added augmenter imgaug.augmenters.color.WithBrightnessChannels.
  • Added augmenter imgaug.augmenters.color.MultiplyAndAddToBrightness.
  • Added augmenter imgaug.augmenters.color.MultiplyBrightness.
  • Added augmenter imgaug.augmenters.color.AddToBrightness.
  • Added method imgaug.parameters.handle_categorical_string_param().
  • Changed change_colorspaces_() to accept any iterable of str for argument to_colorspaces, not just list.

Added More Dropout Augmenters #458

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.)

  • Added a new augmenter 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).
  • Added new augmenter 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.

Added RemoveSaturation #462

  • Added RemoveSaturation, a shortcut for MultiplySaturation((0.0, 1.0)) with outputs similar to Grayscale((0.0, 1.0)).

Added Cartoon Augmenter #463

This 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.

  • Added module imgaug.augmenters.artistic.
  • Added function imgaug.augmenters.artistic.stylize_cartoon(image).
  • Added augmenter imgaug.augmenters.artistic.Cartoon.

Added MeanShiftBlur Augmenter #466

This patch added a mean shift-based blur filter. Note that it is very slow when using the default parameters (high radius).

  • Added function imgaug.augmenters.blur.blur_mean_shift_(image).
  • Added augmenter imgaug.augmenters.blur.MeanShiftBlur.

Added DeterministicList Parameter #475

Added 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.

Added Jigsaw Augmenter #476 #577

This 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.

  • Added function imgaug.augmenters.geometric.apply_jigsaw().
  • Added function imgaug.augmenters.geometric.apply_jigsaw_to_coords().
  • Added function imgaug.augmenters.geometric.generate_jigsaw_destinations().

Added Wrappers around Package PIL #479 #480 #538

This 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.

  • Added module 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.
  • Added the following functions to the module:
    • imgaug.augmenters.pillike.equalize
    • imgaug.augmenters.pillike.equalize_
    • imgaug.augmenters.pillike.autocontrast
    • imgaug.augmenters.pillike.autocontrast_
    • imgaug.augmenters.pillike.solarize
    • imgaug.augmenters.pillike.solarize_
    • imgaug.augmenters.pillike.posterize
    • imgaug.augmenters.pillike.posterize_
    • imgaug.augmenters.pillike.enhance_color
    • imgaug.augmenters.pillike.enhance_contrast
    • imgaug.augmenters.pillike.enhance_brightness
    • imgaug.augmenters.pillike.enhance_sharpness
    • imgaug.augmenters.pillike.filter_blur
    • imgaug.augmenters.pillike.filter_smooth
    • imgaug.augmenters.pillike.filter_smooth_more
    • imgaug.augmenters.pillike.filter_edge_enhance
    • imgaug.augmenters.pillike.filter_edge_enhance_more
    • imgaug.augmenters.pillike.filter_find_edges
    • imgaug.augmenters.pillike.filter_contour
    • imgaug.augmenters.pillike.filter_emboss
    • imgaug.augmenters.pillike.filter_sharpen
    • imgaug.augmenters.pillike.filter_detail
    • imgaug.augmenters.pillike.warp_affine
  • Added the following augmenters to the module:
    • imgaug.augmenters.pillike.Solarize
    • imgaug.augmenters.pillike.Posterize. (Currently alias for imgaug.augmenters.color.Posterize.)
    • imgaug.augmenters.pillike.Equalize
    • imgaug.augmenters.pillike.Autocontrast
    • imgaug.augmenters.pillike.EnhanceColor
    • imgaug.augmenters.pillike.EnhanceContrast
    • imgaug.augmenters.pillike.EnhanceBrightness
    • imgaug.augmenters.pillike.EnhanceSharpness
    • imgaug.augmenters.pillike.FilterBlur
    • imgaug.augmenters.pillike.FilterSmooth
    • imgaug.augmenters.pillike.FilterSmoothMore
    • imgaug.augmenters.pillike.FilterEdgeEnhance
    • imgaug.augmenters.pillike.FilterEdgeEnhanceMore
    • imgaug.augmenters.pillike.FilterFindEdges
    • imgaug.augmenters.pillike.FilterContour
    • imgaug.augmenters.pillike.FilterEmboss
    • imgaug.augmenters.pillike.FilterSharpen
    • imgaug.augmenters.pillike.FilterDetail
    • imgaug.augmenters.pillike.Affine

Added Identity #481

This patch added an identity function augmenter (Identity), which is the same as Noop and will replace the latter one in the long run.

  • [rarely breaking] Added 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.
  • Renamed parameter noop_if_topmost to identity_if_topmost in method imgaug.augmenters.meta.Augmenter.remove_augmenters(). The old name is now deprecated.

Added Shearing on the Y-Axis to Affine #482

Affine 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.

  • [rarely breaking] Extended 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.

Added Wrappers around Affine #484

This patch added a few convenience wrappers around Affine.

  • Added imgaug.augmenters.geometric.ScaleX.
  • Added imgaug.augmenters.geometric.ScaleY.
  • Added imgaug.augmenters.geometric.TranslateX.
  • Added imgaug.augmenters.geometric.TranslateY.
  • Added imgaug.augmenters.geometric.Rotate.
  • Added imgaug.augmenters.geometric.ShearX.
  • Added imgaug.augmenters.geometric.ShearY.

Added More Methods to Remove Out-of-Image Augmentables #487

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).

Added Bounding Box to Polygon Conversion #489

  • Added method imgaug.augmentables.bbs.BoundingBox.to_polygon().
  • Added method imgaug.augmentables.bbs.BoundingBoxesOnImage.to_polygons_on_image().

Added Polygon Subdivision #489

  • Added method 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.
  • Added method imgaug.augmentables.polys.PolygonsOnImage.subdivide(N).

Added WithPolarWarping Augmenter #489

This 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.

  • Added augmenter imgaug.augmenters.geometric.WithPolarWarping, an augmenter that applies child augmenters in a polar representation of the image.

Added Convenient Access Methods to Coordinate-Based Augmentables #495 #541

This patch added various magic functions to coordinate-based augmentables that make their usage more convenient. Example: ```python 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) ```

  • Added module imgaug.augmentables.base.
  • Added interface imgaug.augmentables.base.IAugmentable, implemented by HeatmapsOnImage, SegmentationMapsOnImage, KeypointsOnImage, BoundingBoxesOnImage, PolygonsOnImage and LineStringsOnImage.
  • Added ability to iterate over coordinate-based *OnImage instances (keypoints, bounding boxes, polygons, line strings), e.g. bbsoi = BoundingBoxesOnImage(bbs, shape=...); for bb in bbsoi: .... would iterate now over bbs.
  • Added implementations of __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.
  • Added ability to iterate over coordinates of BoundingBox (top-left, bottom-right), Polygon and LineString via for xy in obj: ....
  • Added ability to access coordinates of BoundingBox, Polygon and LineString using indices or slices, e.g. line_string[1:] to get an array of all coordinates except the first one.
  • Added property Keypoint.xy.
  • Added property Keypoint.xy_int.

Added SaveDebugImageEveryNBatches Augmenter #502

This 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.

  • Added module imgaug.augmenters.debug.
  • Added function 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.).
  • Added augmenter imgaug.augmenters.debug.SaveDebugImageEveryNBatches. Augmenter corresponding to draw_debug_image(). Saves an image at every n-th batch into a provided folder.

Added Multi-Channel cvals in pad() #502

Improved imgaug.augmenters.size.pad() to support multi-channel values for the cval parameter (e.g. RGB colors).

Added Wrappers around Package imagecorruptions #530

Added 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.

  • Added module 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.
  • Added the following functions to module 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()
  • Added function 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.
  • Added the following augmenters to module imgaug.augmenters.imgcorruptlike:
    • GaussianNoise
    • ShotNoise
    • ImpulseNoise
    • SpeckleNoise
    • GaussianBlur
    • GlassBlur
    • DefocusBlur
    • MotionBlur
    • ZoomBlur
    • Fog
    • Frost
    • Snow
    • Spatter
    • Contrast
    • Brightness
    • Saturate
    • JpegCompression
    • Pixelate
    • ElasticTransform
  • Added context imgaug.random.temporary_numpy_seed().

Added Cutout Augmenter #531 #570

This patch added Cutout augmentation, similar to the paper proposal. The augmetner has some similarity with CoarseDropout.

  • Added 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.
  • Added imgaug.augmenters.arithmetic.apply_cutout(). Same as apply_cutout_(), but copies the input images before applying cutout.
  • Added imgaug.augmenters.arithmetic.Cutout.

Added in-place Methods for Coordinate-based Augmentables #532

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.

  • Added Keypoint.project_().
  • Added Keypoint.shift_().
  • Added KeypointsOnImage.on_().
  • Added setter for KeypontsOnImage.items.
  • Added setter for BoundingBoxesOnImage.items.
  • Added setter for LineStringsOnImage.items.
  • Added setter for PolygonsOnImage.items.
  • Added KeypointsOnImage.remove_out_of_image_fraction_().
  • Added KeypointsOnImage.clip_out_of_image_fraction_().
  • Added KeypointsOnImage.shift_().
  • Added BoundingBox.project_().
  • Added BoundingBox.extend_().
  • Added BoundingBox.clip_out_of_image_().
  • Added BoundingBox.shift_().
  • Added BoundingBoxesOnImage.on_().
  • Added BoundingBoxesOnImage.clip_out_of_image_().
  • Added BoundingBoxesOnImage.remove_out_of_image_().
  • Added BoundingBoxesOnImage.remove_out_of_image_fraction_().
  • Added BoundingBoxesOnImage.shift_().
  • Added imgaug.augmentables.utils.project_coords_().
  • Added LineString.project_().
  • Added LineString.shift_().
  • Added LineStringsOnImage.on_().
  • Added LineStringsOnImage.remove_out_of_image_().
  • Added LineStringsOnImage.remove_out_of_image_fraction_().
  • Added LineStringsOnImage.clip_out_of_image_().
  • Added LineStringsOnImage.shift_().
  • Added Polygon.project_().
  • Added Polygon.shift_().
  • Added Polygon.on_().
  • Added Polygon.subdivide_().
  • Added PolygonsOnImage.remove_out_of_image_().
  • Added PolygonsOnImage.remove_out_of_image_fraction_().
  • Added PolygonsOnImage.clip_out_of_image_().
  • Added PolygonsOnImage.shift_().
  • Added PolygonsOnImage.subdivide_().
  • Switched BoundingBoxesOnImage.copy() to a custom copy operation (away from module copy module).
  • Added parameters bounding_boxes and shape to BoundingBoxesOnImage.copy()`.
  • Added parameters bounding_boxes and shape to BoundingBoxesOnImage.deepcopy()`.
  • Switched KeypointsOnImage.copy() to a custom copy operation (away from module copy module).
  • Switched PolygonsOnImage.copy() to a custom copy operation (away from module copy module).
  • Added parameters polygons and shape to PolygonsOnImage.copy()`.
  • Added parameters polygons and shape to PolygonsOnImage.deepcopy()`.
  • Switched augmenters to use in-place functions for keypoints, bounding boxes, line strings and polygons.

Added Standardized LUT Methods #542

This patch standardized the handling of lookup tables throughout the library.

  • Added imgaug.imgaug.apply_lut(), which applies a lookup table to an image.
  • Added imgaug.imgaug.apply_lut_(). In-place version of apply_lut().
  • Refactored all augmenters to use these new LUT functions. This likely fixed some so-far undiscovered bugs in augmenters using LUT tables.

Added Drawing of Bounding Box Labels #545

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().

  • Added method imgaug.augmentables.BoundingBox.draw_label_on_image().
  • Added method imgaug.augmentables.BoundingBox.draw_box_on_image().
  • Changed method imgaug.augmentables.BoundingBox.draw_on_image() to automatically draw a bounding box's label.

Added Index-based Access to Coordinate-based *OnImage Instances #547

Enabled 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];.

  • Added imgaug.augmentables.kps.KeypointsOnImage.__getitem__().
  • Added imgaug.augmentables.bbs.BoundingBoxesOnImage.__getitem__().
  • Added imgaug.augmentables.lines.LineStringsOnImage.__getitem__().
  • Added imgaug.augmentables.polys.PolygonsOnImage.__getitem__().

Added Rain and RainLayer Augmenters #551

Added augmenter(s) to create fake rain effects. They currently seem to work best at around medium-sized images (~224px).

  • Added imgaug.augmenters.weather.Rain.
  • Added imgaug.augmenters.weather.RainLayer.

Added round Parameter to Discretize #553

Added the parameter round to imgaug.parameters.Discretize. The parameter defaults to True, i.e. the default behaviour of Discretize did not change.

Added RandAugment Augmenter #553

Added 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.

  • Added module imgaug.augmenters.collections
  • Added augmenter imgaug.augmenters.collections.RandAugment.

Added and Improved Warnings for Probably-Wrong Image Inputs #594

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.)

  • Added an assert in augment_image() to verify that inputs are arrays.
  • Added warnings for probably-wrong image inputs in augment_image(), augment_images(), augment() (and its alias __call__()).
  • Added module imgaug.augmenters.base.
  • Added warning imgaug.augmenters.base.SuspiciousMultiImageShapeWarning.
  • Added warning imgaug.augmenters.base.SuspiciousSingleImageShapeWarning.
  • Added imgaug.testutils.assertWarns, similar to unittest's assertWarns, but available in python <3.2.

Changed

Improved RNG Handling during Polygon Augmentation #447

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 now Affect Maps #457

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).

Affine Translation Precision #489

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 #508

Changed 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.

Removed Outdated "Don't Import from this Module" Messages #539

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.

Standardized shift() Interfaces of Coordinate-Based Augmentables #548

The 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.

  • Added arguments x, y to BoundingBox.shift(), LineString.shift() and Polygon.shift().
  • Added arguments x, y to BoundingBoxesOnImage.shift(), LineStringsOnImage.shift() and PolygonsOnImage.shift().
  • Marked arguments top, right, bottom, left in BoundingBox.shift(), LineString.shift() and Polygon.shift() as deprecated. This also affects the corresponding *OnImage classes.
  • Added function testutils.wrap_shift_deprecation().

Simplified Standard Parameters of Augmenters #567 #595

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=....

Improved Default Values of Augmenters #582

[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 -> 3
    • Default for size_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 -> 3
    • Default for size_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 -> 3
    • Default for size_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 -> 3
    • Default for size_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 -> 1
  • JpegCompression:
    • 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)
    • These defaults are only used if the user provided neither 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)
    • These defaults are only used if the user provided neither value nor value_hue nor value_saturation.
  • Grayscale:
    • alpha: 0 -> 1

imgaug.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 -> 1
  • Flipud:
    • p: 0 -> 1

imgaug.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)}
    • These defaults are only used if no affine transformation parameter was set by the user. Otherwise the not-set parameters default again towards the identity function.
  • 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=1

imgaug.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)
    • This default is only used if the user has provided neither px nor percent.
  • Pad:
    • percent: None -> (0.0, 0.1)
    • This default is only used if the user has provided neither px nor percent.
  • Crop:
    • percent: None -> (0.0, 0.1)
    • This default is only used if the user has provided neither px nor percent.

setup.py Now Accepts any opencv-* Installation #586

setup.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.

Unified OpenCV Input Normalization #565

Changed various augmenters to use the same normalization for OpenCV inputs. This probably fixes some previously undiscovered bugs.

Renamed In-place Methods #444

  • Renamed Augmenter.reseed() to Augmenter.seed_(). The old name is now deprecated.
  • Renamed Augmenter.remove_augmenters_inplace() to Augmenter.remove_augmenters_(). The old name is now deprecated.

Deprecated AffineCv2 #540

Deprecated imgaug.augmenters.geometric.AffineCv2. Use imgaug.augmenters.geometric.Affine instead. #540

Refactored

Refactored According to pylint Requirements #504

  • Refactored all core library files to fulfill (most) pylint requirements.
  • [rarely breaking] Renamed imgaug.augmenters.size.KeepSizeByResize.get_shapes() to _get_shapes().
  • Added a project-specific pylint configuration.

Fixed

  • 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 #443
  • Fixed Affine 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. #446
  • Fixed keypoint augmentation in PiecewiseAffine potentially being unaligned if a KeypointsOnImage instance contained no keypoints. #446
  • Fixed imgaug.validation.convert_iterable_to_string_of_types() crashing due to not converting types to strings before joining them. #446
  • Fixed imgaug.validation.assert_is_iterable_of() producing a not well-designed error if the input was not an iterable. #446
  • Fixed image normalization crashing when an input ndarray of multiple images was changed during augmentation to a list of multiple images with different shapes and the original input ndarray represented a single image or a collection of 2D (H,W) images. This problem affected augment(), augment_batch() and augment_batches().
  • Fixed a typo in an image normalization error message. #451
  • Fixed a problem in WithChannels that could lead random sampling in child augmenters being unaligned between images and corresponding non-image data. #451
  • Added aliases to imgaug.random.RNG for some outdated numpy random number sampling methods that existed in numpy.random.RandomState but not in numpy's new RNG system (1.17+). These old methods are not used in imgaug, but some custom augmenters and Lambda calls may require them when interacting with the provided random_state instances. #486
  • Fixed Affine producing unaligned augmentations between images and segmentation maps or heatmaps when using translate_px and the segmentation map or heatmap had a different height/width than corresponding image. #489
  • Fixed a crash in SnowflakesLayer that could occur when using values close to 1.0 for flake_size. #471
  • Fixed MultiplyHueAndSaturation crashing if the RNG provided via random_state was not None or imgaug.random.RNG. #493
  • Fixed CloudLayer.draw_on_image() producing tuples instead of arrays as output for float input images. #540
  • Fixed Affine parameter translate_px behaving like translate_percent if a continuous stochastic parameter was provided. Analogously translate_percent would behave like translate_px if a discrete stochastic parameter was provided. #508
  • Fixed code hanging indefinitely when using multicore augmentation on NixOS. #414 #510
  • Fixed a deprecation warning and potential crash in python 3.8 related to the use of collections instead of collections.abc. #527
  • Fixed deprecated scipy.fromfunction() being called. #529
  • Fixed imgaug.random.normalize_generator() crashing in numpy 1.18. The function relied on numpy.random.bit_generator.BitGenerator, which was moved in numpy 1.18 to numpy.random.BitGenerator without a deprecation period for the old name. #534
  • Fixed an issue that could lead to endlessly hanging programs on some OS when using multicore augmentation (e.g. via pool) and augmenters using OpenCV. #535
  • Fixed imgaug.random.seed() not seeding the global RNG in-place in numpy 1.17+. The (unfixed) function instead created a new global RNG with the given seed. This set the seed of augmenters created after the seed() call, but not of augmenters created before the seed() call as they would continue to use the old global RNG. #557
  • Fixed cval in ElasticTransformation resulting in new pixels in RGB images being filled with (cval, 0, 0) instead of (cval, cval, cval). #561 #562
  • Fixed some augmenters in module weather not transferring seed values or random states that were provided upon creation to child augmenters. #568
  • Fixed an inaccuracy in PerspectiveTransform that could lead to slightly misaligned transformations between images and coordinate-based augmentables (e.g. bounding boxes). The problem was more significant the smaller the images and larger the scale values were. It was also worsened by using fit_output. #585
  • Fixed KeepSizeByResize potentially crashing if a single numpy array was provided as the input for an iterable of images (as opposed to a list of numpy arrays). #590

- Python
Published by aleju over 6 years ago

imgaug - 0.3.0

0.3.0 - Summary Of Changes

Improved Segmentation Map Augmentation (#302)

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:

  • Rename all calls of SegmentationMapOnImage to SegmentationMapsOnImage (Map -> Maps).
  • Rename all calls of SegmentationMapsOnImage.get_arr_int() to SegmentationMapsOnImage.get_arr().
  • Remove the argument nb_classes from all calls of SegmentationMapsOnImage.
  • Remove the argument background_threshold from all calls as it is no longer supported.
  • Remove the argument draw_foreground_mask from all calls of SegmentationMapsOnImage.draw_on_image() as it is no longer supported.
  • Ensure that the input array to SegmentationMapsOnImage is always an int-like (int, uint or bool). Float arrays are now deprecated.
  • Adapt all calls 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].)
  • Ensure that if 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.
  • Ensure that calls of <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.

New RNG System (#375, #408)

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 now uses a different seed at each run of the library. Previously, a fixed seed was used for each run, leading to the same agumentations. That confused some users as it differed from numpy's behaviour. The new "dynamic" seed is derived from numpy's seed and hence seeding numpy will also lead to imgaug being seeded. (It is not recommended to rely on that behaviour as it might be changed in the future. Use imgaug.random.seed() to set a custom seed.) * The constants imgaug.SEED_MIN_VALUE and imgaug.SEED_MAX_VALUE were removed. They are now in imgaug.random. * The constant imgaug.CURRENT_RANDOM_STATE was removed. Use imgaug.random.get_global_rng() instead.

Other Changes Related to numpy 1.17 (#302)

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.

New Augmenters

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.

New Augmentation Functions

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(). #369 * imgaug.median_pool(). #369 * augmenters.segmentation.segment_voronoi(). #348 * augmenters.flip.fliplr(). #385 * augmenters.flip.flipud(). #385 * augmenters.color.change_colorspace_(). #409 * augmenters.color.change_colorspace_batch_(). #409 * augmenters.arithmetic.add_scalar(). #411 * augmenters.arithmetic.add_elementwise(). #411 * augmenters.arithmetic.replace_elementwise_(). #411 * augmenters.arithmetic.compress_jpg(). #411

Colorspace Changes (#409)

The 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_RGB * imgaug.CSPACE_BGR * imgaug.CSPACE_GRAY * imgaug.CSPACE_CIE * imgaug.CSPACE_YCrCb * imgaug.CSPACE_HSV * imgaug.CSPACE_HLS * imgaug.CSPACE_Lab * imgaug.CSPACE_Luv * imgaug.CSPACE_YUV * imgaug.CSPACE_ALL

All 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.)

Setting limits on memory usage of background augmentation (#305, #417)

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.

Performance Related Changes

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.

Improved Error Messages (#366, #367, #387)

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.

(Almost) All Augmenters Are Now Classes (#396)

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).

Augmenters are now more robust towards unusual axis-sizes (#428, #433)

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.

Other New Functions

The following (public) functions were added to the library (not listing functions that were already mentioned above): * Added imgaug.is_np_scalar(). #366 * Added dtypes.normalize_dtypes(). #366 * Added dtypes.normalize_dtype(). #366 * Added dtypes.change_dtypes_(). #366 * Added dtypes.change_dtype_(). #366 * Added dtypes.increase_itemsize_of_dtype(). #366 * Added imgaug.warn() function. #367 * Added imgaug.compute_paddings_to_reach_multiples_of(). #369 * Added imgaug.pad_to_multiples_of(). #369 * Added augmentables.utils.copy_augmentables. #410 * Added validation.convert_iterable_to_string_of_types(). #413 * Added validation.is_iterable_of(). #413 * Added validation.assert_is_iterable_of(). #413 * Added random.supports_new_rng_style(). #375 * Added random.get_global_rng(). #375 * Added random.seed(). #375 * Added random.normalize_generator(). #375 * Added random.normalize_generator_(). #375 * Added random.convert_seed_to_generator(). #375 * Added random.convert_seed_sequence_to_generator(). #375 * Added random.create_pseudo_random_generator_(). #375 * Added random.create_fully_random_generator(). #375 * Added random.generate_seed_(). #375 * Added random.generate_seeds_(). #375 * Added random.copy_generator(). #375 * Added random.copy_generator_unless_global_generator(). #375 * Added random.reset_generator_cache_(). #375 * Added random.derive_generator_(). #375 * Added random.derive_generators_(). #375 * Added random.get_generator_state(). #375 * Added random.set_generator_state_(). #375 * Added random.is_generator_equal_to(). #375 * Added random.advance_generator_(). #375 * Added random.polyfill_integers(). #375 * Added random.polyfill_random(). #375

Other New Classes and Interfaces

The following (public) classes were added (not listing classes that were already mentioned above): * Added augmenters.edges.IBinaryImageColorizer. #316 * Added augmenters.edges.RandomColorsBinaryImageColorizer. #316 * Added augmenters.segmentation.IPointsSampler. #348 * Added augmenters.segmentation.RegularGridPointsSampler. #348 * Added augmenters.segmentation.RelativeRegularGridPointsSampler. #348 * Added augmenters.segmentation.DropoutPointsSampler. #348 * Added augmenters.segmentation.UniformPointsSampler. #348 * Added augmenters.segmentation.SubsamplingPointsSampler. #348 * Added testutils.ArgCopyingMagicMock. #413

The image colorization is used for Canny to turn binary images into color images. The points samplers are currently used within Voronoi.

Refactorings

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: * #302, #319, #328, #329, #330, #331, #332, #333, #334, #335, #336, #351, #352, #353, #354, #355, #356, #359, #362, #366, #367, #368, #369, #389, #397, #401, #402, #403, #407, #409, #410, #411, #413, #419

Deprecated

The following functions/classes/arguments are now deprecated: * Function imgaug.augmenters.meta.clip_augmented_image_. Use imgaug.dtypes.clip_() or numpy.clip() instead. #398 * Function imgaug.augmenters.meta.clip_augmented_image. Use imgaug.dtypes.clip_() or numpy.clip() instead. #398 * Function imgaug.augmenters.meta.clip_augmented_images_. Use imgaug.dtypes.clip_() or numpy.clip() instead. #398 * Function imgaug.augmenters.meta.clip_augmented_images. Use imgaug.dtypes.clip_() or numpy.clip() instead. #398 * Function imgaug.normalize_random_state. Use imgaug.random.normalize_generator instead. #375 * Function imgaug.current_random_state. Use imgaug.random.get_global_rng instead. #375 * Function imgaug.new_random_state. Use class imgaug.random.RNG instead. #375 * Function imgaug.dummy_random_state. Use imgaug.random.RNG(1) instead. #375 * Function imgaug.copy_random_state. Use imgaug.random.copy_generator instead. * Function imgaug.derive_random_state. Use imgaug.random.derive_generator_ instead. #375 * Function imgaug.normalize_random_states. Use imgaug.random.derive_generators_ instead. #375 * Function imgaug.forward_random_state. Use imgaug.random.advance_generator_ instead. #375 * Augmenter imgaug.augmenters.arithmetic.ContrastNormalization. Use imgaug.augmenters.contrast.LinearContrast instead. #396 * Argument X in imgaug.augmentables.kps.compute_geometric_median(). Use argument points instead. #402 * Argument cval in imgaug.pool(), imgaug.avg_pool() and imgaug.max_pool(). Use pad_cval instead. #369

Dependencies

The following changes were made to the dependencies of the library: * Increased minimum version requirement for scikit-image to 0.14.2. #377, #399 * Changed dependency opencv-python to opencv-python-headless. This should improve support for some system without GUIs. #324 * Added dependency pytest-subtests for the library's unittests. #366

conda-forge

The 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

Fixes

  • Fixed an issue with 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.
  • Fixed 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
    • [rarely breaking] If 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.
    • Fixed Invert in rare cases restoring dtypes improperly.
  • Fixed dtypes.gate_dtypes() crashing if the input was one or more numpy scalars instead of numpy arrays or dtypes.
  • Fixed augmenters.geometric.PerspectiveTransform producing invalid polygons (more often with higher scale values). #338
  • Fixed errors caused by external/poly_point_isect_py2py3.py related to floating point inaccuracies (changed an epsilon from 1e-10 to 1e-4, rounded some floats). #338
  • Fixed Superpixels breaking when a sampled n_segments was <=0. n_segments is now treated as 1 in these cases.
  • Fixed ReplaceElementwise both allowing and disallowing dtype int64. #346
  • Fixed BoundingBox.deepcopy() creating only shallow copies of labels. #356
  • Fixed dtypes.change_dtypes_() #366
    • Fixed argument round being ignored if input images were a list.
    • Fixed failure if input images were a list and dtypes a single numpy dtype function.
  • Fixed dtypes.get_minimal_dtype() failing if argument arrays contained not exactly two items. #366
  • Fixed calls of CloudLayer.get_parameters() resulting in errors. #309
  • Fixed SimplexNoiseAlpha and FrequencyNoiseAlpha not handling sigmoid argument correctly. #343
  • Fixed SnowflakesLayer crashing for grayscale images. #345
  • Fixed Affine heatmap augmentation crashing for arrays with more than four channels and order!=0. #381
  • Fixed an outdated error message in Affine. #381
  • Fixed Polygon.clip_out_of_image() crashing if the intersection between polygon and image plane was an edge or point. #382
  • Fixed Polygon.clip_out_of_image() potentially failing for polygons containing two or fewer points. #382
  • Fixed Polygon.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. #382
  • Fixed Fliplr and Flipud using for coordinate-based inputs and image-like inputs slightly different conditions for when to actually apply augmentations. #385
  • Fixed Convolve 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). #407
  • Fixed CropAndPad, Pad and PadToFixedSize still clipping cval samples to the uint8. They now clip to the input array's dtype's value range. #407
  • Fixed WithColorspace not propagating polygons to child augmenters. #409
  • Fixed WithHueAndSaturation not propagating segmentation maps and polygons to child augmenters. #409
  • Fixed AlphaElementwise 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. #410
  • Fixed many augmenters and helper functions producing errors if the height, width and/or channels of input arrays were exactly 0 or the channels were >512. See further above for more details. #433
  • Fixed Rot90 not supporting imgaug.ALL. #434
  • Fixed PiecewiseAffine possibly generating samples for non-image data when using absolute_scale=True that were not well aligned with the corresponding images. #437

- Python
Published by aleju over 6 years ago

imgaug - 0.2.9

This update mainly covers the following topics: * Moved classes/methods related to augmentable data to their own modules. * Added polygon augmentation methods. * Added line strings and line string augmentation methods. * Added easier augmentation interface.

New 'augmentables' Modules

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: * Moved Keypoint, KeypointsOnImage and imgaug.imgaug.compute_geometric_median to augmentables/kps.py. * Moved BoundingBox, BoundingBoxesOnImage to augmentables/bbs.py. * Moved Polygon, PolygonsOnImage and related classes/functions to augmentables/polys.py. * Moved HeatmapsOnImage to augmentables/heatmaps.py. * Moved SegmentationMapOnImage to augmentables/segmaps.py. * Moved Batch to augmentables/batches.py. * Added module imgaug.augmentables.utils. * Added function normalize_shape(). * Added function project_coords(). * Moved line interpolation functions _interpolate_points(), _interpolate_point_pair() and _interpolate_points_by_max_distance() to imgaug.augmentables.utils and made them public functions. * Refactored __init__() of PolygonsOnImage, BoundingBoxesOnImage, KeypointsOnImage to make use of imgaug.augmentables.utils.normalize_shape(). * Refactored KeypointsOnImage.on() to use imgaug.augmentables.utils.normalize_shape(). * Refactored Keypoint.project() to use imgaug.augmentables.utils.project_coords().

Polygon Augmentation

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: ```python 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)

imageaug, psoiaug = 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: * Added _ConcavePolygonRecoverer to imgaug.augmentables.polys. * Added PolygonsOnImage to imgaug.augmentables.polys. * Added polygon augmentation methods: * Added augment_polygons() to Augmenter. * Added _augment_polygons() to Augmenter. * Added _augment_polygons_as_keypoints() to Augmenter. * Added argument polygons to imgaug.augmentables.batches.Batch. * Added attributes polygons_aug and polygons_unaug to imgaug.augmentables.batches.Batch. * Added polygon handling to Augmenter.augment_batches(). * Added property Polygon.height. * Added property Polygon.width. * Added method Polygon.to_keypoints(). * Added optional drawing of corner points to Polygon.draw_on_image() and PolygonsOnImage.draw_on_image(). * Added argument raise_if_too_far_away=True to Polygon.change_first_point_by_coords(). * Added imgaug.quokka_polygons() function to generate example polygon data. * [rarely breaking] Polygon.draw_on_image(), PolygonsOnImage.draw_on_image() * Refactored to make partial use LineString methods. * Added arguments size and size_perimeter to control polygon line thickness. * Renamed arguments alpha_perimeter to alpha_line, color_perimeter to color_line to align with LineStrings. * Renamed arguments alpha_fill to alpha_face and color_fill to color_face. * [rarely breaking] Changed the output of Polygon.clip_out_of_image() from MultiPolygon to list of Polygon. This breaks for anybody who has already used Polygon.clip_out_of_image(). * Changed Polygon.exterior_almost_equals() to accept lists of tuples as argument other_polygon. * Changed arguments 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)). * Refactored Polygon.project() to use LineString.project(). * Refactored Polygon.shift() to use LineString.shift(). * [rarely breaking] Polygon.exterior_almost_equals(), Polygon.almost_equals() * Refactored to make use of LineString.coords_almost_equals(). * Renamed argument interpolate to points_per_edge. * Renamed argument other_polygon to other. * Renamed color_line to color_lines, alpha_line to alpha_lines in Polygon.draw_on_image() and PolygonsOnImage.draw_on_image(). * Fixed Polygon.clip_out_of_image(image) not handling image being a tuple. * Fixed Polygon.is_out_of_image() falsely only checking the corner points of the polygon.

LineString Augmentation

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: ```python 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)

imageaug, lsoiaug = iaa.Affine(rotate=45).augment( images=[image], line_strings=[lsoi] ) ```

See imgaug-doc/notebooks for a jupyter notebook with many more examples.

Simplified Augmentation Interface

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: ```python 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)

imageaug, kpsoiaug = 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: ```python import imgaug as ia import imgaug.augmenters as iaa

image = ia.quokka(size=0.2) kps = [(0, 10), (10, 5)]

imageaug, kpsaug = iaa.Affine(rotate=(-45, 45)).augment( image=image, keypoints=kps) `` Examples for other inputs that are automatically handled byaugment(): * Integer arrays as segmentation maps. * Float arrays for heatmaps. *list([N,4] ndarray)for bounding boxes. (One list for images, thenNbounding 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: ```python 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))

heatmapsaug, imagesaug, 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: * Added Augmenter.augment() method. * Added Augmenter.augment_batch() method. * This method is now called by Augmenter.augment_batches() and multicore routines. * Added imgaug.augmentables.batches.UnnormalizedBatch. * Added module imgaug.augmentables.normalization for data normalization routines. * Changed augment_batches(): * Accepts now UnnormalizedBatch as input. It is automatically normalized before augmentation and unnormalized afterwards. This allows to use Batch instances with non-standard datatypes. * Accepts now single instances of Batch (and UnnormalizedBatch). * The input may now also be a generator. * The input may now be any iterable instead of just list (arrays or strings are not allowed). * Marked support for non-Batch (and non-UnnormalizedBatch) inputs to augment_batches() as deprecated. * Refactored Batch.deepcopy() * Does no longer verify attribute datatypes. * Allows now to directly change attributes of created copies, e.g. via batch.deepcopy(images_aug=...).

Other Additions, Changes and Refactorings

Keypoint augmentation * Added method Keypoint.draw_on_image(). * [mildly breaking] Added an 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: * Added optional arguments keypoints and shape to KeypointsOnImage.deepcopy(). * Added optional arguments keypoints and shape to KeypointsOnImage.copy(). * Added method Keypoint.copy(). * Added method Keypoint.deepcopy(). * Refactored methods in 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. * Refactored KeypointsOnImage to use KeypointsOnImage.deepcopy() in as many methods as possible to create copies of itself. * Refactored Affine, AffineCv2, PiecewiseAffine, PerspectiveTransform, ElasticTransformation, Rot90 to use KeypointsOnImage.deepcopy() and Keypoint.deepcopy() during keypoint augmentation. * Changed 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.) * Changed KeypointsOnImage.draw_on_image() to raise an error if an input image has shape (H,W). * Changed KeypointsOnImage.draw_on_image() to handle single-number inputs for color. * KeypointsOnImage.from_coords_array() * Marked as deprecated. * Renamed to from_xy_array(). * Renamed arg coords to xy. * Changed the method from staticmethod to classmethod. * Refactored to make code simpler. * KeypointsOnImage.get_coords_array() * Marked as deprecated. * Renamed to to_xy_array(). * Refactored KeypointsOnImage.draw_on_image() to use Keypoint.draw_on_image().

Heatmap augmentation * Changed Affine, PiecewiseAffine, ElasticTransformation to always use order=3 for heatmap augmentation. * Changed check in 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: * Added imgaug.imgaug.DeprecationWarning. The builtin python DeprecationWarning is silent since 2.7, which is why now a separate deprecation warning is used. * Added imgaug.imgaug.warn_deprecated(). * Refactored deprecation warnings to use this function. * Added imgaug.imgaug.deprecated decorator. * Refactored deprecation warnings to use this decorator.

Bounding Boxes: * Added to BoundingBox.extract_from_image() the arguments pad and pad_max. * Changed BoundingBox.contains() to also accept Keypoint. * Changed BoundingBox.project(from, to) to also accept images instead of shapes. * Renamed argument 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. * Renamed argument 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. * Refactored BoundingBox to reduce code repetition. * Refactored BoundingBox.extract_from_image(). Improved some code fragments that looked wrong. * Refactored BoundingBoxesOnImage.draw_on_image() to improve efficiency by evading unnecessary array copies.

Other: * [rarely breaking] Added arguments 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. * Added dtypes.clip_() function. * Added function imgaug.imgaug.flatten() that flattens nested lists/tuples. * Changed PerspectiveTransform to ensure minimum height and width of output images (by default 2x2). This prevents errors in polygon augmentation (possibly also in keypoint augmentation). * Refactored imgaug.augmenters.blend.blend_alpha() to no longer enforce a channel axis for foreground and background image. * Refactored imgaug/parameters.py to reorder classes within the file. * Re-allowed numpy 1.16 in requirements.txt.

Fixes

  • Fixed possible crash in blend.blend_alpha() if dtype numpy.float128 does not exist.
  • Fixed a crash in ChangeColorspace when cv2.COLOR_Lab2RGB was actually called cv2.COLOR_LAB2RGB in the local OpenCV installation (analogous for BGR). (PR #263)
  • Fixed ReplaceElementwise always sampling replacement per channel.
  • Fixed an error in draw_text() due to arrays that could not be set to writeable after drawing the text via PIL.
  • Fixed errors in docstring of parameters.Subtract.
  • Fixed a division by zero bug in angle_between_vectors().
  • Augmentation of empty KeypointsOnImage instances
    • Fixed Rot90 not changing KeypointsOnImage.shape if .keypoints was empty.
    • Fixed Affine not changing KeypointsOnImage.shape if .keypoints was empty.
    • Fixed PerspectiveTransform not changing KeypointsOnImage.shape if .keypoints was empty.
    • Fixed Resize not changing KeypointsOnImage.shape if .keypoints was empty.
    • Fixed CropAndPad not changing KeypointsOnImage.shape if .keypoints was empty. (Same for Crop, Pad.)
    • Fixed PadToFixedSize not changing KeypointsOnImage.shape if .keypoints was empty.
    • Fixed CropToFixedSize not changing KeypointsOnImage.shape if .keypoints was empty.
    • Fixed KeepSizeByResize not changing KeypointsOnImage.shape if .keypoints was empty.
  • Fixed Affine heatmap augmentation producing arrays with values outside the range [0.0, 1.0] when order was set to 3.
  • Fixed PiecewiseAffine heatmap augmentation producing arrays with values outside the range [0.0, 1.0] when order was set to 3.
  • Fixed assert in SegmentationMapOnImage falsely checking if max class index is <= nb_classes instead of < nb_classes.
  • Fixed an issue in dtypes.clip_to_value_range_() and dtypes.restore_dtypes_() causing errors when clip value range exceeded array dtype's value range.
  • Fixed an issue in dtypes.clip_to_value_range_() and dtypes.restore_dtypes_() when the input array was scalar, i.e. had shape ().
  • Fixed a Permission Denied error when using JpegCompression on windows (possibly also affected other systems). #297

- Python
Published by aleju about 7 years ago