예제 #1
0
파일: vis.py 프로젝트: almarklein/stentseg
def showModel3d(basedir,ptcode, ctcode, cropname='ring', showVol='MIP',
    showmodel=True, graphname='model', **kwargs):
    """ show model and vol in 3d by mip iso or 2D
    graphname 'all' draws all graph models stored in s, if multiple
    """
    s = loadmodel(basedir, ptcode, ctcode, cropname, modelname='modelavgreg')
    vol = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg').vol
    # figure
    f = vv.figure(); vv.clf()
    f.position = 0.00, 22.00,  1920.00, 1018.00
    a = vv.gca()
    a.axis.axisColor = 1,1,1
    a.axis.visible = False
    a.bgcolor = 0,0,0
    a.daspect = 1, 1, -1
    t = show_ctvolume(vol, axis=a, showVol=showVol, removeStent=False, 
                        climEditor=True, **kwargs)
    label = pick3d(a, vol)
    vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)')
    if showmodel:
        if graphname == 'all':
            for key in dir(s):
                if key.startswith('model'):
                    s[key].Draw(mc='b', mw = 5, lc='g', alpha = 0.5)
        else:
            s[graphname].Draw(mc='b', mw = 5, lc='g', alpha = 0.5)
            
    vv.title('Model for LSPEAS %s  -  %s' % (ptcode[8:], ctcode))
    
    # f.eventKeyDown.Bind(lambda event: _utils_GUI.RotateView(event, [a], axishandling=False ))
    f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, [a]) )
    
    return f, a, label, s
예제 #2
0
def make_model_dynamic(basedir, ptcode, ctcode, cropname, what='avgreg'):
    """ Read deforms and model to make model dynamic, ie, add deforms to edges
    and nodes in the graph
    """
    # Load deforms
    s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms')
    deformkeys = []
    for key in dir(s):
        if key.startswith('deform'):
            deformkeys.append(key)
    deforms = [s[key] for key in deformkeys]
    deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms]
    paramsreg = s.params
    
    # Load model
    s = loadmodel(basedir, ptcode, ctcode, cropname, 'model'+what)
    for key in dir(s):
        if key.startswith('model'):
            model = s[key]
        
            # Combine ...
            incorporate_motion_nodes(model, deforms, s.origin) # adds deforms PointSets
            incorporate_motion_edges(model, deforms, s.origin) # adds deforms PointSets
        
            s[key] = model.pack()
        
        # also pack seeds before save
        if key.startswith('seeds'):
            s[key] = s[key].pack()
            
    # Save back
    filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'model'+what)
    s.paramsreg = paramsreg
    ssdf.save(os.path.join(basedir, ptcode, filename), s)
    print('saved dynamic to disk in {} as {}.'.format(basedir, filename) )
예제 #3
0
def makeLandmarkModelDynamic(basedir,
                             ptcode,
                             ctcode,
                             cropname,
                             what='landmarksavgreg',
                             savedir=None):
    """ Make model dynamic with deforms from registration 
        (and store/overwrite to disk)
    """
    #todo: change in default and merge with branch landmarks?
    import pirt
    from stentseg.motion.dynamic import (incorporate_motion_nodes,
                                         incorporate_motion_edges)
    from visvis import ssdf
    import os

    if savedir is None:
        savedir = basedir
    # Load deforms
    s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms')
    deformkeys = []
    for key in dir(s):
        if key.startswith('deform'):
            deformkeys.append(key)
    deforms = [s[key] for key in deformkeys]
    deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms]
    paramsreg = s.params

    # Load model where landmarks were stored
    # s2 = loadmodel(savedir, ptcode, ctcode, cropname, what)
    fname = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, what)
    s2 = ssdf.load(os.path.join(savedir, fname))
    # Turn into graph model
    model = stentgraph.StentGraph()
    model.unpack(s2[what])

    # Combine ...
    incorporate_motion_nodes(model, deforms, s2.origin)
    incorporate_motion_edges(model, deforms, s2.origin)

    # Save back
    filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, what)
    s2.model = model.pack()
    s2.paramsreg = paramsreg
    ssdf.save(os.path.join(savedir, filename), s2)
    print('saved to disk to {}.'.format(os.path.join(savedir, filename)))
def loadvolmodel(basedir,
                 ptcode,
                 ctcode1,
                 cropname,
                 modelname,
                 nstruts=8,
                 ringpart=False):
    """ load vol and model
    """
    s1 = loadmodel(basedir, ptcode, ctcode1, cropname, modelname)
    model = s1.model
    models1 = []
    for ringname in ringnames:
        model1 = s1[ringname]
        if ringpart:
            models = get_model_struts(model1, nstruts=nstruts)
            modelRs = get_model_rings(models[2])  # model_R1R2
            model1 = modelRs[ringpart - 1]  # R1 or R2
        models1.append(model1)
    vol1 = loadvol(basedir, ptcode, ctcode1, cropname, 'avgreg').vol

    return vol1, models1, model
예제 #5
0
    def __init__(self, ptcode, ctcode, basedir, clim=None):
        """ select start and endpoints to be used for centerline generation
        """
        from stentseg.apps._3DPointSelector import select3dpoints
        # from stentseg.apps.ui_dialog import MyDialog
        # from PyQt4 import QtGui

        import imageio
        import os
        from stentseg.utils.datahandling import select_dir, loadvol
        import copy

        # Select dataset to register
        cropname = 'prox'
        what = 'avgreg'

        # Load volumes
        s = loadvol(basedir, ptcode, ctcode, cropname, what)
        vol_org = copy.deepcopy(s.vol)
        s.vol.sampling = [
            vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]
        ]
        s.sampling = s.vol.sampling

        # # Select nr of stents
        # app = QtGui.QApplication([])
        # m = MyDialog()
        # m.show()
        # m.exec_()
        # nr_of_stents = int(m.combo.currentText())

        # Endpoint selection
        points = select3dpoints(s.vol, nr_of_stents=6, clim=clim)
        self.StartPoints = points[0]
        self.EndPoints = points[1]

        print('StartPoints are: ' + str(self.StartPoints))
        print('EndPoints are: ' + str(self.EndPoints))
예제 #6
0
drawVessel = True

clim = (0, 2500)
clim2D = -200, 500  # MPR
clim2 = (0, 2)
isoTh = 180  # 250

## Load data

# Load CT image data for reference, and deform data to measure motion
try:
    # If we run this script without restart, we can re-use volume and deforms
    vol1
    deforms
except NameError:
    vol1 = loadvol(basedir, ptcode, ctcode1, cropvol, 'avgreg').vol
    s_deforms = loadvol(basedir, ptcode, ctcode1, cropvol, 'deforms')
    deforms = [
        s_deforms[key] for key in dir(s_deforms) if key.startswith('deform')
    ]
    deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms]

# Load vessel mesh (mimics)
# We make sure that it is a mesh without faces, which makes our sampling easier
try:
    ppvessel
except NameError:
    # Load mesh with visvis, then put in our meshlib.Mesh() and let it ensure that
    # the mesh is closed, check the winding, etc. so that we can cut it with planes,
    # and reliably calculate volume.
    filename = '{}_{}_neck.stl'.format(ptcode, ctcode1)
예제 #7
0
    def __init__(self,ptcode,ctcode,allcenterlines,basedir):
        """
        Script to show the stent plus centerline model and select points on 
        centerlines for motion analysis 
        """
        import os, time
        import pirt
        import visvis as vv
        import numpy as np
        import math
        import itertools
        import xlsxwriter
        from datetime import datetime

                
        from stentseg.utils.datahandling import select_dir, loadvol, loadmodel
        from stentseg.utils.new_pointset import PointSet
        from stentseg.stentdirect.stentgraph import create_mesh
        from stentseg.motion.vis import create_mesh_with_abs_displacement
        from stentseg.utils.visualization import show_ctvolume
        from pirt.utils.deformvis import DeformableTexture3D, DeformableMesh
        from stentseg.utils import PointSet
        from stentseg.stentdirect import stentgraph
        from visvis import Pointset # for meshes
        from stentseg.stentdirect.stentgraph import create_mesh
        from visvis.processing import lineToMesh, combineMeshes
        from visvis import ssdf
        from stentseg.utils.picker import pick3d
        try:
            from PyQt4 import QtCore, QtGui # PyQt5
        except ImportError:
            from PySide import QtCore, QtGui # PySide2
        from stentseg.apps.ui_dialog import MyDialog
        from stentseg.utils.centerline import dist_over_centerline # added for Mirthe 
        import copy
        
        
        cropname = 'prox'
        
        exceldir = os.path.join(basedir,ptcode)
        
        # Load deformations and avg ct (forward for mesh)
        # centerlines combined in 1 model
        m = loadmodel(basedir, ptcode, ctcode, cropname, modelname = 'centerline_total_modelavgreg_deforms') 
        model = m.model
        # centerlines separated in a model for each centerline
        # m_sep = loadmodel(basedir, ptcode, ctcode, cropname, modelname = 'centerline_modelavgreg_deforms')
        s = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg')
        vol_org = copy.deepcopy(s.vol)
        s.vol.sampling = [vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]]
        s.sampling = s.vol.sampling
        vol = s.vol
        
        # Start visualization and GUI
        
        fig = vv.figure(30); vv.clf()
        
        fig.position = 0.00, 30.00,  944.00, 1002.00
        a = vv.gca()
        a.axis.axisColor = 1,1,1
        a.axis.visible = True
        a.bgcolor = 0,0,0
        a.daspect = 1, 1, -1
        lim = 2500
        t = vv.volshow(vol, clim=(0, lim), renderStyle='mip')
        pick3d(vv.gca(), vol)
        b = model.Draw(mc='b', mw = 0, lc='g', alpha = 0.5)
        vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)')
        vv.title('Model for LSPEAS %s  -  %s' % (ptcode[7:], ctcode))
        
        # Add clickable nodes
        t0 = time.time()
        node_points = []
        for i, node in enumerate(sorted(model.nodes())):
            node_point = vv.solidSphere(translation = (node), scaling = (0.6,0.6,0.6))
            node_point.faceColor = 'b'
            node_point.alpha = 0.5
            node_point.visible = True
            node_point.node = node
            node_point.nr = i
            node_points.append(node_point)
        t1 = time.time()
        print('Clickable nodes created, which took %1.2f min.' % ((t1-t0)/60))
        
        # list of correctly clicked nodes
        selected_nodes_sum = set()
        
        # Initialize labels
        t0 = vv.Label(a, '\b{Node nr|location}: ', fontSize=11, color='w')
        t0.position = 0.1, 25, 0.5, 20  # x (frac w), y, w (frac), h
        t0.bgcolor = None
        t0.visible = True
        t1 = vv.Label(a, '\b{Nodepair}: ', fontSize=11, color='w')
        t1.position = 0.1, 45, 0.5, 20
        t1.bgcolor = None
        t1.visible = True
        
        # Initialize output variable to store pulsatility analysis
        storeOutput = list()
        
        
        def on_key(event): 
            if event.key == vv.KEY_ENTER:
                
                # mogenlijkheden aantal nodes 
                    # 1 voor relative beweging vanuit avg punt
                    # 2 voor onderlinge beweging tussen twee punten
                    # 3 voor hoek in punt 2 van punt 1 naar punt 3
                    
                if len(selected_nodes) == 1:
                    selectn1 = selected_nodes[0].node
                    n1index = selected_nodes[0].nr
                    n1Deforms = model.node[selectn1]['deforms']
                    output = point_pulsatility(selectn1, n1Deforms)
                    output['NodesIndex'] = [n1index]
                    
                    # Store output with name
                    dialog_output = get_index_name()
                    output['Name'] = dialog_output
                    storeOutput.append(output)
                    
                    # update labels
                    t1.text = '\b{Node}: %i' % (n1index)
                    t1.visible = True
                    print('selection of 1 node stored')

                if len(selected_nodes) == 2:
                    # get nodes
                    selectn1 = selected_nodes[0].node
                    selectn2 = selected_nodes[1].node
                    # get index of nodes which are in fixed order
                    n1index = selected_nodes[0].nr
                    n2index = selected_nodes[1].nr
                    nindex = [n1index, n2index]
                    # get deforms of nodes
                    n1Deforms = model.node[selectn1]['deforms']
                    n2Deforms = model.node[selectn2]['deforms']
                    # get pulsatility
                    cl_merged = append_centerlines(allcenterlines) 
                    output = point_to_point_pulsatility(cl_merged, selectn1, 
                                        n1Deforms, selectn2, n2Deforms, type='euclidian')
                    output['NodesIndex'] = nindex
                    
                    # get distance_centerline
                   
                    #dist_cl = dist_over_centerline(cl_merged, selectn1, selectn2, type='euclidian') # toegevoegd Mirthe
                    
                    #dist_cl = dist_centerline_total(cl_merged, selectn1, 
                    #                    n1Deforms, selectn2, n2Deforms, type='euclidian')
                    
                    # Store output with name
                    dialog_output = get_index_name()
                    output['Name'] = dialog_output
                    storeOutput.append(output)  
                   
                    # update labels
                    t1.text = '\b{Node pair}: %i - %i' % (nindex[0], nindex[1])
                    t1.visible = True
                    print('selection of 2 nodes stored')
                        
                if len(selected_nodes) == 3:
                    # get nodes
                    selectn1 = selected_nodes[0].node
                    selectn2 = selected_nodes[1].node
                    selectn3 = selected_nodes[2].node
                    # get index of nodes which are in fixed order
                    n1index = selected_nodes[0].nr
                    n2index = selected_nodes[1].nr
                    n3index = selected_nodes[2].nr
                    nindex = [n1index, n2index, n3index]
                    # get deforms of nodes
                    n1Deforms = model.node[selectn1]['deforms']
                    n2Deforms = model.node[selectn2]['deforms']
                    n3Deforms = model.node[selectn3]['deforms']
                    # get angulation
                    output = line_line_angulation(selectn1, 
                                        n1Deforms, selectn2, n2Deforms, selectn3, n3Deforms)
                    output['NodesIndex'] = nindex
                    
                    # Store output with name
                    dialog_output = get_index_name()
                    output['Name'] = dialog_output
                    storeOutput.append(output)
                    
                    # update labels
                    t1.text = '\b{Nodes}: %i - %i - %i' % (nindex[0], nindex[1], nindex[2])
                    t1.visible = True
                    print('selection of 3 nodes stored')
                    
                if len(selected_nodes) > 3:
                    for node in selected_nodes:
                        node.faceColor = 'b'
                    selected_nodes.clear()
                    print('to many nodes selected, select 1,2 or 3 nodes')
                if len(selected_nodes) < 1:
                    for node in selected_nodes:
                        node.faceColor = 'b'
                    selected_nodes.clear()
                    print('to few nodes selected, select 1,2 or 3 nodes')                
                
                # Visualize analyzed nodes and deselect
                for node in selected_nodes:
                    selected_nodes_sum.add(node)

                for node in selected_nodes_sum:
                    node.faceColor = 'g'  # make green when analyzed
                selected_nodes.clear()
                
            if event.key == vv.KEY_ESCAPE:
                # FINISH MODEL, STORE TO EXCEL
                
                # Store to EXCEL
                storeOutputToExcel(storeOutput, exceldir)
                vv.close(fig)
                print('output stored to excel')
     
        selected_nodes = list()
        def select_node(event):
            """ select and deselect nodes by Double Click
            """
            if event.owner not in selected_nodes:
                event.owner.faceColor = 'r'
                selected_nodes.append(event.owner)
            elif event.owner in selected_nodes:
                event.owner.faceColor = 'b'
                selected_nodes.remove(event.owner)
        
        def pick_node(event):
            nodenr = event.owner.nr
            node = event.owner.node
            t0.text = '\b{Node nr|location}: %i | x=%1.3f y=%1.3f z=%1.3f' % (nodenr,node[0],node[1],node[2])
        
        def unpick_node(event):
            t0.text = '\b{Node nr|location}: '
        
        def point_pulsatility(point1, point1Deforms):
            n1Indices = point1 + point1Deforms
            pos_combinations = list(itertools.combinations(range(len(point1Deforms)),2))
            distances = []
            for i in pos_combinations:
                v = point1Deforms[i[0]] - point1Deforms[i[1]]
                distances.append(((v[0]**2 + v[1]**2 + v[2]**2)**0.5 ))
            distances = np.array(distances)
            
            # get max distance between phases
            point_phase_max = distances.max()
            point_phase_max = [point_phase_max, [x*10 for x in (pos_combinations[list(distances).index(point_phase_max)])]]
            
            # get min distance between phases
            point_phase_min = distances.min()
            point_phase_min = [point_phase_min, [x*10 for x in (pos_combinations[list(distances).index(point_phase_min)])]]
            
            return {'point_phase_min':point_phase_min,'point_phase_max': point_phase_max, 'Node1': [point1, point1Deforms]}

        def point_to_point_pulsatility(cl, point1, point1Deforms, 
                                            point2, point2Deforms,type='euclidian'):
            
            import numpy as np
            
            n1Indices = point1 + point1Deforms
            n2Indices = point2 + point2Deforms
            # define vector between nodes
            v = n1Indices - n2Indices
            distances = ( (v[:,0]**2 + v[:,1]**2 + v[:,2]**2)**0.5 ).reshape(-1,1)
            # get min and max distance
            point_to_pointMax = distances.max()
            point_to_pointMin = distances.min()
            # add phase in cardiac cycle where min and max where found (5th = 50%)
            point_to_pointMax = [point_to_pointMax, (list(distances).index(point_to_pointMax) )*10]
            point_to_pointMin = [point_to_pointMin, (list(distances).index(point_to_pointMin) )*10]
            # get median of distances
            point_to_pointMedian = np.percentile(distances, 50) # Q2
            # median of the lower half, Q1 and upper half, Q3
            point_to_pointQ1 = np.percentile(distances, 25)
            point_to_pointQ3 = np.percentile(distances, 75)
            # Pulsatility min max distance point to point
            point_to_pointP = point_to_pointMax[0] - point_to_pointMin[0]
            # add % change to pulsatility
            point_to_pointP = [point_to_pointP, (point_to_pointP/point_to_pointMin[0])*100 ]
            
            # find index of point on cll and calculate length change cll ???
            if isinstance(cl, PointSet):
                cl = np.asarray(cl).reshape((len(cl),3))
                
            indpoint1 = np.where( np.all(cl == point1, axis=-1) )[0] # -1 counts from last to the first axis
            indpoint2 = np.where( np.all(cl == point2, axis=-1) )[0] # renal point
            n1Indices = point1 + point1Deforms
            n2Indices = point2 + point2Deforms
            
            clDeforms = []
            clpart_deformed = []
            vectors = []
            clpart = []
            d = []
            dist_cl = []   
            clpartDeforms = []
            clpart_deformed_test = []
            
            for i in range(len(cl)):
                clDeforms1 = model.node[cl[i,0], cl[i,1], cl[i,2]]['deforms']
                clDeforms.append(clDeforms1)
                clpart_deformed1 = cl[i] + clDeforms1
                clpart_deformed.append(clpart_deformed1)
            
            # clpart = cl[min(indpoint1[0], indpoint2[0]):max(indpoint1[0], indpoint2[0])+1]
            
            clpart = clpart_deformed[min(indpoint1[0], indpoint2[0]):max(indpoint1[0], indpoint2[0])+1]
            
            # for i in range(len(clpart)):
            #     clpartDeforms1 = model.node[clpart[i,0], clpart[i,1], clpart[i,2]]['deforms']
            #     clpartDeforms.append(clpartDeforms1)
            #     clpart_deformed1_test = cl[i] + clpartDeforms1
            #     clpart_deformed_test.append(clpart_deformed1_test)
                
            # for k in range(len(n1Indices)):
            #     vectors_phases = np.vstack([clpart_deformed_test[i+1][k]-clpart_deformed_test[i][k] for i in range(len(clpart)-1)])
            #     vectors.append(vectors_phases)
                
            for k in range(len(n1Indices)):
                vectors_phases = np.vstack([clpart[i+1][k]-clpart[i][k] for i in range(len(clpart)-1)])
                vectors.append(vectors_phases)
            
            for i in range(len(vectors)):
                if type == 'euclidian':
                    d1 = (vectors[i][:,0]**2 + vectors[i][:,1]**2 + vectors[i][:,2]**2)**0.5  # 3Dvector length in mm
                    d.append(d1)
                elif type == 'z':
                    d = abs(vectors[i][:,2])  # x,y,z ; 1Dvector length in mm
             
            for i in range(len(d)):
                dist = d[i].sum()
                dist_cl.append(dist)
               
            #if indpoint2 > indpoint1: # stent point proximal to renal on centerline: positive
                #dist_cl*=-1
                
            cl_min_index1 = np.argmin(dist_cl)   
            cl_min_index = cl_min_index1*10
            cl_min = min(dist_cl)
            cl_max_index1 = np.argmax(dist_cl)   
            cl_max_index = cl_max_index1*10
            cl_max = max(dist_cl)
            
            print ([dist_cl])
            print ([point1, point2])
            
            return {'point_to_pointMin': point_to_pointMin, 
            'point_to_pointQ1': point_to_pointQ1, 
            'point_to_pointMedian': point_to_pointMedian, 
            'point_to_pointQ3': point_to_pointQ3, 
            'point_to_pointMax': point_to_pointMax, 
            'point_to_pointP': point_to_pointP, 
            'Node1': [point1, point1Deforms], 
            'Node2': [point2, point2Deforms], 'distances': distances, 
            'dist_cl': dist_cl, 'cl_min_index': cl_min_index, 
            'cl_max_index': cl_max_index, 'cl_min': cl_min, 'cl_max': cl_max}
            
        
        def line_line_angulation(point1, point1Deforms, point2, point2Deforms, point3, point3Deforms):
            n1Indices = point1 + point1Deforms
            n2Indices = point2 + point2Deforms
            n3Indices = point3 + point3Deforms
            
            # get vectors
            v1 = n1Indices - n2Indices
            v2 = n3Indices - n2Indices
            
            # get angles
            angles = []
            for i in range(len(v1)):
                angles.append(math.degrees(math.acos((np.dot(v1[i],v2[i]))/
                (np.linalg.norm(v1[i])*np.linalg.norm(v2[i])))))
            angles = np.array(angles)
            
            # get all angle differences of all phases
            pos_combinations = list(itertools.combinations(range(len(v1)),2))
            angle_diff = []
            for i in pos_combinations:
                v = point1Deforms[i[0]] - point1Deforms[i[1]]
                angle_diff.append(abs(angles[i[0]] - angles[i[1]]))
            angle_diff = np.array(angle_diff)
            
            # get max angle differences
            point_angle_diff_max = angle_diff.max()
            point_angle_diff_max = [point_angle_diff_max, [x*10 for x in
            (pos_combinations[list(angle_diff).index(point_angle_diff_max)])]]
            
            # get min angle differences
            point_angle_diff_min = angle_diff.min()
            point_angle_diff_min = [point_angle_diff_min, [x*10 for x in 
            (pos_combinations[list(angle_diff).index(point_angle_diff_min)])]]
            
            return {'point_angle_diff_min':point_angle_diff_min,
            'point_angle_diff_max': point_angle_diff_max, 'angles': angles, 
            'Node1': [point1, point1Deforms], 'Node2': [point2, point2Deforms], 
            'Node3': [point3, point1Deforms]}
            
        
        def append_centerlines(allcenterlines):
            """ Merge seperated PointSet centerlines into one PointSet
            """
            # cl_merged = allcenterlines[0]
            cl_merged = PointSet(3)
            for i in range(0,len(allcenterlines)):
                for point in allcenterlines[i]:
                    cl_merged.append(point)
            return cl_merged
            
            
        def get_index_name():
                # Gui for input name
                app = QtGui.QApplication([])
                m = MyDialog()
                m.show()
                m.exec_()
                dialog_output = m.edit.text()
                return dialog_output  
            
       
        def storeOutputToExcel(storeOutput, exceldir):
            """Create file and add a worksheet or overwrite existing
            """
            # https://pypi.python.org/pypi/XlsxWriter
            workbook = xlsxwriter.Workbook(os.path.join(exceldir,'storeOutput.xlsx'))
            worksheet = workbook.add_worksheet('General')
            # set column width
            worksheet.set_column('A:A', 35)
            worksheet.set_column('B:B', 30)
            # add a bold format to highlight cells
            bold = workbook.add_format({'bold': True})
            # write title and general tab
            worksheet.write('A1', 'Output ChEVAS dynamic CT, 10 Phases', bold)
            analysisID = '%s_%s_%s' % (ptcode, ctcode, cropname)
            worksheet.write('A2', 'Filename:', bold)
            worksheet.write('B2', analysisID)
            worksheet.write('A3', 'Date and Time:', bold)
            date_time = datetime.now() #strftime("%d-%m-%Y %H:%M")
            date_format_str = 'dd-mm-yyyy hh:mm'
            date_format = workbook.add_format({'num_format': date_format_str,
                                      'align': 'left'})
            worksheet.write_datetime('B3', date_time, date_format)
            # write 'storeOutput'
            sort_index = []
            for i in range(len(storeOutput)):
                type = len(storeOutput[i]['NodesIndex'])
                sort_index.append([i, type])
            sort_index = np.array(sort_index)
            sort_index = sort_index[sort_index[:,1].argsort()]
            
            for i, n in sort_index:
                worksheet = workbook.add_worksheet(storeOutput[i]['Name'])
                worksheet.set_column('A:A', 35)
                worksheet.set_column('B:B', 20)
                worksheet.write('A1', 'Name:', bold)
                worksheet.write('B1', storeOutput[i]['Name'])
                if n == 1:
                    worksheet.write('A2', 'Type:', bold)
                    worksheet.write('B2', '1 Node')
                    
                    worksheet.write('A3', 'Minimum translation (mm, Phases)',bold)
                    worksheet.write('B3', storeOutput[i]['point_phase_min'][0])
                    worksheet.write_row('C3', list(storeOutput[i]['point_phase_min'][1]))
                    
                    worksheet.write('A4', 'Maximum translation (mm, Phases)',bold)
                    worksheet.write('B4', storeOutput[i]['point_phase_max'][0])
                    worksheet.write_row('C4', list(storeOutput[i]['point_phase_max'][1]))
                    
                    worksheet.write('A5', 'Avg node position and deformations', bold)
                    worksheet.write('B5', str(list(storeOutput[i]['Node1'][0])))
                    worksheet.write_row('C5', [str(x)for x in list(storeOutput[i]['Node1'][1])])
                    
                    worksheet.write('A6', 'Node Index Number', bold)
                    worksheet.write_row('B6', list(storeOutput[i]['NodesIndex'])) 
                                       
                elif n == 2:
                    worksheet.write('A2', 'Type:', bold)
                    worksheet.write('B2', '2 Nodes')
                    
                    worksheet.write('A3', 'Minimum distance (mm, Phases)',bold)
                    worksheet.write('B3', storeOutput[i]['point_to_pointMin'][0])
                    worksheet.write('C3', storeOutput[i]['point_to_pointMin'][1])
                    
                    worksheet.write('A4', 'Q1 distance (mm)',bold)
                    worksheet.write('B4', storeOutput[i]['point_to_pointQ1'])

                    worksheet.write('A5', 'Median distance (mm)',bold)
                    worksheet.write('B5', storeOutput[i]['point_to_pointMedian'])
                    
                    worksheet.write('A6', 'Q3 distance (mm)',bold)
                    worksheet.write('B6', storeOutput[i]['point_to_pointQ3'])
                    
                    worksheet.write('A7', 'Maximum distance (mm, phases)',bold)
                    worksheet.write('B7', storeOutput[i]['point_to_pointMax'][0])
                    worksheet.write('C7', storeOutput[i]['point_to_pointMax'][1])
                    
                    worksheet.write('A8', 'Maximum distance difference (mm)', bold)
                    worksheet.write('B8', storeOutput[i]['point_to_pointP'][0])
                    
                    worksheet.write('A9', 'Distances for each phase', bold)
                    worksheet.write_row('B9', [str(x) for x in list(storeOutput[i]['distances'])])
                    
                    worksheet.write('A10', 'Avg node1 position and deformations', bold)
                    worksheet.write('B10', str(list(storeOutput[i]['Node1'][0])))
                    worksheet.write_row('C10', [str(x) for x in list(storeOutput[i]['Node1'][1])])
                    
                    worksheet.write('A11', 'Avg node2 position and deformations', bold)
                    worksheet.write('B11', str(list(storeOutput[i]['Node2'][0])))
                    worksheet.write_row('C11', [str(x) for x in list(storeOutput[i]['Node2'][1])])
                    
                    worksheet.write('A12', 'Node Index Number', bold)
                    worksheet.write_row('B12', list(storeOutput[i]['NodesIndex'])) 
                    
                    worksheet.write('A13', 'Length centerline', bold) 
                    worksheet.write('B13', str(list(storeOutput[i]['dist_cl']))) 
                    
                    worksheet.write('A14', 'Minimum length centerline', bold) 
                    worksheet.write('B14', storeOutput[i]['cl_min']) 
                    worksheet.write('C14', storeOutput[i]['cl_min_index']) 
                    
                    worksheet.write('A15', 'Maximum length centerline', bold) 
                    worksheet.write('B15', storeOutput[i]['cl_max'])  
                    worksheet.write('C15', storeOutput[i]['cl_max_index']) 
                
                elif n == 3:
                    worksheet.write('A2', 'Type:', bold)
                    worksheet.write('B2', '3 Nodes')
                    
                    worksheet.write('A3', 'Minimum angle difference (degrees, Phases)',bold)
                    worksheet.write('B3', storeOutput[i]['point_angle_diff_min'][0])
                    worksheet.write_row('C3', list(storeOutput[i]['point_angle_diff_min'][1]))
                    
                    worksheet.write('A4', 'Maximum angle difference (degrees, Phases)',bold)
                    worksheet.write('B4', storeOutput[i]['point_angle_diff_max'][0])
                    worksheet.write_row('C4', list(storeOutput[i]['point_angle_diff_max'][1]))
                    
                    worksheet.write('A5', 'Angles for each phase (degrees)',bold)
                    worksheet.write_row('B5', list(storeOutput[i]['angles']))
                    
                    worksheet.write('A6', 'Avg node1 position and deformations', bold)
                    worksheet.write('B6', str(list(storeOutput[i]['Node1'][0])))
                    worksheet.write_row('C6', [str(x) for x in list(storeOutput[i]['Node1'][1])])
                    
                    worksheet.write('A7', 'Avg node2 position and deformations', bold)
                    worksheet.write('B7', str(list(storeOutput[i]['Node2'][0])))
                    worksheet.write_row('C7', [str(x) for x in list(storeOutput[i]['Node2'][1])])
                    
                    worksheet.write('A8', 'Avg node2 position and deformations', bold)
                    worksheet.write('B8', str(list(storeOutput[i]['Node3'][0])))
                    worksheet.write_row('C8', [str(x) for x in list(storeOutput[i]['Node3'][1])])
                    
                    worksheet.write('A9', 'Node Index Number', bold)
                    worksheet.write_row('B9', list(storeOutput[i]['NodesIndex']))   
                    
            workbook.close()
        
        # Bind event handlers
        fig.eventKeyDown.Bind(on_key)
        for node_point in node_points:
            node_point.eventDoubleClick.Bind(select_node)
            node_point.eventEnter.Bind(pick_node)
            node_point.eventLeave.Bind(unpick_node)
예제 #8
0
from stentseg.utils.visualization import DrawModelAxes
import visvis as vv
from stentseg.utils import _utils_GUI

# Select the ssdf basedir
basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf',
                     r'F:\LSPEAS_ssdf_backup', r'G:\LSPEAS_ssdf_backup')

# Select dataset to register
ptcode = 'LSPEAS_008'
ctcode = '1month'
cropname = 'stent'
what = 'phases'  # avgreg

# Load volumes
s = loadvol(basedir, ptcode, ctcode, cropname, what)
vol = s.vol80

clim = (0, 2500)
# clim = (-100,300)
showVol = '2D'

fig = vv.figure(2)
vv.clf()
fig.position = 0.00, 22.00, 1920.00, 1018.00

label = DrawModelAxes(vol, clim=clim, showVol=showVol)  # lc, mc
a = vv.gca()

# bind rotate view [a,d rotate; z,x axes]
fig.eventKeyDown.Bind(lambda event: _utils_GUI.RotateView(event, [a]))
예제 #9
0
for i, vol in enumerate(vols2):
    print(vol.meta.sampling)
    phase = int(vol.meta.SeriesDescription[:1])
    vols[phase] = vol
for j, vol in enumerate(vols):
    print(vol.meta.SeriesDescription)
    assert vol.shape == vols[0].shape
    assert str(j * 10) in vol.meta.SeriesDescription  # 0% , 10% etc.

## Step B: Crop and Save SSDF
for cropname in cropnames:
    savecropvols(vols, basedir, ptcode, ctcode, cropname, stenttype)

## Visualize result

s1 = loadvol(basedir, ptcode, ctcode, cropnames[0], what='10phases')
vol1 = s1.vol40
vol2 = s1.vol90

# Visualize and compare
colormap = {
    'r': [(0.0, 0.0), (0.17727272, 1.0)],
    'g': [(0.0, 0.0), (0.27272728, 1.0)],
    'b': [(0.0, 0.0), (0.34545454, 1.0)],
    'a': [(0.0, 1.0), (1.0, 1.0)]
}

import visvis as vv
fig = vv.figure(1)
vv.clf()
fig.position = 0, 22, 1366, 706
예제 #10
0
# Select the ssdf basedir
basedir = select_dir(r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup',
                     r'G:\LSPEAS_ssdf_backup')
basedirstl = select_dir(
    r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation',
    r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation')

# Select dataset
ptcode = 'LSPEAS_008'
ctcode = 'discharge'
cropname = 'stent'
what = 'centerline'

# Load deforms
s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms')
deformkeys = []
for key in dir(s):
    if key.startswith('deform'):
        deformkeys.append(key)
deforms = [s[key] for key in deformkeys]
deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms]
paramsreg = s.params

# Load centerline mat
matName = '%s_%s_%s_%s.mat' % (ptcode, ctcode, cropname, what)
centerlineMat = scipy.io.loadmat(os.path.join(basedirstl, ptcode, matName))

# Load model
s = loadmodel(basedirstl, ptcode, ctcode, cropname, what)
for key in dir(s):
예제 #11
0
    def __init__(self, dicom_basedir, ptcode, ctcode, basedir):

        import imageio
        #import easygui

        from stentseg.utils.datahandling import loadvol
        from stentseg.utils.datahandling import savecropvols, saveaveraged

        ## Select base directory for LOADING DICOM data

        #dicom_basedir = easygui.diropenbox()
        print('DICOM Path = ', dicom_basedir)

        #ctcode = '12months'  # 'pre', 'post_x', '12months'
        stenttype = 'nellix'

        ## Select base directory to SAVE SSDF
        #basedir = easygui.diropenbox()
        print('Base Path = ', basedir)

        # Set which crops to save
        cropnames = ['prox']  #,'stent'] # ['ring'] or ['ring','stent'] or ..

        #===============================================================================
        ## Step A: read single volumes to get vols:
        #  folder1 = '10%'
        #  folder2 = '60%'
        #  vol1 = imageio.volread(os.path.join(dicom_basedir, folder1), 'dicom')
        #  vol2 = imageio.volread(os.path.join(dicom_basedir, folder2), 'dicom')
        #  print(  )
        #
        #  if vol1.meta.SeriesDescription[:2] < vol2.meta.SeriesDescription[:2]:
        #      vols4078 = [vol1,vol2]
        #  else:
        #      vols4078 = [vol2,vol1]
        #
        #  vols = vols4078.copy()
        #
        #  for vol in vols:
        #      vol.meta.PatientName = ptcode # anonimyze
        #      vol.meta.PatientID = 'anonymous'
        #     print(vol.meta.SeriesDescription,'-', vol.meta.sampling)
        #===============================================================================

        ##Orginele code
        #===============================================================================
        #
        # folder1 = '40% iDose'
        # folder2 = '78 iDose'
        # vol1 = imageio.volread(os.path.join(dicom_basedir, folder1), 'dicom')
        # vol2 = imageio.volread(os.path.join(dicom_basedir, folder2), 'dicom')
        # print(  )
        #
        # if vol1.meta.SeriesDescription[:2] < vol2.meta.SeriesDescription[:2]:
        #     vols4078 = [vol1,vol2]
        # else:
        #     vols4078 = [vol2,vol1]
        #
        # vols = vols4078.copy()
        #
        # for vol in vols:
        #     vol.meta.PatientName = ptcode # anonimyze
        #     vol.meta.PatientID = 'anonymous'
        #     print(vol.meta.SeriesDescription,'-', vol.meta.sampling)
        #===============================================================================

        ## Step A: read 10 volumes to get vols
        # Deze zoekt alle mappen en dat zijn er dus 10 maar niet in de goede volgorde
        vols2 = [
            vol2 for vol2 in imageio.get_reader(dicom_basedir, 'DICOM', 'V')
        ]

        vols = [None] * len(vols2)
        for i, vol in enumerate(vols2):
            #    print(vol.meta.sampling)
            print(vol.meta.SeriesDescription)
            phase = int(vol.meta.SeriesDescription[:1])
            # use phase to fix order of phases
            vols[phase] = vol
            #vols[phase].meta.ImagePositionPatient = (0.0,0.0,0.0)

        for i, vol in enumerate(
                vols):  #wat ik heb veranderd is i, en enumerate()
            print(vol.meta.SeriesDescription)
            assert vol.shape == vols[0].shape
            assert str(i * 10) in vol.meta.SeriesDescription  # 0% , 10% etc.

        ## Step B: Crop and Save SSDF
        # 1 of 2 cropnames opgeven voor opslaan 1 of 2 crpos.
        # Het eerste volume wordt geladen in MIP, crop met marges van minimaal 30 mm
        for cropname in cropnames:
            savecropvols(vols, basedir, ptcode, ctcode, cropname, stenttype)
        #    saveaveraged(basedir, ptcode, ctcode, cropname, range(0,100,10))

        ## Visualize result

        #s1 = loadvol(basedir, ptcode, ctcode, cropnames[0], what ='10avgreg')
        #s2 = loadvol(basedir, ptcode, ctcode, cropnames[0], what ='10phases')
        s1 = loadvol(basedir, ptcode, ctcode, cropnames[0], what='phases')
        #s2 = loadvol(basedir, ptcode, ctcode, cropnames[0], what = 'avg010')
        #vol1 = s1.vol
        vol1 = s1.vol40

        # Visualize and compare
        colormap = {
            'r': [(0.0, 0.0), (0.17727272, 1.0)],
            'g': [(0.0, 0.0), (0.27272728, 1.0)],
            'b': [(0.0, 0.0), (0.34545454, 1.0)],
            'a': [(0.0, 1.0), (1.0, 1.0)]
        }

        import visvis as vv

        fig = vv.figure(1)
        vv.clf()
        fig.position = 0, 22, 1366, 706
        a1 = vv.subplot(111)
        a1.daspect = 1, 1, -1
        # t1 = vv.volshow(vol1, clim=(0, 3000), renderStyle='iso') # iso or mip
        # t1.isoThreshold = 600 # stond op 400 maar je moet hoger zetten als je alleen stent wil
        # t1.colormap = colormap
        a1 = vv.volshow2(vol1, clim=(-500, 1500), renderStyle='mip')
        vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z')
        # vv.title('One volume at %i procent of cardiac cycle' % phase )
        vv.title('Vol40')
예제 #12
0
from stentseg.utils.visualization import DrawModelAxes, show_ctvolume
from stentseg.utils.utils_graphs_pointsets import get_graph_in_phase
from stentseg.utils.picker import pick3d

basedir = select_dir(r'E:\Nellix_chevas\CT_SSDF\SSDF_automated',
                     r'D:\Nellix_chevas_BACKUP\CT_SSDF\SSDF_automated')

ptcode = 'chevas_09_thin'
ctcode = '12months'
phases = range(10)  # all 10 phases

showmodelavgreg = True
showvol = True

# get vol for reference
s = loadvol(basedir, ptcode, ctcode, 'prox', what='avgreg')
# set sampling for cases where this was not stored correctly
s.vol.sampling = [s.sampling[1], s.sampling[1], s.sampling[2]]
vol = s.vol

s_modelcll = loadmodel(basedir,
                       ptcode,
                       ctcode,
                       'prox',
                       modelname='centerline_total_modelavgreg_deforms')
# get graph
modelcll = s_modelcll.model

s_modelcll_vessel = loadmodel(basedir,
                              ptcode,
                              ctcode,
예제 #13
0
else:
    vol = imageio.volread(os.path.join(dicom_basedir, ptcode, ctcode), 'dicom')
print ()
print(vol.meta.SeriesDescription)
print(vol.meta.sampling)
print()

# Step B: Crop and Save SSDF
vols = [vol]
for cropname in cropnames:
    savecropvols(vols, ssdf_basedir, ptcode, ctcode, cropname, stenttype)


## Visualize result

s1 = loadvol(ssdf_basedir, ptcode, ctcode, cropnames[0], what ='phase')
vol = s1.vol

# Visualize and compare
colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)],
 'g': [(0.0, 0.0), (0.27272728, 1.0)],
 'b': [(0.0, 0.0), (0.34545454, 1.0)],
 'a': [(0.0, 1.0), (1.0, 1.0)]}
 
import visvis as vv
fig = vv.figure(1); vv.clf()
fig.position = 0, 22, 1366, 706
a = vv.gca()
a.daspect = 1,1,-1
t1 = vv.volshow(vol, clim=(0, 2500), renderStyle='iso') # iso or mip
t1.isoThreshold = 400
예제 #14
0
파일: vis.py 프로젝트: almarklein/stentseg
def showVolPhases(basedir, vols=None, ptcode=None, ctcode=None, cropname=None, 
    showVol='iso', mipIsocolor=False, isoTh=310,
            slider=False, clim=(0,3000), clim2D=(-550, 500), fname=None):
    """ Show vol phases in motion container
    showVol= mip or iso or 2D; Provide either vols or location
    """
    if vols is None:
        # Load volumes
        s = loadvol(basedir, ptcode, ctcode, cropname, 'phases', fname=fname)
        vols = []
        for key in dir(s):
            if key.startswith('vol'):
                vols.append(s[key])
        
    # Start vis
    f = vv.figure(1); vv.clf()
    f.position = 9.00, 38.00,  992.00, 944.00
    a = vv.gca()
    a.daspect = 1, 1, -1
    a.axis.axisColor = 1,1,1
    a.axis.visible = False
    a.bgcolor = 0,0,0
    if showVol=='mip':
        if not ptcode is None and not ctcode is None:
            vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode))
        else:
            vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes ')
    else:
        if not ptcode is None and not ctcode is None:
            vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode))
        else:
            vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes ')
    
    # Setup data container
    container = vv.MotionDataContainer(a)
    for vol in vols:
        if showVol == '2D':
            t = vv.volshow2(vol, clim=clim2D) # -750, 1000
            t.parent = container
        else:
            t = vv.volshow(vol, clim=clim, renderStyle = showVol)
            t.parent = container
            if showVol == 'iso':
                t.isoThreshold = isoTh    # iso or mip work well 
                t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)],
                            'g': [(0.0, 0.0), (0.27272728, 1.0)],
                            'b': [(0.0, 0.0), (0.34545454, 1.0)],
                            'a': [(0.0, 1.0), (1.0, 1.0)]}
            if mipIsocolor:
                t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)],
                            'g': [(0.0, 0.0), (0.27272728, 1.0)],
                            'b': [(0.0, 0.0), (0.34545454, 1.0)],
                            'a': [(0.0, 1.0), (1.0, 1.0)]}
    # bind ClimEditor to figure
    if slider:
        if showVol=='mip':
            c = vv.ClimEditor(vv.gcf())
            c.position = (10, 50)
            f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) )
        if showVol=='iso':
            c = IsoThEditor(vv.gcf())
            c.position = (10, 50)
            f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) )
    
    f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, [a]) )
    print('------------------------')
    print('Use keys 1, 2, 3, 4 and 5 for preset anatomic views')
    print('Use v for a default zoomed view')
    print('Use x to show and hide axis')
    print('------------------------')
    
    return t
예제 #15
0
 def __init__(self,ptcode,ctcode,basedir, threshold=300, show=True, 
             normalize=False, modelname='modelvessel'):
     
     import os
     
     import numpy as np
     import visvis as vv
     from visvis import ssdf
     
     from stentseg.utils import PointSet, _utils_GUI
     from stentseg.utils.datahandling import select_dir, loadvol, loadmodel
     from stentseg.stentdirect.stentgraph import create_mesh
     from stentseg.stentdirect import stentgraph, StentDirect, getDefaultParams
     from stentseg.stentdirect import AnacondaDirect, EndurantDirect, NellixDirect
     from stentseg.utils.visualization import show_ctvolume
     from stentseg.utils.picker import pick3d, label2worldcoordinates, label2volindices
     import scipy
     from scipy import ndimage
     import copy
     from stentseg.utils.get_isosurface import get_isosurface3d, isosurface_to_graph, show_surface_and_vol
     
     # Select dataset to register
     cropname = 'prox'
     #phase = 10
     #what = 'phase'+str(phase)
     what = 'avgreg'
     
     # Load volumes
     s = loadvol(basedir, ptcode, ctcode, cropname, what)
     
     # sampling was not properly stored after registration for all cases: reset sampling
     vol_org = copy.deepcopy(s.vol)
     s.vol.sampling = [vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]] # z,y,x
     s.sampling = s.vol.sampling
     vol = s.vol
     
     # Get isosurface
     verts, faces, pp_vertices, mesh = get_isosurface3d(vol, threshold=threshold, showsurface=False)
     
     if show:
         self.label = show_surface_and_vol(vol, pp_vertices, showVol='MIP')
     
     # Convert to graph
     model = isosurface_to_graph(pp_vertices) # model with nodes
     
     # Store segmentation to disk
     p = threshold
     stentType = 'isosurface'
     
     # Build struct
     s2 = vv.ssdf.new()
     s2.sampling = s.sampling
     s2.origin = s.origin
     s2.stenttype = s.stenttype
     s2.croprange = s.croprange
     for key in dir(s):
             if key.startswith('meta'):
                 suffix = key[4:]
                 s2['meta'+suffix] = s['meta'+suffix]
     s2.what = what
     s2.params = p
     s2.stentType = stentType
     # Store model (not also volume)
     s2.model = model.pack()
     
     
     # Save
     filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, modelname+ what)
     ssdf.save(os.path.join(basedir, ptcode, filename), s2)
     print('saved to disk as {}.'.format(filename) )
예제 #16
0
    from stentseg.utils import PointSet, _utils_GUI, visualization

    basedir = select_dir(os.getenv('LSPEAS_BASEDIR',
                                   ''), r'D:\LSPEAS\LSPEAS_ssdf',
                         r'F:\LSPEAS_ssdf_BACKUP', r'G:\LSPEAS_ssdf_BACKUP')

    ptcode = 'LSPEAS_025'
    ctcode = '1month'
    cropname = 'ring'
    modelname = 'modelavgreg'

    s = loadmodel(basedir, ptcode, ctcode, cropname, modelname)
    model = s.model.copy()

    # Load volume
    s_vol = loadvol(basedir, ptcode, ctcode, cropname, 'avgreg')
    vol = s_vol.vol

    # Load deforms
    s_deforms = loadvol(basedir, ptcode, ctcode, cropname, 'deforms')
    deformkeys = []
    for key in dir(s_deforms):
        if key.startswith('deform'):
            deformkeys.append(key)
    deforms = [s_deforms[key] for key in deformkeys]
    deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms]

    selected_nodes = list()
    node_points, t3 = nodeInteraction(model, vol, selected_nodes)

    print(s.origin)  # for same crop the origins should be the same
예제 #17
0
def identifyCenterlines(s,
                        ptcode,
                        ctcode,
                        basedir,
                        modelname,
                        showVol='MIP',
                        **kwargs):
    """ s is struct with models
    """
    from stentseg.utils.datahandling import select_dir, loadvol, loadmodel
    from stentseg.utils.picker import pick3d
    from stentseg.utils.visualization import show_ctvolume
    from stentseg.utils import _utils_GUI

    showAxis = False
    # showVol  = 'MIP'  # MIP or ISO or 2D or None
    clim = (0, 2500)
    # clim = -200,500 # 2D
    isoTh = 250
    cropname = 'prox'

    # init fig
    f = vv.figure()
    vv.clf()
    f.position = 0.00, 22.00, 1920.00, 1018.00
    # load vol
    svol = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg')
    # set sampling for cases where this was not stored correctly
    svol.vol.sampling = [svol.sampling[1], svol.sampling[1], svol.sampling[2]]
    vol = svol.vol
    s.sampling = [svol.sampling[1], svol.sampling[1],
                  svol.sampling[2]]  # for model
    # show vol
    t = show_ctvolume(vol, showVol=showVol, clim=clim, isoTh=isoTh, **kwargs)
    label = pick3d(vv.gca(), vol)
    vv.xlabel('x (mm)')
    vv.ylabel('y (mm)')
    vv.zlabel('z (mm)')

    if showVol == 'MIP':
        c = vv.ClimEditor(vv.gca())
        c.position = (10, 50)
        f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c))
        print('Use "s" to show/hide slider')
    if showVol == 'ISO':
        c = _utils_GUI.IsoThEditor(vv.gca())
        c.position = (10, 50)
        f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c))
        print('Use "s" to show/hide slider')

    f.eventKeyDown.Bind(
        lambda event: _utils_GUI.ViewPresets(event, [vv.gca()]))
    print('------------------------')
    print('Use keys 1, 2, 3, 4 and 5 for preset anatomic views')
    print('Use v for a default zoomed view')
    print('Use x to show and hide axis')
    print('------------------------')

    ax, s2 = interactiveCenterlineID(s, ptcode, ctcode, basedir, cropname,
                                     modelname)

    return ax, s2
예제 #18
0
    def __init__(self,
                 ptcode,
                 ctcode,
                 StartPoints,
                 EndPoints,
                 basedir,
                 modelname='modelavgreg'):
        """ with start and endpoints provided, calculate centerline and save as
        ssdf in basedir as model and dynamic model
        """
        #todo: name of dynamic model is now deforms, unclear, should be dynamic
        #import numpy as np
        import visvis as vv
        import numpy as np
        import os
        import copy

        from stentseg.utils import PointSet, _utils_GUI
        from stentseg.utils.centerline import (find_centerline,
                                               points_from_nodes_in_graph,
                                               points_from_mesh,
                                               smooth_centerline)
        from stentseg.utils.datahandling import loadmodel, loadvol
        from stentseg.utils.visualization import show_ctvolume
        from stentseg.utils.picker import pick3d

        stentnr = len(StartPoints)

        cropname = 'prox'
        what = modelname
        what_vol = 'avgreg'
        vismids = True
        m = loadmodel(basedir, ptcode, ctcode, cropname, what)
        s = loadvol(basedir, ptcode, ctcode, cropname, what_vol)
        s.vol.sampling = [s.sampling[1], s.sampling[1], s.sampling[2]]
        s.sampling = s.vol.sampling

        start1 = StartPoints.copy()
        ends = EndPoints.copy()

        from stentseg.stentdirect import stentgraph
        ppp = points_from_nodes_in_graph(m.model)

        allcenterlines = []  # for pp
        allcenterlines_nosmooth = []  # for pp
        centerlines = []  # for stentgraph
        nodes_total = stentgraph.StentGraph()
        for j in range(stentnr):
            if j == 0 or not start1[j] == ends[j - 1]:
                # if first stent or when stent did not continue with this start point
                nodes = stentgraph.StentGraph()
                centerline = PointSet(3)  # empty

            # Find main centerline
            # if j > 3: # for stent with midpoints
            #     centerline1 = find_centerline(ppp, start1[j], ends[j], step= 1,
            #     ndist=10, regfactor=0.5, regsteps=10, verbose=False)

            #else:
            centerline1 = find_centerline(ppp,
                                          start1[j],
                                          ends[j],
                                          step=1,
                                          ndist=10,
                                          regfactor=0.5,
                                          regsteps=1,
                                          verbose=False)
            # centerline1 is a PointSet

            print('Centerline calculation completed')

            # ========= Maaike =======
            smoothfactor = 15  # Mirthe used 2 or 4

            # check if cll continued here from last end point
            if not j == 0 and start1[j] == ends[j - 1]:
                # yes we continued
                ppart = centerline1[:
                                    -1]  # cut last but do not cut first point as this is midpoint
            else:
                # do not use first points, as they are influenced by user selected points
                ppart = centerline1[1:-1]

            for p in ppart:
                centerline.append(p)

            # if last stent or stent does not continue with next start-endpoint
            if j == stentnr - 1 or not ends[j] == start1[j + 1]:
                # store non-smoothed for vis
                allcenterlines_nosmooth.append(centerline)
                pp = smooth_centerline(centerline, n=smoothfactor)
                # add pp to list
                allcenterlines.append(pp)  # list with PointSet per centerline
                self.allcenterlines = allcenterlines

                # add pp as nodes
                for i, p in enumerate(pp):
                    p_as_tuple = tuple(p.flat)
                    nodes.add_node(p_as_tuple)
                    nodes_total.add_node(p_as_tuple)
                # add pp as one edge so that pathpoints are in fixed order
                pstart = tuple(pp[0].flat)
                pend = tuple(pp[-1].flat)
                nodes.add_edge(pstart, pend, path=pp)
                nodes_total.add_edge(pstart, pend, path=pp)
                # add final centerline nodes model to list
                centerlines.append(nodes)

            # ========= Maaike =======

        ## Store segmentation to disk

        # Build struct
        s2 = vv.ssdf.new()
        s2.sampling = s.sampling
        s2.origin = s.origin
        s2.stenttype = m.stenttype
        s2.croprange = m.croprange
        for key in dir(m):
            if key.startswith('meta'):
                suffix = key[4:]
                s2['meta' + suffix] = m['meta' + suffix]
        s2.what = what
        s2.params = s.params  #reg
        s2.paramsseeds = m.params
        s2.stentType = 'nellix'
        s2.StartPoints = StartPoints
        s2.EndPoints = EndPoints
        # keep centerlines as pp also [Maaike]
        s2.ppallCenterlines = allcenterlines
        for k in range(len(allcenterlines)):
            suffix = str(k)
            pp = allcenterlines[k]
            s2['ppCenterline' + suffix] = pp

        s3 = copy.deepcopy(s2)
        s3['model'] = nodes_total.pack()

        # Store model for each centerline
        for j in range(len(centerlines)):
            suffix = str(j)
            model = centerlines[j]
            s2['model' + suffix] = model.pack()

        # Save model with seperate centerlines.
        filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname,
                                         'centerline_' + what)
        vv.ssdf.save(os.path.join(basedir, ptcode, filename), s2)
        print('saved to disk as {}.'.format(filename))

        # Save model with combined centerlines
        filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname,
                                         'centerline_total_' + what)
        vv.ssdf.save(os.path.join(basedir, ptcode, filename), s3)
        print('saved to disk as {}.'.format(filename))

        # remove intermediate centerline points
        # start1 = map(tuple, start1)
        # ends = map(tuple, ends)
        startpoints_clean = copy.deepcopy(start1)
        endpoints_clean = copy.deepcopy(ends)
        duplicates = list(set(start1) & set(ends))
        for i in range(len(duplicates)):
            startpoints_clean.remove(duplicates[i])
            endpoints_clean.remove(duplicates[i])

        #Visualize
        f = vv.figure(10)
        vv.clf()
        a1 = vv.subplot(121)
        a1.daspect = 1, 1, -1

        vv.plot(ppp, ms='.', ls='', alpha=0.6, mw=2)
        for j in range(len(startpoints_clean)):
            vv.plot(PointSet(list(startpoints_clean[j])),
                    ms='.',
                    ls='',
                    mc='g',
                    mw=20)  # startpoint green
            vv.plot(PointSet(list(endpoints_clean[j])),
                    ms='.',
                    ls='',
                    mc='r',
                    mw=20)  # endpoint red
        for j in range(len(allcenterlines)):
            vv.plot(allcenterlines[j], ms='.', ls='', mw=10, mc='y')
        vv.title('Centerlines and seed points')
        vv.xlabel('x (mm)')
        vv.ylabel('y (mm)')
        vv.zlabel('z (mm)')
        # for j in range(len(allcenterlines_nosmooth)):
        #     vv.plot(allcenterlines_nosmooth[j], ms='o', ls='', mw=10, mc='c', alpha=0.6)

        a2 = vv.subplot(122)
        a2.daspect = 1, 1, -1

        vv.plot(ppp, ms='.', ls='', alpha=0.6, mw=2)
        # vv.volshow(s.vol, clim=clim, renderStyle = 'mip')
        t = show_ctvolume(s.vol,
                          axis=a2,
                          showVol='ISO',
                          clim=(0, 2500),
                          isoTh=250,
                          removeStent=False,
                          climEditor=True)
        label = pick3d(vv.gca(), s.vol)
        for j in range(len(startpoints_clean)):
            vv.plot(PointSet(list(startpoints_clean[j])),
                    ms='.',
                    ls='',
                    mc='g',
                    mw=20,
                    alpha=0.6)  # startpoint green
            vv.plot(PointSet(list(endpoints_clean[j])),
                    ms='.',
                    ls='',
                    mc='r',
                    mw=20,
                    alpha=0.6)  # endpoint red
        for j in range(len(allcenterlines)):
            vv.plot(allcenterlines[j], ms='o', ls='', mw=10, mc='y', alpha=0.6)

        # show midpoints (e.g. duplicates)
        if vismids:
            for p in duplicates:
                vv.plot(p[0], p[1], p[2], mc='m', ms='o', mw=10, alpha=0.6)

        a2.axis.visible = False

        vv.title('Centerlines and seed points')

        a1.camera = a2.camera

        f.eventKeyDown.Bind(
            lambda event: _utils_GUI.RotateView(event, [a1, a2]))
        f.eventKeyDown.Bind(
            lambda event: _utils_GUI.ViewPresets(event, [a1, a2]))

        # Pick node for midpoint to redo get_centerline
        self.pickedCLLpoint = _utils_GUI.Event_pick_graph_point(
            nodes_total, s.vol, label, nodesOnly=True)  # x,y,z
        # use key p to select point

        #===============================================================================
        vv.figure(11)
        vv.gca().daspect = 1, 1, -1
        t = show_ctvolume(s.vol,
                          showVol='ISO',
                          clim=(0, 2500),
                          isoTh=250,
                          removeStent=False,
                          climEditor=True)
        label2 = pick3d(vv.gca(), s.vol)
        for j in range(len(startpoints_clean)):
            vv.plot(PointSet(list(startpoints_clean[j])),
                    ms='.',
                    ls='',
                    mc='g',
                    mw=20,
                    alpha=0.6)  # startpoint green
            vv.plot(PointSet(list(endpoints_clean[j])),
                    ms='.',
                    ls='',
                    mc='r',
                    mw=20,
                    alpha=0.6)  # endpoint red
        vv.xlabel('x (mm)')
        vv.ylabel('y (mm)')
        vv.zlabel('z (mm)')
        #===============================================================================

        ## Make model dynamic (and store/overwrite to disk)
        import pirt
        from stentseg.motion.dynamic import incorporate_motion_nodes, incorporate_motion_edges

        # Load deforms
        filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'deforms')
        s1 = vv.ssdf.load(os.path.join(basedir, ptcode, filename))
        deformkeys = []
        for key in dir(s1):
            if key.startswith('deform'):
                deformkeys.append(key)
        deforms = [s1[key] for key in deformkeys]
        deforms = [
            pirt.DeformationFieldBackward(*fields) for fields in deforms
        ]
        for i in range(len(deforms)):
            deforms[i]._field_sampling = tuple(s1.sampling)
        paramsreg = s1.params

        # Load model
        s2 = loadmodel(basedir, ptcode, ctcode, cropname, 'centerline_' + what)
        s3 = loadmodel(basedir, ptcode, ctcode, cropname,
                       'centerline_total_' + what)

        # Combine ...
        for key in dir(s2):
            if key.startswith('model'):
                incorporate_motion_nodes(s2[key], deforms, s.origin)
                incorporate_motion_edges(s2[key], deforms, s.origin)
                model = s2[key]
                s2[key] = model.pack()
        # Combine ...
        for key in dir(s3):
            if key.startswith('model'):
                incorporate_motion_nodes(s3[key], deforms, s.origin)
                incorporate_motion_edges(s3[key], deforms, s.origin)
                model = s3[key]
                s3[key] = model.pack()

        # Save
        s2.paramsreg = paramsreg
        filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname,
                                         'centerline_' + what + '_deforms')
        vv.ssdf.save(os.path.join(basedir, ptcode, filename), s2)
        print('saved to disk as {}.'.format(filename))

        # Save
        s3.paramsreg = paramsreg
        filename = '%s_%s_%s_%s.ssdf' % (
            ptcode, ctcode, cropname, 'centerline_total_' + what + '_deforms')
        vv.ssdf.save(os.path.join(basedir, ptcode, filename), s3)
        print('saved to disk as {}.'.format(filename))
        print("avgreg saved to disk.")

        t1 = time.time()
        t_in_min = (t1 - t0) / 60
        print('Registration completed for %s - %s, which took %1.2f min.' %
              (ptcode, ctcode, t_in_min))

    ## Load deforms and apply deform to registered phases/vols

    if visualize:
        #load avgreg
        avg = 'avgreg'
        filename = '%s_%s.ssdf' % (fileTr, avg)
        savg = loadvol(dirsaveinsilico,
                       ptcode,
                       ctcode,
                       None,
                       'avgreg',
                       fname=filename)
        # loadvol sets savg.sampling and savg.origin
        vol = savg.vol
        # show
        #f = vv.figure(2); vv.clf()
        #f.position = 968.00, 30.00,  944.00, 1002.00
        #a = vv.subplot(111)
        #a.daspect = 1, 1, -1
        if reg2d:
            t = vv.imshow(vol, clim=clim, axes=a4)
        else:
            t = vv.volshow(vol, clim=clim, renderStyle='mip', axes=a4)
            #t.isoThreshold = 600
        vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z')
예제 #20
0
    def __init__(self,ptcode,ctcode,basedir, seed_th=[600], show=True, 
                normalize=False, modelname='model'):
        
        import os
        
        import numpy as np
        import visvis as vv
        from visvis import ssdf
        
        from stentseg.utils import PointSet, _utils_GUI
        from stentseg.utils.datahandling import select_dir, loadvol, loadmodel
        from stentseg.stentdirect.stentgraph import create_mesh
        from stentseg.stentdirect import stentgraph, StentDirect, getDefaultParams
        from stentseg.stentdirect import AnacondaDirect, EndurantDirect, NellixDirect
        from stentseg.utils.visualization import show_ctvolume
        from stentseg.utils.picker import pick3d, label2worldcoordinates, label2volindices
        import scipy
        from scipy import ndimage
        import copy
        
        # Select dataset to register
        cropname = 'prox'
        # phase = 10
        #dataset = 'avgreg'
        #what = str(phase) + dataset # avgreg
        what = 'avgreg'
        
        # Load volumes
        s = loadvol(basedir, ptcode, ctcode, cropname, what)
        
        # sampling was not properly stored after registration for all cases: reset sampling
        vol_org = copy.deepcopy(s.vol)
        s.vol.sampling = [vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]] # z,y,x
        s.sampling = s.vol.sampling
        vol = s.vol
        
        ## Initialize segmentation parameters
        stentType = 'nellix'  # 'zenith';'nellix' runs modified pruning algorithm in Step3
        
        p = getDefaultParams(stentType)
        p.seed_threshold = seed_th     # step 1 [lower th] or [lower th, higher th]
        # p.seedSampleRate = 7                  # step 1, nellix
        p.whatphase = what                
        
        
        ## Perform segmentation
        # Instantiate stentdirect segmenter object
        if stentType == 'anacondaRing':
                sd = AnacondaDirect(vol, p) # inherit _Step3_iter from AnacondaDirect class
                #runtime warning using anacondadirect due to mesh creation, ignore
        elif stentType == 'endurant':
                sd = EndurantDirect(vol, p)
        elif stentType == 'nellix':
                sd = NellixDirect(vol, p)
        else:
                sd = StentDirect(vol, p) 

        ## show histogram and normalize
        # f = vv.figure(3)
        # a = vv.gca()
        # vv.hist(vol, drange=(300,vol.max()))
        
        # normalize vol to certain limit
        if normalize:
                sd.Step0(3071)
                vol = sd._vol
                # b= vv.hist(vol, drange=(300,3071))
                # b.color = (1,0,0)
       
        ## Perform step 1 for seeds
        sd.Step1()
        
        ## Visualize
        if show:
                fig = vv.figure(2); vv.clf()
                fig.position = 0.00, 22.00,  1920.00, 1018.00
                clim = (0,2000)
                
                # Show volume and model as graph
                a1 = vv.subplot(121)
                a1.daspect = 1,1,-1
                # t = vv.volshow(vol, clim=clim)
                t = show_ctvolume(vol, axis=a1, showVol='MIP', clim =clim, isoTh=250, 
                                removeStent=False, climEditor=True)
                label = pick3d(vv.gca(), vol)
                sd._nodes1.Draw(mc='b', mw = 2)       # draw seeded nodes
                #sd._nodes2.Draw(mc='b', lc = 'g')    # draw seeded and MCP connected nodes
                vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)')
                
                # Show volume and cleaned up graph
                a2 = vv.subplot(122)
                a2.daspect = 1,1,-1
                sd._nodes1.Draw(mc='b', mw = 2)       # draw seeded nodes
                # t = vv.volshow(vol, clim=clim)
                # label = pick3d(vv.gca(), vol)
                # sd._nodes2.Draw(mc='b', lc='g')
                # sd._nodes3.Draw(mc='b', lc='g')
                vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)')
                
                # # Show the mesh
                #===============================================================================
                # a3 = vv.subplot(133)
                # a3.daspect = 1,1,-1
                # t = vv.volshow(vol, clim=clim)
                # pick3d(vv.gca(), vol)
                # #sd._nodes3.Draw(mc='b', lc='g')
                # m = vv.mesh(bm)
                # m.faceColor = 'g'
                # # _utils_GUI.vis_spared_edges(sd._nodes3)
                # vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)')
                #===============================================================================
                
                # Use same camera
                a1.camera = a2.camera #= a3.camera
                
                switch = True
                a1.axis.visible = switch
                a2.axis.visible = switch
                #a3.axis.visible = switch
                

        ## Store segmentation to disk
        
        # Get graph model
        model = sd._nodes1
                
        # Build struct
        s2 = vv.ssdf.new()
        s2.sampling = s.sampling
        s2.origin = s.origin
        s2.stenttype = s.stenttype
        s2.croprange = s.croprange
        for key in dir(s):
                if key.startswith('meta'):
                    suffix = key[4:]
                    s2['meta'+suffix] = s['meta'+suffix]
        s2.what = what
        s2.params = p
        s2.stentType = stentType
        # Store model (not also volume)
        s2.model = model.pack()
        
        
        # Save
        filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, modelname+ what)
        ssdf.save(os.path.join(basedir, ptcode, filename), s2)
        print('saved to disk as {}.'.format(filename) )

        ## Make model dynamic (and store/overwrite to disk)
        #===============================================================================
        # 
        # import pirt
        # from stentsegf.motion.dynamic import incorporate_motion_nodes, incorporate_motion_edges  
        # 
        # # Load deforms
        # s = loadvol(basedir, ptcode, ctcode, cropname, '10deforms')
        # deformkeys = []
        # for key in dir(s):
        #     if key.startswith('deform'):
        #         deformkeys.append(key)
        # deforms = [s[key] for key in deformkeys]
        # deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms]
        # paramsreg = s.params
        # 
        # # Load model
        # s = loadmodel(basedir, ptcode, ctcode, cropname, 'model'+what)
        # model = s.model
        # 
        # # Combine ...
        # incorporate_motion_nodes(model, deforms, s.origin)
        # incorporate_motion_edges(model, deforms, s.origin)
        # 
        # # Save back
        # filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'model'+what)
        # s.model = model.pack()
        # s.paramsreg = paramsreg
        # ssdf.save(os.path.join(basedir, ptcode, filename), s)
        # print('saved to disk as {}.'.format(filename) )
        #===============================================================================
예제 #21
0
    def __init__(self,
                 ptcode,
                 ctcode,
                 basedir,
                 showVol='mip',
                 meshWithColors=False,
                 motion='amplitude',
                 clim2=(0, 2)):
        """
        Script to show the stent model. [ nellix]
        """

        import os
        import pirt
        import visvis as vv

        from stentseg.utils.datahandling import select_dir, loadvol, loadmodel
        from pirt.utils.deformvis import DeformableTexture3D, DeformableMesh
        from stentseg.stentdirect.stentgraph import create_mesh
        from stentseg.stentdirect import stentgraph
        from stentseg.utils.visualization import show_ctvolume
        from stentseg.motion.vis import create_mesh_with_abs_displacement
        import copy
        from stentseg.motion.dynamic import incorporate_motion_nodes, incorporate_motion_edges
        from lspeas.utils.ecgslider import runEcgSlider
        from stentseg.utils import _utils_GUI

        import numpy as np

        cropname = 'prox'
        # params
        nr = 1
        # motion = 'amplitude'  # amplitude or sum
        dimension = 'xyz'
        showVol = showVol  # MIP or ISO or 2D or None
        clim0 = (0, 2000)
        # clim2 = (0,2)
        motionPlay = 9, 1  # each x ms, a step of x %

        s = loadvol(basedir, ptcode, ctcode, cropname, what='deforms')
        m = loadmodel(basedir, ptcode, ctcode, cropname,
                      'centerline_total_modelavgreg_deforms')
        v = loadmodel(basedir,
                      ptcode,
                      ctcode,
                      cropname,
                      modelname='centerline_total_modelvesselavgreg_deforms')
        s2 = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg')
        vol_org = copy.deepcopy(s2.vol)
        s2.vol.sampling = [
            vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]
        ]
        s2.sampling = s2.vol.sampling
        vol = s2.vol

        # merge models into one for dynamic visualization
        model_total = stentgraph.StentGraph()
        for key in dir(m):
            if key.startswith('model'):
                model_total.add_nodes_from(
                    m[key].nodes(data=True))  # also attributes
                model_total.add_edges_from(m[key].edges(data=True))
        for key in dir(v):
            if key.startswith('model'):
                model_total.add_nodes_from(
                    v[key].nodes(data=True))  # also attributes
                model_total.add_edges_from(v[key].edges(data=True))

        # Load deformations (forward for mesh)
        deformkeys = []
        for key in dir(s):
            if key.startswith('deform'):
                deformkeys.append(key)
        deforms = [s[key] for key in deformkeys]
        deforms = [[field[::2, ::2, ::2] for field in fields]
                   for fields in deforms]

        # These deforms are forward mapping. Turn into DeformationFields.
        # Also get the backwards mapping variants (i.e. the inverse deforms).
        # The forward mapping deforms should be used to deform meshes (since
        # the information is used to displace vertices). The backward mapping
        # deforms should be used to deform textures (since they are used in
        # interpolating the texture data).
        deforms_f = [pirt.DeformationFieldForward(*f) for f in deforms]
        deforms_b = [f.as_backward() for f in deforms_f]

        # Create mesh
        if meshWithColors:
            try:
                modelmesh = create_mesh_with_abs_displacement(model_total,
                                                              radius=0.7,
                                                              dim=dimension,
                                                              motion=motion)
            except KeyError:
                print('Centerline model has no pathdeforms so we create them')
                # use unsampled deforms
                deforms2 = [s[key] for key in deformkeys]
                # deforms as backward for model
                deformsB = [
                    pirt.DeformationFieldBackward(*fields)
                    for fields in deforms2
                ]
                # set sampling to original
                # for i in range(len(deformsB)):
                #         deformsB[i]._field_sampling = tuple(s.sampling)
                # not needed because we use unsampled deforms
                # Combine ...
                incorporate_motion_nodes(model_total, deformsB, s2.origin)
                convert_paths_to_PointSet(model_total)
                incorporate_motion_edges(model_total, deformsB, s2.origin)
                convert_paths_to_ndarray(model_total)
                modelmesh = create_mesh_with_abs_displacement(model_total,
                                                              radius=0.7,
                                                              dim=dimension,
                                                              motion=motion)
        else:
            modelmesh = create_mesh(model_total, 0.7, fullPaths=True)

        ## Start vis
        f = vv.figure(nr)
        vv.clf()
        if nr == 1:
            f.position = 8.00, 30.00, 944.00, 1002.00
        else:
            f.position = 968.00, 30.00, 944.00, 1002.00
        a = vv.gca()
        a.axis.axisColor = 1, 1, 1
        a.axis.visible = False
        a.bgcolor = 0, 0, 0
        a.daspect = 1, 1, -1
        t = vv.volshow(vol, clim=clim0, renderStyle=showVol, axes=a)
        vv.xlabel('x (mm)')
        vv.ylabel('y (mm)')
        vv.zlabel('z (mm)')
        if meshWithColors:
            if dimension == 'xyz':
                dim = '3D'
            vv.title(
                'Model for chEVAS %s  (color-coded %s of movement in %s in mm)'
                % (ptcode[8:], motion, dim))
        else:
            vv.title('Model for chEVAS %s' % (ptcode[8:]))

        colorbar = True
        # Create deformable mesh
        dm = DeformableMesh(a, modelmesh)  # in x,y,z
        dm.SetDeforms(*[list(reversed(deform))
                        for deform in deforms_f])  # from z,y,x to x,y,z
        if meshWithColors:
            dm.clim = clim2
            dm.colormap = vv.CM_JET  #todo: use colormap Viridis or Magma as JET is not linear (https://bids.github.io/colormap/)
            if colorbar:
                vv.colorbar()
            colorbar = False
        else:
            dm.faceColor = 'g'

        # Run mesh
        a.SetLimits()
        # a.SetView(viewringcrop)
        dm.MotionPlay(motionPlay[0],
                      motionPlay[1])  # (10, 0.2) = each 10 ms do a step of 20%
        dm.motionSplineType = 'B-spline'
        dm.motionAmplitude = 0.5

        ## run ecgslider
        ecg = runEcgSlider(dm, f, a, motionPlay)
예제 #22
0
# basedir = select_dir(r'D:\LSPEAS_F\LSPEASF_ssdf')

# Select dataset to register
# ptcode = 'QRM_FANTOOM_20160121'
# ctcode = '12months'
cropnames = ['stent']
ptcodes = ['LSPEAS_018', 'LSPEAS_025', 'LSPEAS_023', 'LSPEAS_024']
ctcodes = ['24months']

for ptcode in ptcodes:
    for ctcode in ctcodes:
        for cropname in cropnames:
            # Load volumes
            try:
                s = loadvol(basedir, ptcode, ctcode, cropname, 'phases')
            except FileNotFoundError:
                continue
            vols = [s['vol%i' % (i * 10)] for i in range(10)]

            #todo: resample to isotropic?
            # for vol in vols:
            # see function in datahandling

            #todo: normalize data!! comparable histograms, comparable mass image forces
            t0 = time.time()

            # Initialize registration object
            reg = pirt.reg.GravityRegistration(*vols)
            # Set params
            reg.params.mass_transforms = 2  # 2nd order (Laplacian) triggers more at lines
예제 #23
0
    def __init__(self, ptcode, ctcode, basedir):
        ## Perform image registration

        import os, time

        import numpy as np
        import visvis as vv
        import pirt.reg  # Python Image Registration Toolkit
        from stentseg.utils.datahandling import select_dir, loadvol
        import scipy
        from scipy import ndimage

        # Select dataset to register
        cropname = 'prox'
        what = 'phases'

        # Load volumes
        s = loadvol(basedir, ptcode, ctcode, cropname, what)

        vols = []
        phases = []
        for key in dir(s):
            if key.startswith('vol'):
                print(key)
                # create vol with zoom in z-direction
                zscale = (s[key].sampling[0] / s[key].sampling[1])  # z / y
                # resample vol using spline interpolation, 3rd order piecewise polynomial
                vol_zoom = scipy.ndimage.interpolation.zoom(
                    s[key], [zscale, 1, 1], 'float32')
                s[key].sampling = [
                    s[key].sampling[1], s[key].sampling[1], s[key].sampling[2]
                ]

                # set scale and origin
                vol_zoom_type = vv.Aarray(vol_zoom, s[key].sampling,
                                          s[key].origin)
                vol = vol_zoom_type

                phases.append(key)
                vols.append(vol)

        t0 = time.time()

        # Initialize registration object
        reg = pirt.reg.GravityRegistration(*vols)

        reg.params.mass_transforms = 2  # 2nd order (Laplacian) triggers more at lines
        reg.params.speed_factor = 1.0
        reg.params.deform_wise = 'groupwise'  # groupwise!
        reg.params.mapping = 'backward'
        reg.params.deform_limit = 1.0
        reg.params.final_scale = 1.0  # We might set this a wee bit lower than 1 (but slower!)
        reg.params.scale_sampling = 16
        reg.params.final_grid_sampling = 20
        reg.params.grid_sampling_factor = 0.5

        # Go!
        reg.register(verbose=1)

        t1 = time.time()
        print('Registration completed, which took %1.2f min.' %
              ((t1 - t0) / 60))

        # Store registration result

        from visvis import ssdf

        # Create struct

        s2 = vv.ssdf.new()
        N = len(vols)
        for key in dir(s):
            if key.startswith('meta'):
                s2[key] = s[key]
        s2.origin = s.origin
        s2.stenttype = s.stenttype
        s2.croprange = s.croprange

        # Obtain deform fields
        for i in range(N):
            fields = [field for field in reg.get_deform(i).as_backward()]
            phase = phases[i][3:]
            s2['deform%s' % phase] = fields
        s2.sampling = s2['deform%s' %
                         phase][0].sampling  # Sampling of deform is different!
        s2.originDeforms = s2['deform%s' %
                              phase][0].origin  # But origin is zero
        s2.params = reg.params

        # Save
        filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'deforms')
        ssdf.save(os.path.join(basedir, ptcode, filename), s2)
        print("deforms saved to disk.")

        #============================================================================
        # Store averaged volume, where the volumes are registered

        #from visvis import ssdf

        # Create average volume from *all* volumes deformed to the "center"
        N = len(reg._ims)
        mean_vol = np.zeros(reg._ims[0].shape, 'float64')
        for i in range(N):
            vol, deform = reg._ims[i], reg.get_deform(i)
            mean_vol += deform.as_backward().apply_deformation(vol)
        mean_vol *= 1.0 / N

        # Create struct
        s_avg = ssdf.new()
        for key in dir(s):
            if key.startswith('meta'):
                s_avg[key] = s[key]
        s_avg.sampling = s.vol0.sampling  # z, y, x after interpolation
        s_avg.origin = s.origin
        s_avg.stenttype = s.stenttype
        s_avg.croprange = s.croprange
        s_avg.vol = mean_vol.astype('float32')
        s_avg.params = s2.params

        fig1 = vv.figure(1)
        vv.clf()
        fig1.position = 0, 22, 1366, 706
        a1 = vv.subplot(111)
        a1.daspect = 1, 1, -1
        renderstyle = 'mip'
        a1b = vv.volshow(s_avg.vol, clim=(0, 2000), renderStyle=renderstyle)
        #a1b.isoThreshold = 600
        vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z')
        vv.title('Average volume of %s phases (%s) (resized data)' %
                 (len(phases), renderstyle))

        # Save
        avg = 'avgreg'
        filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, avg)
        ssdf.save(os.path.join(basedir, ptcode, filename), s_avg)
        print("avgreg saved to disk.")

        t1 = time.time()
        print('Registration completed, which took %1.2f min.' %
              ((t1 - t0) / 60))
예제 #24
0
## Renal origin coordinates: input by user/read excel
# coordinates, left and right most caudal renal
# ctcode1
xrenal1, yrenal1, zrenal1 = 132.7, 89.2, 85.5
renal1 = PointSet(list((xrenal1, yrenal1, zrenal1)))
# ctcode2
if ctcode2:
    xrenal2, yrenal2, zrenal2 = 171, 165.1, 39.5
    renal2 = PointSet(list((xrenal2, yrenal2, zrenal2)))

# renal_left, renal_right = foo.readRenalsExcel(sheet_renals_obs, ptcode, ctcode1)
# renal1 = renal_left

## Load (dynamic) stent models, vessel, ct
# Load static CT image to add as reference
s = loadvol(basedir, ptcode, ctcode1, cropname, 'avgreg')
vol1 = s.vol
if ctcode2:
    s = loadvol(basedir, ptcode, ctcode2, cropname, 'avgreg')
    vol2 = s.vol

# load stent model
s2 = loadmodel(basedir, ptcode, ctcode1, cropname, modelname)
model1 = s2.model
modelmesh1 = create_mesh(model1, meshradius)
if ctcode2:
    s2 = loadmodel(basedir, ptcode, ctcode2, cropname, modelname)
    model2 = s2.model
    modelmesh2 = create_mesh(model2, meshradius)

# Load vessel mesh (output Mimics)
예제 #25
0
from stentseg.utils import _utils_GUI
import copy
from stentseg.utils.picker import pick3d
from stentseg.apps.record_movie import recordMovie

# Select the ssdf basedir
basedir = select_dir(r'F:\Nellix_chevas\CT_SSDF\SSDF_automated',
                     r'D:\Nellix_chevas_BACKUP\CT_SSDF\SSDF_automated')

# Select dataset to register
ptcode = 'chevas_02'
ctcode, nr = '12months', 1
cropname = 'prox'

## Show single vol
s0 = loadvol(basedir, ptcode, ctcode, cropname, 'phases')
# vol = s0.vol
vol = s0.vol20
key = 'vol20'
zscale = (s0[key].sampling[0] / s0[key].sampling[1])  # z / y
# resample vol using spline interpolation, 3rd order polynomial
vol_zoom = scipy.ndimage.interpolation.zoom(s0[key], [zscale, 1, 1], 'float32')
s0[key].sampling = [
    s0[key].sampling[1], s0[key].sampling[1], s0[key].sampling[2]
]
# aanpassingen voor scale en origin
vol_zoom_type = vv.Aarray(vol_zoom, s0[key].sampling, s0[key].origin)
vol = vol_zoom_type

fig = vv.figure()
vv.clf()
# ptcode = 'QRM_FANTOOM_20160121'
# ctcode, nr = 'ZA3-75-1.2', 1
cropname = 'ring'
modelname = 'modelavgreg'
motion = 'amplitude'  # amplitude or sum
dimension = 'xyz'
showVol = 'ISO'  # MIP or ISO or 2D or None
clim0 = (-10, 2500)
clim2 = (0, 3)
isoTh = 250
motionPlay = 9, 1  # each x ms, a step of perc of T
staticref = 'avgreg'  # 'avg7020'
meshWithColors = True

# Load deformations (forward for mesh)
s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms')
# deforms = [s['deform%i'%(i*10)] for i in range(10)]
deformkeys = []
for key in dir(s):
    if key.startswith('deform'):
        deformkeys.append(key)
deforms = [s[key] for key in deformkeys]
# deforms = [[field[::2,::2,::2] for field in fields] for fields in deforms]

try:
    s2 = loadvol(basedir, ptcode, ctcode, 'ring', staticref)
except FileNotFoundError:
    s2 = loadvol(basedir, ptcode, ctcode, 'ring', staticref)
vol = s2.vol

s3 = loadvol(basedir, ptcode, ctcode, cropname, 'phases')
예제 #27
0
    basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''),
                         r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup')

    # Select dataset to register
    ptcode = 'LSPEAS_025'
    ctcode = '24months'
    cropname = 'ring'
    modelname = 'modelavgreg'

    # Load the stent model and mesh
    s = loadmodel(basedir, ptcode, ctcode, cropname, modelname)
    model = s.model
    model2 = model.copy()

    # Load static CT image to add as reference
    s2 = loadvol(basedir, ptcode, ctcode, cropname, 'avgreg')
    vol = s2.vol

    f = vv.figure(1)
    vv.clf()
    a = vv.subplot(1, 2, 1)
    a.axis.axisColor = 1, 1, 1
    a.axis.visible = False
    a.bgcolor = 0, 0, 0
    a.daspect = 1, 1, -1
    t = vv.volshow(vol, clim=(0, 2500), renderStyle='mip')
    label = pick3d(a, vol)
    # model.Draw(mc='b', mw = 10, lc='g')
    vv.xlabel('x (mm)')
    vv.ylabel('y (mm)')
    vv.zlabel('z (mm)')