使用python从CT扫描中制作3D模型的最佳方法?

时间:2018-09-25 09:41:19

标签: python 3d blender

我想通过使用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")

2 个答案:

答案 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。