2

这是一个更笼统的问题,但是,无论我阅读多少次 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
4

2 回答 2

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,这可能会主导角落的行为)。

于 2013-06-20T18:43:35.183 回答
2
  1. why im2col? why not nlfilter?

    >> trimmed = nlfilter( image, [filter_size filter_size],...
                           @(x) treimmean( trimmean(x, percent), percent ) );
    
  2. Are you sure you process the entire image?
    i and j only goes up to rows and columns respectively. However, when you update trimmed you access i-n and j-n. What about the last n rows and columns?

  3. Why do you apply trimmean twice for each block? Isn't it more appropriate to process the block at once, as in trimmean( x(:), percent)?
    I believe the results of trimmean( trimmean(x, percent), percent) will be different than those of trimmean( x(:), percent). Have you give it a thought?

  4. A small remark, it is best not to use i and j as variable names in matlab.

于 2013-06-20T18:27:28.447 回答