Лучший способ сделать 3D-модель из компьютерной томографии с помощью Python? - PullRequest
0 голосов
/ 25 сентября 2018

Я хочу сделать 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 голосов
/ 29 сентября 2018

Вы можете сделать это без ЛЮБОГО Python! Просто используйте Meshroom.

0 голосов
/ 28 сентября 2018

Blender быстрее с одним объектом , который имеет один миллион вершин, чем если бы он имел 1000 объектов по 1000 вершин в каждом.Вместо того, чтобы создавать несколько кубов и объединять их вместе, используйте bmesh , чтобы добавить несколько кубов в один объект сетки.

Другим соображением является использование операторов , каждый операторcall выполняет обновление и перерисовку сцены, работая напрямую с данными сетки, а затем, выполнив одно обновление, вы предотвращаете множество ненужных обновлений.

Используя случайные цвета вместо изображений 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)
...