高斯平滑
高斯平滑即采用高斯卷积核对图像矩阵进行卷积操作。高斯卷积核是一个近似服从高斯分布的矩阵,随着距离中心点的距离增加,其值变小。这样进行平滑处理时,图像矩阵中锚点处像素值权重大,边缘处像素值权重小,下为一个3*3的高斯卷积核:
opencv中提供了GaussianBlur()函数来进行高斯平滑,其对应参数如下:
dst = cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)
src: 输入图像矩阵,可为单通道或多通道,多通道时分别对每个通道进行卷积
dst:输出图像矩阵,大小和数据类型都与src相同
ksize:高斯卷积核的大小,宽,高都为奇数,且可以不相同
sigmaX: 一维水平方向高斯卷积核的标准差
sigmaY: 一维垂直方向高斯卷积核的标准差,默认值为0,表示与sigmaX相同
borderType:填充边界类型
代码使用示例和效果如下:(相比于原图,平滑后图片变模糊)
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
img = cv.imread(r"D:\new20200726213331.png")
img_gauss = cv.GaussianBlur(img,(3,3),1)
cv.imshow("img",img)
cv.imshow("img_gauss",img_gauss)
cv.waitKey(0)
cv.destroyAllWindows()
对于上面的高斯卷积核,可以由如下两个矩阵相乘进行构建,说明高斯核是可分离卷积核,因此高斯卷积操作可以分成先进行垂直方向的一维卷积,再进行一维水平方向卷积。
opencv中getGaussianKernel()能用来产生一维的高斯核,分别获得水平和垂直的高斯核,分两步也能完成高斯卷积,获得和GaussianBlur一样的结果。其参数如下:
cv2.getGaussianKernel(ksize,sigma,ktype)
ksize:奇数,一维核长度
sigma:标准差
ktype:数据格式,应该为CV_32F 或者 CV_64F返回矩阵如下:垂直的矩阵[[ 0.27406862] [ 0.45186276] [ 0.27406862]
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
#convolve2d只是对单通道进行卷积,若要实现cv.GaussianBlur()多通道高斯卷积,需要拆分三个通道进行,再合并
def gaussianBlur(img,h,w,sigma,boundary="fill",fillvalue=0):
kernel_x = cv.getGaussianKernel(w,sigma,cv.CV_64F) #默认得到的为垂直矩阵
kernel_x = np.transpose(kernel_x) #转置操作,得到水平矩阵
#水平方向卷积
gaussian_x = signal.convolve2d(img,kernel_x,mode="same",boundary=boundary,fillvalue=fillvalue)
#垂直方向卷积
kernel_y = cv.getGaussianKernel(h,sigma,cv.CV_64F)
gaussian_xy = signal.convolve2d(gaussian_x,kernel_y,mode="same",boundary=boundary,fillvalue=fillvalue)
#cv.CV_64F数据转换为uint8
gaussian_xy = np.round(gaussian_xy)
gaussian_xy = gaussian_xy.astype(np.uint8)
return gaussian_xy
if __name__=="__main__":
img = cv.imread(r"C:\Users\Administrator\Desktop\timg.jpg",0)
img_gauss = gaussianBlur(img,3,3,1)
cv.imshow("img",img)
cv.imshow