一、原理
双边滤波有两个功能:滤波和保留边界。使用两个核处理图像,记作K核、v核。
其中:K核满足空域的高斯分布(滤波),V核满足值域的高斯分布(保留边界)。
空域的高斯分布:离中心像素点越近,权值越大,否则越小。

其中u,v为核的中心坐标。
值域的高斯分布:与中心像素点差值越大,权值越小,否则越大。

其中f(u,v)为中心点像素值。
那么双边滤波的核为K*V。
二、Opencv代码实现
1.K核
代码如下(示例):
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include<cmath>
using namespace cv;
using namespace std;
Mat get_K(Size size, float kesi,int type) {
Mat filter = Mat::zeros(size, type);
int center = filter.rows / 2;
float sum=0.0;
for (int i = 0; i < filter.rows; i++)
{
for (int j = 0; j < filter.cols; j++)
{
filter.at<float>(i, j) = std::exp(-0.5*pow((sqrt((i - center)* (i - center) + (j - center) * (j - center)) / kesi),2.0));
sum += filter.at<float>(i, j);
}
}
filter /= sum;
return filter;
}
2.V核
代码如下(示例):
Mat get_val(const Mat &srcpart, Size size, float kesi, int type) {
Mat filter = Mat::zeros(size, type);
float sum = 0.0;
int center = filter.rows / 2;
for (int i = 0; i < filter.rows; i++)
{
for (int j = 0; j < filter.cols; j++)
{
filter.at<float>(i, j) = std::exp(-0.5 * pow(srcpart.at<uchar>(i, j) - srcpart.at<uchar>(center, center) / kesi, 2));
sum += filter.at<float>(i, j);
}
}
filter /= sum;
return filter;
}
3.Opencv 库函数bilateralFilter
可以发现,有两个sigma,对应值域与空域高斯分布的方差。

总结
双边滤波由空域核值域的高斯分布核构成。
本文详细介绍了双边滤波的工作原理,包括空域高斯分布和值域高斯分布的作用,并提供了使用OpenCV实现双边滤波的C++代码示例,重点讲解了K核和V核的构造方法。同时,提到了Opencv库函数bilateralFilter中两个sigma参数的含义。

被折叠的 条评论
为什么被折叠?



