用C++语言写一个双边滤波器
双边滤波器是一种基于空间和灰度两个维度进行滤波的图像处理算法,可以用来平滑图像并保留边缘信息。下面是一个基于C++语言实现的双边滤波器代码:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <cmath>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
// 读取输入图像
Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);
if (img.empty())
{
cout << "Could not read the image: " << argv[1] << endl;
return 1;
}
// 设置滤波器参数
int d = 15; // 空间域直径
double sigma1 = 50; // 空间域标准差
double sigma2 = 50; // 灰度域标准差
// 创建输出图像
Mat dst(img.size(), img.type());
// 对每个像素进行滤波
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
double sum = 0;
double weight = 0;
// 计算滤波器中心点与当前像素之间的距离
for (int k = -d / 2; k <= d / 2; k++)
{
for (int l = -d / 2; l <= d / 2; l++)
{
int pi = i + k;
int pj = j + l;
// 判断像素是否越界
if (pi >= 0 && pi < img.rows && pj >= 0 && pj < img.cols)
{
// 计算空间域权重
double space_weight = exp(-(k * k + l * l) / (2 * sigma1 * sigma1));
// 计算灰度域权重
double gray_weight = exp(-(img.at<uchar>(i, j) - img.at<uchar>(pi, pj)) * (img.at<uchar>(i, j) - img.at<uchar>(pi, pj)) / (2 * sigma2 * sigma2));
// 计算双边滤波器权重
double w = space_weight * gray_weight;
// 更新滤波器输出值和权重
sum += w * img.at<uchar>(pi, pj);
weight += w;
}
}
}
// 更新输出图像像素值
dst.at<uchar>(i, j) = sum / weight;
}
}
// 显示输入和输出图像
namedWindow("Input", WINDOW_NORMAL);
namedWindow("Output", WINDOW_NORMAL);
imshow("Input", img);
imshow("Output", dst);
waitKey(0);
return 0;
}
在这个代码中,我们首先读取了输入图像,然后设置了滤波器的参数(即空间域直径、空间域标准差和灰度域标准差)。接下来,我们创建了一个与输入图像大小相同的输出图像,然后对每个像素进行滤波。在双层循环中,我们首先计算当前像素与滤波器中心点之间的距离,然后计算空间域权重、灰度域权重和双边滤波器权重,并更新滤波器输出值和权重。最后,我们更新输出图像的像素值并显示输入和输出图像。
原文地址: https://www.cveoy.top/t/topic/qig 著作权归作者所有。请勿转载和采集!