简体   繁体   English

当我使用nlfilter函数时如何输出结构数组?

[英]How to output a struct array when I use the nlfilter function?

I have the following function which calculates statistic parameters. 我有以下函数来计算统计参数。 I would like to pass this function to nlfilter to do the calculation for a whole image. 我想将此函数传递给nlfilter来对整个图像进行计算。 But the output of nlfilter must be a scalar. 但是nlfilter的输出必须是标量。

How can I convert this to a function handle suitable for use with nlfilter so I can save the output of the function getStatistics2 ? 如何将其转换为适合与nlfilter一起使用的函数句柄,以便我可以保存函数getStatistics2的输出?

The getStatistics2 function's output is an struct array. getStatistics2函数的输出是一个struct数组。

function [out] = getStatistics2(D)
D = double(D);   
% out.MAX = max(D);%maximum
% out.MIN = min(D);%minimum
out.MEA = mean(D);%mean
out.MAD = mad(D);% mean absolute deviation y=mean(abs(X-mean(x)))
out.MED = median(D);%median
out.RAN = max(D) - min(D);%range
out.RMS = rms(D);%root mean square
out.STD = std(D);%stardard deviation
out.VAR= var(D);%variance

This is an interesting question. 这是个有趣的问题。 What's interesting is that your approach is almost perfect. 有趣的是,你的方法几乎是完美的。 The only reason it fails is because struct cannot be constructed using a numeric scalar input (ie struct(3) ). 它失败的唯一原因是因为struct不能使用数字标量输入(即struct(3) )构造。 The reason I mention this is because somewhere during the execution of nlfilter (specifically in mkconstarray.m ), it calls the the following code: 我提到这个的原因是因为在执行nlfilter期间的某个地方(特别是在mkconstarray.m ),它调用以下代码:

repmat(feval(class, value), size);

Where: 哪里:

  • class is 'struct' . class'struct'
  • value is 0 . value 0
  • size is the size() of the input image, eg [100,100] . size是输入图像的size() ,例如[100,100]

... and this fails because feval('struct', 0) , which is equivalent to struct(0) - and this we already know to be invalid. ...这失败了因为feval('struct', 0) ,它等同于struct(0) - 而且我们已经知道这是无效的。

So what do we do? 那么我们该怎么办? Create a custom class that can be constructed this way! 创建一个可以这种方式构建的自定义类!

Here's an example of one such class: 以下是一个这样的类的示例:

classdef MyStatsClass % Value class

  properties (GetAccess = public, SetAccess = private)
    MAX@double scalar = NaN;  % Maximum
    MIN@double scalar = NaN;  % Minimum
    MEA@double scalar = NaN;  % Mean
    MAD@double scalar = NaN;  % Mean absolute deviation y = mean(abs(X-mean(x)))
    MED@double scalar = NaN;  % Median
    RMS@double scalar = NaN;  % Root mean square
    STD@double scalar = NaN;  % Stardard deviation
    VAR@double scalar = NaN;  % Variance
    RAN@double scalar = NaN;  % Range    
  end % properties

  methods (Access = public)
    %% Constructor:
    function obj = MyStatsClass(vec)
      %% Special case:
      if (nargin == 0) || (numel(vec) == 1) && (vec == 0)
        % This happens during nlfilter allocation
        return
      end      
      %% Regular case:
      obj.MAX = max(vec(:));       
      obj.MIN = min(vec(:));
      obj.MEA = mean(vec(:));
      obj.MAD = mad(vec(:));
      obj.MED = median(vec(:));
      obj.RMS = rms(vec(:));
      obj.STD = std(vec(:));
      obj.VAR = var(vec(:));
      obj.RAN = obj.MAX - obj.MIN;
    end % default constructor
  end % public methods
end % classdef

And here's how you can use it: 以下是如何使用它:

function imF = q35693068(outputAsStruct)
if nargin == 0 || ~islogical(outputAsStruct) || ~isscalar(outputAsStruct)
  outputAsStruct = false;
end

rng(35693068); % Set the random seed, for repeatability
WINDOW_SZ = 3;
im = randn(100);
imF = nlfilter(im, [WINDOW_SZ WINDOW_SZ], @MyStatsClass);

% If output is strictly needed as a struct:
if outputAsStruct
  warning off MATLAB:structOnObject
  imF = arrayfun(@struct,imF);
  warning on MATLAB:structOnObject
end

Notice that I have added an optional input ( outputAsStruct ) that can force the output to be a struct array (and not an array of the type of our custom class, which is functionally identical to a read-only struct ). 请注意,我添加了一个可选输入( outputAsStruct ),它可以强制输出为struct数组(而不是我们的自定义类的数组,它在功能上与只读struct相同)。

Notice also that by default nlfilter pads your array with zeros, which means that the (1,1) output will operate on an array that looks like this (assuming WINDOW_SZ=3 ): 另请注意,默认情况下, nlfilter用零nlfilter数组,这意味着(1,1)输出将在一个看起来像这样的数组上运行(假设WINDOW_SZ=3 ):

[0    0      0    
 0  1.8096 0.5189 
 0 -0.3434 0.6586]

and not on im(1:WINDOW_SZ,1:WINDOW_SZ) which is: 而不是在im(1:WINDOW_SZ,1:WINDOW_SZ) ,它是:

[ 1.8096 0.5189 0.2811
 -0.3434 0.6586 0.8919
 -0.1525 0.7549 0.4497]

the "expected result" for im(1:WINDOW_SZ,1:WINDOW_SZ) will be found further "inside" the output array (in the case of WINDOW_SZ=3 at index (2,2) ). im(1:WINDOW_SZ,1:WINDOW_SZ)的“预期结果”将在输出数组的“内部”中找到(在索引(2,2)WINDOW_SZ=3的情况下)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM