Пример #1
0
    def __init__(self, path):

        self.path = path

        try:
            with open(self.path, 'r') as f:
                lines = f.readlines()
        except:
            print('Cannot read file!')

        start = [idx + 1 for idx, i in enumerate(lines) if i[0] == '#']
        end = [idx - 1 for idx, i in enumerate(lines) if i[0] == '#']
        end = end[1:]

        for idx, i in enumerate(lines[end[-1]:]):
            if i[0] == '[':
                end.append(end[-1] + idx)
                break

        pathes = []

        for s, e in zip(start, end):
            a = np.array([[float(j) for j in i.split(' ') if j != '']
                          for i in lines[s:e]])
            pathes.append(a[:, (2, 3, 4)])

        g = Graph()

        for i in pathes:

            n = g.number_of_nodes()
            nodes = range(n, n + len(i))
            g.add_nodes_from(nodes)

            for idx, k in enumerate(nodes):
                g.node[k]['pos'] = np.array(i[idx])

            e1 = nodes[0:-1]
            e2 = nodes[1:]

            e = [[k1, k2] for k1, k2 in zip(e1, e2)]

            g.add_edges_from(e)

        self.graph = g
Пример #2
0
    def __init__(self, filepath, sampling=1):
        
        from VascGraph.GeomGraph import Graph
        
        try:
            import h5py
        except:
            print('To run this function, \'h5py\' sould be installed.')
            return   

        # ---- read ----#
        f=h5py.File(filepath, 'r')
        refs=[i[0] for i in f.get('GeodesicMSTs/CGPathContinuous')]
        pathes=[np.array(f[i]).T for i in refs]
        
        data=f.get('GeodesicMSTsMatrix/M/data')
        ir=np.array(f.get('GeodesicMSTsMatrix/M/ir'))
        jc=np.array(f.get('GeodesicMSTsMatrix/M/jc'))




        # ----- sampling of pathes nodes ----#
        ind=[len(i)/sampling for i in pathes]
        ind=[np.array(range(i))*sampling for i in ind]
        pathes=[i[indx] for i, indx in zip(pathes, ind)]
        
        
        # ----- build graph from pathes -----#
        path_ext=[]
        g=Graph()
        for path in pathes:
            n=g.number_of_nodes()
            nodes=np.array(range(len(path)))+n
            e1=nodes[1:]
            e2=nodes[:-1]
            e=np.array([e1,e2]).T
            
            path_ext.append([nodes[0], nodes[-1]])
            
            g.add_nodes_from(nodes)
            g.add_edges_from(e)
            
            for node, pos in zip(nodes, path):
                g.node[node]['pos']=np.array([pos[1], pos[0], pos[2]])
        
 
        # ------- connection between pathes ----#
        path_ext=np.array(path_ext)
        a = sparse.csc_matrix((data, ir, jc))
        ind1, ind2 = np.where(a.todense()>0)       
        
        e=[]
        for i,j in zip(ind1,ind2): 
            
            ee=[[path_ext[i][0], path_ext[j][1]],
             [path_ext[i][1], path_ext[j][0]],
             [path_ext[i][0], path_ext[j][0]],
             [path_ext[i][1], path_ext[j][1]]]
            
            
            poss=np.array([[g.node[k[0]]['pos'], g.node[k[1]]['pos']] for k in ee])
            poss= poss[:,0,:]-poss[:,1,:]
            norm=np.linalg.norm(poss, axis=1)
            indx=np.where(norm==norm.min())[0][0]
            e.append(ee[indx])
        
        g.add_edges_from(e)
             
        self.graph=g 
Пример #3
0
    def UpdateWithStitching(self,
                            size,
                            niter1=10,
                            niter2=5,
                            is_parallel=False,
                            n_parallel=5,
                            ret=False):
        '''
        this funtion allow to generate graphs as follows:
            1) image patching -->  2) patch-based contraction (fixing boundary nodes) 
            --> 3) graph stitching --> 4) boundary contraction --> 5) global contraction --> refinement 
        
        it is helpful when graphing large inputs.
        
        Inputs:
            size: dimention of a 3D patch --> [size, size, size] 
            niter1: number of contraction iterations on patches 
            niter2: number of contraction iterations on boundary nodes 
            is_parallel: if True, patch-based contraction will run in parallel using 'ray'
            n_parallel: number of parallel processes (note: for limited RAM memory, 'n_parallel' should be smaller) 
            ret: if True, this function will return the output graph
        '''
        try:
            from sklearn import neighbors
        except:
            print('  \'scikit-learn\' must be instaled to run this funtion!')

        if is_parallel:

            try:
                import ray
            except:
                print(
                    '  \'ray\' must be installed to run patch-based contraction in parallel!'
                )

            GraphParallel = activate_parallel()

        # obtain distance map
        #self.label=image.morphology.distance_transform_edt(self.label)
        self.label = DistMap3D(self.label)

        # patching
        print('--Extract patches ...')
        patches, patchesid = Decompose(self.label,
                                       size=size)  # extract patches
        patches_shape = [patches.shape[0], patches.shape[1], patches.shape[2]]

        print('--Obtain semi-contracted graphs from patches ...')
        # run contraction avoiding boundary nodes for each patch
        graphs = []
        inds = np.arange(0, len(patchesid), n_parallel)
        patchesid_ = [patchesid[ind:ind + n_parallel] for ind in inds]

        for inds in patchesid_:

            if is_parallel:  # in parallel
                ray.init()
                subpatches = [ray.put(patches[ind]) for ind in inds]
                subgraphs = [
                    GraphParallel.remote(
                        patch,
                        niter=niter1,
                        Sampling=self.sampling,
                        DistParam=self.dist_param,
                        MedParam=self.med_param,
                        SpeedParam=self.speed_param,
                        DegreeThreshold=self.degree_threshold,
                        ClusteringResolution=self.clustering_resolution)
                    for patch in subpatches
                ]
                subgraphs = [ray.get(g) for g in subgraphs]
                ray.shutdown()
                graphs.append(subgraphs)

            else:  # in serial
                subpatches = [patches[ind] for ind in inds]
                subgraphs = [
                    GraphSerial(
                        patch,
                        niter=niter1,
                        Sampling=self.sampling,
                        DistParam=self.dist_param,
                        MedParam=self.med_param,
                        SpeedParam=self.speed_param,
                        DegreeThreshold=self.degree_threshold,
                        ClusteringResolution=self.clustering_resolution)
                    for patch in subpatches
                ]
                subgraphs = [g for g in subgraphs]
                graphs.append(subgraphs)
        graphs = [k1 for k in graphs for k1 in k]  # uravel
        del patches

        # adjust the position of graph nodes coming from each patch
        area = np.sum([k.Area for k in graphs if k is not None])
        pluspos = (size) * np.array(patchesid)
        for plus, g in zip(pluspos, graphs):
            if g is not None:
                AddPos(g, plus)

        print('--Combine semi-contracted graphs ...')
        fullgraph = EmptyGraph()
        nnodes = 0
        for idx, g in enumerate(graphs):
            if g is not None:
                print('    graph id ' + str(idx) + ' added')
                nnodes += fullgraph.number_of_nodes()
                new_nodes = nnodes + np.array(range(g.number_of_nodes()))
                mapping = dict(zip(g.GetNodes(), new_nodes))
                g = nx.relabel_nodes(g, mapping)
                fullgraph.add_nodes_from(g.GetNodes())
                fullgraph.add_edges_from(g.GetEdges())
                for k in new_nodes:
                    fullgraph.node[k]['pos'] = g.node[k]['pos']
                    fullgraph.node[k]['r'] = g.node[k]['r']
                    fullgraph.node[k]['ext'] = g.node[k]['ext']
            else:
                print('    graph id ' + str(idx) + ' is None')

        fullgraph = fixG(fullgraph)
        fullgraph.Area = area
        del graphs

        print('--Stitch semi-contracted graphs ...')
        nodes = np.array(
            [k for k in fullgraph.GetNodes() if fullgraph.node[k]['ext'] == 1])
        nodesid = dict(zip(range(len(nodes)), nodes))
        pos = np.array([fullgraph.node[k]['pos'] for k in nodes])
        pos_tree = neighbors.KDTree(pos)
        a = pos_tree.query_radius(pos, r=1.0)
        new_edges = [[(nodesid[k[0]], nodesid[k1]) for k1 in k[1:]] for k in a]
        new_edges = [k1 for k in new_edges for k1 in k]
        fullgraph.add_edges_from(new_edges)

        del a
        del nodes
        del pos
        del new_edges
        del pos_tree

        print('--Contract ext nodes ...')
        ContractExt(fullgraph,
                    niter=niter2,
                    DistParam=self.dist_param,
                    MedParam=self.med_param,
                    SpeedParam=self.speed_param,
                    DegreeThreshold=self.degree_threshold,
                    ClusteringResolution=self.clustering_resolution)

        print('--Generate final skeleton ...')
        contract_final = ContractGraph(Graph=fullgraph)
        contract_final.Update(DistParam=self.dist_param,
                              MedParam=self.med_param,
                              SpeedParam=self.speed_param,
                              DegreeThreshold=self.degree_threshold,
                              StopParam=self.stop_param,
                              NFreeIteration=self.n_free_iteration)
        gc = contract_final.GetOutput()

        print('--Refine final skeleton ...')
        refine = RefineGraph(Graph=gc)
        refine.Update()
        gr = refine.GetOutput()
        gr = fixG(gr)

        # ----- return ----#
        if ret:
            return gr
        else:
            self.Graph = gr