如何在matlab中填充不规则形状矩阵



我有一个矩阵,值在中心,nan在边界(想象一个矩阵代表一个分水岭,它不是正方形的)。我需要用一个单元填充它来做一些分量应力计算。我试图避免使用核心Matlab功能的外部库,但我想做的是类似于padarray对称,但对于不规则的边界:

padarray(Zb,[1 1],'symmetric','both');

例如:

NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
NaN   NaN   NaN     2     5    39    55    44     8   NaN   NaN   NaN
NaN   NaN   NaN   NaN     7    33    48    31    66    17   NaN   NaN
NaN   NaN   NaN   NaN    28   NaN    89   NaN   NaN   NaN   NaN   NaN
NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN

就变成:

NaN   NaN     2     2     5    39    55    44     8    8   NaN   NaN
NaN   NaN     2     2     5    39    55    44     8    17    17   NaN
NaN   NaN     2     2     7    33    48    31    66    17    17   NaN
NaN   NaN   NaN    28    28    33    89    31    66    17    17   NaN
NaN   NaN   NaN    28    28    28    89    89   NaN   NaN   NaN   NaN

(不知道如何处理两个相邻值的凸角,因为我需要控制边缘效果)。

这篇文章遵循今天早些时候的一个问题,在这个问题中,我能够将这些填充单元(缓冲区)的位置提取到扩展的逻辑中。然而,使用fillmissing和nearest并没有产生我所期望的效果(padarray所做的)。

Zb_ext(logical(ZbDilated)) = fillmissing(Zb_ext(logical(ZbDilated)),'nearest');

我可能能够逆转我所做的查找垫单元以查找相邻值并使用这些值来替换垫单元nan。但我想先看看有没有更简单的解决办法?

您可以使用两个2D卷积来实现这一点,其中conv2在核心MATLAB库中,因此不需要外部任何东西,并且它应该很快。

然而,你注意到这个:

不知道如何处理两个相邻值的凸角,因为我需要控制边缘效果

我冒昧地定义了一个"合理的"凸角的输出是取平均值,因为从你的例子中,似乎没有定义如何处理这些情况,以及更复杂的情况,如cell(5,6)。

我已经给下面的代码添加了详细的注释来解释

% Example matrix 
A = [
NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
NaN   NaN   NaN     2     5    39    55    44     8   NaN   NaN   NaN
NaN   NaN   NaN   NaN     7    33    48    31    66    17   NaN   NaN
NaN   NaN   NaN   NaN    28   NaN    89   NaN   NaN   NaN   NaN   NaN
NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
];
% Track the "inner" indices, where values are defined
inner = (~isnan(A));
B = A;                 % Copy A so we don't change it
B(~inner) = 0;         % Replace NaN with 0 so that convolutions work OK
% First dilate the inner region by one element, taking the average of
% neighbours which are up/down/left/right (no diagonals). This is required
% to avoid including interior points (which only touch diagonally) in the
% averaging. These can be considered the "cardinal neighbours"
kernel = [0 1 0 ; 1 0 1; 0 1 0]; % Cardinal directions in 3x3 stencil
s = conv2(B,kernel,'same');      % 2D convolution to get sum of neighbours
n = conv2(inner,kernel,'same');  % 2D convolution to get count of neighbours
s(inner) = 0;                    % Zero out the inner region
s = s./n;                        % Get the mean of neighbours
% Second, dilate the inner region but including the mean from all
% directions. This lets us handle convex corners in the image
s2 = conv2(B,ones(3),'same');     % Sum of neighbours (and self, doesn't matter)
n = conv2(inner,ones(3),'same');  % Count of neighbours (self=0 for dilated elems)
s2 = s2./n;                       % Get the mean of neighbours
% Finally piece together the 3 matrices:
out = s2;                       % Start with outmost dilation inc. corners
out(~isnan(s)) = s(~isnan(s));  % Override with inner dilation for cardinal neighbours
out(inner) = A(inner);          % Override with original inner data

所以对于这个例子,输出将与你的例子输出相同,除了前面提到的角:

NaN  NaN    2    2     5     39   55   44    8    8   NaN  NaN 
NaN  NaN    2    2     5     39   55   44    8  12.5   17  NaN 
NaN  NaN    2    4.5   7     33   48   31   66   17    17  NaN 
NaN  NaN  NaN   28    28     50   89   60   66   17    17  NaN 
NaN  NaN  NaN   28    28   58.5   89   89  NaN  NaN   NaN  NaN

相关(和使用):MATLAB/Octave:计算矩阵中相邻/相邻元素的和

相关内容

  • 没有找到相关文章

最新更新