tensorlayer3/tensorlayer/vision/transforms.py

1257 lines
38 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#! /usr/bin/python
# -*- coding: utf-8 -*-
import tensorlayer as tl
from . import load_vision_backend as F
import numbers
import numpy as np
__all__ = [
'Crop',
'CentralCrop',
'HsvToRgb',
'AdjustBrightness',
'AdjustContrast',
'AdjustHue',
'AdjustSaturation',
'FlipHorizontal',
'FlipVertical',
'RgbToGray',
'PadToBoundingbox',
'Pad',
'Normalize',
'StandardizePerImage',
'RandomBrightness',
'RandomContrast',
'RandomHue',
'RandomSaturation',
'RandomCrop',
'Resize',
'RgbToHsv',
'Transpose',
'RandomRotation',
'RandomShift',
'RandomShear',
'RandomZoom',
'RandomFlipVertical',
'RandomFlipHorizontal',
'HWC2CHW',
'CHW2HWC',
'ToTensor',
'Compose',
'RandomResizedCrop',
'RandomAffine',
'ColorJitter',
]
class ToTensor(object):
"""Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor.
Parameters
----------
data_format : str
Data format of output tensor, should be 'HWC' or 'CHW'. Default: 'HWC'.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.ToTensor(data_format='HWC')
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, data_format='HWC'):
if not data_format in ['CHW', 'HWC']:
raise ValueError('data_format should be CHW or HWC. Got {}'.format(data_format))
self.data_format = data_format
def __call__(self, image):
F.to_tensor(image, self.data_format)
class CentralCrop(object):
"""Crops the given image at the center.If the size is given, image will be cropped as size.
If the central_fraction is given, image will cropped as (H * central_fraction, W * fraction).
Size has a higher priority.
Parameters
----------
size : int or sequence of int
The output size of the cropped image.
If size is an integer, a square crop of size (size, size) is returned.
If size is a sequence of length 2, it should be (height, width).
central_fraction : float
float (0, 1], fraction of size to crop
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.CentralCrop(size = (50, 50))
>>> image = transform(image)
>>> print(image)
>>> image shape : (50, 50, 3)
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.CentralCrop(central_fraction=0.5)
>>> image = transform(image)
>>> print(image)
>>> image shape : (112, 112, 3)
"""
def __init__(self, size=None, central_fraction=None):
self.central_fraction = central_fraction
self.size = size
def __call__(self, image):
F.central_crop(image, self.size, self.central_fraction)
class Compose(object):
"""Composes several transforms together.
Parameters
----------
transforms : list of 'transform' objects
list of transforms to compose.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.Compose([tl.vision.transforms.ToTensor(data_format='HWC'),tl.vision.transforms.CentralCrop(size = 100)])
>>> image = transform(image)
>>> print(image)
>>> image shape : (100, 100, 3)
"""
def __init__(self, transforms):
self.transforms = transforms
def __call__(self, data):
for t in self.transforms:
data = t(data)
return data
class Crop(object):
"""Crops an image to a specified bounding box.
Parameters
----------
offset_height : int
Vertical coordinate of the top-left corner of the bounding box in image.
offset_width: int
Horizontal coordinate of the top-left corner of the bounding box in image.
target_height: int
Height of the bounding box.
target_width: int
Width of the bounding box.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.Crop(offset_height=10, offset_width=10, target_height=100, target_width=100)
>>> image = transform(image)
>>> print(image)
>>> image shape : (100, 100, 3)
"""
def __init__(self, offset_height, offset_width, target_height, target_width):
self.offset_height = offset_height
self.offset_width = offset_width
self.target_height = target_height
self.target_width = target_width
def __call__(self, image):
return F.crop(image, self.offset_height, self.offset_width, self.target_height, self.target_width)
class Pad(object):
"""Pad the given image on all sides with the given "pad" value.
Parameters
----------
padding : int or sequenece
Padding on each border.
If a single int is provided this is used to pad all borders.
If sequence of length 2 is provided this is the padding on left/right and top/bottom respectively.
If a sequence of length 4 is provided this is the padding for the left, top, right and bottom borders respectively.
padding_value : number or sequenece
Pixel fill value for constant fill. Default is 0.
If a tuple of length 3, it is used to fill R, G, B channels respectively.
This value is only used when the mode is constant.
mode : str
Type of padding. Default is constant.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.Pad(padding=10, padding_value=0, mode='constant')
>>> image = transform(image)
>>> print(image)
>>> image shape : (244, 244, 3)
"""
def __init__(self, padding, padding_value=0, mode='constant'):
self.padding = padding
self.padding_value = padding_value
self.mode = mode
def __call__(self, image):
return F.pad(image, self.padding, self.padding_value, self.mode)
class Resize(object):
"""Resize the input image to the given size.
Parameters
----------
size : int or sequenece
Desired output size.
If size is a sequence like (h, w), output size will be matched to this.
If size is an int, smaller edge of the image will be matched to this number.
i.e, if height > width, then image will be rescaled to (size * height / width, size).
interpolation : str
Interpolation method. Default: 'bilinear'.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.Resize(size = (100,100), interpolation='bilinear')
>>> image = transform(image)
>>> print(image)
>>> image shape : (100, 100, 3)
"""
def __init__(self, size, interpolation='bilinear'):
self.size = size
self.interpolation = interpolation
def __call__(self, image):
return F.resize(image, self.size, self.interpolation)
class Transpose(object):
"""Transpose image(s) by swapping dimension.
Parameters
----------
order : sequenece of int
Desired output dimension order.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.Transpose(order=(2, 0 ,1))
>>> image = transform(image)
>>> print(image)
>>> image shape : (3, 224, 224)
"""
def __init__(self, order):
self.order = order
def __call__(self, image):
return F.transpose(image, self.order)
class HWC2CHW(object):
"""Transpose a image shape (H, W, C) to shape (C, H, W).
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.HWC2CHW()
>>> image = transform(image)
>>> print(image)
>>> image shape : (3, 224, 224)
"""
def __call__(self, image):
F.hwc_to_chw(image)
class CHW2HWC(object):
"""Transpose a image shape (C, H, W) to shape (H, W, C).
Examples
----------
With TensorLayer
>>> image = (np.random.rand(3, 224, 224) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.CHW2HWC()
>>> image = transform(image)
>>> print(image)
>>> image shape : (224, 224, 3)
"""
def __call__(self, image):
F.chw_to_hwc(image)
class RgbToHsv(object):
"""Converts a image from RGB to HSV.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RgbToHsv()
>>> image = transform(image)
>>> print(image)
>>> image shape : (224, 224, 3)
"""
def __call__(self, image):
F.rgb_to_hsv(image)
class HsvToRgb(object):
"""Converts a image from HSV to RGB.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.HsvToRgb()
>>> image = transform(image)
>>> print(image)
>>> image shape : (224, 224, 3)
"""
def __call__(self, image):
F.hsv_to_rgb(image)
class RgbToGray(object):
"""Converts a image from RGB to grayscale.
Parameters
----------
num_output_channels: int
(1 or 3) number of channels desired for output image. Default is 1.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RgbToGray(num_output_channels=1)
>>> image = transform(image)
>>> print(image)
>>> image shape : (224, 224, 1)
"""
def __init__(self, num_output_channels=1):
self.num_output_channels = num_output_channels
def __call__(self, image):
F.rgb_to_gray(image, self.num_output_channels)
class AdjustBrightness(object):
"""Adjust brightness of the image.
Parameters
----------
brightness_factor: float
How much to adjust the brightness. Can be any non negative number. 1 gives the original image.
Default is 1.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.AdjustBrightness(brightness_factor=1)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, brightness_factor=1):
self.brightness_factor = brightness_factor
def __call__(self, image):
return F.adjust_brightness(image, self.brightness_factor)
class AdjustContrast(object):
"""Adjust contrast of the image.
Parameters
----------
contrast_factor: float
How much to adjust the contrast. Can be any non negative number. 1 gives the original image.
Default is 1.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.AdjustContrast(contrast_factor=1)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, contrast_factor=1):
self.contrast_factor = contrast_factor
def __call__(self, image):
return F.adjust_contrast(image, self.contrast_factor)
class AdjustHue(object):
"""Adjust hue of the image.
Parameters
----------
hue_factor: float
How much to shift the hue channel. Should be in [-0.5, 0.5].
0.5 and -0.5 give complete reversal of hue channel in HSV space in positive and negative direction respectively.
0 means no shift. Therefore, both -0.5 and 0.5 will give an image with complementary colors while 0 gives the original image.
Default is 0.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.AdjustHue(hue_factor=0)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, hue_factor=0):
self.hue_factor = hue_factor
def __call__(self, image):
return F.adjust_hue(image, self.hue_factor)
class AdjustSaturation(object):
"""Adjust saturation of the image.
Parameters
----------
saturation_factor: float
How much to adjust the saturation. Can be any non negative number. 1 gives the original image.
Default is 1.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.AdjustSaturation(saturation_factor=1)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, saturation_factor=1):
self.saturation_factor = saturation_factor
def __call__(self, image):
return F.adjust_saturation(image, self.saturation_factor)
class FlipHorizontal(object):
"""Flip an image horizontally.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.FlipHorizontal()
>>> image = transform(image)
>>> print(image)
"""
def __call__(self, image):
return F.hflip(image)
class FlipVertical(object):
"""Flip an image vertically.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.FlipVertical()
>>> image = transform(image)
>>> print(image)
"""
def __call__(self, image):
return F.vflip(image)
class PadToBoundingbox(object):
"""Pad image with the specified height and width to target size.
Parameters
----------
offset_height: int
Number of rows to add on top.
offset_width: int
Number of columns to add on the left.
target_height: int
Height of output image.
target_width: int
Width of output image.
padding_value: int or sequence
value to pad.
Examples
----------
With TensorLayer
>>> image = (np.random.rand( 224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.PadToBoundingbox(offset_height=10, offset_width=10, target_height=300, target_width=300, padding_value=0)
>>> image = transform(image)
>>> print(image)
>>> image shape : (300, 300, 3)
"""
def __init__(self, offset_height, offset_width, target_height, target_width, padding_value=0):
self.offset_height = offset_height
self.offset_width = offset_width
self.target_height = target_height
self.target_width = target_width
self.padding_value = padding_value
def __call__(self, image):
return F.padtoboundingbox(
image, self.offset_height, self.offset_width, self.target_height, self.target_width, self.padding_value
)
class Normalize(object):
"""Normalize a tensor image with mean and standard deviation.
Parameters
----------
mean: number or sequence
If mean is a number, mean will be applied for all channels. Sequence of means for each channel.
std: number or sequnece
If std is a number, std will be applied for all channels.Sequence of standard deviations for each channel.
data_format: str
Data format of input image, should be 'HWC' or 'CHW'. Default: 'HWC'.
Examples
----------
With TensorLayer
>>> image = (np.random.rand( 224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.Normalize(mean = (155.0, 155.0, 155.0), std = (75.0, 75.0, 75.0),data_format='HWC')
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, mean, std, data_format='HWC'):
self.mean = mean
self.std = std
self.data_format = data_format
def __call__(self, image):
return F.normalize(image, self.mean, self.std, self.data_format)
class StandardizePerImage(object):
"""For each 3-D image x in image, computes (x - mean) / adjusted_stddev, where mean is the average of all values in x.
adjusted_stddev = max(stddev, 1.0/sqrt(N)) is capped away from 0 to protect against division by 0 when handling uniform images.
N is the number of elements in x. stddev is the standard deviation of all values in x
Examples
----------
With TensorLayer
>>> image = (np.random.rand( 224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.StandardizePerImage()
>>> image = transform(image)
>>> print(image)
"""
def __call__(self, image):
return F.standardize(image)
class RandomBrightness(object):
"""Random adjust brightness of the image.
Parameters
----------
brightness_factor: float or sequence
Brightness adjustment factor (default=(1, 1)).
If it is a float, the factor is uniformly chosen from the range [max(0, 1-brightness_factor), 1+brightness_factor].
If it is a sequence, it should be [min, max] for the range.Should be non negative numbers.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomBrightness(brightness_factor=(0.5, 2))
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, brightness_factor=(1, 1)):
self.brighthness_factor = brightness_factor
def __call__(self, image):
return F.random_brightness(image, self.brighthness_factor)
class RandomContrast(object):
"""Random adjust contrast of the image.
Parameters
----------
contrast_factor: float or sequence
Contrast adjustment factor (default=(1, 1)).
If it is a float, the factor is uniformly chosen from the range [max(0, 1-contrast_factor), 1+contrast_factor].
If it is a sequence, it should be [min, max] for the range.Should be non negative numbers.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomContrast(contrast_factor=(0.5, 2))
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, contrast_factor=(1, 1)):
self.contrast_factor = contrast_factor
def __call__(self, image):
return F.random_contrast(image, self.contrast_factor)
class RandomSaturation(object):
"""Random adjust saturation of the image.
Parameters
----------
saturation_factor: float or sequence
Saturation adjustment factor (default=(1, 1)).
If it is a float, the factor is uniformly chosen from the range [max(0, 1-saturation_factor), 1+saturation_factor].
If it is a sequence, it should be [min, max] for the range.Should be non negative numbers.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomSaturation(saturation_factor=(0.5, 2))
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, saturation_factor=(1, 1)):
self.saturation_factor = saturation_factor
def __call__(self, image):
return F.random_saturation(image, self.saturation_factor)
class RandomHue(object):
"""Random adjust hue of the image.
Parameters
----------
hue_factor: float or sequence
Hue adjustment factor (default=(0, 0)).
If it is a float, the factor is uniformly chosen from the range [-hue_factor, hue_factor].
If it is a sequence, it should be [min, max] for the range.Should have 0<= hue <= 0.5 or -0.5 <= min <= max <= 0.5.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomHue(hue_factor=(-0.5, 0.5))
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, hue_factor=(0, 0)):
self.hue_factor = hue_factor
def __call__(self, image):
return F.random_hue(image, self.hue_factor)
class RandomCrop(object):
"""Crop the given image at a random location.
Parameters
----------
size: int or sequence
Desired output size of the crop.
If size is an int instead of sequence like (h, w), a square crop (size, size) is made.
If provided a sequence of length 1, it will be interpreted as (size[0], size[0]).
padding: int or sequence, optional
Optional padding on each border of the image.
If a single int is provided this is used to pad all borders.
If sequence of length 2 is provided this is the padding on left/right and top/bottom respectively.
If a sequence of length 4 is provided, it is used to pad left, top, right, bottom borders respectively.
Default: 0.
pad_if_needed: boolean
It will pad the image if smaller than the desired size to avoid raising an exception.
Since cropping is done after padding, the padding seems to be done at a random offset.
fill: number or sequence
Pixel fill value for constant fill. Default is 0.
If a tuple of length 3, it is used to fill R, G, B channels respectively.
padding_mode: str
Type of padding. Default is constant.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomCrop(size=50, padding=10, pad_if_needed=False, fill=0, padding_mode='constant')
>>> image = transform(image)
>>> print(image)
>>> image shape : (70,70,3)
"""
def __init__(self, size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant'):
self.size = size
self.padding = padding
self.pad_if_needed = pad_if_needed
self.fill = fill
self.padding_mode = padding_mode
def __call__(self, image):
return F.random_crop(
image,
size=self.size,
padding=self.padding,
pad_if_needed=self.pad_if_needed,
fill=self.fill,
padding_mode=self.padding_mode,
)
class RandomResizedCrop(object):
"""Crop the given image to random size and aspect ratio.
Parameters
----------
size: int or sequence
Desired output size of the crop.
If size is an int instead of sequence like (h, w), a square crop (size, size) is made.
If provided a sequence of length 1, it will be interpreted as (size[0], size[0]).
scale: tuple of float
scale range of the cropped image before resizing, relatively to the origin image.
ratio: tuple of float
aspect ratio range of the cropped image before resizing.
interpolation: str
Type of interpolation. Default is bilinear.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomResizedCrop(size = (100, 100), scale = (0.08, 1.0), ratio = (3./4.,4./3.), interpolation = 'bilinear')
>>> image = transform(image)
>>> print(image)
>>> image shape : (100,100,3)
"""
def __init__(self, size, scale=(0.08, 1.0), ratio=(3. / 4., 4. / 3.), interpolation='bilinear'):
self.size = size
self.scale = scale
self.ratio = ratio
self.interpolation = interpolation
def __call__(self, image):
return F.random_resized_crop(image, self.size, self.scale, self.ratio, self.interpolation)
class RandomFlipVertical(object):
"""Vertically flip the given image randomly with a given probability.
Parameters
----------
prob: float
probability of the image being flipped. Default value is 0.5
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomFlipVertical(prob = 0.5)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, prob=0.5):
self.prob = prob
def __call__(self, image):
return F.random_vflip(image, self.prob)
class RandomFlipHorizontal(object):
"""Horizontally flip the given image randomly with a given probability.
Parameters
----------
prob: float
probability of the image being flipped. Default value is 0.5
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomFlipHorizontal(prob = 0.5)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, prob=0.5):
self.prob = prob
def __call__(self, image):
return F.random_hflip(image, self.prob)
class RandomRotation(object):
"""Rotate the image by random angle.
Parameters
----------
degrees: number or sequnence
Range of degrees to select from.
If degrees is a number, the range of degrees will be (-degrees, +degrees).
If degrees is a sequence, the range of degrees will (degrees[0], degrees[1]).
interpolation: str
Interpolation method. Default is 'bilinear'.
expand: boolean
If true, expands the output to make it large enough to hold the entire rotated image.
If false or omitted, make the output image the same size as the input image.
Note that the expand flag assumes rotation around the center and no translation.
center: sequence or None
Optional center of rotation, (x, y). Origin is the upper left corner.
Default is the center of the image.
fill: number or sequence
Pixel fill value for the area outside the rotated image. Default is 0.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomRotation(degrees=30, interpolation='bilinear', expand=False, center=None, fill=0)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, degrees, interpolation='bilinear', expand=False, center=None, fill=0):
self.degrees = degrees
self.interpolation = interpolation
self.expand = expand
self.center = center
self.fill = fill
def __call__(self, image):
return F.random_rotation(image, self.degrees, self.interpolation, self.expand, self.center, self.fill)
class RandomShear(object):
"""Shear the image by random angle.
Parameters
----------
degrees: number or sequnence
Range of degrees to select from.
If degrees is a number, a shear parallel to the x axis in the range (-shear, +shear) will be applied.
If shear is a sequence of 2 values a shear parallel to the x axis in the range (shear[0], shear[1]) will be applied.
If shear is a sequence of 4 values, a x-axis shear in (shear[0], shear[1]) and y-axis shear in (shear[2], shear[3]) will be applied.
interpolation: str
Interpolation method. Default is 'bilinear'.
fill: number or sequence
Pixel fill value for the area outside the sheared image. Default is 0.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomShear(degrees=30, interpolation='bilinear', fill=0)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, degrees, interpolation='bilinear', fill=0):
self.degrees = degrees
self.interpolation = interpolation
self.fill = fill
def __call__(self, image):
return F.random_shear(image, self.degrees, self.interpolation, self.fill)
class RandomShift(object):
"""Shift the image by random translations.
Parameters
----------
shift: list or tuple
Maximum absolute fraction for horizontal and vertical translations.
shift=(a, b), then horizontal shift is randomly sampled in the range -img_width * a < dx < img_width * a.
vertical shift is randomly sampled in the range -img_height * b < dy < img_height * b.
interpolation: str
Interpolation method. Default is 'bilinear'.
fill: number or sequence
Pixel fill value for the area outside the sheared image. Default is 0.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomShift(shift=(0.2, 0.2), interpolation='bilinear', fill=0)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, shift, interpolation='bilinear', fill=0):
self.shift = shift
self.interpolation = interpolation
self.fill = fill
def __call__(self, image):
return F.random_shift(image, self.shift, self.interpolation, self.fill)
class RandomZoom(object):
"""Zoom the image by random scale.
Parameters
----------
zoom: list or tuple
Scaling factor interval, e.g (a, b), then scale is randomly sampled from the range a <= scale <= b.
interpolation: str
Interpolation method. Default is 'bilinear'.
fill: number or sequence
Pixel fill value for the area outside the sheared image. Default is 0.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomZoom(zoom=(0.2, 0.5), interpolation='bilinear', fill=0)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, zoom, interpolation='bilinear', fill=0):
self.zoom = zoom
self.interpolation = interpolation
self.fill = fill
def __call__(self, image):
return F.random_zoom(image, self.zoom, self.interpolation, self.fill)
class RandomAffine(object):
"""Random affine transformation of the image keeping center invariant.
Parameters
----------
degrees: number or sequnence
Range of degrees to select from.
If degrees is a number, the range of degrees will be (-degrees, +degrees).
If degrees is a sequence, the range of degrees will (degrees[0], degrees[1]).
Set to 0 to deactivate rotations.
shift: sequence or None
Maximum absolute fraction for horizontal and vertical translations.
shift=(a, b), then horizontal shift is randomly sampled in the range -img_width * a < dx < img_width * a.
vertical shift is randomly sampled in the range -img_height * b < dy < img_height * b.
Will not shift by default.
shear: number or sequnence or None
Range of degrees to select from.
If degrees is a number, a shear parallel to the x axis in the range (-shear, +shear) will be applied.
If shear is a sequence of 2 values a shear parallel to the x axis in the range (shear[0], shear[1]) will be applied.
If shear is a sequence of 4 values, a x-axis shear in (shear[0], shear[1]) and y-axis shear in (shear[2], shear[3]) will be applied.
Will not apply shear by default.
zoom: sequence or None
Scaling factor interval, e.g (a, b), then scale is randomly sampled from the range a <= scale <= b.
Will not zoom by default.
interpolation: str
Interpolation method. Default is 'bilinear'.
fill: number or sequence
Pixel fill value for the area outside the sheared image. Default is 0.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.RandomAffine(degrees=30, shift=(0.2,0.2), zoom=(0.2, 0.5), shear=30, interpolation='bilinear', fill=0)
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, degrees, shift=None, zoom=None, shear=None, interpolation='bilinear', fill=0):
if isinstance(degrees, numbers.Number):
if degrees < 0:
raise ValueError('If degrees is a single number, it must be positive.' 'But got {}.'.format(degrees))
degrees = [-degrees, degrees]
elif not (isinstance(degrees, (list, tuple)) and len(degrees) == 2):
raise TypeError('If degrees is a list or tuple, it should be length of 2.' 'But got {}'.format(degrees))
self.degrees = (float(x) for x in degrees)
if shift is not None:
if not (isinstance(shift, (list, tuple)) and len(shift) == 2):
raise TypeError("shift should be a list or tuple of length 2." "But got {}.".format(shift))
for s in shift:
if not (0.0 <= s <= 1.0):
raise ValueError('shift values should be between 0 and 1.' 'But got {}.'.format(shift))
self.shift = shift
if zoom is not None:
if not (isinstance(zoom, (list, tuple)) and len(zoom) == 2):
raise TypeError("zoom should be a list or tuple of length 2." "But got {}.".format(zoom))
if not (0 <= zoom[0] <= zoom[1]):
raise ValueError("zoom valuse should be positive, and zoom[1] should be less than zoom[0].")
self.zoom = zoom
if shear is not None:
if isinstance(shear, numbers.Number):
if shear < 0:
raise ValueError("If shear is a single number, it must be positive.")
shear = [-shear, shear]
elif not (isinstance(shear, (list, tuple)) and len(shear) in (2, 4)):
raise TypeError('shear should be a list or tuple of length (2, 4).')
self.shear = (float(x) for x in shear)
self.interpolation = interpolation
if fill is None:
fill = 0
elif not isinstance(fill, (list, tuple, numbers.Number)):
raise TypeError("Fill should be either a sequence or a number.")
self.fill = fill
def __call__(self, image):
return F.random_affine(image, self.degrees, self.shift, self.zoom, self.shear, self.interpolation, self.fill)
class ColorJitter(object):
"""Randomly change the brightness, contrast, saturation and hue of an image.
Parameters
----------
brightness: float or sequence
Brightness adjustment factor (default=(1, 1)).
If it is a float, the factor is uniformly chosen from the range [max(0, 1-brightness_factor), 1+brightness_factor].
If it is a sequence, it should be [min, max] for the range.Should be non negative numbers.
contrast: float or sequence
Contrast adjustment factor (default=(1, 1)).
If it is a float, the factor is uniformly chosen from the range [max(0, 1-contrast_factor), 1+contrast_factor].
If it is a sequence, it should be [min, max] for the range.Should be non negative numbers.
saturation: float or sequence
Saturation adjustment factor (default=(1, 1)).
If it is a float, the factor is uniformly chosen from the range [max(0, 1-saturation_factor), 1+saturation_factor].
If it is a sequence, it should be [min, max] for the range.Should be non negative numbers.
hue: float or sequence
Hue adjustment factor (default=(0, 0)).
If it is a float, the factor is uniformly chosen from the range [-hue_factor, hue_factor].
If it is a sequence, it should be [min, max] for the range.Should have 0<= hue <= 0.5 or -0.5 <= min <= max <= 0.5.
Examples
----------
With TensorLayer
>>> image = (np.random.rand(224, 224, 3) * 255.).astype(np.uint8)
>>> transform = tl.vision.transforms.ColorJitter(brightness=(1,5), contrast=(1,5), saturation=(1,5), hue=(-0.2,0.2))
>>> image = transform(image)
>>> print(image)
"""
def __init__(self, brightness=0, contrast=0, saturation=0, hue=0):
self.brightness = self._check_input(brightness, 'brightness')
self.contrast = self._check_input(contrast, 'contrast')
self.saturation = self._check_input(saturation, 'saturation')
self.hue = self._check_input(hue, 'hue', center=0, bound=(-0.5, 0.5), clip_first_on_zero=False)
def _check_input(self, value, name, center=1, bound=(0, float('inf')), clip_first_on_zero=True):
if isinstance(value, numbers.Number):
if value < 0:
raise ValueError("If {} is a single number, it must be non negative.".format(name))
value = [center - float(value), center + float(value)]
if clip_first_on_zero:
value[0] = max(value[0], 0.0)
elif isinstance(value, (tuple, list)) and len(value) == 2:
if not bound[0] <= value[0] <= value[1] <= bound[1]:
raise ValueError("{} values should be between {}".format(name, bound))
else:
raise TypeError("{} should be a single number or a list/tuple with lenght 2.".format(name))
if value[0] == value[1] == center:
value = None
return value
@staticmethod
def get_params(brightness, contrast, saturation, hue):
fn_idx = np.random.permutation(np.arange(4))
b = None if brightness is None else float(np.random.uniform(brightness[0], brightness[1]))
c = None if contrast is None else float(np.random.uniform(contrast[0], contrast[1]))
s = None if saturation is None else float(np.random.uniform(saturation[0], saturation[1]))
h = None if hue is None else float(np.random.uniform(hue[0], hue[1]))
return fn_idx, b, c, s, h
def __call__(self, image):
fn_idx, brightness_factor, contrast_factor, saturation_factor, hue_factor = \
self.get_params(self.brightness, self.contrast, self.saturation, self.hue)
for fn_id in fn_idx:
if fn_id == 0 and brightness_factor is not None:
image = F.adjust_brightness(image, brightness_factor)
elif fn_id == 1 and contrast_factor is not None:
image = F.adjust_contrast(image, contrast_factor)
elif fn_id == 2 and saturation_factor is not None:
image = F.adjust_saturation(image, saturation_factor)
elif fn_id == 3 and hue_factor is not None:
image = F.adjust_hue(image, hue_factor)
return image