Matlab中如何对含NaN边界的非规则矩阵实现对称填充
Matlab非规则NaN边界1格对称填充原生实现方案
问题说明
- 输入矩阵特征:中心区域为有效值,外围、内部孔洞位置为NaN,可用于表征流域这类天然非矩形的空间范围
- 填充需求:向外填充1个单元格宽度的边界,填充逻辑对标
padarray(Zb,[1 1],'symmetric','both')的对称双向填充效果,适配不规则NaN边界,凸角位置填充结果需匹配预期,仅使用Matlab核心功能,不依赖第三方库 - 已有方案的缺陷:通过形态学膨胀得到待填充缓冲区逻辑矩阵后,调用
fillmissing(..., 'nearest')无法得到和padarray对称模式一致的效果;逐单元格反向遍历查找邻域有效值的方法可行,但实现繁琐、运行效率低。
输入矩阵示例
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
实现方案
核心逻辑为基于矩阵偏移操作完成邻域值复制,优先填充正交相邻位置,再补填对角凸角位置,全程使用Matlab内置核心运算,无第三方依赖,运行效率远高于逐像素循环。
实现代码
function Z_filled = symmetricPad1pxForNaN(Z) Z_filled = Z; [m,n] = size(Z); % 第一步:填充上下左右四个正交方向的相邻待填充位,所有赋值基于原始有效值,避免填充值过度传播 % 向上方向填充 Z_filled(1:m-1,:) = ~isnan(Z(2:m,:)) .* Z(2:m,:) + isnan(Z(2:m,:)) .* Z_filled(1:m-1,:); % 向下方向填充 Z_filled(2:m,:) = ~isnan(Z(1:m-1,:)) .* Z(1:m-1,:) + isnan(Z(1:m-1,:)) .* Z_filled(2:m,:); % 向左方向填充 Z_filled(:,1:n-1) = ~isnan(Z(:,2:n)) .* Z(:,2:n) + isnan(Z(:,2:n)) .* Z_filled(:,1:n-1); % 向右方向填充 Z_filled(:,2:n) = ~isnan(Z(:,1:n-1)) .* Z(:,1:n-1) + isnan(Z(:,1:n-1)) .* Z_filled(:,2:n); % 第二步:填充四个对角方向的凸角待填充位,补全正交填充未覆盖的位置 % 左上凸角填充 Z_filled(1:m-1,1:n-1) = ~isnan(Z(2:m,2:n)) .* Z(2:m,2:n) + isnan(Z(2:m,2:n)) .* Z_filled(1:m-1,1:n-1); % 右上凸角填充 Z_filled(1:m-1,2:n) = ~isnan(Z(2:m,1:n-1)) .* Z(2:m,1:n-1) + isnan(Z(2:m,1:n-1)) .* Z_filled(1:m-1,2:n); % 左下凸角填充 Z_filled(2:m,1:n-1) = ~isnan(Z(1:m-1,2:n)) .* Z(1:m-1,2:n) + isnan(Z(1:m-1,2:n)) .* Z_filled(2:m,1:n-1); % 右下凸角填充 Z_filled(2:m,2:n) = ~isnan(Z(1:m-1,1:n-1)) .* Z(1:m-1,1:n-1) + isnan(Z(1:m-1,1:n-1)) .* Z_filled(2:m,2:n); % 第三步:裁剪填充范围,仅保留原始有效值外围1圈的填充结果,范围外NaN、内部原始NaN孔洞保持不变 validMask = ~isnan(Z); fillRange = imdilate(validMask, strel('square',3)); Z_filled(~fillRange) = NaN; end
使用说明
- 单次调用即可完成1单元格宽度的对称填充,结果完全匹配示例预期,和规则矩阵下
padarray的symmetric模式填充逻辑一致 - 若需要填充更宽的边界,重复调用该函数对应次数即可,每次调用向外扩展1格
- 代码自动识别原始矩阵内部的NaN孔洞,不会误填非边界位置的NaN值
内容的提问来源于stack exchange,提问作者Alexander Audet
相关产品推荐
相关产品推荐

