Python实现三维数组中目标物体的定位与重标记
问题描述
现有一个10×10×10的三维数组,背景值为0,物体区域标记为1,包含两个物体:
- 一个位于坐标范围(0,0,0)-(2,2,2)
- 另一个位于坐标范围(3,5,5)-(5,6,8)
需要定位坐标(1,1,1)所属的物体,并将该物体的所有1重标记为5,如何实现?
原三维数组如下:
a = [ [[1,1,1,0,0,0,0,0,0,0], [1,1,1,0,0,0,0,0,0,0], [1,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [1,1,1,0,0,0,0,0,0,0], [1,1,1,0,0,0,0,0,0,0], [1,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [1,1,1,0,0,0,0,0,0,0], [1,1,1,0,0,0,0,0,0,0], [1,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,1,1,1,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]], [ [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]] ]
实现方案
可以采用**广度优先搜索(BFS)**遍历目标坐标所属的连通区域,将所有1替换为5。这种方法适用于任意形状的连通物体,通用性强。
步骤说明
- 确认目标坐标(1,1,1)的值为1,属于待标记的物体区域
- 定义三维空间的六个遍历方向(上下、左右、前后)
- 使用队列存储待访问的坐标,用集合记录已访问的坐标避免重复处理
- 遍历队列中的每个坐标,将其值设为5,并检查六个方向的相邻坐标,符合条件则加入队列继续处理
Python代码实现
# 三维方向向量:上下、左右、前后六个方向 directions = [(-1,0,0), (1,0,0), (0,-1,0), (0,1,0), (0,0,-1), (0,0,1)] # 目标坐标 target_x, target_y, target_z = 1, 1, 1 # 检查目标坐标是否属于物体区域 if a[target_x][target_y][target_z] != 1: print("目标坐标不属于物体区域") else: # 初始化队列和已访问集合 queue = [(target_x, target_y, target_z)] visited = set() visited.add((target_x, target_y, target_z)) # 广度优先遍历 while queue: x, y, z = queue.pop(0) # 将当前位置标记为5 a[x][y][z] = 5 # 遍历所有相邻方向 for dx, dy, dz in directions: nx, ny, nz = x + dx, y + dy, z + dz # 检查相邻坐标是否在数组范围内、值为1且未被访问 if 0 <= nx < 10 and 0 <= ny < 10 and 0 <= nz < 10: if a[nx][ny][nz] == 1 and (nx, ny, nz) not in visited: visited.add((nx, ny, nz)) queue.append((nx, ny, nz)) # 验证结果(打印前3层的前3行前3列,应为全5) for layer in range(3): print(f"第{layer}层:") for row in range(3): print(a[layer][row][:3])
简化方案(仅针对规则立方体)
如果已知目标物体是规则的立方体,也可以直接遍历坐标范围完成标记,代码更简洁:
# 遍历目标物体的坐标范围(0,0,0)-(2,2,2) for x in range(3): for y in range(3): for z in range(3): if a[x][y][z] == 1: a[x][y][z] = 5
内容的提问来源于stack exchange,提问作者Donnerhorn
相关产品推荐
相关产品推荐

