"""
Noise filters to apply on images
"""
# main imports
import numpy as np
import random
def _normalise(x):
if isinstance(x, np.ndarray):
return np.array(list(map(_normalise, x)))
if x > 255:
return 255
if x < 0:
return 0
return x
def _global_noise_filter(image, generator, updator, identical=False):
"""White noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
generator: lambda function used to generate random numpy array with specific distribution
updator: lambda function used to update pixel value
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
Returns:
2D Numpy array with specified noise applied
Example:
>>> from ipfml.filters.noise import _global_noise_filter as gf
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> generator = lambda h, w: np.random.uniform(-0.5, 0.5, (h, w))
>>> n = 10
>>> k = 0.2
>>> updator = lambda x, noise: x + n * k * noise
>>> noisy_image = gf(image, generator, updator)
>>> noisy_image.shape
(100, 100)
"""
image_array = np.asarray(image)
nb_chanel = 1
if image_array.ndim != 3:
height, width = image_array.shape
else:
height, width, nb_chanel = image_array.shape
if nb_chanel == 1 or identical:
noise_filter = generator(height, width)
# final output numpy array
output_array = []
# check number of chanel
if nb_chanel == 1:
noisy_image = np.array(list(map(updator, image_array, noise_filter)))
# normalise values
return np.array(list(map(_normalise, noisy_image)), 'uint8')
else:
# final output numpy array
output_array = []
for chanel in range(0, nb_chanel):
# getting flatten information from image and noise
image_array_chanel = image_array[:, :, chanel]
# redefine noise if necessary
if not identical:
noise_filter = generator(height, width)
# compute new pixel value
# x + n * k * white_noise_filter[i] as example
noisy_image = np.array(
list(map(updator, image_array_chanel, noise_filter)))
# normalise values
noisy_image = np.array(list(map(_normalise, noisy_image)), 'uint8')
# in order to concatenate output array
noisy_image = noisy_image[:, :, np.newaxis]
# append new chanel
output_array.append(noisy_image)
# concatenate RGB image
output_array = np.concatenate(output_array, axis=2)
return output_array
[docs]def white_noise(image,
n,
identical=False,
distribution_interval=(-0.5, 0.5),
k=0.2):
"""White noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
n: used to set importance of noise [1, 999]
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
distribution_interval: set the distribution interval of normal law distribution (default (-0.5, 0.5))
k: variable that specifies the amount of noise to be taken into account in the output image (default 0.2)
Returns:
2D Numpy array with white noise applied
Example:
>>> from ipfml.filters.noise import white_noise
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> noisy_image = white_noise(image, 10)
>>> noisy_image.shape
(100, 100)
"""
a, b = distribution_interval
generator = lambda h, w: np.random.uniform(a, b, (h, w))
updator = lambda x, noise: x + n * k * noise
return _global_noise_filter(image, generator, updator, identical)
[docs]def gaussian_noise(image,
n,
identical=False,
distribution_interval=(0, 1),
k=0.1):
"""Gaussian noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
n: used to set importance of noise [1, 999]
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
k: variable that specifies the amount of noise to be taken into account in the output image (default 0.1)
Returns:
2D Numpy array with gaussian noise applied
Example:
>>> from ipfml.filters.noise import gaussian_noise
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> noisy_image = gaussian_noise(image, 10)
>>> noisy_image.shape
(100, 100)
"""
a, b = distribution_interval
generator = lambda h, w: np.random.normal(a, b, (h, w))
updator = lambda x, noise: x + n * k * noise
return _global_noise_filter(image, generator, updator, identical)
[docs]def laplace_noise(image,
n,
identical=False,
distribution_interval=(0, 1),
k=0.1):
"""Laplace noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
n: used to set importance of noise [1, 999]
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
k: variable that specifies the amount of noise to be taken into account in the output image (default 0.1)
Returns:
2D Numpay array with Laplace noise applied
Example:
>>> from ipfml.filters.noise import laplace_noise
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> noisy_image = laplace_noise(image, 10)
>>> noisy_image.shape
(100, 100)
"""
a, b = distribution_interval
generator = lambda h, w: np.random.laplace(a, b, (h, w))
updator = lambda x, noise: x + n * k * noise
return _global_noise_filter(image, generator, updator, identical)
[docs]def cauchy_noise(image,
n,
identical=False,
distribution_interval=(0, 1),
k=0.0002):
"""Cauchy noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
n: used to set importance of noise [1, 999]
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
k: variable that specifies the amount of noise to be taken into account in the output image (default 0.0002)
Returns:
2D Numpy array with Cauchy noise applied
Example:
>>> from ipfml.filters.noise import cauchy_noise
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> noisy_image = cauchy_noise(image, 10)
>>> noisy_image.shape
(100, 100)
"""
a, b = distribution_interval
generator = lambda h, w: np.random.standard_cauchy((h, w))
updator = lambda x, noise: x + n * k * noise
return _global_noise_filter(image, generator, updator, identical)
[docs]def log_normal_noise(image,
n,
identical=False,
distribution_interval=(0, 1),
k=0.05):
"""Log-normal noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
n: used to set importance of noise [1, 999]
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
k: variable that specifies the amount of noise to be taken into account in the output image (default 0.05)
Returns:
2D Numpy array with Log-normal noise applied
Example:
>>> from ipfml.filters.noise import log_normal_noise
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> noisy_image = log_normal_noise(image, 10)
>>> noisy_image.shape
(100, 100)
"""
a, b = distribution_interval
generator = lambda h, w: np.random.lognormal(a, b, (h, w))
updator = lambda x, noise: x + n * k * noise
return _global_noise_filter(image, generator, updator, identical)
[docs]def mut_white_noise(image,
n,
identical=False,
distribution_interval=(0, 1),
k=0.002):
"""Multiplied White noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
n: used to set importance of noise [1, 999]
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
k: variable that specifies the amount of noise to be taken into account in the output image (default 0.002)
Returns:
2D Numpy array with multiplied white noise applied
Example:
>>> from ipfml.filters.noise import mut_white_noise
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> noisy_image = mut_white_noise(image, 10)
>>> noisy_image.shape
(100, 100)
"""
min_value = 1 - (k / 2)
max_value = 1 + (k / 2)
a, b = distribution_interval
generator = lambda h, w: min_value + (np.random.uniform(a, b, (h, w)) * (max_value - min_value))
updator = lambda x, noise: x * pow(noise, n)
return _global_noise_filter(image, generator, updator, identical)
[docs]def salt_pepper_noise(image, n, identical=False, p=0.1, k=0.5):
"""Pepper salt noise filter to apply on image
Args:
image: image used as input (2D or 3D image representation)
n: used to set importance of noise [1, 999]
identical: keep or not identical noise distribution for each canal if RGB Image (default False)
p: probability to increase pixel value otherwise decrease it
k: variable that specifies the amount of noise to be taken into account in the output image (default 0.5)
Returns:
2D Numpy array with salt and pepper noise applied
Example:
>>> from ipfml.filters.noise import salt_pepper_noise
>>> import numpy as np
>>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
>>> noisy_image = salt_pepper_noise(image, 10)
>>> noisy_image.shape
(100, 100)
"""
def _generator(h, w):
x = w * h
nb_elem = int(p * x)
elements = np.full(x, 0)
elements[0:nb_elem] = 1
np.random.shuffle(elements)
return elements.reshape(h, w)
image_array = np.array(image)
if image_array.ndim == 3:
height, width, _ = image_array.shape
else:
height, width = image_array.shape
# need same random variable for each pixel value if identical
if identical:
gen = np.random.uniform(0, 1, height * width)
for i in range(2):
gen = np.insert(gen, 0, gen)
gen = iter(gen)
# here noise variable is boolean to update or not pixel value
def _updator(x, noise):
# apply specific changes to each value of 1D array
if isinstance(x, np.ndarray):
return np.array(list(map(_updator, x, noise)))
# probabilty to increase or decrease pixel value
if identical:
rand = next(gen)
else:
rand = random.uniform(0, 1)
if noise:
if rand > 0.5:
return x + n * k
else:
return x - n * k
else:
return x
return _global_noise_filter(image, _generator, _updator, identical)