1

这个问题与这两个有关:
MATLAB中的向量化简介-有什么好的教程吗?
同时使用两个数组中的元素的过滤器

根据我阅读的教程,我试图对一些需要大量时间的过程进行矢量化。

我重写了这个:

function B = bfltGray(A,w,sigma_r)
dim = size(A);
B = zeros(dim);
for i = 1:dim(1)
    for j = 1:dim(2)

        % Extract local region.
        iMin = max(i-w,1);
        iMax = min(i+w,dim(1));
        jMin = max(j-w,1);
        jMax = min(j+w,dim(2));
        I = A(iMin:iMax,jMin:jMax);

        % Compute Gaussian intensity weights.
        F = exp(-0.5*(abs(I-A(i,j))/sigma_r).^2);
        B(i,j) = sum(F(:).*I(:))/sum(F(:));

    end
end

进入这个:

function B = rngVect(A, w, sigma)
W = 2*w+1;
I = padarray(A, [w,w],'symmetric');
I = im2col(I, [W,W]);
H = exp(-0.5*(abs(I-repmat(A(:)', size(I,1),1))/sigma).^2);
B = reshape(sum(H.*I,1)./sum(H,1), size(A, 1), []);

哪里
A是矩阵 512x512
w是窗口大小的一半,通常等于 5
sigma是范围 [0 1] 中的参数(通常是:0.1、0.2 或 0.3 之一)
所以I矩阵将有 512x512x121 = 31719424 个元素

但是这个版本似乎和第一个一样慢,而且它使用了大量的内存,有时会导致内存问题。

我想我做错了什么。可能是关于矢量化的一些逻辑错误。好吧,事实上我并不感到惊讶 - 这种方法创建了非常大的矩阵,并且计算可能成比例地更长。

我也尝试使用 nlfilter 编写它(类似于Jonas 给出的第二个解决方案),但它似乎很难,因为我使用的是Matlab 6.5 (R13)(没有可用的复杂函数句柄)。

所以再一次,我要求的不是现成的解决方案,而是一些可以帮助我在合理时间内解决这个问题的想法。也许你会指出我做错了什么。

编辑:
正如 Mikhail 所建议的,分析的结果如下:
65% 的时间花在线路上 H= exp(...)
25% 的时间用于im2col

4

1 回答 1

1

numel(I)*8I 和 H(即字节)有多大?如果您开始分页,那么您的第二个解决方案的性能将受到非常严重的影响。

要测试您是否真的因为数组太大而遇到问题,您可以尝试使用 和 来衡量计算速度,tic用于增加大小toc的数组A。如果执行时间增加的速度快于 A 大小的平方,或者如果执行时间以某个大小跳跃A,您可以尝试将填充的子数组拆分I为多个子数组并执行类似的计算。

否则,我看不到任何明显的地方可能会浪费很多时间。好吧,也许你可以跳过重塑,通过在你的函数中替换BA也节省一点内存),然后写 A(:) = sum(H.*I,1)./sum(H,1);

您可能还想考虑升级到最新版本的 Matlab - 他们一直在努力提高性能。

于 2010-05-23T18:53:25.417 回答