如何通过Scipy修改结构元实现LiDAR高程数组的单向腐蚀?
单方向腐蚀LiDAR高程数组的实现方案
我有一个来自.tif格式LiDAR表面的高程数组,示例数组如下:
Existing_example_arrayV0 = [[ 0, 0, 1, 0, 0, 0, 0], [ 0, 1, 1, 1, 0, 0, 0], [ 0, 1, 1, 1, 1, 0, 0], [ 1, 1, 1, 1, 1, 0, 0], [ 0, 1, 1, 1, 1, 0, 0], [ 0, 1, 1, 0, 0, 0, 0]]
以下代码会从所有方向均匀腐蚀图像:
for i in range(0, 1): erosion_mask = binary_erosion(Existing_example_arrayV0 >= 100, structure=np.ones((3, 3)), iterations=i) Existing_example_arrayV0[erosion_mask] += 100 Proposed_example_array = [[ 0, 0, 1, 0, 0, 0, 0], [ 0, 1, 101, 1, 0, 0, 0], [ 0, 1, 101, 101, 1, 0, 0], [ 1, 100, 101, 101, 1, 0, 0], [ 0, 1, 101, 101, 1, 0, 0], [ 0, 1, 1, 0, 0, 0, 0]]
能否修改结构元,仅从单一方向(左侧或右侧)进行腐蚀,生成如下所示的目标数组?
仅从左侧腐蚀的目标结果
Proposed_example_array = [[ 0, 0, 1, 0, 0, 0, 0], [ 0, 1, 101, 101, 0, 0, 0], [ 0, 1, 101, 101, 101, 0, 0], [ 1, 100, 101, 101, 101, 0, 0], [ 0, 1, 101, 101, 101, 0, 0], [ 0, 1, 101, 0, 0, 0, 0]]
仅从右侧腐蚀的目标结果
Proposed_example_array = [[ 0, 0, 1, 0, 0, 0, 0], [ 0, 101, 101, 1, 0, 0, 0], [ 0, 101, 101, 101, 1, 0, 0], [ 101, 101, 101, 101, 1, 0, 0], [ 0, 101, 101, 101, 1, 0, 0], [ 0, 101, 1, 0, 0, 0, 0]]
解决方案
完全可以通过自定义结构元实现单方向腐蚀,结构元的形状直接决定腐蚀的作用方向,只需构造仅包含目标方向邻域的结构元即可:
1. 左侧腐蚀实现
左侧腐蚀的核心逻辑是:仅当像素的左侧相邻像素属于前景(值≥1)时,该像素才会被标记为腐蚀区域。我们使用横向结构元[[0,0,0],[1,1,0],[0,0,0]],让腐蚀操作只关注当前像素及其左侧的邻域:
import numpy as np from scipy.ndimage import binary_erosion # 初始化原始数组 Existing_example_arrayV0 = np.array([[ 0, 0, 1, 0, 0, 0, 0], [ 0, 1, 1, 1, 0, 0, 0], [ 0, 1, 1, 1, 1, 0, 0], [ 1, 1, 1, 1, 1, 0, 0], [ 0, 1, 1, 1, 1, 0, 0], [ 0, 1, 1, 0, 0, 0, 0]]) # 复制数组避免修改原始数据 left_erosion_array = Existing_example_arrayV0.copy() # 定义左侧腐蚀的结构元 left_structure = np.array([[0,0,0], [1,1,0], [0,0,0]]) # 执行腐蚀并更新数组(注意原始数组前景值为1,所以判断条件改为>=1) erosion_mask = binary_erosion(left_erosion_array >= 1, structure=left_structure, iterations=1) left_erosion_array[erosion_mask] += 100 print("左侧腐蚀结果:") print(left_erosion_array)
2. 右侧腐蚀实现
右侧腐蚀则使用结构元[[0,0,0],[0,1,1],[0,0,0]],仅关注当前像素及其右侧的邻域:
# 复制数组避免修改原始数据 right_erosion_array = Existing_example_arrayV0.copy() # 定义右侧腐蚀的结构元 right_structure = np.array([[0,0,0], [0,1,1], [0,0,0]]) # 执行腐蚀并更新数组 erosion_mask = binary_erosion(right_erosion_array >= 1, structure=right_structure, iterations=1) right_erosion_array[erosion_mask] += 100 print("\n右侧腐蚀结果:") print(right_erosion_array)
补充说明
- 原代码中
Existing_example_arrayV0 >= 100的条件不符合场景,因为原始数组的前景值是1,所以需要改为>=1来正确识别前景区域。 - 结构元可灵活调整,比如需要更宽的左侧腐蚀范围,可以将结构元改为
[[0,0,0],[1,1,1],[0,0,0]],实现横向三像素范围的左侧腐蚀。
内容的提问来源于stack exchange,提问作者Patstro
相关产品推荐
相关产品推荐

