尽量保留图像原有信息的情况下,过滤图像内部的噪声,这一过程叫做图像的平滑处理。通过图像平滑处理,我们可以有效过滤掉图像内的噪声信息。对应英文为Soomthing Images,图像平滑处理经常伴随图像牧户操作,因此图像平滑处理有时也被称为图像模糊处理(Blurring Images)
对图像中与周围像素点的像素差异值较大的像素点进行处理,将其值调整为周围像素点像素值的近似值
均值滤波指当前像素点周围N*N个像素值的均值来代替当前像素值,使用该方法遍历处理图像内的每一个像素点,即可完成整个图像的均值滤波
先考虑对周围多少个像素点取平均值,以当前像素点为中心,对行数和列数相等的一块区域所有像素点的像素值进行取平均值。对于边缘像素点(如第一行第一列)可以只取图像内存在的周围邻域点的像素值均值(M*N越大,失真越严重)
dst是返回值,得到均值滤波处理结果。src是原始图像,可以由任意数量的通道。Ksize是滤波核大小(均值处理过程中,邻域图像高度和宽度)。Anchor是锚点,默认(-1,-1)表示当前计算均值的点位于核的中心点位置,一般采用默认值。BorderType是边界样式,决定了以何种方式处理边界,一般采用默认值
所以cv2.blur()的一半形式为:cv2.blur(scr,ksize,)
#均值滤波
img=cv2.imread("C:\photo\lenaNoise.png")
r1=cv2.blur(img,(9,9))
r2=cv2.blur(img,(5,5))
cv2.imshow("original",img)
cv2.imshow("result_big",r1)
cv2.imshow("result_small",r2)
cv2.waitKey()
cv2.destroyAllWindows()
卷积核越大,去噪音效果越好,花费的运算时间越多,同时图像越失真
可以自由选择是否对均值滤波结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值还是邻域像素值之和,如果不进行归一化,则效果和均值滤波一样
ddepth是处理结果图像的图像深度,一般使用-1表示与原始图像使用相同的图像深度
Normalize表示是否需要进行归一化(0/1),1表示需要,0表示不需要进行归一化
常用形式:cv2.boxFilter(scr,ddepth,ksize)
#方框滤波
img=cv2.imread("C:\photo\lenaNoise.png")
r1=cv2.boxFilter(img,-1,(5,5))#使用归一化处理
r2=cv2.boxFilter(img,-1,(5,5),normalize=0)#不使用归一化处理
cv2.imshow("original",img)
cv2.imshow("result_nor",r1)
cv2.imshow("result",r2)
cv2.waitKey()
cv2.destroyAllWindows()
使用归一化处理的图片接近白色,因为5*5像素之和一般都会超过当前最大值255
在进行均值滤波和方框滤波,邻域内像素的权重都是相等的,在高斯滤波中,会将中心点的权重值加大,远离中心点的权重值减小
在此基础上计算邻域内各个像素值不同权重的和,在高斯滤波中核的长度和宽度可以不相等,但必须是奇数。在实际计算中,卷积核是要归一化处理的,严格来讲,没有归一化处理的卷积核进行滤波,得到的结果往往是错误的。
sigmaX是卷积核在水平方向上(X轴方向)的标准差,其控制的是权重比例,是必选参数
sigmaY是卷积核在垂直方向上(Y轴方向)的标准差,如果将该值设置为0,则只采用sigmaX的值,如果sigmaX和sigmaY的值都为0,就通过ksize.width.height计算得到。
Sigmax=0.3*[(ksize.width-1)0.5-1]+0.8
sigmaY=0.3[(ksize.height-1)*0.5-1]+0.8
常见形式:dst=cv2.GaussianBlur(src,ksize,0,0)#官方文档建议指定ksize、signmaX、signmaY三个参数的值,以避免将来函数修改后可能造成的语法错误,所以将其默认为0
#高斯滤波
img=cv2.imread("C:\photo\lenaNoise.png")
r1=cv2.GaussianBlur(img,(7,5),0,0)
cv2.imshow("original",img)
cv2.imshow("reuslt",r1)
cv2.waitKey()
cv2.destroyAllWindows()
与之前三种处理方式不同,不再采用加权求平均值的方式来计算滤波结果,用邻域所有像素值的中间值来代替当前像素点的像素值
采用当前像素点及周围邻近像素点(个数为奇数)的像素值,将这些像素值排列,然后将位于中间的像素值作为当前像素点的像素值
#中值滤波
img=cv2.imread("C:\photo\lenaNoise.png")
r1=cv2.medianBlur(img,3)
cv2.imshow("original",img)
cv2.imshow("reuslt",r1)
cv2.waitKey()
cv2.destroyAllWindows()
因为没有进行均值处理,所以不存在均值滤波带来的细节模糊问题,在中值滤波操作中,噪音很难被选上,可以在几乎不影响换图情况下去除全部噪音,但是由于要进行排序等操作,中值滤波需要的运算量较大
综合图像空间和色彩信息的滤波方式,在滤波过程中能有效保护图像内的边缘信息
###基本原理
前面滤波只考虑空间的权重信息,计算起来比较方便,但是边缘信息的处理上存在较大问题。滤波处理过程中对邻域像素取均值会造成边界模糊,双边滤波在计算某一个像素点的新值时,不仅考虑距离问题(距离越远,权重越小),也考虑色彩信息(色彩差别越大,权重越小)。综合考虑距离和色彩的权重结果,既能有效去除噪音,也能较好保护边沿信息。处于边缘时,与当前色彩相近的像素点会被给予较大的权重值;而在与当前色彩差别较大的像素点会被给予较小的权重值,这样就保护了边缘信息。
d是滤波时选取的空间距离参数,表示以当前像素点为中心的直径。如果非正数,则会自动从参数sigmaSpace中计算得到。如果滤波空间较大,推荐d=5.对于噪声较大的离线滤波,可以选择d=9;
sigmaColor是滤波时选取的颜色差别范围,决定了周围哪些像素点能够参与滤波中来,与当前像素点的像素值小于sigmaColor时,就能参与到滤波中来,该值为0表示滤波失去意义,该值为255表示直径内所有点都能参与运算
sigmaSpace是坐标中的sigma值,值越大,表明有越多的点能参与到滤波计算中,当d>0时,无论sigmaSpace的值如何,d都指定邻域大小,否则d与sigmaSpace成比例
为了简单起见,可以将sigmaSpace和sigmaColor的值设置相同,如果他们的值较小,滤波效果就不明显,如果值较大,滤波效果会比较明显,产生卡通效果。
#双边滤波
img=cv2.imread("C:\photo\pie.png")
g=r=cv2.GaussianBlur(img,(55,55),0,0)
b=cv2.bilateralFilter(img,55,100,100)
cv2.imshow("original",img)
cv2.imshow("bilateralFilter",b)
cv2.imshow("GaussianBlur",g)
cv2.waitKey()
cv2.destroyAllWindows()
使用特定的卷积核实现卷积操作,前面的滤波函数都无法将卷积核确定为特定形式,所以需要使用自定义卷积函数
###语法格式
dst=cv2.filter2D(scr,ddrpth,kernel,anchor,delta,borderType)
kernel是卷积核,是一个单通道的数组,如果想在处理彩色图像时,让每个通道使用不同的核,则必须将彩色图像分解后使用不同的核完成操作
delta是修正值,是可选项,如果该值存在,会在基础滤波值上加上该值作为最终的滤波处理结果
#2D卷积滤波
img=cv2.imread("C:\photo\lenaNoise.png")
kernel=np.ones((9,9),np.float32)/81
r=cv2.filter2D(img,-1,kernel)
cv2.imshow("original",img)
cv2.imshow("filter2D",r)
cv2.waitKey()
cv2.destroyAllWindows()