matlab 邻域操作 colfilt、nlfilter、imfilter的使用详解和比较
(2013-11-13 11:13:26)
转载▼
标签: 教育 |
一 img = colfilt(img,[m n],'block_type', @myfunction);
colfilt是matlab中邻域操作速度最快的一种,但它占有内存较大。
usage:(参见help colfilt)
1 读入img,得到img.rows*img.size矩阵;
2 对每个像素,取[m n]的邻域,对边界处,默认为0填充;(也可用replicate等填充,举例见下)
3 对每个邻域像素,按列顺序遍历,展开成m*n为列向量;
4 调用im2col函数,将img.rows*img.size个列向量组合成(m*n)*(img.rows*img.size)的临时矩阵;
5 myfunction对整个临时矩阵的每一列操作,如myfunction为mean,则对临时矩阵的每一列算平均值,最后返回
1*(img.rows*img.size)的行向量;
6 调用col2im函数,将1*(img.rows*img.size)的行向量转化成img.rows*img.size的矩阵,得到结果。
另外:
1 matlab中矩阵的第一行是1,而c++中是0!
2 colfilt步骤4中临时矩阵的列是动态的,故所有涉及到某一列的操作都出错,但是为什么这样设计呢?
(一个理解:matlab每次在临时矩阵中取随机列数的子矩阵,对其进行myfunction的操作)
实例:
% testing 对矩阵取邻域中中间位置的值,返回原矩阵;
b= [1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5]
c=colfilt(b, [3 3], 'sliding', @myfilter);
function re = myfilter(A)
rows = size(A, 1);
rows = floor(rows/2 +1);
re = A(rows, :);
end
以上得到正确的结果。
关键:自定义函数返回的必须是1*(???)的行向量!
如果将:
rows = size(A, 1);
rows = floor(rows/2 +1);
re = A(rows, :);
改为:
[rows cols] = size(A);
rows = floor(rows*cols/2 +1);
re = A(rows, :);
结果出错:
Error in ==> colfilt at 149
b = reshape(feval_r(fun,x,params{:}), size(a));
原因在于:cols是动态变化的!
填充举例:
在应用colfilt前进行相关填充操作,这里举例replicate:
b=[1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5];
c = padarray(b, [2 2], 'replicate')
replicate后面的参数direction默认为both,即四个方向都填充。得到:
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
在应用colfilter: a=colfilt(c, [3 3], 'sliding', @myfilter),得到:
a =
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
1 1 1 2 3 4 5 5 5
还原到原来的大小:
[m n]= size(a)
a = a(3:m-2,3:n-2),得到:
a =
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
二 B = nlfilter(A, [m n], @myfun)
usage:(参见help nlfilter)
1 读入img,得到img.rows*img.size矩阵;
2 对每个像素,取[m n]的邻域,对边界处,默认为0填充;(也可用replicate等填充,举例见下)
3 调用fun函数,传入参数为m*n矩阵,返回的是邻域中心的新值;
4 循环遍历整张图片所有像素,得到结果。
比较:colfilt中的myfuncition处理的是(m*n)*(img.rows*img.size)的临时矩阵,实际应用
myfunction时,每次传入的矩阵列数是动态变化的!故定义中任何有关列数的操作都是错误的!
nlfilter中的myfuncition处理的是每个像素对应的邻域构成的m*n矩阵,定义时就当固定矩阵处理。
三 B = imfilter(A, H, option1, option2,...)
usage:colfilt和nlfilter主要用在非线性滤波中,imfilter则用在线性滤波中。
A:待处理的矩阵;
H:滤波模板,matlab中定义了很多现成的滤波模板;
option1:边界参数,定义怎样填充A的边界,replicate还是0或者是circular;
option2:输出参数,'same'表示输出矩阵和输入一样大;'full'输出矩阵和填充后矩阵一样大。
matlab 邻域操作 colfilt、nlfilter、imfilter的使用详解和比较_流浪的大锤_新浪博客 http://blog.sina.com.cn/s/blog_bfb1429c0101kkzm.html