我想通过使用CT扫描从心脏制作3D模型。我使用了Blender,但效果不佳。此Python脚本运行太慢。有人知道更好的方法吗?
import bpy
import os
import pydicom
import numpy as np
path = "./Desktop/EMC/"
files = sorted(os.listdir(path + "/Data/Head/"))
data = np.zeros((245, 512, 512))
for i in range(len(files)):
layer = pydicom.dcmread(path + "/Data/Head/" + files[i]) # read dcm files
data[i] = layer.pixel_array
for yy in range(245):
for xx in range(512):
for zz in range(512):
print("X: {}, Y: {}, Z: {}".format(xx, yy, zz))
c = data[yy, xx, zz]
bpy.ops.mesh.primitive_cube_add(location=(xx / 500, zz / 500, yy / 500))
bpy.ops.transform.resize(value=(0.001, 0.001, 0.001))
activeObject = bpy.context.active_object # Select active object
mat = bpy.data.materials.new(name="MaterialName")
activeObject.data.materials.append(mat) #Add Material
bpy.context.object.active_material.diffuse_color = (c, c, c) #change color
if zz == 511: #Join objects and remove doubles
item='MESH'
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_by_type(type=item)
bpy.ops.object.join()
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.remove_doubles()
bpy.ops.object.mode_set(mode='OBJECT')
print("DONE")
答案 0 :(得分:0)
Blender是faster with one object,它具有一百万个顶点,如果它有1000个对象(每个对象具有1000个顶点)。与其创建多个多维数据集并将它们连接在一起,不如使用bmesh在一个网格对象中添加多个多维数据集。
另一个要考虑的因素是use of operators,每个操作员调用都直接通过处理网格数据来进行场景更新和重绘,然后进行一次更新可以防止很多不必要的更新。
使用随机颜色而不是ct图像,以下脚本的运行时间约为10%。我还使多维数据集变大了,如果初始的多维数据集太小,则删除双精度对象的合并可能会超出您想要的数量,您可以在构建网格之后始终按比例缩小它。
import bpy
import bmesh
import mathutils
import numpy as np
# replace these two lines with your data filling code
x_size = y_size = z_size = 10
data = np.random.rand(x_size, y_size, z_size)
me = bpy.data.meshes.new("Mesh_new")
scene = bpy.context.scene
obj = bpy.data.objects.new("CT_Scan_new", me)
scene.objects.link(obj)
scene.objects.active = obj
obj.select = True
bm = bmesh.new()
for yy in range(y_size):
for xx in range(x_size):
for zz in range(z_size):
c = data[yy, xx, zz]
bmesh.ops.create_cube(bm, size=0.1,
matrix=mathutils.Matrix.Translation((xx / 10, zz / 10, yy / 10)))
mat = bpy.data.materials.new(name="MaterialName")
mat.diffuse_color = (c, c, c)
obj.data.materials.append(mat)
mat_idx = len(obj.data.materials)-1
bm.faces.ensure_lookup_table()
for i in range(6):
# assign the last material to the last six faces created
bm.faces[-i].material_index = mat_idx
bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.001)
bm.to_mesh(me)
答案 1 :(得分:0)
您可以在没有任何Python的情况下完成此操作!只需使用Meshroom。