分层存储的图片叠层成为3d,并显示。

文件夹D:\mask内的分层存储的图像文件mask_1.PNG至mask_12.PNG:

分层存储的图片的3d显示-LMLPHP

1、显示为3d点云:

import open3d as o3d
import numpy as np
from PIL import Image


def images2point_cloud(paths, layer_height):
    points = []

    for i, image_path in enumerate(paths):     # 分层读取
        img = Image.open(image_path)
        img_array = np.array(img)

        img_height, img_width = img_array.shape

        for y in range(img_height):    
            for x in range(img_width):
                if img_array[y][x] > 0:  # 假设非黑色点为感兴趣的点
                    points.append([x, y, i * layer_height])  # 将 2D 像素点转换为 3D 点,高度使用索引值

    return points

# 替换为你实际存储图像的路径
image_paths = ['D:\\mask\\mask_1.PNG', 'D:\\mask\\mask_2.PNG', 'D:\\mask\\mask_3.PNG', 'D:\\mask\\mask_4.PNG', 'D:\\mask\\mask_5.PNG', 'D:\\mask\\mask_6.PNG', 'D:\\mask\\mask_7.PNG', 'D:\\mask\\mask_8.PNG', 'D:\\mask\\mask_9.PNG', 'D:\\mask\\mask_10.PNG', 'D:\\mask\\mask_11.PNG', 'D:\\mask\\mask_12.PNG']

# 定义层间距离
height = 5.0

points = images2point_cloud(image_paths, height)
point_cloud = o3d.geometry.PointCloud()

point_cloud.points = o3d.utility.Vector3dVector(points)
o3d.visualization.draw_geometries([point_cloud])

 输出:

分层存储的图片的3d显示-LMLPHP

 分层存储的图片的3d显示-LMLPHP

进一步,可以自定义云点的颜色:

import open3d as o3d
import numpy as np
from PIL import Image

def images2point_cloud(paths, layer_height):
    points = []
    colors = []

    for i, image_path in enumerate(paths):     # 分层读取
        img = Image.open(image_path)
        img_array = np.array(img)

        img_height, img_width = img_array.shape

        for y in range(img_height):
            for x in range(img_width):
                if img_array[y][x] > 0:  # 假设非黑色点为感兴趣的点
                    points.append([x, y, i * layer_height])  # 将 2D 像素点转换为 3D 点,高度使用索引值
                    colors.append([1, 0, 0])  # 设置颜色为红色

    return points, colors

# 替换为你实际存储图像的路径
image_paths = ['D:\\mask\\mask_1.PNG', 'D:\\mask\\mask_2.PNG', 'D:\\mask\\mask_3.PNG', 'D:\\mask\\mask_4.PNG', 'D:\\mask\\mask_5.PNG', 'D:\\mask\\mask_6.PNG', 'D:\\mask\\mask_7.PNG', 'D:\\mask\\mask_8.PNG', 'D:\\mask\\mask_9.PNG', 'D:\\mask\\mask_10.PNG', 'D:\\mask\\mask_11.PNG', 'D:\\mask\\mask_12.PNG']

# 定义层间距离
height = 5.0

points, colors = images2point_cloud(image_paths, height)
point_cloud = o3d.geometry.PointCloud()

point_cloud.points = o3d.utility.Vector3dVector(points)
point_cloud.colors = o3d.utility.Vector3dVector(colors)

# 显示渲染后的 3D 实体
o3d.visualization.draw_geometries([point_cloud])

 分层存储的图片的3d显示-LMLPHP

 2、将点云渲染为体素网格

import open3d as o3d
import numpy as np
from PIL import Image


def images2point_cloud(paths, layer_height):
    points = []

    for i, image_path in enumerate(paths):     # 分层读取
        img = Image.open(image_path)
        img_array = np.array(img)

        img_height, img_width = img_array.shape

        for y in range(img_height):    
            for x in range(img_width):
                if img_array[y][x] > 0:  # 假设非黑色点为感兴趣的点
                    points.append([x, y, i * layer_height])  # 将 2D 像素点转换为 3D 点,高度使用索引值

    return points

# 替换为你实际存储图像的路径
image_paths = ['D:\\mask\\mask_1.PNG', 'D:\\mask\\mask_2.PNG', 'D:\\mask\\mask_3.PNG', 'D:\\mask\\mask_4.PNG', 'D:\\mask\\mask_5.PNG', 'D:\\mask\\mask_6.PNG', 'D:\\mask\\mask_7.PNG', 'D:\\mask\\mask_8.PNG', 'D:\\mask\\mask_9.PNG', 'D:\\mask\\mask_10.PNG', 'D:\\mask\\mask_11.PNG', 'D:\\mask\\mask_12.PNG']

# 定义层间距离
height = 5.0

points = images2point_cloud(image_paths, height)
point_cloud = o3d.geometry.PointCloud()

point_cloud.points = o3d.utility.Vector3dVector(points)

# 创建点云体素网格
voxel_size = 1
voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(point_cloud, voxel_size=voxel_size)

# 显示体素网格,指定渲染模式为网格
o3d.visualization.draw_geometries([voxel_grid], mesh_show_wireframe=True)


分层存储的图片的3d显示-LMLPHP

 3、使用vtk库显示3d实体

参照博文:【Python VTK】读取二维序列医学图像分割结果并进行三维重建_vtk三维重建-CSDN博客

 

import vtk

# 创建渲染器、窗口和交互器
renderer = vtk.vtkRenderer()
window = vtk.vtkRenderWindow()
window.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(window)

# 图像读取
reader = vtk.vtkPNGReader()
reader.SetDataExtent(0, 300, 0, 300, 0, 12) # 定义图像大小和层数
name_prefix = 'D:/mask/mask_'   # 设置图像前缀名字
reader.SetFilePrefix(name_prefix)
reader.SetFilePattern("%s%d.PNG")
reader.Update()

reader.SetDataByteOrderToLittleEndian()
spacing = [1.0, 1.0, 5.0]  # x, y 方向上的间距为 1 像素,层间距距为 5 像素
reader.GetOutput().SetSpacing(spacing)


# 高斯平滑
gauss = vtk.vtkImageGaussianSmooth()
gauss.SetInputConnection(reader.GetOutputPort())
gauss.SetStandardDeviations(1.0, 1.0, 1.0)
gauss.SetRadiusFactors(1.0, 1.0, 1.0)
gauss.Update()

# 计算轮廓
contour = vtk.vtkMarchingCubes()
gauss.GetOutput().SetSpacing(spacing)
contour.SetInputConnection(gauss.GetOutputPort())
contour.ComputeNormalsOn()
contour.SetValue(0, 100)

# 映射器和演员
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(contour.GetOutputPort())
mapper.ScalarVisibilityOff()

actor = vtk.vtkActor()
actor.SetMapper(mapper)

# 设置渲染器背景颜色
renderer.SetBackground([0.0, 0.0, 0.0])
renderer.AddActor(actor)

# 开始显示
if __name__ == '__main__':
    window.Render()
    interactor.Initialize()
    interactor.Start()

 显示效果:

分层存储的图片的3d显示-LMLPHP​​​​​​​

 持续寻找新的方法中。。。

06-05 05:48