这是一个更普遍的问题,但是,无论我多少次读过MATLAB的im2col函数的描述,我都无法完全理解它。我需要它来提高计算效率,因为MATLAB对嵌套for循环很糟糕。这是我正在尝试做的事情,但使用嵌套for循环:
[TRIMMED]=TM_FILTER(IMAGE, FILTER_SIZE, PERCENT)
Takes a 2-D array and returns the array, filtered with a
square trimed mean filter with length/width equal to FILTER_SIZE and percent equal to PERCENT.
%}
function [trimmed]=tm_filter(image, filter_size, percent)
if rem(filter_size, 2)==0 %make sure filter has a center pixel
error('filter size must be odd numbered'); %error and return if number is odd
return
end
if percent > 100 || percent < 0
error('Percentage must be ? [0, 100]');
return
end
[rows, columns]=size(image); %figure out pixels needed
n=(filter_size-1)/2; %n is pixel distance from center pixel to boundaries
padded=(padarray(image, [n,n],128)); %padding on boundaries so center pixel always has neighborhood
for i=1+n:rows %rows from first non-padded entry to last nonpadded entry
for j=1+n:columns %colums from first non-padded entry to last nonpadded entry
subimage=padded(i-n:i+n,j-n:j+n); %neighborhood same size as filter
average=trimmean(trimmean(subimage, percent), percent); %computes trimmed mean of neighborhood as trimmed mean of vector of trimmed means
trimmed(i-n, j-n)=average; %stores averaged pixel in new array
end
end
trimmed=uint8(trimmed); %converts image to gray levels from 0-255
答案 0 :(得分:3)
以下是您想要的代码:请注意整个嵌套循环已替换为单个语句。
[TRIMMED]=TM_FILTER(IMAGE, FILTER_SIZE, PERCENT)
Takes a 2-D array and returns the array, filtered with a
square trimed mean filter with length/width equal to FILTER_SIZE and percent equal to PERCENT.
%}
function [trimmed]=tm_filter(image, filter_size, percent)
if rem(filter_size, 2)==0 %make sure filter has a center pixel
error('filter size must be odd numbered'); %error and return if number is odd
return
end
if percent > 100 || percent < 0
error('Percentage must be ? [0, 100]');
return
end
trimmed = (uint8)trimmean(im2col(image, filter_size), percent);
说明:
im2col
函数将filter_size
的每个区域转换为一列。然后,您的trimmean
函数可以在单个操作中对每个区域(列)进行操作 - 比依次提取每个形状更有效。另请注意,这只需要trimmean
的单个应用程序 - 在您的原始文件中,您首先在列上执行,然后再在行上执行,这实际上会导致比我想要的更严重的修剪(首先排除50%)时间,然后再50% - 感觉就像排除75%。不完全正确,但你得到我的观点)。您还会发现更改操作的顺序(行,然后列与列,然后是行)将更改结果,因为过滤器是非线性的。
例如
im = reshape(1:9, [3 3]);
disp(im2col(im,[2 2])
结果
1 2 4 5
2 3 5 6
4 5 7 8
5 6 8 9
因为你从这个矩阵中取出了4个可能的2x2块中的每一个:
1 4 7
2 5 8
3 6 9
并将其转换为列
注意 - 使用此技术(应用于未填充的图像),您会在边缘丢失一些像素;你的方法添加了一些填充,这样每个像素(甚至是边缘上的像素)都有一个完整的邻域,因此过滤器会返回一个与原始像素大小相同的图像(但是不清楚填充/过滤的效果是什么靠近边缘,特别是角落:你有近75%的像素固定在128,这可能会主导角落里的行为。)
答案 1 :(得分:2)
为什么im2col
?为什么不nlfilter
?
>> trimmed = nlfilter( image, [filter_size filter_size],...
@(x) treimmean( trimmean(x, percent), percent ) );
您确定要处理整个图像吗?
i
和j
分别只有rows
和columns
。但是,当您更新trimmed
时,您可以访问i-n
和j-n
。最后n
行和列怎么样?
为什么每个块都应用trimmean
两次?是否更适合一次处理块,如trimmean( x(:), percent)
?
我相信trimmean( trimmean(x, percent), percent)
的结果与<{1}}的结果相比不同。你有没有想过?