线性滤波(对像素滤波)
线性运算包括将邻域中每个像素与相应的系数相乘,然后将结果进行累加,从而得到点(x, y)处的响应。若邻域的大小为mxn,则总共需要mn个系数。这些系数排列为一个矩阵,我们称其为滤波器、掩模、滤波掩模、核、模板或窗口,前三种术语最为通用。为简便起见,也常使用卷积滤波、掩模或核等术语。
在每个点(x,y)处,滤波器在该点处的响应是滤波掩模所限定的相应邻域像素与滤波器系数的乘积结果的累加。
所有假设都是基于掩模的大小应均为奇数的原则,有意义掩模的最小尺寸是3 x 3。尽管并不是一个必须具备的条件,但处理奇数尺寸的掩模会更加直观,因为它们都有惟一的一个中心点。
实际中的线性滤波要用到这两个易混淆的概念
-
相关
掩模w按上图所示的方式在图像f中移动的过程。 -
卷积
从技术上讲,卷积是相同的过程,只是在图像f中移动w前,要将w旋转180°。
语法实现imfilter
g = imfilter(f, W,filtering_ mode, boundary_ options,...
size_options)
%f是输人图像,w为滤波掩模,g为滤波结果
%filtering_mode用于指定在滤波过程中是使用相关( 'corr' )还是卷积( 'conv' )
%boundary_ options 用于处理边界充零问题,边界的大小由滤波器的大小确定
%size_options可以是'same'或'full'
具体使用见下表:
imfilter的选项
滤波类型
选项 | 描述 |
---|---|
‘corr’ | 滤波通过使用相关来完成。该值是默认值 |
‘conv’ | 滤波通过使用卷积来完成 |
边界选项
选项 | 描述 |
---|---|
P | 输入图像的边界通过用值P (无引号)来填充来扩展。P的默认值为0 |
‘replicate’ | 图像大小通过复制外边界的值来扩展 |
‘symmetric’ | 图像大小通过镜像反射其边界来扩展 |
‘circular’ | 图像大小通过将图像看成是一个二维周期函数的一个周期来扩展 |
大小选项
选项 | 描述 |
---|---|
‘full’ | 输出图像的大小与被扩展图像的大小相同 |
‘same’ | 输出图像的大小与输入图像的大小相同。这可通过将滤波掩模的中心点的偏移限制到原图像中包含的点来实现。该值为默认值 |
A = [1 0; 0 1];
B = ones(256, 256);
C = kron(A, B); %得到一幅512*512的图像
subplot(121)
imshow(C) %原图
subplot(122)
w = ones(31,31);%平均滤波器
gd = imfilter(C, w);
imshow(gd, [])
对比原图可以知道,滤波器处理之后会产生模糊的效果,由于我们没有设定边界条件,默认为黑色填充了边界。
选择边界条件之后来看看效果
A = [1 0; 0 1];
B = ones(256, 256);
C = kron(A, B); %得到一幅512*512的图像
subplot(221)
imshow(C) %原图
subplot(222)
w = ones(31,31);
gr = imfilter(C, w,'replicate');
imshow(gr, [])
subplot(223)
gs = imfilter(C, w,'symmetric');
imshow(gs, [])
subplot(224)
gc = imfilter(C, w,'circular');
imshow(gc, [])
下图显示了原图和选择了三种边界条件之后的结果图
replicate和symmetric体现了较好的效果,但circular出现的问题与使用零填充的问题相同。因为周期的使用可使得图像像的黑暗部分靠近光亮区域。
如果图像为uint8类型会怎么样呢
f8 = im2uint8(C);
gr8 = imfilter(f8, w,'replicate');
imshow(gr8, [])
从图中很容易看到数据发生了丢失。故实际中要进行归一化处理。
非线性滤波
工具箱提供了两个执行常规非线性滤波的函数,即函数nlfilter和函数colfilt。
- 函数nlfilter直接执行二维操作
- 函数colfilt以列的形式组织数据。需要占用更多的内存,但是执行起来要比nlfilter快得多。在执行常规的非线性空间滤波时,我们更多采用的是colfilt而不是nlfllter。
给定一个大小为M x N的图像f和一个大小为为m x n的邻域,函数colfilt生成一个最大尺寸为mn x MN的矩阵A,在该矩阵中,每一列对应于其中心位于图像内某个位置的邻域所包围的像素。
colfilt
g = colfilt(f, [m n], 'sliding', @fun, parameters)
%m和n也是滤波区域的维数
%'sliding' 表示处理过程是在输人图像f中逐个像素地滑动该m x n区域
% @ fun引用一个函数,我们将该函数任意表示为fun
%parameters表示函数fun可能需要的参数(由逗号分隔开)
%符号@称为函数句柄,它是一种MATLAB数据类型,它包含有引用函数用到的一些信息
而实际上在对图像滤波之前,要进行输入前图像的填充,使用padarray
padarray
对于二维函数,它的语法为
fp = padarray(f, [r c],method, direction)
% f为输入图像
% fp为填充后的图像
% [r c]用于给出填充f的行数和列数
函数padarray的选项
method
选项 | 描述 |
---|---|
‘symnetric’ | 图像大小通过围绕边界进行镜像反射来扩展 |
‘replicate’ | 图像大小通过复制外边界中的值来扩展 |
‘circular’ | 图像大小通过将图像看成是一个二维周期函数的一个周期来进行扩展 |
direction
选项 | 描述 |
---|---|
‘pre’ | 在每一维的第一个元素前填充 |
‘post’ | 在每一维的最后一个元素后填充 |
‘both’ | 在每一维的第一个元素前和最后一个元素后填充。此选项为默认值 |
举个例子:
f = [1 2; 3 4];
fp = padarray(f, [3 2], 'replicate', 'post' )
输出如下:
若参量中不包括direct ion,则默认值为’both’。若参量中不包含method,则默认用零来填充。
若参量中不包括任何参数,则默认填充为零且默认方向为’both’。
在计算结束时,图像会被修剪为原始大小。
实例
使用两者结合来执行一个非线性滤波,该非线性滤波在任何点处的响应都是中心在该点的邻城内的像素亮度值的几何平均。大小为mxn的邻域中的几何平均是邻域内亮度值的乘积的1/mm次幂。我们首先执行非线性滤波函数
- 调用gmean
function v = gmean (A)
mn = size(A, 1);
%各The length of the columns of A is always mn.
V = prod(A, 1) .^ (1/mn) ;
- 滤波
f = padarray(f, [m n],' replicate') ;
g = colfilt(f, [m n], 'sliding', @gmean) ;
或者
f = [1 2; 3 4];
m = 3;
n = 2;
h = @(A) prod(A, 1).^(1/size(A, 1));
f = padarray(f, [m n],'replicate') ;
g = colfilt(f, [m n], 'sliding', h)
得到输出为: