分层存储的图片叠层成为3d,并显示。
文件夹D:\mask内的分层存储的图像文件mask_1.PNG至mask_12.PNG:
1、显示为3d点云:
import open3d as o3d
import numpy as np
from PIL import Imagedef 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.shapefor 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.0points = images2point_cloud(image_paths, height)
point_cloud = o3d.geometry.PointCloud()point_cloud.points = o3d.utility.Vector3dVector(points)
o3d.visualization.draw_geometries([point_cloud])
输出:
进一步,可以自定义云点的颜色:
import open3d as o3d
import numpy as np
from PIL import Imagedef 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.shapefor 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.0points, 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])
2、将点云渲染为体素网格
import open3d as o3d
import numpy as np
from PIL import Imagedef 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.shapefor 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.0points = 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)
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()
显示效果:
持续寻找新的方法中。。。