如果你把图像看作信号,那么噪声就是干扰信号。我们在采集图像时可能因为各种各样的干扰而引入图像噪声。前面提到,我们可以把图像看作一个函数,那么带有噪声的图像,就可以看作是原始图像函数与噪声函数相加的和。
f ( x , y ) = I( x , y ) + noise
常见的噪声有椒盐噪声(salt and pepper noise),为什么叫椒盐噪声?因为图像的像素点由于噪声影响随机变成了黑点(dark spot)或白点(white spot)。这里的“椒”不是我们常见的红辣椒或青辣椒,而是外国的“胡椒”(香料的一种)。我们知道,胡椒是黑色的,盐是白色的,所以才取了这么个形象的名字。
下面是原始图片:
我们要给图像添加椒盐噪声,就要把图像的像素点的强度值改为黑点或者白点,黑点的强度值是0,白点的强度值是255。原始图像的强度值区间是[0, 255],那么噪声函数中相应点是255或者是-255,加起来就可以达到是0或255的效果。需要注意,椒盐噪声是随机的改变图像中像素点的值为黑点或白点,并不是对每个像素点都进行操作。
下面是生成10%的盐噪声和椒噪声函数矩阵:
import cv2 import numpy as np peppers = cv2.imread("peppers.bmp", 0) row, column = peppers.shape noise_salt = np.random.randint(0, 256, (row, column)) noise_pepper = np.random.randint(0, 256, (row, column)) rand = 0.1 noise_salt = np.where(noise_salt < rand * 256, 255, 0) noise_pepper = np.where(noise_pepper < rand * 256, -255, 0)
我们要注意,opencv的图像矩阵类型是uint8,低于0和高于255的值并不截断,而是使用了模操作。即200+60=260 % 256 = 4。所以我们需要先将原始图像矩阵和噪声图像矩阵都转成浮点数类型进行相加操作,然后再转回来。
peppers.astype("float") noise_salt.astype("float") noise_pepper.astype("float") salt = peppers + noise_salt pepper = peppers + noise_pepper salt = np.where(salt > 255, 255, salt) pepper = np.where(pepper < 0, 0, pepper) cv2.imshow("salt", salt.astype("uint8")) cv2.imshow("pepper", pepper.astype("uint8")) cv2.waitKey()
还有一种常见的噪声是高斯噪声。椒盐噪声出现在随机的像素点位置,而高斯噪声不同,每个像素点都出现噪声。同样的,在opencv中需要将图像矩阵转换成浮点数再进行加法操作,注意这里用了嵌套的where用于截断小于0和大于255的值。
peppers.astype("float") Gauss_noise = np.random.normal(0, 50, (row, column)) Gauss = peppers + Gauss_noise Gauss = np.where(Gauss < 0, 0, np.where(Gauss > 255, 255, Gauss)) cv2.imshow("peppers_Gauss", Gauss.astype("uint8")) cv2.waitKey()
来源:CSDN,作者:saltriver,转载此文目的在于传递更多信息,版权归原作者所有。
原文:https://blog.csdn.net/saltriver/article/details/78882669
版权声明:本文为博主原创文章,转载请附上博文链接!