开门见山,直接使用 skimage 库为图像添加高斯噪声是很简单的:

import skimageorigin = skimage.io.imread("./lena.png")
noisy = skimage.util.random_noise(origin, mode='gaussian', var=0.01)

但是如果不用库函数而自己实现的话,有几个问题是值得注意的。

彩图 or 灰度图

读取图片时,图片可能是有三通道的RGB图片,也有可能是单通道的灰度图,甚至四通道的RGBA图。

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

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

# RGB
noise = sigma * np.random.randn(256, 256, 3)
# GRAY
noise = sigma * np.random.randn(256, 256)

为了通用的处理,最好使用 np.random.normal 生成高斯噪声。

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

前两个参数分别为 均值和标准差,第三个参数为生成数据的 shape,直接将图像本身shape输入进去,更加优雅。

uint8 or float64

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

如果手贱直接在整型数据上添加高斯噪声,如:

image = io.imread("lena.png")
noise = np.random.normal(0, 10, image.shape)
noisy = image + noise

你会发现 plt.imshow 出来的是一片空白,或者有零星几个噪点。

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

  • 图像本身是[0, 255]的整数:[226 137 125]

  • 生成的噪声是浮点数:[-2.92864248 4.04786763 12.23436435]

  • 相加后最后的数据:[223.07135752 141.04786763 137.23436435]

matplotlib 的 imshow 要求输入是 (0-1 float or 0-255 int),所以上述不伦不类的数据是无法正确显示的(只显示了恰好落在0-1之间的像素)。

在很多应用中,为了方便计算,都会将图像数据转换为浮点数,float64,取值范围为 [0, 1]

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

image = io.imread("./lena.png")
print(image.dtype)                  # uint8image = image/255
print(image.dtype)                  # float64

更稳妥的做法,可以使用skimage的img_to_float()

image = img_as_float(image)

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

方差 or 标准差

高斯噪声符合一个均值为0,方差为 σ2\sigma^2σ2 的高斯分布。

均值为0,是保证图像的亮度不会有变化,而方差大小则决定了高斯噪声的强度。

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

这里有一点点初中数学的细节,就是在[0, 1]区间内,y=xy=\sqrt{x}y=x​ 比 y=xy=xy=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 npmean = 0
var = 0.01image = 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 skimageorigin = skimage.io.imread("./lena.png")
noisy = skimage.util.random_noise(origin, mode='gaussian', var=0.01)

推荐学习skimage的源码。

参考

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

https://blog.csdn.net/u013044310/article/details/80739623

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相关推荐

  1. 如何正确地给图像添加高斯噪声

    高斯噪声是一个均值为 0 方差为 σn2\sigma_n^2σn2​ 的正态分布,是一个加性噪声.但要正确地给图片添加高斯噪声,还要取决于程序中读入图片的数据格式. 如果图片的数据格式为 uint8, ...

  2. 对一幅图像添加高斯噪声

    参考别人的程序写的,因为网上对图像添加高斯噪声的程序很难找到,我就自己整理出来一份. #include "cv.h"   #include "highgui.h" ...

  3. c语言给图片添加椒盐噪声,图像添加高斯噪声、胡椒噪声、盐噪声和椒盐噪声...

    1.盐椒噪声 图像加入椒盐噪声开始,椒盐噪声其实就是使图像的一些随机的像素为黑色(0)或者白色(255): 盐噪声又称白噪声,在图像中添加一些随机的白色像素点(255):胡椒噪声是在图像中添加一些随机 ...

  4. 高斯噪音 matlab,如何给图像添加高斯噪声(MATLAB)

    噪声分两种性质,加性噪声和乘性噪声.加性噪声一般指热噪声.散弹噪声等,它们与信号的关系是相加,不管有没有信号,噪声都存在.而乘性噪声一般由信道不理想引起,它们与信号的关系是相乘,信号在它在,信号不在他 ...

  5. C++版本OpenCv教程(二十七)图像中添加高斯噪声

    OpenCV 4中同样没有专门为图像添加高斯噪声的函数,对照在图像中添加椒盐噪声的过程,我们可以根据需求利用能够产生随机数的函数来完成在图像中添加高斯噪声的任务.在OpenCV 4中提供了fill() ...

  6. python高斯滤波和降噪_python添加高斯噪声和椒盐噪声,实现中值滤波和均值滤波,实现Roberts算子和Sobel算子...

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验一,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验一. 由于时间紧张,代码没有进行任何优化, ...

  7. 通过matlab编程,对以下图像分别添加高斯噪声和椒盐噪声(参数自定),并使用理想低通滤波器、高斯低通滤波器和巴特沃斯低通滤波器进行去噪。

    添加高斯噪声和椒盐噪声,并用理想低通滤波器进行去噪 t=imread('C:\Users\Administrator\Desktop\123.jpg'); subplot(3,2,1) imshow( ...

  8. python使用opencv对图像添加(高斯/椒盐/泊松/斑点)噪声

    导读 这篇文章主要介绍如何利用opencv来对图像添加各类噪声,原图 高斯噪声 高斯噪声就是给图片添加一个服从高斯分布的噪声,可以通过调节高斯分布标准差(sigma)的大小来控制添加噪声程度,sigm ...

  9. python添加高斯噪声_使用Python-OpenCV向图片添加噪声(高斯噪声、椒盐噪声)

    在matlab中,存在执行直接得函数来添加高斯噪声和椒盐噪声.Python-OpenCV中虽然不存在直接得函数,但是很容易使用相关的函数来实现. 代码: import numpy as np impo ...

最新文章

  1. CNN回应中方谴责 否认冒犯中国人
  2. Linux基金会六大项目合并成LF Networking Fund
  3. ant 驱动 svnkit 下载代码
  4. 作一个真正合格的飞秋局域网聊天
  5. java properties $,如何引用java.util.Properties中的另一个属性?
  6. 如何在内存中存储有序数据?
  7. Oracle的三种高可用集群方案
  8. MySQL乱码的问题
  9. VSFlexGrid控件
  10. 【web前端技术】dicebear一句话生成头像
  11. 普及组noip2015年问题求解——重新排列1234和根节点数为2015的二叉树最多有__个叶子节点
  12. Chromium Embedded Framework (CEF) 介绍
  13. weblogic 14c 的下载和安装
  14. 一些前端的开发环境配置
  15. linux 浏览器崩溃,Firefox DoS漏洞导致浏览器崩溃 影响到Windows操作系统
  16. WIFI共享精灵 2013 电脑共享wifi
  17. 红帽考试资料_冰山一角
  18. [论文解读]Going out on a limb: Joint Extraction of Entity Mentions and Relations without...
  19. 二、staticMetaObject’ is not a member of **
  20. 中国图形图象学报和计算机科学,lbrack;中国图象图形学报rsqb;参考文献格式

热门文章

  1. 宇多田光-prisoner of love(日剧 Last Friends)
  2. ESP8266 RTOS SDK学习之 TCP
  3. WeSing 用 Kotlin 和歌声连接用户 | Android 开发者故事
  4. 分库分表中间件 Sharding-Sphere
  5. 【大二 电子信息工程】
  6. 米格实验室助力医工结合
  7. IIS 7、8启用nginx代理后日志中获取访客真实IP方法
  8. SQLite数据库下载安装、配置、测试
  9. [思想连载4]思想就像种子,种什么,就会生长什么.
  10. Voice Control for ChatGPT 轻松实现使用语音与ChatGPT进行对话。