作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
实现原理
AMF(Adaptive Median Filter,自适应中值滤波)是一种用于图像处理和信号处理的滤波算法,其目的是在保持图像细节的同时去除噪声。它是基于中值滤波的一种改进,可以根据局部像素的灰度值特征自适应地调整滤波器的大小和形状。
AMF算法的主要思想是根据像素邻域的特征动态调整滤波器的尺寸和形状,以适应不同区域的噪声水平和图像细节。具体步骤如下:
-
参数和初始化:
- 函数接受一个输入图像
input
和一个整数参数winSize
,表示滤波器的初始大小。 - 创建一个和输入图像大小相同的输出图像
output
,用于存储滤波结果。 - 变量
R
为窗口半径的最大限制值。
- 函数接受一个输入图像
-
窗口处理:
- 对于每个像素
(i, j)
,以其为中心构建一个大小为(2*r+1)*(2*r+1)
的窗口。 - 在窗口边界进行限制,防止越界。
- 对于每个像素
-
窗口数据排序:
- 将窗口内的像素值存储在
datas
中,并进行排序。
- 将窗口内的像素值存储在
-
计算中值和最值:
- 计算排序后的数据中的最小值
minValue
、最大值maxValue
和中值midValue
。
- 计算排序后的数据中的最小值
-
判断是否需要扩大窗口:
- 根据中值与最小值、最大值的差值是否超过某个阈值
thresh
来决定是否需要扩大窗口。 - 如果窗口内的中值不在最小值和最大值之间一定范围内,则继续扩大窗口,直到r大于R。
- 根据中值与最小值、最大值的差值是否超过某个阈值
-
滤波处理:
- 如果当前像素值与窗口最值的差值大于阈值,说明不需要滤波,直接将当前像素值赋给输出图像的对应位置。
- 否则,将窗口内的中值赋给输出图像的对应位置。
-
返回结果:
- 返回处理后的输出图像。
AMF算法的优点是能够有效地处理不同区域的噪声和图像细节,因为它在滤波器大小和形状上具有自适应性。然而,它也有一些缺点,比如计算复杂度较高,处理速度较慢,特别是对于大尺寸的滤波器。
总的来说,AMF算法是一种灵活而有效的滤波器,特别适用于那些噪声水平不均匀且图像细节丰富的场景,尤其是针对椒盐噪声。
功能函数代码
为了对比效果,我自写了一个经典的中值滤波,和AMF进行对比。注意别用Matlab自带的中值滤波,那个是内部函数执行,速度很快,脚本M代码和其没有可比性。如下是两个算法的代码。
function output = adaptiveMedianFiltering(input, winSize)
[row, col] = size(input);
output = uint8(zeros(row, col));
R = floor(winSize / 2);
% 遍历处理
for i = 1:row
for j = 1:col
r = 1;
while r <= R
% 卷积窗口边界限制,防止越界
ms = max(i - r, 1);
me = min(i + r, row);
ns = max(j - r, 1);
ne = min(j + r, col);
% 窗口内有效数据排序
datas = reshape(input(ms:me, ns:ne), [], 1);
% 计算数值
minValue = min(datas);
maxValue = max(datas);
midValue = median(datas);
% 若窗口内中值不为在最值一定范围内,则说明当前窗口尺寸足够,不需要扩展也可完成有效滤波;反之,则继续扩大窗口,直到最大窗口尺寸
thresh = (maxValue - minValue) * 0.02;
if (midValue - minValue) > thresh && (maxValue - midValue) > thresh
% 若数据本身就不为最值,则不需要滤波,这也是自适应算法保持高分辨的关键
if (input(i, j) - minValue) > thresh && (maxValue - input(i, j)) > thresh
output(i, j) = input(i, j);
% 若为最值,则说明当前数值大概率是噪声信息,进行中值滤波
else
output(i, j) = midValue;
end
break;
else
r = r + 1;
end
% 如果窗口尺寸达到限制了,则直接滤波
if r > R
output(i, j) = midValue;
end
end
end
end
end
cpp
function output = myMedianFilter(input, windowSize)
[rows, cols] = size(input);
output = uint8(zeros(rows, cols));
% 计算窗口半径
R = floor(windowSize / 2);
% 对每个像素进行处理
for i = 1:rows
for j = 1:cols
% 获取当前像素的窗口范围
start_row = max(1, i - R);
end_row = min(rows, i + R);
start_col = max(1, j - R);
end_col = min(cols, j + R);
% 提取窗口内的像素值
window = input(start_row:end_row, start_col:end_col);
% 对窗口内的像素进行排序,并计算中值
sorted_window = sort(window(:));
median_index = floor(numel(sorted_window) / 2) + 1;
median_value = sorted_window(median_index);
% 将中值赋给输出图像的当前像素
output(i, j) = median_value;
end
end
end
Matlab测试代码
cpp
% 读取图像
image = imread('test.jpg');
image_gray = rgb2gray(image);
% 添加随机椒盐噪声
noise = image_gray;
[row, col] = size(image_gray);
for i = 1:10:row
for j = 1:10:col
noise(i, j) = randi([0, 255]);
end
end
% 传统中值滤波
winSize = 15;
tic
median = myMedianFilter(noise, [winSize, winSize]);
toc
% AMF算法处理
tic
resultimage = adaptiveMedianFiltering(noise, winSize);
toc
% 显示图像
figure;
subplot(2, 2, 1);
imshow(image_gray);
title('Original Image');
subplot(2, 2, 2);
imshow(noise);
title('Noisy Image');
subplot(2, 2, 3);
imshow(median);
title('Median Processed Image');
subplot(2, 2, 4);
imshow(resultimage);
title('AMF Processed Image');
测试效果
图1 对比
如上图所示,经典中值滤波算法会让整个图模糊失真,而AMF算法可以很好保证图像细节不丢失。
图2 计算速度
计算速度方面,滤波窗尺寸15*15,经典中值滤波速度16s,AMF只有6s,这是因为自适应窗口并非每次都会扩展到15,可能3、5、7的时候就已经完成滤波了,因此速度快。
C++版本见(OpenCV):
OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering)-CSDN博客
如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!