1. 什么是图像去噪?
图像去噪是指减少数字图像中噪声的过程.
2. 去噪方法
2.1 均值滤波
均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度g(x,y),即g(x,y)=1/m ∑f(x,y) m为该模板中包含当前像素在内的像素总个数。
函数实现:cv2.blur(img,ksize) , ksize为卷积核的大小。
2.2 中值滤波
中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。
函数实现:cv2.medianBlur(img, k) ,k为方框的尺寸
中值滤波最适合去除椒盐噪声。
2.3 自定义去噪
函数原型:cv2.filter2D( src, dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT )
参数说明:
1. int ddepth: 目标图像深度,如果没写将生成与原图像深度相同的图像。当ddepth输入值为-1时,目标图像和原图像深度保持一致。
2. Point anchor: 内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点。
3. double delta: 在储存目标图像前可选的添加到像素的值,默认值为0
4. int borderType: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。
代码如下:
def blur_demo(image):# dst = cv.blur(image, (5, 5)) # 卷积核为5x5,均值模糊# dst = cv.medianBlur(image, 5) # 中值模糊,对椒盐噪声去噪较好# 自定义滤波器kernel = np.ones([5, 5], np.float32) / 25 # 内核大小kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32) # 锐化算子# filter2D(src, ddepth(图像深度,-1表示默认和src一样深度), kernel, dst=None, anchor=None(锚点,卷积核中心), delta=None, borderType=None)dst = cv.filter2D(image, -1, kernel=kernel) # 二维滤波器cv.imshow("blur_demo", dst)
2.4 高斯去噪
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
函数原型:cv2.GuassianBlur(img, ksize,sigmaX,sigmaY)
参数说明: 1. img 输入图像 2. ksize 卷积核大小(必须为正奇数,也可以为0) 3.sigmaX、sigmaY(x和y方向上的高斯核标准差)
实现代码:
import cv2 as cv
import numpy as npdef clamp(pv):if pv > 255:return 255elif pv < 0:return 0else:return pvdef gaussian_noise(image): # 加高斯噪声h, w, c = image.shapefor row in range(h):for col in range(w):s = np.random.normal(0, 20, 3) # normal(loc=0.0, scale=1.0, size=None),均值,标准差,大小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])cv.imshow("gaussian_noise", image)if __name__ == '__main__':src = cv.imread("../images/CrystalLiu1.jpg") # 读入图片放进src中# cv.namedWindow("Crystal Liu") # 创建窗口# cv.imshow("Crystal Liu", src) # 将src图片放入该创建的窗口中# blur_demo(src)# t1 = cv.getTickCount()# gaussian_noise(src)# t2 = cv.getTickCount()# time = (t2 - t1)/cv.getTickFrequency()# print("time consume: %s"%(time * 1000))# GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)# ksize表示卷积核大小,sigmaX,Y表示x,y方向上的标准差,这两者只需一个即可,并且ksize为大于0的奇数dst = cv.GaussianBlur(src, (5, 5), 0) # 高斯模糊,sigmaX与ksize一个为0cv.imshow("Gaussian blur", dst)cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口cv.destroyAllWindows() # 关闭所有窗口