You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何连接2D切片中的二进制曲面并绘制3D连接轮廓?

连接二进制曲面生成3D轮廓的实现方案

你可以通过提取每个2D切片的轮廓点,再将相邻切片的对应轮廓点连接,来生成3D连接轮廓。以下提供两种实现方式:

方式一:针对规则矩形区域(无需额外依赖)

如果你的二进制区域是规则的矩形(如示例中的2x2方块),可以直接计算区域的角点坐标,再绘制轮廓和连接线段:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib
matplotlib.use('Qt5Agg')

# 生成网格数据
x, y = np.meshgrid(np.linspace(0,1,20), np.linspace(0,1,20))
z_vals = np.linspace(0, 2, 4)
u = np.zeros((len(z_vals), 20, 20))

# 填充二进制数据
for i in range(len(z_vals)):
    u[i, i+5:i+7, i+5:i+7] = 1

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 存储每个切片的轮廓点
slice_contours = []

# 绘制每个切片的2D轮廓线
for idx, z in enumerate(z_vals):
    # 获取矩形区域的边界坐标
    y_min = y[idx+5, 0]
    y_max = y[idx+7, 0]
    x_min = x[0, idx+5]
    x_max = x[0, idx+7]
    
    # 定义矩形的四个角点(闭合轮廓)
    points = np.array([
        [x_min, y_min],
        [x_max, y_min],
        [x_max, y_max],
        [x_min, y_max],
        [x_min, y_min]
    ])
    slice_contours.append((points, z))
    
    # 在当前z高度绘制轮廓线
    ax.plot(points[:,0], points[:,1], zs=z, zdir='z', color='gold', linewidth=2)

# 连接相邻切片的对应角点
for i in range(len(slice_contours)-1):
    curr_points, curr_z = slice_contours[i]
    next_points, next_z = slice_contours[i+1]
    
    # 逐个连接对应点(跳过最后一个重复的闭合点)
    for p_curr, p_next in zip(curr_points[:-1], next_points[:-1]):
        ax.plot([p_curr[0], p_next[0]], [p_curr[1], p_next[1]], [curr_z, next_z], color='gold', linewidth=2)

# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

方式二:通用不规则区域(依赖scikit-image)

如果你的二进制区域形状不规则,可以用scikit-image的find_contours函数提取轮廓,再连接相邻切片的轮廓点:

首先确保安装scikit-image:

pip install scikit-image

然后运行以下代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage.measure import find_contours
import matplotlib
matplotlib.use('Qt5Agg')

# 生成网格数据
x, y = np.meshgrid(np.linspace(0,1,20), np.linspace(0,1,20))
z_vals = np.linspace(0, 2, 4)
u = np.zeros((len(z_vals), 20, 20))

# 填充二进制数据
for i in range(len(z_vals)):
    u[i, i+5:i+7, i+5:i+7] = 1

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 存储每个切片的轮廓点
slice_contours = []

# 提取并绘制每个切片的轮廓线
for idx, z in enumerate(z_vals):
    # 提取水平集为0.5的轮廓(区分0和1的区域)
    contours = find_contours(u[idx], level=0.5)
    for contour in contours:
        # 将轮廓的索引坐标转换为实际x、y值
        y_coords = y[contour[:,0].astype(int), 0]
        x_coords = x[0, contour[:,1].astype(int)]
        contour_points = np.column_stack((x_coords, y_coords))
        slice_contours.append((contour_points, z))
        
        # 在当前z高度绘制轮廓线
        ax.plot(contour_points[:,0], contour_points[:,1], zs=z, zdir='z', color='gold', linewidth=2)

# 连接相邻切片的对应轮廓点(假设每个切片只有一个轮廓且点顺序对应)
for i in range(len(slice_contours)-1):
    curr_points, curr_z = slice_contours[i]
    next_points, next_z = slice_contours[i+1]
    
    # 若轮廓点数量一致,逐个连接对应点
    if len(curr_points) == len(next_points):
        for p_curr, p_next in zip(curr_points, next_points):
            ax.plot([p_curr[0], p_next[0]], [p_curr[1], p_next[1]], [curr_z, next_z], color='gold', linewidth=2)

# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

这两种方式都能将各个切片的黄色区域连接成完整的3D轮廓框架,其中方式一适合规则形状,方式二更通用。

内容的提问来源于stack exchange,提问作者A. Heintz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 08:34:59