nlfilter两次使用相同的值

时间:2011-04-17 07:18:22

标签: matlab

我使用nlfilter作为我的测试函数,如下所示:

function funct
clear all;
clc;
I = rand(11,11);
ld = input('Enter the lag = ') % prompt for lag distance
A = nlfilter(I, [7 7], @dirvar);

% Subfunction
    function [h] = dirvar(I)
        c = (size(I)+1)/2
        EW = I(c(1),c(2):end)
        h = length(EW) - ld
    end
end

该函数工作正常,但预期nlfilter逐个元素地进行,但在前两次迭代中,EW的值将相同0.2089 0.4162 0.9398 0.1058。但是然后在所有迭代中选择下一个元素,第三个是0.4162 0.9398 0.1058 0.1920,第四个是0.9398 0.1058 0.1920 0.5201,依此类推。为什么会这样?

2 个答案:

答案 0 :(得分:1)

这无需担心。之所以会发生这种情况,是因为 nlfilter 需要评估您的函数以了解要创建的输出类型。所以它在开始移动图像之前使用 feval 一次。此 feval 调用的输出是您第一次看到的。

来自 nlfilter 代码:

% Find out what output type to make.
rows = 0:(nhood(1)-1);
cols = 0:(nhood(2)-1);
b = mkconstarray(class(feval(fun,aa(1+rows,1+cols),params{:})), 0, size(a));

% Apply fun to each neighborhood of a
f = waitbar(0,'Applying neighborhood operation...');
for i=1:ma,
    for j=1:na,
        x = aa(i+rows,j+cols);
        b(i,j) = feval(fun,x,params{:});
    end
    waitbar(i/ma)
end

eval 的第4行调用是您从EW的第一个输出中观察到的,但除了使b矩阵成为正确的类之外,它不被用于任何其他内容。所有正确的迭代都发生在下面的 for 循环中。这意味着您观察到的“重复”值不会影响最终输出矩阵,您无需担心。

答案 1 :(得分:0)

我希望你知道length函数的功能吗?它不会给出向量的欧几里德长度,而是给出向量的最大维数(所以在你的情况下,应该是4)。如果您想要欧几里德长度(或2范数),请改用函数norm。如果你的代码做的正确,你可能想要使用类似的东西:

sz = size(I,2);
h = sz - (sz+1)/2 - ld;

在您的示例中,这意味着根据您提供的延迟,输出应该是常量。另请注意,您可能希望在子函数中的每一行之后放置分号,并且使用clear all作为函数的第一行是无用的,因为函数将始终在其自己的工作空间中执行(但是这将清除持久性或全局变量,但不要在代码中使用它们。)