opencv高斯滤波GaussianBlur()详解(sigma取值)

滤波(blur)操作是一种基于邻域的图像平滑方法。
当图像噪声只是图像的一小部分时,用某一像素点的邻域进行变换得到的新的像素点可以减小噪声的影响,从而很好的平滑噪声。
均值滤波是对中心点的邻域求算术平均和,中值滤波是对中心点的邻域求中值。
本文主要说的高斯滤波,高斯滤波可以看作对均值滤波的改进,
以33的邻域为例,均值滤波是对这九个数求平均,而高斯滤波是对这个九个数求加权平均,其中心思想是邻域中每个点离中心点的距离不一样,不应该像均值滤波一样每个点的权重一样,而是离中心点越近,权值越大。而每个点的权重就是高斯分布(也就是正态分布)。
正态分布如下:
f ( x ) = 1 2 π σ exp ⁡ ( − ( x − μ ) 2 2 σ 2 ) f(x)=\frac{1}{\sqrt{2 \pi} \sigma} \exp \left(-\frac{(x-\mu)^{2}}{2 \sigma^{2}}\right) f(x)=2π σ1exp(2σ2(xμ)2)
其中u为均值, σ \sigma σ为方差
x看作像素点距离中心点的距离,则 μ \mu μ取0,
f ( x ) = 1 2 π σ exp ⁡ ( − ( x ) 2 2 σ 2 ) f(x)=\frac{1}{\sqrt{2 \pi} \sigma} \exp \left(-\frac{(x)^{2}}{2 \sigma^{2}}\right) f(x)=2π σ1exp(2σ2(x)2)
基于正态分布的思想,3
3的邻域权重矩阵(高斯卷积核kernel)即为
∣ f ( 2 ) f ( 1 ) f ( 2 ) f ( 1 ) f ( 0 ) f ( 1 ) f ( 2 ) f ( 1 ) f ( 2 ) ∣ \begin{vmatrix} f(2)&f(1) & f(2)\\ f(1)& f(0) &f(1) \\ f(2)& f(1) & f(2) \end{vmatrix} f(2)f(1)f(2)f(1)f(0)f(1)f(2)f(1)f(2)
,然后将权重矩阵归一化,最终的权重矩阵为
∣ f ( 2 ) / s u m f ( 1 ) / s u m f ( 2 ) / s u m f ( 1 ) / s u m f ( 0 ) / s u m f ( 1 ) / s u m f ( 2 ) / s u m f ( 1 ) / s u m f ( 2 ) / s u m ∣ \begin{vmatrix} f(2)/sum &f(1)/sum & f(2)/sum\\ f(1)/sum& f(0)/sum &f(1)/sum \\ f(2)/sum & f(1)/sum & f(2)/sum \end{vmatrix} f(2)/sumf(1)/sumf(2)/sumf(1)/sumf(0)/sumf(1)/sumf(2)/sumf(1)/sumf(2)/sum,其中sum=f(0)+4f(1)+4f(2);

#假使sigma = 1,卷积核ksize=3
def f(x):
    return np.power(np.e,-x*x/2) #因为最后需要归一化,所以可以不管正态分布前面的参数
f0 = f(0)
f1 = f(1)
f2 = f(2)
sum=f0+4*(f1+f2)
kernel = np.array(
[[f2/sum,f1/sum,f2/sum],
 [f1/sum,f0/sum,f1/sum],
 [f2/sum,f1/sum,f2/sum],
]
)
print(kernel)

用这种方法计算的卷积核如下
在这里插入图片描述
但如果用这个卷积核与图片做卷积得到的结果和opencv的
GaussianBlur()方法得到的结果完全不同;
opencv的计算方式显然并不是这种。
首先看看opencv的GaussianBlur()方法:

cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) → dst

其中src,dst分别是输入和输出图片,borderType为边界填充方式。
ksize为卷积核大小,即邻域大小,比如ksize为(3,3),则对以中心点为中心点3 * 3的邻域做操作;
而在高斯分布中,需要设定的参数为 μ \mu μ σ \sigma σ,因为对称性,所以 μ \mu μ设定为0,而与想象的不同,opencv的高斯模糊函数输入了两个 σ \sigma σ(sigma)参数,sigmaX,sigmaY,显然opencv实现的高斯滤波和上文写的方法不太相同。
仔细阅读官方文档GaussianBlur后,可以看到
高斯滤波
描述的很清楚,sigmaX是X轴的高斯核的 σ \sigma σ,sigmaY是Y轴的高斯核的 σ \sigma σ
再阅读官方文档getGaussianKernel函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-InVaziju-1577241692856)(en-resource://database/4670:0)]可知:
这个函数可以根据ksize和sigma求出对应的高斯核,计算方式就是上文提到的计算方式,而返回值是一个一维高斯核。
其中需要注意的是,如果sigma为非正数(负数或0)的话,就会根据ksize来自动计算sigma,计算公式为sigma = 0.3*((ksize-1)*0.5-1)+0.8
由上述公式可以计算得出,
当ksize=3时,sigma=0.8
当ksize=5时,sigma为1.1.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qGMD83VZ-1577241692857)(en-resource://database/4672:3)]
再继续往下阅读,两个这样产生的一维高斯核可以传递给sepFilter2D函数,
继续阅读官方文档的sepFilter2D

cv2.sepFilter2D(src, ddepth, kernelX, kernelY[, dst[, anchor[, delta[, borderType]]]]) → dst

cv2.sepFilter2D函数传入两个一维kernel,然后对图像的每一行以kernelX为卷积核做卷积,对结果的每一列以kernelY为卷积核做卷积,最后归一化得到新的高斯滤波后的图像。
综上:opencv实现的高斯滤波,是对传入的sigmaX,sigmaY分别产生两个一维卷积核,然后分别再行和列上做卷积,其中sigmaX和sigmaY如果没有传入参数,则由ksize计算得到。
进行验证:

image_ori = cv2.imread('car.png')
image_gray = cv2.cvtColor(image_ori,cv2.COLOR_BGR2GRAY)
image1 = cv2.GaussianBlur(image_gray,(3,3),0.8,0.8)
image2 = cv2.sepFilter2D(image_gray,-1,cv2.getGaussianKernel(3,0.8),cv2.getGaussianKernel(3,0.8))
print(image1==image2)

验证结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aiJc40eH-1577241692858)(en-resource://database/4674:0)]

  • 54
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
OpenCV提供了GaussianBlur()函数用于实现高斯滤波。该函数接受输入图像、卷积核的大小、sigmaX和sigmaY等参数,并返回滤波后的图像。具体的函数原型为: cv2.GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT) 通过该函数,OpenCV会根据传入的sigmaX和sigmaY参数生成对应的一维卷积核。如果sigmaX和sigmaY未传入参数,则会使用ksize计算得到。接着,OpenCV会将生成的卷积核分别应用于图像的行和列进行卷积操作。最后,对卷积结果进行归一化处理,得到高斯滤波后的图像。 为了验证这个过程,可以使用以下代码: image_ori = cv2.imread('car.png') image_gray = cv2.cvtColor(image_ori, cv2.COLOR_BGR2GRAY) image1 = cv2.GaussianBlur(image_gray, (3,3), 0.8, 0.8) image2 = cv2.sepFilter2D(image_gray, -1, cv2.getGaussianKernel(3, 0.8), cv2.getGaussianKernel(3, 0.8)) print(image1==image2) 在这段代码中,首先读取输入图像,并将其转换为灰度图像。然后,分别使用GaussianBlur()函数和sepFilter2D()函数实现高斯滤波,并将结果保存在image1和image2中。最后,使用print语句比较image1和image2是否相等。 通过以上步骤,可以验证OpenCV高斯滤波的实现过程。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [opencv高斯滤波GaussianBlur()详解(sigma取值)](https://blog.csdn.net/wuqindeyunque/article/details/103694900)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [opencv学习(二十)之高斯滤波GaussianBlur()](https://blog.csdn.net/keith_bb/article/details/54412493)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值