這是一個有趣的問題。有趣的是你的方法幾乎完美。它失敗的唯一原因是因爲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)
[email protected] scalar = NaN; % Maximum
[email protected] scalar = NaN; % Minimum
[email protected] scalar = NaN; % Mean
[email protected] scalar = NaN; % Mean absolute deviation y = mean(abs(X-mean(x)))
[email protected] scalar = NaN; % Median
[email protected] scalar = NaN; % Root mean square
[email protected] scalar = NaN; % Stardard deviation
[email protected] scalar = NaN; % Variance
[email protected] 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
墊用零您的陣列,這意味着(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)
將在索引中找到進一步的「內部」的輸出陣列(在WINDOW_SZ=3
的情況下)。
你不能直接做,因爲(如你所寫),'nlfilter'接受一個標量函數句柄。您可以爲'out'結構的每個字段編寫一次調用'nlfilter'的封裝器。 –
什麼是包裝?我無法理解。你能爲我編輯一個示例代碼嗎?現在,我有一個想法,我可以將out結構數組保存爲mat文件。但是如果我這樣做,將會有太多的mat文件。如果我想使用輸出結果,加載這些文件需要很長時間mat文件。我只是想將輸出保存到一個mat文件中。你有什麼好主意嗎?謝謝! @Itamar Katz –
目前尚不清楚您的期望輸出是什麼。 'nlfilter'返回一個矩陣,如果你的結構體具有'n'字段,並且你有一個這樣的長度爲'm'的結構體的數組,那麼你就得到了m * n'矩陣。你想如何存儲它們? –