python给图像加噪声,python添加高斯白噪声

  python给图像加噪声,python添加高斯白噪声

  本文主要介绍如何使用python对图像正确添加高斯噪声的相关信息。有需要的朋友可以参考一下。

  00-1010彩色图像或灰度图像uint8orfloat64方差或标准差被截断(clip)。参考摘要开门见山。直接使用skimage库向图像添加高斯噪声非常简单:

  进口不足

  origin=skimage.io.imread(。/Lena . png’)

  noise=skim age . util . random _ noise(origin,mode=gaussian ,var=0.01)

  但是如果自己实现,没有库函数,有几个问题值得注意。

  

目录

  当读取图片时,它可能是三个通道的RGB图片,一个通道的灰度图片,甚至是四个通道的RGBA图片。

  不同数量的通道会影响图像数据的形状,例如:(256,256,3),(256,256)

  很多人按照MATLAB的习惯使用np.random.randn生成高斯噪声,需要根据通道数调整参数。

  # RGB

  噪声=sigma * np.random.randn(256,256,3)

  #灰色

  噪声=sigma * np.random.randn(256,256)

  对于一般处理,最好使用np.random.normal生成高斯噪声。

  noise=np.random.normal(平均值,var ** 0.5,image.shape)

  前两个参数分别是均值和标准差,第三个参数是生成数据的形状。直接输入图像本身的形状更优雅。

  

彩图 or 灰度图

  一般遇到的图像都是8bit。用skimage或opencv读取后,会发现数据类型为uint8的ndarray,取值范围为[0,255]。

  如果将高斯噪声直接添加到整数数据中,例如:

  image=io.imread(lena.png )

  noise=np.random.normal(0,10,image.shape)

  嘈杂=图像噪声

  你会发现plt.imshow是空白的,或者有零星的杂音。

  以一个像素为例分析原因:

  图像本身是[0,25的整数]: [226 137 125]产生的噪声是浮点数:[-2.92864248 4.04786763 12.2346435]加法后的最终数据:[226 137 125] Matplotlib的imshow要求输入是(0-1 float或0-255 int),所以无法正确显示上述不伦不类的数据(只有刚好落在之间的像素

  在许多应用中,为了便于计算,将图像数据转换成浮点数,float64,和值的范围是[0, 1].

  为了转换数据类型,最简单的方法是直接除以255:

  image=io.imread(。/Lena . png’)

  print(image.dtype)# uint8

  image=image/255

  print(image.dtype)# float64

  为了更谨慎,可以使用skimage的img_to_float():

  image=img_as_float(image)

  这样,可以添加高斯噪声以正确显示。

  

uint8 or float64

  高斯噪声符合高斯分布,平均值为0,方差为2 \22。

  平均值为0保证了图像的亮度不会改变,而方差决定了高斯噪声的强度。

  方差/标准差越大,噪声越强。

  这里有一点点初中数学的细节,就是在[0, 1]区间内, y = x y=\sqrt{x} y=x ​ 比 y = x y=x y=x 要大。

  

  所以,设置方差为0.1,噪声要比设置标准差为0.1大不少。注意不要用混了就可以。

  

  

  

是否截断(clip)

  由于需要把噪声叠加到原图像中,因此叠加后的数据值就可能超出对应数据类型的取值范围

  如果用matplotlib显示超出范围的彩色图像,则可能遇到以下提示:

  

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

  matplotlib自动将图片做了截断。

  而不知为何,matplotlib并不会自动对灰度图进行截断,例如:

  

  叠加噪声之后,图片数据的最小值和最大值分别为 -0.32 和 1.25,这明显超过了[0, 1]的范围。

  这样显示出的图片是不正确的(中间图像),更像是重新将图像缩放到了[0, 1]范围内,就像将色阶向外扩了一样,对比度也下降了。

  使用 np.clip,将图像截断到 [0, 1]之间,如右图所示,图像明显正常了很多。

  

  

总结

  完整的代码如下:

  

from skimage import io, img_as_float

  import numpy as np

  mean = 0

  var = 0.01

  image = io.imread("./lena.png")

  image = img_as_float(image)

  noise = np.random.normal(mean, var**0.5, image.shape)

  noisy = image + noise

  noisy = np.clip(noisy, 0.0, 1.0)

  

  当然,上述问题在 skimage.util.random_noise 中都已解决,工程中可以直接使用。

  

import skimage

  origin = skimage.io.imread("./lena.png")

  noisy = skimage.util.random_noise(origin, mode=gaussian, var=0.01)

  

  推荐学习skimage的源码。

  

  

参考

  https://zhuanlan.zhihu.com/p/50820267

  https://www.jb51.net/article/241120.htm

  https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.imshow.html

  https://github.com/scikit-image/scikit-image/blob/v0.17.2/skimage/util/noise.py#L8

  到此这篇关于如何利用python正确地为图像添加高斯噪声的文章就介绍到这了,更多相关python为图像加高斯噪声内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: