基于Matlab的双边滤波去噪
在图像处理领域,噪声就像是不速之客,破坏了图像原本的清晰与美感。双边滤波作为一种强大的去噪技术,如同图像的“美颜滤镜”,能在有效去除噪声的同时,最大程度保留图像的边缘细节。今天咱就来唠唠基于Matlab实现双边滤波去噪。
双边滤波原理速览
双边滤波综合考虑了空间距离和像素值差异的权重。简单说,对于目标像素,不仅会考虑它周围像素在空间位置上离它有多近(空间邻近度),还会看这些像素的灰度值和它有多相似(灰度相似性)。这就好比选朋友,既要住得近,性格脾气还得合得来。
数学公式表达如下:
基于Matlab的双边滤波去噪
\[ g(i,j) = \frac{1}{W{ij}} \sum{m,n} f(m,n) \cdot e^{-\frac{(i - m)^2+(j - n)^2}{2\sigmad^2}} \cdot e^{-\frac{(f(i,j)-f(m,n))^2}{2\sigmar^2}} \]
其中 \( g(i,j) \) 是滤波后输出像素值,\( f(m,n) \) 是输入图像像素值,\( W{ij} \) 是归一化系数,\( \sigmad \) 是空间域标准差,\( \sigma_r \) 是值域标准差 。
Matlab实现双边滤波
Matlab提供了便捷的函数imgaussfilt2来实现双边滤波,不过咱自己动手实现一下,能更好理解其中门道。
function filtered_img = bilateral_filter_manual(input_img, d, sigma_d, sigma_r) % 获取图像尺寸 [height, width] = size(input_img); % 初始化滤波后的图像 filtered_img = zeros(height, width); % 计算高斯核半径 r = floor(d / 2); for i = 1:height for j = 1:width % 初始化权重和加权像素值总和 weight_sum = 0; intensity_sum = 0; for m = max(1, i - r):min(height, i + r) for n = max(1, j - r):min(width, j + r) % 空间距离权重 spatial_weight = exp(-((i - m)^2 + (j - n)^2) / (2 * sigma_d^2)); % 灰度值差异权重 range_weight = exp(-(input_img(i, j) - input_img(m, n))^2 / (2 * sigma_r^2)); % 总权重 weight = spatial_weight * range_weight; % 累加加权像素值和权重 intensity_sum = intensity_sum + input_img(m, n) * weight; weight_sum = weight_sum + weight; end end % 计算滤波后的像素值 filtered_img(i, j) = intensity_sum / weight_sum; end end end代码分析
- 尺寸获取与初始化:
[height, width] = size(input_img); filtered_img = zeros(height, width);这部分获取输入图像的高度和宽度,并初始化一个与输入图像大小相同的全零矩阵filtered_img,用于存储滤波后的图像。
- 高斯核半径计算:
r = floor(d / 2);d代表邻域直径,通过floor(d / 2)计算出高斯核的半径r,用于确定参与滤波的邻域范围。
- 双重循环遍历像素:
for i = 1:height for j = 1:width这两层循环遍历输入图像的每一个像素,对每个像素进行双边滤波操作。
- 权重计算与累加:
for m = max(1, i - r):min(height, i + r) for n = max(1, j - r):min(width, j + r) spatial_weight = exp(-((i - m)^2 + (j - n)^2) / (2 * sigma_d^2)); range_weight = exp(-(input_img(i, j) - input_img(m, n))^2 / (2 * sigma_r^2)); weight = spatial_weight * range_weight; intensity_sum = intensity_sum + input_img(m, n) * weight; weight_sum = weight_sum + weight; end end这里面又嵌套了两层循环,遍历以当前像素(i,j)为中心的邻域像素(m,n)。分别计算空间距离权重spatialweight和灰度值差异权重rangeweight,两者相乘得到总权重weight。然后将邻域像素值乘以权重累加到intensitysum,权重累加到weightsum。
- 滤波后像素值计算:
filtered_img(i, j) = intensity_sum / weight_sum;最后用累加的加权像素值总和intensitysum除以权重总和weightsum,得到滤波后当前像素(i,j)的值,存入filtered_img中。
使用示例
% 读取图像 original_img = imread('lena.png'); % 将图像转换为灰度图 gray_img = rgb2gray(original_img); % 添加高斯噪声 noisy_img = imnoise(gray_img, 'gaussian', 0, 0.01); % 设置双边滤波参数 d = 5; % 邻域直径 sigma_d = 1.5; % 空间域标准差 sigma_r = 0.1; % 值域标准差 % 调用手动实现的双边滤波 filtered_img_manual = bilateral_filter_manual(noisy_img, d, sigma_d, sigma_r); % 显示图像 subplot(1,3,1); imshow(noisy_img); title('含噪声图像'); subplot(1,3,2); imshow(filtered_img_manual); title('手动双边滤波后图像'); subplot(1,3,3); imshow(original_img); title('原始图像');这段代码读取一张图像,将其转为灰度图后添加高斯噪声,然后调用手动实现的双边滤波函数对噪声图像进行处理,最后展示含噪声图像、滤波后图像以及原始图像。
双边滤波在图像去噪方面表现出色,无论是处理自然图像还是医学影像等专业领域图像,都能发挥重要作用。希望通过自己动手实现双边滤波,大家能对这个强大的图像处理技术有更深入的理解和掌握。