【问题标题】:nlfilter taking same values twicenlfilter 两次取相同的值
【发布时间】:2011-04-17 07:18:22
【问题描述】:

我使用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,依此类推。为什么会这样?

【问题讨论】:

    标签: matlab


    【解决方案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 循环中。这意味着您观察到的“重复”值不会影响您的最终输出矩阵,您不必担心。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 我使用length函数获取元素个数。我在这里没有使用分号,因为我想检查函数的进展情况。感谢您的建议!
      猜你喜欢
      • 2020-04-10
      • 2018-03-13
      • 1970-01-01
      • 2021-06-04
      • 1970-01-01
      • 2021-05-24
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多