[英]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.