Source code for gluoncv.data.transforms.experimental.image
"""Experimental image transformations."""
from __future__ import division
import random
import numpy as np
import mxnet as mx
from mxnet import nd
[docs]def random_color_distort(src, brightness_delta=32, contrast_low=0.5, contrast_high=1.5,
saturation_low=0.5, saturation_high=1.5, hue_delta=18):
"""Randomly distort image color space.
Note that input image should in original range [0, 255].
Parameters
----------
src : mxnet.nd.NDArray
Input image as HWC format.
brightness_delta : int
Maximum brightness delta. Defaults to 32.
contrast_low : float
Lowest contrast. Defaults to 0.5.
contrast_high : float
Highest contrast. Defaults to 1.5.
saturation_low : float
Lowest saturation. Defaults to 0.5.
saturation_high : float
Highest saturation. Defaults to 1.5.
hue_delta : int
Maximum hue delta. Defaults to 18.
Returns
-------
mxnet.nd.NDArray
Distorted image in HWC format.
"""
def brightness(src, delta, p=0.5):
"""Brightness distortion."""
if np.random.uniform(0, 1) > p:
delta = np.random.uniform(-delta, delta)
src += delta
return src
return src
def contrast(src, low, high, p=0.5):
"""Contrast distortion"""
if np.random.uniform(0, 1) > p:
alpha = np.random.uniform(low, high)
src *= alpha
return src
return src
def saturation(src, low, high, p=0.5):
"""Saturation distortion."""
if np.random.uniform(0, 1) > p:
alpha = np.random.uniform(low, high)
gray = src * nd.array([[[0.299, 0.587, 0.114]]], ctx=src.context)
gray = mx.nd.sum(gray, axis=2, keepdims=True)
gray *= (1.0 - alpha)
src *= alpha
src += gray
return src
return src
def hue(src, delta, p=0.5):
"""Hue distortion"""
if np.random.uniform(0, 1) > p:
alpha = random.uniform(-delta, delta)
u = np.cos(alpha * np.pi)
w = np.sin(alpha * np.pi)
bt = np.array([[1.0, 0.0, 0.0],
[0.0, u, -w],
[0.0, w, u]])
tyiq = np.array([[0.299, 0.587, 0.114],
[0.596, -0.274, -0.321],
[0.211, -0.523, 0.311]])
ityiq = np.array([[1.0, 0.956, 0.621],
[1.0, -0.272, -0.647],
[1.0, -1.107, 1.705]])
t = np.dot(np.dot(ityiq, bt), tyiq).T
src = nd.dot(src, nd.array(t, ctx=src.context))
return src
return src
src = src.astype('float32')
# brightness
src = brightness(src, brightness_delta)
# color jitter
if np.random.randint(0, 2):
src = contrast(src, contrast_low, contrast_high)
src = saturation(src, saturation_low, saturation_high)
src = hue(src, hue_delta)
else:
src = saturation(src, saturation_low, saturation_high)
src = hue(src, hue_delta)
src = contrast(src, contrast_low, contrast_high)
return src
_data_rng = np.random.RandomState(None)
[docs]def np_random_color_distort(image, data_rng=None, eig_val=None,
eig_vec=None, var=0.4, alphastd=0.1):
"""Numpy version of random color jitter.
Parameters
----------
image : numpy.ndarray
original image.
data_rng : numpy.random.rng
Numpy random number generator.
eig_val : numpy.ndarray
Eigen values.
eig_vec : numpy.ndarray
Eigen vectors.
var : float
Variance for the color jitters.
alphastd : type
Jitter for the brightness.
Returns
-------
numpy.ndarray
The jittered image
"""
from ....utils.filesystem import try_import_cv2
cv2 = try_import_cv2()
if data_rng is None:
data_rng = _data_rng
if eig_val is None:
eig_val = np.array([0.2141788, 0.01817699, 0.00341571],
dtype=np.float32)
if eig_vec is None:
eig_vec = np.array([[-0.58752847, -0.69563484, 0.41340352],
[-0.5832747, 0.00994535, -0.81221408],
[-0.56089297, 0.71832671, 0.41158938]], dtype=np.float32)
def grayscale(image):
return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
def lighting_(data_rng, image, alphastd, eigval, eigvec):
alpha = data_rng.normal(scale=alphastd, size=(3, ))
image += np.dot(eigvec, eigval * alpha)
def blend_(alpha, image1, image2):
image1 *= alpha
image2 *= (1 - alpha)
image1 += image2
def saturation_(data_rng, image, gs, gs_mean, var):
# pylint: disable=unused-argument
alpha = 1. + data_rng.uniform(low=-var, high=var)
blend_(alpha, image, gs[:, :, None])
def brightness_(data_rng, image, gs, gs_mean, var):
# pylint: disable=unused-argument
alpha = 1. + data_rng.uniform(low=-var, high=var)
image *= alpha
def contrast_(data_rng, image, gs, gs_mean, var):
# pylint: disable=unused-argument
alpha = 1. + data_rng.uniform(low=-var, high=var)
blend_(alpha, image, gs_mean)
functions = [brightness_, contrast_, saturation_]
random.shuffle(functions)
gs = grayscale(image)
gs_mean = gs.mean()
for f in functions:
f(data_rng, image, gs, gs_mean, var)
lighting_(data_rng, image, alphastd, eig_val, eig_vec)
return image