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