椒盐噪声又称作脉冲噪声,会随机改变图像中的像索值,是相机、传输通道、解码处理等过程中产生的黑白相间的亮暗点噪声。它就像在图像上随机撒上的一些盐粒 和黑胡椒粒,因此而得名。OpenCV4 中没有提供专门为图像添加椒盐噪声的函数,需要使用者根据自己需求编写生成椒盐噪声的程序。
考虑到椒盐噪声会随机产生在图像中的任何一个位置,因此要生成椒盐噪声,我们需要用到随机数生成函数。由于NumPy在数据处理中的优异表现,对于随机数的生成,我们可以使用np.random.randint()函数。
#np.random.randint()函数原型
output = np.random.randint(low
[, high
[, size
[, dtype]]])
其中各返回值和参数的含义分别为:
low:生成的随机数的最小值
high:生成的随机数的最大值
size:生成的随机数的维度
dtype:生成的随机数的格式
该函数可以用于随机数的生成,并将生成的随机数通过值返回。生成的随机数范围是[low,high),包括low但不包括high 。
向图像中添加椒盐噪声的步骤如下:
(1)确定添加椒盐噪声的位置。根据椒盐噪声会随机出现在图像中的任何一个位置的特性, 我们可以利用np.random.randint()函数生成两个随机数,分别用于确定椒盐噪声产生的行和列。
(2)确定噪声的种类。不仅椒盐噪声的位置是随机的,噪声是黑色的还是白色同样是随机的,因此可以再次生成随机数,通过判断随机数是0还是1来确定该像素是白色噪声还是黑色噪声。
(3)修改图像像素的灰度值。判断图像通道数,对于通道数不同的图像,表示像素白色的方式也不相同。若图像为多通道的,则每个通道中的值都将改变;否则,只需要改变单通道中的一个值。
(4)得到含有椒盐噪声的图像。
示例代码
# -*- coding:utf-8 -*-
import cv2 as cv
import numpy as np
import sys
def add_noisy(image, n=10000):
result = image.copy()
w, h = image.shape[:2]
for i in range(n):
# 分别在宽和高的范围内生成一个随机值,模拟代表x, y坐标
x = np.random.randint(1, w)
y = np.random.randint(1, h)
if np.random.randint(0, 2) == 0:
# 生成白色噪声(盐噪声)
result[x, y] = 0
else:
# 生成黑色噪声(椒噪声)
result[x, y] = 255
return result
if __name__ == '__main__':
# 读取图像并判断是否读取成功
img = cv.imread('../images/cat.jpg')
if img is None:
print('Failed to read cat.jpg.')
sys.exit()
# 灰度图像添加椒盐噪声
gray_image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray_image_noisy = add_noisy(gray_image, 10000)
# 彩色图像添加椒盐噪声
color_image_noisy = add_noisy(img, 10000)
# 展示结果
cv.imshow("Gray Image", gray_image)
cv.imshow("Gray Image Noisy", gray_image_noisy)
cv.imshow("Color Image", img)
cv.imshow("Color Image Noisy", color_image_noisy)
cv.waitKey(0)
cv.destroyAllWindows()
高斯噪声是指噪声分布的概率密度函数服从高斯分布(正态分布)的一类噪声,其产生的主要原因是在拍摄时视场较暗且亮度不均匀,这会产生高斯噪声。除此之外,电子元器件自身的噪声和它们互相影响也是造成高斯噪声的重要原因。高斯噪声的概率密度函数如下式所示。
p ( z ) = 1 2 π σ e − ( z − μ ) 2 2 σ 2 p(z)=\frac{1}{\sqrt{2 \pi} \sigma} \mathrm{e}^{\frac{-(z-\mu)^{2}}{2 \sigma^{2}}} p(z)=2πσ1e2σ2−(z−μ)2
其中, z z z 表示图像像素的灰度值; μ \mu μ 表示像素值的平均值或期望值;
σ \sigma σ 表示像素的标准差,标准差的平方 ( σ 2 ) (\sigma^2) (σ2)。椒盐噪声随机出现在图像中的任意位置,高斯噪声出现在图像中所有位置。
OpenCV4中没有专门提供为图像添加高斯噪声的函数,对照在图像中添加椒盐噪声的过程,我们可以利用产生随机数的函数来对图像添加高斯噪声。NumPy中提供了可以产生符合高斯分布(正态分布)的随机数的 np.random.normal()函数。
#np.random.normal()函数原型
output = np.random.normal(loc,
scale
[, size])
其中各返回值和参数的含义分别为:
loc:高斯分布的平均值
scale:高斯分布的标准差
size:输出的随机数据维度
该函数用于生成一个指定形状的符合高斯分布的随机数,并将生成的结果通过值返回。第1个参数对应整个高斯分布的中心。第2个参数对应高斯分布的宽度。scale 值越大,分布越扁平;反之,分布越高耸。第3个参数为可选参数,可根据需求进行输出尺寸的设置,若未指定,则仅输出单个值。当参数loc设置为0,scale 设置为1时,即代表标准正态分布。
在图像中添加高斯噪声的过程大致分为以下3个步骤。
(1) 根据图像尺寸,使用np.random.normal()函数生成符合高斯分布的随机数矩阵。
(2)将原图像和生成的随机数矩阵相加。
(3)得到添加高斯噪声之后的图像。
依照上述思想,示例程序用于对灰度图像和彩色图像添加高斯噪声。由于高斯噪声是随机生成的,因此每次运行结果会有差异。
示例代码
# -*- coding:utf-8 -*-
import cv2 as cv
import numpy as np
import sys
def add_noise(image, mean=0, val=0.01):
size = image.shape
image = image / 255
gauss = np.random.normal(mean, val ** 0.5, size)
noise = image + gauss
return gauss, noise
if __name__ == '__main__':
# 读取图像并判断是否读取成功
img = cv.imread('../images/cat.jpg')
if img is None:
print('Failed to read cat.jpg.')
sys.exit()
# 灰度图像添加高斯噪声
gray_image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray_gauss, gray_noisy_image = add_noise(gray_image)
# 彩色图像添加高斯噪声
color_gauss, color_noisy_image = add_noise(img)
# 展示结果
cv.imshow("Gray Image", gray_image)
cv.imshow("Gray Noisy Image", gray_noisy_image)
cv.imshow("Color Image", img)
cv.imshow("Color Noisy Image", color_noisy_image)
cv.waitKey(0)
cv.destroyAllWindows()