noise.py 11 KB

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