noise.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. import numpy as np
  2. import random
  3. from ipfml import processing
  4. def _global_noise_filter(image, n, generator, updator, identical=False, k=0.2):
  5. """White noise filter to apply on image
  6. Args:
  7. image: image used as input (2D or 3D image representation)
  8. n: used to set importance of noise [1, 999]
  9. generator: lambda function used to generate random numpy array with specific distribution
  10. updator: lambda function used to update pixel value
  11. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  12. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.2)
  13. Returns:
  14. 2D Numpy array with specified noise applied
  15. Example:
  16. >>> from ipfml.filters.noise import _global_noise_filter as gf
  17. >>> import numpy as np
  18. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  19. >>> generator = lambda x: np.random.uniform(-0.5, 0.5, x)
  20. >>> updator = lambda x, n, k, noise: x + n * k * noise
  21. >>> noisy_image = gf(image, 10, generator, updator)
  22. >>> noisy_image.shape
  23. (100, 100)
  24. """
  25. image_array = np.asarray(image)
  26. nb_chanel = 1
  27. if image_array.ndim != 3:
  28. width, height = image_array.shape
  29. else:
  30. width, height, nb_chanel = image_array.shape
  31. nb_pixels = width * height
  32. if identical:
  33. noise_filter = generator(nb_pixels)
  34. # final output numpy array
  35. output_array = []
  36. for chanel in range(0, nb_chanel):
  37. # getting flatten information from image and noise
  38. if nb_chanel == 3:
  39. image_array_flatten = image_array[:, :, chanel].reshape(nb_pixels)
  40. else:
  41. image_array_flatten = image_array.reshape(nb_pixels)
  42. # redefine noise if necessary
  43. if not identical:
  44. noise_filter = generator(nb_pixels)
  45. # compute new pixel value
  46. # n * k * white_noise_filter[i]
  47. noisy_image = np.asarray([
  48. updator(image_array_flatten[i], n, k, noise_filter[i])
  49. for i in range(0, nb_pixels)
  50. ])
  51. # reshape and normalize new value
  52. noisy_image = noisy_image.reshape((width, height))
  53. noisy_image = np.asarray(noisy_image, 'uint8')
  54. # in order to concatenae output array
  55. if nb_chanel == 3:
  56. noisy_image = noisy_image[:, :, np.newaxis]
  57. # append new chanel
  58. output_array.append(noisy_image)
  59. # concatenate RGB image
  60. if nb_chanel == 3:
  61. output_array = np.concatenate(output_array, axis=2)
  62. else:
  63. output_array = np.asarray(output_array).reshape(width, height)
  64. return output_array
  65. def white_noise(image,
  66. n,
  67. identical=False,
  68. distribution_interval=(-0.5, 0.5),
  69. k=0.2):
  70. """White noise filter to apply on image
  71. Args:
  72. image: image used as input (2D or 3D image representation)
  73. n: used to set importance of noise [1, 999]
  74. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  75. distribution_interval: set the distribution interval of normal law distribution (default (-0.5, 0.5))
  76. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.2)
  77. Returns:
  78. 2D Numpy array with white noise applied
  79. Example:
  80. >>> from ipfml.filters.noise import white_noise
  81. >>> import numpy as np
  82. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  83. >>> noisy_image = white_noise(image, 10)
  84. >>> noisy_image.shape
  85. (100, 100)
  86. """
  87. a, b = distribution_interval
  88. generator = lambda x: np.random.uniform(a, b, x)
  89. updator = lambda x, n, k, noise: x + n * k * noise
  90. return _global_noise_filter(image, n, generator, updator, identical, k)
  91. def gaussian_noise(image,
  92. n,
  93. identical=False,
  94. distribution_interval=(0, 1),
  95. k=0.1):
  96. """Gaussian noise filter to apply on image
  97. Args:
  98. image: image used as input (2D or 3D image representation)
  99. n: used to set importance of noise [1, 999]
  100. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  101. distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
  102. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.1)
  103. Returns:
  104. 2D Numpy array with gaussian noise applied
  105. Example:
  106. >>> from ipfml.filters.noise import gaussian_noise
  107. >>> import numpy as np
  108. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  109. >>> noisy_image = gaussian_noise(image, 10)
  110. >>> noisy_image.shape
  111. (100, 100)
  112. """
  113. a, b = distribution_interval
  114. generator = lambda x: np.random.normal(a, b, x)
  115. updator = lambda x, n, k, noise: x + n * k * noise
  116. return _global_noise_filter(image, n, generator, updator, identical, k)
  117. def laplace_noise(image,
  118. n,
  119. identical=False,
  120. distribution_interval=(0, 1),
  121. k=0.1):
  122. """Laplace noise filter to apply on image
  123. Args:
  124. image: image used as input (2D or 3D image representation)
  125. n: used to set importance of noise [1, 999]
  126. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  127. distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
  128. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.1)
  129. Returns:
  130. 2D Numpay array with Laplace noise applied
  131. Example:
  132. >>> from ipfml.filters.noise import laplace_noise
  133. >>> import numpy as np
  134. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  135. >>> noisy_image = laplace_noise(image, 10)
  136. >>> noisy_image.shape
  137. (100, 100)
  138. """
  139. a, b = distribution_interval
  140. generator = lambda x: np.random.laplace(a, b, x)
  141. updator = lambda x, n, k, noise: x + n * k * noise
  142. return _global_noise_filter(image, n, generator, updator, identical, k)
  143. def cauchy_noise(image,
  144. n,
  145. identical=False,
  146. distribution_interval=(0, 1),
  147. k=0.0002):
  148. """Cauchy noise filter to apply on image
  149. Args:
  150. image: image used as input (2D or 3D image representation)
  151. n: used to set importance of noise [1, 999]
  152. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  153. distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
  154. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.0002)
  155. Returns:
  156. 2D Numpy array with Cauchy noise applied
  157. Example:
  158. >>> from ipfml.filters.noise import cauchy_noise
  159. >>> import numpy as np
  160. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  161. >>> noisy_image = cauchy_noise(image, 10)
  162. >>> noisy_image.shape
  163. (100, 100)
  164. """
  165. a, b = distribution_interval
  166. generator = lambda x: np.random.standard_cauchy(x)
  167. updator = lambda x, n, k, noise: x + n * k * noise
  168. return _global_noise_filter(image, n, generator, updator, identical, k)
  169. def log_normal_noise(image,
  170. n,
  171. identical=False,
  172. distribution_interval=(0, 1),
  173. k=0.05):
  174. """Log-normal noise filter to apply on image
  175. Args:
  176. image: image used as input (2D or 3D image representation)
  177. n: used to set importance of noise [1, 999]
  178. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  179. distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
  180. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.05)
  181. Returns:
  182. 2D Numpy array with Log-normal noise applied
  183. Example:
  184. >>> from ipfml.filters.noise import log_normal_noise
  185. >>> import numpy as np
  186. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  187. >>> noisy_image = log_normal_noise(image, 10)
  188. >>> noisy_image.shape
  189. (100, 100)
  190. """
  191. a, b = distribution_interval
  192. generator = lambda x: np.random.lognormal(a, b, x)
  193. updator = lambda x, n, k, noise: x + n * k * noise
  194. return _global_noise_filter(image, n, generator, updator, identical, k)
  195. def mut_white_noise(image,
  196. n,
  197. identical=False,
  198. distribution_interval=(-0.5, 0.5),
  199. k=0.2):
  200. """Multiplied White noise filter to apply on image
  201. Args:
  202. image: image used as input (2D or 3D image representation)
  203. n: used to set importance of noise [1, 999]
  204. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  205. distribution_interval: set the distribution interval of normal law distribution (default (-0.5, 0.5))
  206. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.2)
  207. Returns:
  208. 2D Numpy array with multiplied white noise applied
  209. Example:
  210. >>> from ipfml.filters.noise import mut_white_noise
  211. >>> import numpy as np
  212. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  213. >>> noisy_image = mut_white_noise(image, 10)
  214. >>> noisy_image.shape
  215. (100, 100)
  216. """
  217. a, b = distribution_interval
  218. generator = lambda x: np.random.uniform(a, b, x)
  219. updator = lambda x, n, k, noise: x * n * k * noise
  220. return _global_noise_filter(image, n, generator, updator, identical, k)
  221. def salt_pepper_noise(image, n, identical=False, p=0.1, k=0.5):
  222. """Pepper salt noise filter to apply on image
  223. Args:
  224. image: image used as input (2D or 3D image representation)
  225. n: used to set importance of noise [1, 999]
  226. identical: keep or not identical noise distribution for each canal if RGB Image (default False)
  227. p: probability to increase pixel value otherwise decrease it
  228. k: variable that specifies the amount of noise to be taken into account in the output image (default 0.5)
  229. Returns:
  230. 2D Numpy array with salt and pepper noise applied
  231. Example:
  232. >>> from ipfml.filters.noise import salt_pepper_noise
  233. >>> import numpy as np
  234. >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
  235. >>> noisy_image = salt_pepper_noise(image, 10)
  236. >>> noisy_image.shape
  237. (100, 100)
  238. """
  239. def _generator(x):
  240. nb_elem = int(p * x)
  241. elements = np.full(x, 0)
  242. elements[0:nb_elem] = 1
  243. np.random.shuffle(elements)
  244. return elements
  245. # here noise variable is boolean to update or not pixel value
  246. def _updator(x, n, k, noise):
  247. # probabilty to increase or decrease pixel value
  248. rand = random.uniform(0, 1)
  249. if noise:
  250. if rand >= 0.5:
  251. return x + n * k
  252. else:
  253. return x - n * k
  254. else:
  255. return x
  256. return _global_noise_filter(image, n, _generator, _updator, identical, k)