欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在OpenCV里实现双边滤波

程序员文章站 2022-07-14 23:34:40
...

前面学习了高斯平滑、均值平滑,在一些图像处理里非常有效果,但是它在去除噪声同时,也把图像的边缘进行模糊。现在就得考虑有没有这样方法,既可以平滑图像,又可以保留图像边缘的信息。我们来回顾一下前面使用的高斯平滑,其实是构造一个正态分布的矩阵,以中心点像素为主,周边距离远的像素为次,这样是按距离进行加权平滑,因此距离中心点近的像素权值越大,距离远的像素权值越小。现在要增加一个领域里像素值的考虑,与中心点的像素值差别,因此在每一个像素点计算卷积时,都需要重新计算相乘的卷积核。与高斯平滑相比,高斯平滑是一个固定的卷积核,而双边滤波是一个动态的卷积核,这个卷积核根据每个像素点的像素值进行计算。由此可见双边滤波比高斯平滑要多计算一步,速度上要比高斯平滑要慢得多。其原理大体如下图所示:

在OpenCV里实现双边滤波

左边是输入图像,中间是高斯卷积核与像素值权重核进行对应位置相乘(点乘),从而构造了一个新的卷积核,经过这个卷积核处理后输出右边的图片。

其数学的公式如下:

在OpenCV里实现双边滤波

在这里C是表示靠近距离的高斯函数,S是表示像素相似程度的高斯函数。

在OpenCV里实现双边滤波

其中 I 是像素的强度值,所以在强度差距大的地方(边缘),权重会减小,滤波效应也就变小。总体而言,在像素强度变换不大的区域,双边滤波有类似于高斯滤波的效果,而在图像边缘等强度梯度较大的地方,可以保持梯度。

由这里可知,双边滤波的算法分成以下几步:

  1. 计算高斯平滑的卷积核G。
  2. 计算每个像素点的相似性卷积核S。
  3. K=G*S,把K归一化。
  4. K与窗口大小的像素进行卷积,即求出该像素点值。

 

在OpenCV里可以采用下面函数bilateralFilter来计算:

#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import cv2
import numpy as np

#图片的路径
imgname = "gauss1.jpg"

#读取图片
image = cv2.imread(imgname, cv2.IMREAD_GRAYSCALE)

#图片的高度和宽度
h,w = image.shape[:2]
print('imagesize={}-{}'.format(w,h))

#显示原图
cv2.imshow("Image",image)

#平滑
out = cv2.bilateralFilter(image,9,75,75)
out = out.astype(np.uint8)
cv2.imshow("out",out)


cv2.waitKey(0)
cv2.destroyAllWindows()

结果输出如下:

在OpenCV里实现双边滤波

输入图片

在OpenCV里实现双边滤波

输出图片

其中函数定义如下:

dst=cv.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

参数解释:

src:输入图像

d:过滤时周围每个像素领域的直径

sigmaColor:在color space中过滤sigma。参数越大,临近像素将会在越远的地方mix。

sigmaSpace:在coordinate space中过滤sigma。参数越大,那些颜色足够相近的的颜色的影响越大。

dst是返回结果。

https://blog.csdn.net/caimouse/article/details/51749579

相关标签: opencv