这里主要通过实现一个均值滤波来阐述图像滤波的具体操作。本系列博客,注重图像处理领域基本算法的原理,主要用matlab语言实现。
1、滤波模板的产生
首先,滤波要有模板,在matlab中。得到模板的途径主要有两种,一种是自己定义,另一种是通过调用函数fspecial得到各种类型的模板。
下面看一个均值滤波器的模板的产生,模板就是一个矩阵,这个没疑问吧!!!
fspecial('average')
ans =
1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
顺便说一下啊,通过库函数实现图像滤波的基本过程
对于线性滤波器,通常使用imfilter函数实现滤波。
对于非线性滤波,通常使用colfilt函数实现。中值滤波由于太常用,有单独封装的函数medfilt2.
2、滤波具体实现过程
有了模板之后,要做的工作主要就是让模板滑过我们的图像,然后与对应模板下面的元素做卷积运算(别把卷积看到吓死人,从上一篇博客可以看出,卷积对应离散的图像而言就是相乘求和的一个过程),不过在这个操作之前,一般需要对图像的边缘进行填充,想一下就能理解为什么要进行填充了是吧!!不懂的可以见这篇博客点击打开链接
或者还是参考冈萨雷斯的书,实在是太经典了,经典到每个字,真心的!!!
input = imread('lena.bmp');
mask = 1 / 16 * [1 2 1; 2 4 2; 1 2 1]; % 考虑3*3的滤波模板
% 使用库函数实现(在对sobel求取边缘的时候貌似也得分别求水平和垂直边缘)
output1 = imfilter(double(input), mask, 'conv', 0, 'full'); %求竖边缘
% 下面自己实现
[m, n] = size(input);
% 先填充输入图像,这里依旧通过0来填充外边界
input_temp = zeros(m + 4, n + 4);
% 初始化输入图像
input_temp(3: m + 3 - 1, 3: n + 3 - 1) = input;
% 让模板滑过扩展的输入向量
xx = size(input_temp, 1) - 3 + 1;
yy = size(input_temp, 2) - 3 + 1;
output = zeros(xx,yy);
for i = 1: xx
for j = 1: yy
output(i, j) = sum( sum( input_temp(i: i + 3 - 1 , j : j + 3 - 1) .* mask ) ) ;
end
end
fprintf('调用库函数imfilter完成相关运算');
subplot(131);imshow( uint8(input) ); title('原图像');
subplot(132);imshow( uint8(output1) );title('调用库函数实现均值滤波');
subplot(133);imshow( uint8(output) ); title('自己实现均值滤波');
% 看自己的滤波函数是否有问题
equal = sum(sum(output1 ~= output)) % equal = 0 表示处理后的结果一样
运行图:
equal =
0
equal等于0,表明自己实现的均值滤波和库函数得到同样的结果。
ok,搞定!!!!