目录
1、高斯噪声
顾名思义指服从高斯分布(正态分布)的一类噪声,通常是因为不良照明和温度引起的传感器噪声。通常在RGB图像中,显现比较明显。如图:
高斯噪声+模糊/高斯滤波操作:
def clamp(pv):
if pv>255:
return 255
elif pv<0:
return 0
else:
return pv
def gaussian_noise(image):
h,w,c=image.shape
for row in range(h):
for col in range(w):
s=np.random.normal(0,20,3)
b=image[row,col,0]
g=image[row,col,1]
r=image[row,col,2]
image[row,col,0]=clamp(b+s[0])
image[row,col,1]=clamp(g+s[1])
image[row,col,2]=clamp(r+s[2])
cv2.imshow("noise image",image)
if __name__ == '__main__':
image=cv2.imread("../opencv-python-img/lena.png")
t1=cv2.getTickCount()
gaussian_noise(image)
#dst=cv2.GaussianBlur(image,(0,0),15)
#cv2.imshow('dst',dst)
t2=cv2.getTickCount()
time=(t2-t1)/cv2.getTickFrequency()
print(time)
cv2.waitKey(0)
#说明:
#自定义函数高斯模糊耗时3.4s
#调用opencv高斯模糊函数耗时0.1s
2、椒盐噪声
通常是由图像传感器,传输通道,解压处理等产生的黑白相间的亮暗点噪声(椒-黑,盐-白)。椒盐噪声往往由图像切割引起,去除脉冲干扰及椒盐噪声最常用的算法是中值滤波。
降噪是图像卷积运算的重要功能之一;中值模板的卷积对去除椒盐噪声有比较好的作用但均值滤波的降噪效果不佳。对于高斯噪声通过高斯滤波去除噪声。
我们使用信噪比(Signal NoiseRate)衡量图像噪声,图象的信噪比应该等于信号与噪声的功率谱之比,但通常功率谱难以计算,有一种方法可以近似估计图象信噪比,即信号与噪声的方差之比(其实在均值为零的情况下,功率就是方差)。首先计算图象所有像素的局部方差,将局部方差的最大值认为是信号方差,最小值是噪声方差,求出它们的比值,再转成dB数,最后用经验公式修正。
如果是灰度图像的话,SNR=(洁净图片中的像素点的灰度值之和)/abs(噪声图片的灰度值之和-洁净图片中的灰度值之和)为该图像的信噪比。
如何给一幅数字图像加上椒盐噪声:
- 指定信噪比 SNR (其取值范围在[0, 1]之间)
- 计算总像素数目 SP, 得到要加噪的像素数目 NP = SP * (1-SNR)
- 随机获取要加噪的每个像素位置P(i, j)
- 指定像素值为255或者0。
- 重复3,4两个步骤完成所有像素的NP个像素
- 输出加噪以后的图像
生成椒盐噪声+中值滤波(在第三部分模糊操作中):
import cv2
import numpy as np
filename = "d:/1.jpg"
winname = "figure"
img = cv2.imread(filename)
def addSaltNoise():
# 指定信噪比
SNR = 0.9
# 获取总共像素个数
size = img.size
# 因为信噪比是 SNR ,所以噪声占据百分之10,所以需要对这百分之10加噪声
noiseSize = int(size * (1 - SNR))
# 对这些点加噪声
for k in range(0, noiseSize):
# 随机获取 某个点
xi = int(np.random.uniform(0, img.shape[1]))
xj = int(np.random.uniform(0, img.shape[0]))
# 增加噪声
if img.ndim == 2:
img[xj, xi] = 255
elif img.ndim == 3:
img[xj, xi] = 0
cv2.imshow(winname, img)
cv2.waitKey(0)
def main():
addSaltNoise()
if __name__ == '__main__':
main()
3、模糊操作
模糊操作:均值模糊、中值模糊、自定义模糊
#均值模糊、中值模糊、自定义模糊
#模糊操作的基本原理
#1、基于离散卷积
#2、定义好每个卷积核
#3、不同卷积核得到不同的卷积效果
#4、模糊是卷积的一种表现
def blur_demo(image):
#均值模糊
dst=cv2.blur(image,(1,10))
cv2.imshow("blur_demo",dst)
def median_blur_demo(image):
#中值模糊
dst=cv2.medianBlur(image,5)#奇数
cv2.imshow("medianBlur",dst)
def custom_blur_demo(image):
#自定义模糊
kernel=np.array([[0,-1,0],[-1,5,-1],[0,-1,0]],np.float32)
#dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
#ddepth:目标图像所需深度
#kernel:卷积核(或相当于相关核),单通道浮点矩阵;如果要将不同的内核应用于不同的通道,请使用拆分将图像拆分为单独的颜色平面,然后单独处理它们。
#anchor:内核的锚点,指示内核中过滤点的相对位置;锚应位于内核中;默认值(-1,-1)表示锚位于内核中心。
#detal:在将它们存储在dst中之前,将可选值添加到已过滤的像素中。类似于偏置。
#borderType:像素外推法,参见BorderTypes
dst=cv2.filter2D(image,-1,kernel=kernel)
cv2.imshow("custom_blur_demo",dst)
if __name__ == '__main__':
image=cv2.imread('../opencv-python-img/lena.png')
#blur_demo(image)
#median_blur_demo(image)
custom_blur_demo(image)
cv2.waitKey(0)