如何闭合带间隔的标记numpy数组的间隔且不重新标记矩阵?
Numpy标记数组间隔闭合实现方案
你之前用scipy.ndimage.measurements.label得到全1的结果,是因为该方法会将连通的同值区域统一标记为同一个数值,不符合你保留标记递增顺序、仅补全间隔的需求。下面给出两种实现方案:
方案1:适配单列连续标记场景(匹配你给出的示例)
如果你仅需要处理单列按顺序递增、间隔为单个像素的标记,可直接提取标记列做线性补全,代码如下:
import numpy as np # 原始数组 a = np.array([[1,1,1],[1,3,1],[1,5,1]]) # 提取标记所在列(示例中为第二列,索引为1) mark_col = a[:, 1] # 筛选非背景的标记值并排序 mark_vals = np.sort(mark_col[mark_col != 1]) # 生成连续填充值 filled_col = np.linspace(mark_vals.min(), mark_vals.max(), num=len(mark_col), dtype=int) # 替换回原数组 a[:, 1] = filled_col print(a)
运行输出:
[[1 1 1] [1 2 1] [1 3 1]]
方案2:通用场景(支持任意长度间隔、多列处理)
如果需要处理任意位置、任意长度的间隔,可通过线性插值的方式补全,不会修改原有标记的相对顺序:
import numpy as np from scipy.interpolate import interp1d def fill_label_gaps(arr, background_val=1): # 遍历数组每一列,若为行方向间隔可修改为遍历行 for col_idx in range(arr.shape[1]): col = arr[:, col_idx] # 提取非背景的位置和对应标记值 non_bg_pos = np.where(col != background_val)[0] non_bg_vals = col[non_bg_pos] # 标记点不足2个无需补全 if len(non_bg_pos) < 2: continue # 生成线性插值函数 interp_func = interp1d(non_bg_pos, non_bg_vals, kind='linear') # 确定需要填充的位置范围 fill_range = np.arange(non_bg_pos.min(), non_bg_pos.max() + 1) # 生成填充值并替换 col[fill_range] = interp_func(fill_range).astype(int) arr[:, col_idx] = col return arr # 测试调用 a = np.array([[1,1,1],[1,3,1],[1,5,1]]) result = fill_label_gaps(a) print(result)
内容的提问来源于stack exchange,提问作者Godsend
相关产品推荐
相关产品推荐

