簡體   English   中英

當我使用nlfilter函數時如何輸出結構數組?

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

我有以下函數來計算統計參數。 我想將此函數傳遞給nlfilter來對整個圖像進行計算。 但是nlfilter的輸出必須是標量。

如何將其轉換為適合與nlfilter一起使用的函數句柄,以便我可以保存函數getStatistics2的輸出?

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

這是個有趣的問題。 有趣的是,你的方法幾乎是完美的。 它失敗的唯一原因是因為struct不能使用數字標量輸入(即struct(3) )構造。 我提到這個的原因是因為在執行nlfilter期間的某個地方(特別是在mkconstarray.m ),它調用以下代碼:

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

哪里:

  • class'struct'
  • value 0
  • size是輸入圖像的size() ,例如[100,100]

...這失敗了因為feval('struct', 0) ,它等同於struct(0) - 而且我們已經知道這是無效的。

那么我們該怎么辦? 創建一個可以這種方式構建的自定義類!

以下是一個這樣的類的示例:

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

以下是如何使用它:

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

請注意,我添加了一個可選輸入( outputAsStruct ),它可以強制輸出為struct數組(而不是我們的自定義類的數組,它在功能上與只讀struct相同)。

另請注意,默認情況下, nlfilter用零nlfilter數組,這意味着(1,1)輸出將在一個看起來像這樣的數組上運行(假設WINDOW_SZ=3 ):

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

而不是在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]

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