예제 #1
0
def nuclei_detection(reference_img, threshold=1000, radius_range=(0.8,1.4), step=0.2, segmentation_centering=False, subsampling=4, microscope_orientation=1):

    size = np.array(reference_img.shape)
    voxelsize = microscope_orientation*np.array(reference_img.voxelsize)


    positions = detect_nuclei(reference_img,threshold=threshold,radius_range=radius_range, step=step)
    positions = array_dict(positions)
    positions = array_dict(positions.values(),positions.keys()+2).to_dict()

    if segmentation_centering:
        nuclei_img = deepcopy(reference_img)
        image_coords = tuple(np.transpose((positions.values()/voxelsize).astype(int)))

        if subsampling>1:
            #nuclei_img = nd.gaussian_filter(nuclei_img,sigma=subsampling/4.)[::subsampling,::subsampling,::subsampling]
            nuclei_img = nd.gaussian_filter1d(nd.gaussian_filter1d(nuclei_img,sigma=subsampling/8.,axis=0),sigma=subsampling/8.,axis=1)[::subsampling,::subsampling,:]
            nuclei_img = SpatialImage(nuclei_img,voxelsize=(subsampling*reference_img.voxelsize[0],subsampling*reference_img.voxelsize[1],reference_img.voxelsize[2]))
            image_coords = tuple(np.transpose((positions.values()/(microscope_orientation*np.array(nuclei_img.voxelsize))).astype(int)))

        intensity_min = np.percentile(nuclei_img[image_coords],0)-1
        segmented_img = nuclei_active_region_segmentation(nuclei_img, positions, display=False, omega_energies=dict(intensity=subsampling,gradient=1.5,smoothness=10000.0*np.power(subsampling,1.5)), intensity_min=intensity_min)

        positions = nuclei_positions_from_segmented_image(segmented_img)
    
    positions = array_dict(positions)
    positions = array_dict(positions.values()*microscope_orientation,positions.keys()).to_dict()

    return positions
def cut_surface_topomesh(input_topomesh, z_cut=0, below=True):

    topomesh = deepcopy(input_topomesh)    

    compute_topomesh_property(topomesh,'vertices',2)

    if below:
        triangle_below = array_dict(np.all(topomesh.wisp_property('barycenter',0).values(topomesh.wisp_property('vertices',2).values())[...,2] < z_cut,axis=1),list(topomesh.wisps(2)))
    else:
        triangle_below = array_dict(np.all(topomesh.wisp_property('barycenter',0).values(topomesh.wisp_property('vertices',2).values())[...,2] > z_cut,axis=1),list(topomesh.wisps(2)))
    topomesh.update_wisp_property('below',2,triangle_below)

    triangles_to_remove = [t for t in topomesh.wisps(2) if triangle_below[t]]
    for t in triangles_to_remove:
        topomesh.remove_wisp(2,t)

    topomesh = clean_topomesh(topomesh)

    compute_topomesh_property(topomesh,'triangles',1)
    compute_topomesh_property(topomesh,'vertices',1)
    compute_topomesh_property(topomesh,'length',1)

    topomesh.update_wisp_property('boundary',1,array_dict((np.array(map(len,topomesh.wisp_property('triangles',1).values()))==1).astype(int),list(topomesh.wisps(1))))

    boundary_edges = np.array(list(topomesh.wisps(1)))[topomesh.wisp_property('boundary',1).values()==1]
    boundary_vertices = np.unique(topomesh.wisp_property('vertices',1).values(boundary_edges))

    # z_offset = topomesh.wisp_property('barycenter',0).values()[:,2].std()/8.
    z_offset = np.percentile(topomesh.wisp_property('length',1).values(),10)
    iso_z_positions = np.array([np.concatenate([topomesh.wisp_property('barycenter',0)[v][:2],[z_cut+(1-2*below)*z_offset]]) if v in boundary_vertices else  topomesh.wisp_property('barycenter',0)[v] for v in topomesh.wisps(0)])
    topomesh.update_wisp_property('barycenter',0,array_dict(iso_z_positions,list(topomesh.wisps(0))))

    return topomesh
예제 #3
0
    def characteristic_dimension(self):
        if self.char_dimension is None:
            if len(self.points)>1:
                if len(self.triangles)>0:
                    triangle_edge_list = [[1,2],[0,2],[0,1]]
                    triangle_edges = np.concatenate(np.array(self.triangles.values())[:,triangle_edge_list])
                    triangle_edge_points = array_dict(self.points).values(triangle_edges)
                    triangle_edge_vectors = triangle_edge_points[:,1] - triangle_edge_points[:,0]
                    triangle_edge_lengths = np.linalg.norm(triangle_edge_vectors,axis=1)
                    self.char_dimension = triangle_edge_lengths.mean()
                elif len(self.edges)>0:
                    edges = np.array(self.edges.values())
                    edge_points = array_dict(self.points).values(edges)
                    edge_vectors = edge_points[:,1] - edge_points[:,0]
                    edge_lengths = np.linalg.norm(edge_vectors,axis=1)
                    self.char_dimension = edge_lengths.mean()
                else:
                    #from scipy.cluster.vq import vq
                    #point_distances = np.sort([vq(np.array(self.points.values()),np.array([self.points[p]]))[1] for p in self.points.keys()])
                    # self.char_dimension = point_distances[:,1].mean()
                    bbox = np.array(self.bounding_box())
                    bbox_volume = np.prod(bbox[:,1] - bbox[:,0])
                    point_volume = bbox_volume/float(2.*len(self.points))
                    self.char_dimension = np.power(3.*point_volume/(4.*np.pi),1/3.)

                return self.char_dimension
            else:
                return 1.
        else:
            return self.char_dimension
예제 #4
0
def draw_triangular_mesh(mesh, mesh_id=None, colormap=None):
    import openalea.plantgl.all as pgl
    import openalea.plantgl.ext.color as color

    triangle_points = array_dict(mesh.points).values(np.array(mesh.triangles.values()))
    triangle_normals = np.cross(triangle_points[:,1]-triangle_points[:,0],triangle_points[:,2]-triangle_points[:,0])
    mesh_center = np.mean(mesh.points.values(),axis=0)
    reversed_normals = np.array(mesh.triangles.keys())[np.where(np.einsum('ij,ij->i',triangle_normals,triangle_points[:,0]-mesh_center) < 0)[0]]
    for t in reversed_normals:
        mesh.triangles[t] = list(reversed(mesh.triangles[t]))

    if colormap is None:
        colormap = color.GlasbeyMap(0,255)

    points_index = array_dict(np.arange(len(mesh.points)),mesh.points.keys())

    if isinstance(colormap,color.GlasbeyMap):
        if isiterable(mesh.triangle_data.values()[0]):
            colors = [pgl.Color4(colormap(mesh.triangle_data[t][0]%256).i3tuple()) if mesh.triangle_data.has_key(t) else pgl.Color4(colormap(0).i3tuple()) for t in mesh.triangles.keys()]
        else:
            colors = [pgl.Color4(colormap(mesh.triangle_data[t]%256).i3tuple()) if mesh.triangle_data.has_key(t) else pgl.Color4(colormap(0).i3tuple()) for t in mesh.triangles.keys()]
    else:
        if isiterable(mesh.triangle_data.values()[0]):
            colors = [pgl.Color4(colormap(mesh.triangle_data[t][0]).i3tuple()) if mesh.triangle_data.has_key(t) else pgl.Color4(colormap(0).i3tuple()) for t in mesh.triangles.keys()]
        else:
            colors = [pgl.Color4(colormap(mesh.triangle_data[t]).i3tuple()) if mesh.triangle_data.has_key(t) else pgl.Color4(colormap(0).i3tuple()) for t in mesh.triangles.keys()]

    scene = pgl.Scene()
    if mesh_id is not None:
        scene += pgl.Shape(pgl.FaceSet(mesh.points.values(),list(points_index.values(np.array(mesh.triangles.values()))),colorList=colors,colorPerVertex=False),id=int(mesh_id))
    else:
        scene += pgl.Shape(pgl.FaceSet(mesh.points.values(),list(points_index.values(np.array(mesh.triangles.values()))),colorList=colors,colorPerVertex=False))
    return scene
예제 #5
0
    def _repr_geom_(self):
        import openalea.plantgl.all as pgl
        import vplants.plantgl.ext.color as color
        from openalea.container import array_dict
        
        scene = pgl.Scene()
        colormap = color.GlasbeyMap(0,256)

        if len(self.triangles) > 0:
            triangle_points = array_dict(self.points).values(self.triangles.values())
            triangle_normals = np.cross(triangle_points[:,1]-triangle_points[:,0],triangle_points[:,2]-triangle_points[:,0])
            mesh_center = np.mean(self.points.values(),axis=0)
            reversed_normals = np.array(self.triangles.keys())[np.where(np.einsum('ij,ij->i',triangle_normals,triangle_points[:,0]-mesh_center) < 0)[0]]
            for t in reversed_normals:
                self.triangles[t] = list(reversed(self.triangles[t]))
                                         

            points_index = array_dict(np.arange(len(self.points)),self.points.keys())

            if isiterable(self.triangle_data.values()[0]):
                colors = [pgl.Color4(colormap(self.triangle_data[t][0]%256).i3tuple()) if self.triangle_data.has_key(t) else pgl.Color4(colormap(0).i3tuple()) for t in self.triangles.keys()]
            else:
                colors = [pgl.Color4(colormap(self.triangle_data[t]%256).i3tuple()) if self.triangle_data.has_key(t) else pgl.Color4(colormap(0).i3tuple()) for t in self.triangles.keys()]

            # scene += pgl.Shape(pgl.FaceSet(self.points.values(),list(points_index.values(self.triangles.values()))),pgl.Material((255,255,255)))
            scene += pgl.Shape(pgl.FaceSet(self.points.values(),list(points_index.values(self.triangles.values())),colorList=colors,colorPerVertex=False))
            #for t in self.triangles.keys():
            #    scene += pgl.Shape(pgl.FaceSet([self.points[p] for p in self.triangles[t]],[list(range(3))]),pgl.Material(colormap(self.triangle_data[t]%256).i3tuple()),id=t)
        else:
            for p in self.points.keys():
                mat = pgl.Material(colormap(p%256).i3tuple(),transparency=0.0,name=p)
                scene += pgl.Shape(pgl.Translated(self.points[p],pgl.Sphere(self.point_radius,slices=16,stacks=16)),mat,id=p)
        return scene
예제 #6
0
def property_spatial_image_to_triangular_mesh(image,
                                              property_name=None,
                                              labels=None,
                                              coef=1):
    from openalea.cellcomplex.property_topomesh.utils.image_tools import composed_triangular_mesh

    cell_triangular_meshes = deepcopy(image.cell_meshes)
    img_labels = cell_triangular_meshes.keys()
    if labels is None:
        labels = image.labels

    if coef != 1:
        for l in labels:
            cell_center = np.mean(cell_triangular_meshes[l].points.values(),
                                  axis=0)
            points = cell_center + coef * (
                cell_triangular_meshes[l].points.values() - cell_center)
            cell_triangular_meshes[l].points = array_dict(
                points, cell_triangular_meshes[l].points.keys())

    mesh, matching = composed_triangular_mesh(
        dict([(c, cell_triangular_meshes[c]) for c in labels
              if c in cell_triangular_meshes.keys()]))

    if property_name in image.image_property_names():
        property_dict = image.image_property(property_name)
    else:
        property_dict = array_dict(labels, keys=labels)

    mesh.triangle_data = dict(
        zip(matching.keys(), property_dict.values(matching.values())))

    return mesh, matching
예제 #7
0
def sphere_tissue_image(size=100, n_points=12):

    center = np.array([size/2,size/2,size/2],float)
    radius = size/4.

    points = {}
    for p in range(n_points):
        theta = np.random.rand()*2.*np.pi
        phi = np.random.rand()*np.pi - np.pi/2.
        
        points[p+3] = center + radius*np.array([np.cos(theta)*np.cos(phi),np.sin(theta)*np.cos(phi),np.sin(phi)])
    points = array_dict(points)

    point_target_area = 4.*np.pi*np.power(radius,2.)/float(n_points)
    point_target_distance = np.power(point_target_area/np.pi,0.5)

    sigma_deformation = (size/100.)*(20./n_points)
    omega_forces = dict(distance=0.1*size/100., repulsion=100.0*np.power(size/100.,2))

    for iterations in xrange(100):
        point_vectors = np.array([points[p]- points.values() for p in points.keys()])
        point_distances = np.array([vq(points.values(),np.array([points[p]]))[1] for p in points.keys()])
        point_vectors = point_vectors/(point_distances[...,np.newaxis]+1e-7)

        point_distance_forces = omega_forces['distance']*((point_distances-point_target_distance)[...,np.newaxis]*point_vectors/point_target_distance).sum(axis=1)
        
        point_repulsion_forces = omega_forces['repulsion']*np.power(point_target_distance,2)*(point_vectors/(np.power(point_distances,2)+1e-7)[...,np.newaxis]).sum(axis=1)
        
        point_forces = np.zeros((len(points),3))
        point_forces += point_distance_forces
        point_forces += point_repulsion_forces
        
        point_forces = np.minimum(1.0,sigma_deformation/np.linalg.norm(point_forces,axis=1))[:,np.newaxis] * point_forces
        
        new_points = points.values() + point_forces
        
        new_points = center+ radius*((new_points-center)/np.linalg.norm((new_points-center),axis=1)[:,np.newaxis])
        
        points = array_dict(new_points,points.keys())
    points[2] = center

    coords = np.transpose(np.mgrid[0:size,0:size,0:size],(1,2,3,0)).reshape((np.power(size,3),3)).astype(int)
    labels = points.keys()[vq(coords,points.values())[0]]

    ext_coords = coords[vq(coords,np.array([center]))[1]>size/3.]

    img = np.ones((size,size,size),np.uint8)
    img[tuple(np.transpose(coords))] = labels
    img[tuple(np.transpose(ext_coords))] = 1
    img = SpatialImage(img,resolution=(60./size,60./size,60./size))

    return img
def triangle_topomesh(triangles, positions, **kwargs):

    triangles = np.array(triangles)
    positions = array_dict(positions)

    edges = array_unique(np.sort(np.concatenate(triangles[:,triangle_edge_list],axis=0)))

    triangle_edges = np.sort(np.concatenate(triangles[:,triangle_edge_list]))

    start_time = time()
    print "--> Generating triangle topomesh"

    triangle_edge_matching = vq(triangle_edges,edges)[0]

    triangle_topomesh = PropertyTopomesh(3)
    for c in np.unique(triangles):
        triangle_topomesh.add_wisp(0,c)
    for e in edges:
        eid = triangle_topomesh.add_wisp(1)
        for pid in e:
            triangle_topomesh.link(1,eid,pid)
    for t in triangles:
        fid = triangle_topomesh.add_wisp(2)
        for eid in triangle_edge_matching[3*fid:3*fid+3]:
            triangle_topomesh.link(2,fid,eid)
    triangle_topomesh.add_wisp(3,0)
    for fid in triangle_topomesh.wisps(2):
        triangle_topomesh.link(3,0,fid)
    triangle_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(triangles)),keys=np.unique(triangles))    

    end_time = time()
    print "<-- Generating triangle topomesh [",end_time-start_time,"s]"

    return triangle_topomesh
예제 #9
0
def circle_voronoi_topomesh(size = 1,resolution = 1.,circle_size = 100.,z_coef = 0.):
    n_cells = 3*size*(size-1)+1
    radius = size*resolution

    circle_thetas = np.linspace(-np.pi,np.pi-2*np.pi/float(circle_size),circle_size)
    circle_points = np.transpose([radius*np.cos(circle_thetas),radius*np.sin(circle_thetas)])

    cell_thetas = np.array([np.pi*np.random.randint(-180,180)/180. for c in xrange(n_cells)])
    cell_distances = 0.5*radius*np.sqrt([np.random.rand() for c in xrange(n_cells)])

    cell_points = np.transpose([cell_distances*np.cos(cell_thetas),cell_distances*np.sin(cell_thetas)])

    omega_forces = dict(repulsion=0.5)
    sigma_deformation = 2.*radius/float(n_cells)

    for iteration in xrange(n_cells/2):
        cell_to_cell_vectors = np.array([[p-q for q in cell_points] for p in cell_points])
        cell_to_cell_distances = np.linalg.norm(cell_to_cell_vectors,axis=2)/radius
        cell_to_circle_vectors = np.array([[p-q for q in circle_points] for p in cell_points])
        cell_to_circle_distances = np.linalg.norm(cell_to_circle_vectors,axis=2)/radius
        
        deformation_force = np.zeros_like(cell_points)
        
        cell_repulsion_force = np.nansum(cell_to_cell_vectors/np.power(cell_to_cell_distances,3)[:,:,np.newaxis],axis=1)
        circle_repulsion_force = np.nansum(cell_to_circle_vectors/np.power(cell_to_circle_distances,3)[:,:,np.newaxis],axis=1)

        deformation_force += omega_forces['repulsion']*cell_repulsion_force
        deformation_force += 1.5*(n_cells/float(circle_size))*omega_forces['repulsion']*circle_repulsion_force

        deformation_force_amplitude = np.linalg.norm(deformation_force,axis=1)
        deformation_force = np.minimum(1.0,sigma_deformation/deformation_force_amplitude)[:,np.newaxis] * deformation_force

        cell_points += deformation_force
        cell_points = np.minimum(1.0,radius/(np.linalg.norm(cell_points,axis=1)))[:,np.newaxis] * cell_points

    all_positions = array_dict(np.transpose([np.concatenate([cell_points[:,0],circle_points[:,0]]),np.concatenate([cell_points[:,1],circle_points[:,1]]),np.zeros(n_cells+circle_size)]),keys=np.arange(n_cells+circle_size).astype(int))
    triangles = all_positions.keys()[delaunay_triangulation(all_positions.values())]

    radial_distances = np.linalg.norm(all_positions.values(),axis=1)
    radial_z = z_coef*np.power(radial_distances/radius,2)
    all_positions = array_dict(np.transpose([all_positions.values()[:,0],all_positions.values()[:,1],radial_z]),keys=all_positions.keys())

    triangulation_topomesh = triangle_topomesh(triangles,all_positions)
    cell_topomesh = dual_topomesh(triangulation_topomesh,2,vertex_positions='voronoi')

    return cell_topomesh
def dual_topomesh(topomesh,degree=2,vertex_positions='barycenter'):

    dual_topomesh = PropertyTopomesh(topomesh.degree())
    
    if degree == 2:
        for d in xrange(3):
            if d<2:
                dual_topomesh._regions[d] = deepcopy(topomesh._borders[2-d])
            if d>0:
                dual_topomesh._borders[d] = deepcopy(topomesh._regions[2-d])
        
        dual_topomesh._borders[3] = dict(zip(dual_topomesh._borders[2].keys(),[[w] for w in dual_topomesh._borders[2].keys()]))
        dual_topomesh._regions[2] = dict(zip(dual_topomesh._borders[2].keys(),[[w] for w in dual_topomesh._borders[2].keys()]))
    
        edges_to_remove = [e for e in dual_topomesh.wisps(1) if len(list(dual_topomesh.borders(1,e)))<2]
        faces_to_remove = [f for f in dual_topomesh.wisps(2) if np.any([e in edges_to_remove for e in dual_topomesh.borders(2,f)])]
        cells_to_remove = faces_to_remove
    
    for e in edges_to_remove:
        dual_topomesh.remove_wisp(1,e)
    for f in faces_to_remove:
        dual_topomesh.remove_wisp(2,f)
    for c in cells_to_remove:
        dual_topomesh.remove_wisp(3,c)
    
    if 'voronoi' in vertex_positions:
        assert is_triangular(topomesh)
        if degree==2:
            from openalea.cellcomplex.property_topomesh.utils.geometry_tools import triangle_geometric_features
            compute_topomesh_property(topomesh,'vertices',2)
            triangles = topomesh.wisp_property('vertices',2).values(list(dual_topomesh.wisps(0)))
            positions = topomesh.wisp_property('barycenter',0)
            if vertex_positions == 'projected_voronoi':
                centers = triangle_geometric_features(triangles,positions,features=['projected_circumscribed_circle_center'])[:,0]
            else:
                centers = triangle_geometric_features(triangles,positions,features=['circumscribed_circle_center'])[:,0]
            dual_positions = array_dict(centers,list(dual_topomesh.wisps(0)))
    else:
        compute_topomesh_property(topomesh,'barycenter',degree)
        dual_positions = array_dict(topomesh.wisp_property('barycenter',degree).values(list(dual_topomesh.wisps(0))),list(dual_topomesh.wisps(0)))
    
   
    dual_topomesh.update_wisp_property('barycenter',0,dual_positions)
    
    return dual_topomesh
예제 #11
0
def point_position_optimization(points,
                                omega_forces=dict(distance=1, repulsion=1),
                                target_distance=1,
                                sigma_deformation=0.1,
                                n_iterations=100,
                                force_centering=True,
                                center=np.zeros(3)):

    points = array_dict(points)

    for iterations in xrange(100):
        point_vectors = np.array(
            [points[p] - points.values() for p in points.keys()])
        point_distances = np.array([
            vq(points.values(), np.array([points[p]]))[1]
            for p in points.keys()
        ])
        point_vectors = point_vectors / (point_distances[..., np.newaxis] +
                                         1e-7)

        point_distance_forces = omega_forces['distance'] * (
            (target_distance - point_distances)[..., np.newaxis] *
            point_vectors / target_distance).sum(axis=1)
        point_repulsion_forces = omega_forces['repulsion'] * np.power(
            target_distance, 2) * (point_vectors /
                                   (np.power(point_distances, 2) +
                                    1e-7)[..., np.newaxis]).sum(axis=1)

        point_forces = np.zeros((len(points), 3))
        point_forces += point_distance_forces
        point_forces += point_repulsion_forces

        point_forces = np.minimum(
            1.0, sigma_deformation /
            np.linalg.norm(point_forces, axis=1))[:, np.newaxis] * point_forces

        new_points = points.values() + point_forces
        new_points += center - points.values().mean(axis=0)

        points = array_dict(new_points, points.keys())

    return points
예제 #12
0
def spatial_image_analysis_property(sia, property_name, labels=None):
    
    if property_name == 'volume':
        property_data = sia.volume(labels)
    elif property_name == 'neighborhood_size':
        property_data = sia.neighbors_number(labels)
    elif property_name == 'shape_anisotropy':
        inertia_axes_vectors, inertia_axes_values = sia.inertia_axis(labels)
        property_data = [fractional_anisotropy(inertia_axes_values[l]) for l in labels]
    elif property_name == 'gaussian_curvature':
        property_data = sia.gaussian_curvature_CGAL(labels)
    else:
        property_data = dict(zip(labels,labels))

    if isinstance(property_data,np.ndarray) or isinstance(property_data,list):
        property_data = array_dict(property_data, keys=labels)
    elif isinstance(property_data,dict):
        property_data = array_dict(property_data) 

    return property_data
예제 #13
0
def sphere_topomesh(radius=1.0,center=np.zeros(3)):
    from openalea.container import array_dict
    from openalea.cellcomplex.property_topomesh.property_topomesh_optimization import topomesh_triangle_split

    ico = icosahedron_topomesh()
    topomesh = topomesh_triangle_split(topomesh_triangle_split(ico))

    positions = topomesh.wisp_property('barycenter',0)
    new_positions = array_dict(center + radius*positions.values()/np.linalg.norm(positions.values(),axis=1)[:,np.newaxis],positions.keys())
    topomesh.update_wisp_property('barycenter',0,new_positions)

    return topomesh
예제 #14
0
def nuclei_image_surface_topomesh(nuclei_img,
                                  nuclei_sigma=2.,
                                  density_voxelsize=1.,
                                  intensity_threshold=2000.,
                                  microscope_orientation=1,
                                  maximal_length=10.,
                                  remeshing_iterations=10,
                                  erosion_radius=0.0):
    voxelsize = np.array(nuclei_img.voxelsize)
    size = np.array(nuclei_img.shape)
    subsampling = np.ceil(density_voxelsize / voxelsize).astype(int)

    # nuclei_density = nd.gaussian_filter(nuclei_img,nuclei_sigma/voxelsize)/(2.*intensity_threshold)
    nuclei_density = (nd.gaussian_filter(nuclei_img, nuclei_sigma / voxelsize)
                      > (2. * intensity_threshold)).astype(np.uint8)
    nuclei_density = nuclei_density[::subsampling[0], ::subsampling[1], ::
                                    subsampling[2]]

    pad_shape = np.transpose(
        np.tile(np.array(nuclei_density.shape) / 2, (2, 1)))
    nuclei_density = np.pad(nuclei_density, pad_shape, mode='constant')

    if erosion_radius > 0:
        structuring_element = spherical_structuring_element(
            erosion_radius, voxelsize * subsampling)
        nuclei_density = nd.binary_erosion(
            nuclei_density, structuring_element).astype(np.uint8)

    surface_topomesh = implicit_surface_topomesh(
        nuclei_density,
        np.array(nuclei_density).shape,
        microscope_orientation * voxelsize * subsampling,
        smoothing=50,
        decimation=100,
        iso=0.5,
        center=False)
    surface_topomesh.update_wisp_property(
        'barycenter', 0,
        array_dict(
            surface_topomesh.wisp_property('barycenter', 0).values() -
            0.25 * microscope_orientation * voxelsize * subsampling *
            np.array(nuclei_density.shape),
            surface_topomesh.wisp_property('barycenter', 0).keys()))

    if remeshing_iterations > 0:
        surface_topomesh = property_topomesh_isotropic_remeshing(
            surface_topomesh,
            maximal_length=maximal_length,
            iterations=remeshing_iterations)

    return surface_topomesh
def nuclei_positions_from_segmented_image(segmented_img, background_label=1):
    """
    """
    voxelsize = np.array(segmented_img.voxelsize)
    segmented_cells = np.array(
        [c for c in np.unique(segmented_img) if c != background_label])
    segmented_positions = array_dict(
        np.array(
            nd.center_of_mass(np.ones_like(segmented_img),
                              segmented_img,
                              index=segmented_cells)) * voxelsize,
        segmented_cells)

    return segmented_positions
예제 #16
0
def vtk_polydata_to_cell_triangular_meshes(polydata):
    mesh = {} 

    polydata_cell_data = polydata.GetCellData().GetArray(0)
    triangle_cell_start_time = time()
    print "  --> Listing triangles"
    print "      - ",polydata.GetNumberOfCells()," triangles"
    # polydata_triangles = np.sort([[polydata.GetCell(t).GetPointIds().GetId(i) for i in xrange(3)] for t in xrange(polydata.GetNumberOfCells())])   
    polydata_triangles = np.array([[polydata.GetCell(t).GetPointIds().GetId(i) for i in xrange(3)] for t in xrange(polydata.GetNumberOfCells())])   
    triangle_cell_end_time = time()
    print "  <-- Listing triangles            [",triangle_cell_end_time - triangle_cell_start_time,"s]"

    triangle_cell_start_time = time()
    print "  --> Listing triangle cells"
    triangle_cell = np.array([polydata_cell_data.GetTuple(t)[0] for t in xrange(polydata.GetNumberOfCells())],np.uint16)
    triangle_cell_end_time = time()
    print "  <-- Listing triangle cells     [",triangle_cell_end_time - triangle_cell_start_time,"s]"

    start_time = time()
    print "  --> Creating cell meshes"
    for c in np.unique(triangle_cell):
        
        mesh[c] = TriangularMesh()
        cell_triangles = np.arange(polydata.GetNumberOfCells())[np.where(triangle_cell==c)]
        # cell_triangle_points = np.sort([[polydata.GetCell(t).GetPointIds().GetId(i) for i in xrange(3)] for t in cell_triangles])
        cell_triangle_points = np.array([[polydata.GetCell(t).GetPointIds().GetId(i) for i in xrange(3)] for t in cell_triangles])
        cell_vertices = np.sort(np.unique(cell_triangle_points))


        mesh[c].points = array_dict(np.array([polydata.GetPoints().GetPoint(v) for v in cell_vertices]),cell_vertices).to_dict()
        mesh[c].triangles = array_dict(cell_triangle_points,cell_triangles).to_dict()
        mesh[c].triangle_data = array_dict(np.ones_like(cell_triangles)*c,cell_triangles).to_dict()
    end_time = time()
    print "  <-- Creating cell meshes   [",end_time-start_time,"s]"

    return mesh
예제 #17
0
    def update_image_property(self,
                              property_name,
                              property_data,
                              erase_property=False):
        if isinstance(property_data, list) or isinstance(
                property_data, np.ndarray):
            assert len(property_data) == len(self._labels)
            property_keys = self._labels
        elif isinstance(property_data, dict) or isinstance(
                property_data, array_dict):
            property_keys = np.sort(property_data.keys())
            property_data = [property_data[l] for l in property_keys]

        if property_name in self._properties.keys():
            if erase_property:
                self._properties[property_name] = array_dict(
                    property_data, keys=property_keys)
            else:
                for l, v in zip(property_keys, property_data):
                    self._properties[property_name][l] = v
        else:
            print "Creating property ", property_name, " on image"
            self._properties[property_name] = array_dict(property_data,
                                                         keys=property_keys)
def spatial_image_analysis_to_spatial_image(input_sia,
                                            property_name=None,
                                            labels=None):
    """
    """

    sia = deepcopy(input_sia)

    img_labels = sia.labels()
    if labels is not None:
        labels_to_remove = set(img_labels) - set(list(labels))
        sia.remove_labels_from_image(labels_to_remove)

    img_labels = sia.labels()
    segmented_img = deepcopy(sia.image)
    background = sia.background()

    print background

    if property_name == 'volume':
        img_volumes = sia.volume(img_labels)
        if isinstance(img_volumes, np.ndarray) or isinstance(
                img_volumes, list):
            img_volumes = array_dict(img_volumes, keys=img_labels)
        elif isinstance(img_volumes, dict):
            img_volumes = array_dict(img_volumes)

        property_img = SpatialImage(img_volumes.values(segmented_img).astype(
            np.uint16),
                                    resolution=segmented_img.resolution)
        property_img[segmented_img == background] = background

    else:
        property_img = segmented_img

    return property_img
예제 #19
0
def test_draco():
    n_points = 12
    img = sphere_tissue_image(size=100, n_points=n_points)

    draco = DracoMesh(img)

    assert draco.point_topomesh.nb_wisps(0) == n_points + 1

    draco.delaunay_adjacency_complex(surface_cleaning_criteria=[])

    image_tetrahedra = np.sort(draco.image_cell_vertex.keys())
    image_tetrahedra = image_tetrahedra[image_tetrahedra[:, 0] != 1]
    draco_tetrahedra = np.sort([
        list(draco.triangulation_topomesh.borders(3, t, 3))
        for t in draco.triangulation_topomesh.wisps(3)
    ])
    delaunay_consistency = jaccard_index(image_tetrahedra, draco_tetrahedra)

    draco.adjacency_complex_optimization(n_iterations=2)

    assert draco.triangulation_topomesh.nb_region_neighbors(0, 2) == n_points

    image_tetrahedra = np.sort(draco.image_cell_vertex.keys())
    image_tetrahedra = image_tetrahedra[image_tetrahedra[:, 0] != 1]
    draco_tetrahedra = np.sort([
        list(draco.triangulation_topomesh.borders(3, t, 3))
        for t in draco.triangulation_topomesh.wisps(3)
    ])
    draco_consistency = jaccard_index(image_tetrahedra, draco_tetrahedra)

    # print delaunay_consistency,' -> ',draco_consistency

    assert draco_consistency == 1 or (draco_consistency >= 0.9 and
                                      draco_consistency > delaunay_consistency)

    triangular = ['star', 'remeshed', 'projected', 'regular', 'flat']
    image_dual_topomesh = draco.dual_reconstruction(
        reconstruction_triangulation=triangular, adjacency_complex_degree=3)

    image_volumes = array_dict(
        nd.sum(np.ones_like(img), img, index=np.unique(img)[1:]) *
        np.prod(img.voxelsize),
        np.unique(img)[1:])
    compute_topomesh_property(image_dual_topomesh, 'volume', 3)
    draco_volumes = image_dual_topomesh.wisp_property('volume', 3)

    for c in image_dual_topomesh.wisps(3):
        assert np.isclose(image_volumes[c], draco_volumes[c], 0.33)
def vertex_topomesh(positions, **kwargs):
    
    positions = array_dict(positions)

    start_time = time()
    print "--> Generating vertex topomesh"

    vertex_topomesh = PropertyTopomesh(3)
    for c in positions.keys():
        vertex_topomesh.add_wisp(0,c)
    vertex_topomesh.update_wisp_property('barycenter',0,positions.values(positions.keys()),keys=positions.keys())    

    end_time = time()
    print "<-- Generating vertex topomesh [",end_time-start_time,"s]"

    return vertex_topomesh
def test_length_scaling():
    side_length = 1.
    scale_factor = 2.

    topomesh = hexagon_topomesh(side_length)
    compute_topomesh_property(topomesh, 'length', 1)

    topomesh.update_wisp_property('barycenter', 0, array_dict(
        topomesh.wisp_property('barycenter', 0).values() * scale_factor,
        list(topomesh.wisps(0))))
    side_length *= scale_factor

    compute_topomesh_property(topomesh, 'length', 1)
    for eid in topomesh.wisps(1):
        assert np.isclose(topomesh.wisp_property('length', 1)[eid], side_length,
                          1e-7)
예제 #22
0
def filter_topomesh_vertices(topomesh, vtx_list="L1"):
    """
    Return a filtered topomesh containing only the values found in `vtx_list`.

    Parameters
    ----------
    topomesh : vertex_topomesh
        a topomesh to edit
    vtx_list : str | list
        if a list, the ids it contains will be used to filter the `topomesh`
        can be a string like "L1", then propery "layer" should exists!

    Returns
    -------
    vertex_topomesh
    """
    if isinstance(vtx_list, str):
        try:
            assert "layer" in list(topomesh.wisp_property_names(0))
        except AssertionError:
            raise ValueError("Property 'layer' is missing in the topomesh!")
    # - Duplicate the topomesh:
    filtered_topomesh = deepcopy(topomesh)
    # - Define selected vertices:
    if vtx_list == "L1":
        # -- Filter L1 seeds from 'detected_topomesh':
        filtered_cells = np.array(list(filtered_topomesh.wisps(0)))[filtered_topomesh.wisp_property('layer',0).values()==1]
    elif vtx_list == "L2":
        # -- Filter L2 seeds from 'detected_topomesh':
        filtered_cells = np.array(list(filtered_topomesh.wisps(0)))[filtered_topomesh.wisp_property('layer',0).values()==2]
    elif isinstance(vtx_list, list):
        filtered_cells = [v for v in vtx_list if v in filtered_topomesh.wisps(0)]
    else:
        raise ValueError("Unable to use given `vtx_list`, please check it!")
    # - Remove unwanted vertices:
    vtx2remove = list(set(filtered_topomesh.wisps(0)) - set(filtered_cells))
    for c in vtx2remove:
        filtered_topomesh.remove_wisp(0,c)
    # - Update properies found in the original topomesh:
    for ppty in filtered_topomesh.wisp_property_names(0):
        vtx = list(filtered_topomesh.wisps(0))
        ppty_dict = array_dict(filtered_topomesh.wisp_property(ppty, 0).values(vtx), keys=vtx)
        filtered_topomesh.update_wisp_property(ppty, 0, ppty_dict)

    return filtered_topomesh
예제 #23
0
 def compute_image_property_from_function(self, property_name,
                                          property_function):
     """
     property_function : a function taking as an input a binary image and computing
     a specific cell property.
     """
     from time import time
     start_time = time()
     print "--> Computing " + property_name + " property"
     self._properties[property_name] = array_dict()
     for l in self.labels:
         label_start_time = time()
         binary_img = (self.image == l).astype(int)
         self._properties[property_name][l] = property_function(binary_img)
         print "  --> Computing label " + str(
             l) + " " + property_name + " [", time(
             ) - label_start_time, " s]"
     print "<-- Computing " + property_name + " property [", time(
     ) - start_time, " s]"
def poly_topomesh(polys, positions, faces_as_cells=False, **kwargs):
    polys = np.array(polys)
    positions = array_dict(positions)

    poly_lengths = np.array(map(len,polys))
    poly_edge_list = [np.transpose([np.arange(l),(np.arange(l)+1)%l]) for l in poly_lengths]

    edges = array_unique(np.sort(np.concatenate([np.array(p)[l] for p,l in zip(polys,poly_edge_list)],axis=0)))

    poly_edges = np.sort(np.concatenate([np.array(p)[l] for p,l in zip(polys,poly_edge_list)],axis=0))

    start_time = time()
    print "--> Generating poly topomesh"

    poly_edge_matching = vq(poly_edges,edges)[0]

    poly_topomesh = PropertyTopomesh(3)
    for c in np.unique(polys):
        poly_topomesh.add_wisp(0,c)
    for e in edges:
        eid = poly_topomesh.add_wisp(1)
        for pid in e:
            poly_topomesh.link(1,eid,pid)
    total_poly_length = 0
    for q,l in zip(polys,poly_lengths):
        fid = poly_topomesh.add_wisp(2)
        for eid in poly_edge_matching[total_poly_length:total_poly_length+l]:
            poly_topomesh.link(2,fid,eid)
        total_poly_length += l
    if not faces_as_cells:
        poly_topomesh.add_wisp(3,0)
        for fid in poly_topomesh.wisps(2):
            poly_topomesh.link(3,0,fid)
    else:
        for fid in poly_topomesh.wisps(2):
            poly_topomesh.add_wisp(3,fid)
            poly_topomesh.link(3,fid,fid)
    poly_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(polys)),keys=np.unique(polys))    

    end_time = time()
    print "<-- Generating poly topomesh [",end_time-start_time,"s]"

    return poly_topomesh
def tetrahedra_topomesh(tetrahedra, positions, **kwargs):

    tetrahedra = np.array(tetrahedra)
    positions = array_dict(positions)

    tetrahedra_triangles = array_unique(np.concatenate(np.sort(tetrahedra[:,tetra_triangle_list])))

    tetrahedra_triangle_edges = tetrahedra_triangles[:,triangle_edge_list]
    tetrahedra_triangle_vectors = positions.values(tetrahedra_triangle_edges[...,1]) - positions.values(tetrahedra_triangle_edges[...,0])
    tetrahedra_triangle_lengths = np.linalg.norm(tetrahedra_triangle_vectors,axis=2)
    tetrahedra_triangle_perimeters = tetrahedra_triangle_lengths.sum(axis=1)

    tetrahedra_edges = array_unique(np.concatenate(tetrahedra_triangles[:,triangle_edge_list],axis=0))

    start_time = time()
    print "--> Generating tetrahedra topomesh"
    triangle_edges = np.concatenate(tetrahedra_triangles[:,triangle_edge_list],axis=0)
    triangle_edge_matching = vq(triangle_edges,tetrahedra_edges)[0]

    tetrahedra_faces = np.concatenate(np.sort(tetrahedra[:,tetra_triangle_list]))
    tetrahedra_triangle_matching = vq(tetrahedra_faces,tetrahedra_triangles)[0]

    tetrahedra_topomesh = PropertyTopomesh(3)
    for c in np.unique(tetrahedra_triangles):
        tetrahedra_topomesh.add_wisp(0,c)
    for e in tetrahedra_edges:
        eid = tetrahedra_topomesh.add_wisp(1)
        for pid in e:
            tetrahedra_topomesh.link(1,eid,pid)
    for t in tetrahedra_triangles:
        fid = tetrahedra_topomesh.add_wisp(2)
        for eid in triangle_edge_matching[3*fid:3*fid+3]:
            tetrahedra_topomesh.link(2,fid,eid)
    for t in tetrahedra:
        cid = tetrahedra_topomesh.add_wisp(3)
        for fid in tetrahedra_triangle_matching[4*cid:4*cid+4]:
            tetrahedra_topomesh.link(3,cid,fid)
    tetrahedra_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(tetrahedra_triangles)),keys=np.unique(tetrahedra_triangles))        

    end_time = time()
    print "<-- Generating tetrahedra topomesh [",end_time-start_time,"s]"

    return tetrahedra_topomesh
def edge_topomesh(edges, positions, **kwargs):

    positions = array_dict(positions)

    start_time = time()
    print "--> Generating edge topomesh"

    edge_topomesh = PropertyTopomesh(3)
    for c in np.unique(edges):
        edge_topomesh.add_wisp(0,c)
    for e in edges:
        eid = edge_topomesh.add_wisp(1)
        for pid in e:
            edge_topomesh.link(1,eid,pid)
    edge_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(edges)),keys=np.unique(edges))    

    end_time = time()
    print "<-- Generating edge topomesh [",end_time-start_time,"s]"

    return edge_topomesh
def compute_temporal_topomesh_property(topomesh, property_name, degree=0, positions=None, verbose=False):
    """
    """
    from openalea.cellcomplex.property_topomesh.property_topomesh_analysis import compute_topomesh_property

    if positions is None:
        positions = topomesh.wisp_property('barycenter',degree=0)
    
    if property_name == 'time':
        assert degree>0
        if not 'time' in topomesh.wisp_property_names(degree):
            topomesh.add_wisp_property('time',degree=degree)
        compute_topomesh_property(topomesh,'vertices',degree)
        topomesh.update_wisp_property('time',degree=degree,values=array_dict([np.unique(topomesh.wisp_property('time',0).values(topomesh.wisp_property('vertices',degree)[w]))[0] for w in topomesh.wisps(degree)],keys=list(topomesh.wisps(degree))))
       
    if property_name == 'mother_cell':
        assert degree==3
        if not 'mother_cell' in topomesh.wisp_property_names(degree):
            topomesh.add_wisp_property('mother_cell',degree=degree)
        topomesh.update_wisp_property('mother_cell',degree=degree,values=np.array([int(list(topomesh.ancestors(degree,w))[0]) for w in topomesh.wisps(degree)]),keys=np.array(list(topomesh.wisps(degree))))
예제 #28
0
def implicit_surface(density_field,size,resolution,iso=0.5):
    import numpy as np
    from scipy.cluster.vq                       import kmeans, vq
    from openalea.container import array_dict
   
    from skimage.measure import marching_cubes
    surface_points, surface_triangles = marching_cubes(density_field,iso)
    
    surface_points = (np.array(surface_points))*(size*resolution/np.array(density_field.shape)) - size*resolution/2.

    points_ids = np.arange(len(surface_points))
    points_to_delete = []
    for p,point in enumerate(surface_points):
        matching_points = np.sort(np.where(vq(surface_points,np.array([point]))[1] == 0)[0])
        if len(matching_points) > 1:
            points_to_fuse = matching_points[1:]
            for m_p in points_to_fuse:
                surface_triangles[np.where(surface_triangles==m_p)] = matching_points[0]
                points_to_delete.append(m_p)

    points_to_delete = np.unique(points_to_delete)
    print len(points_to_delete),"points deleted"
    surface_points = np.delete(surface_points,points_to_delete,0)
    points_ids = np.delete(points_ids,points_to_delete,0)
    surface_triangles = array_dict(np.arange(len(surface_points)),points_ids).values(surface_triangles)

    for p,point in enumerate(surface_points):
        matching_points = np.where(vq(surface_points,np.array([point]))[1] == 0)[0]
        if len(matching_points) > 1:
            print p,point
            raw_input()

    triangles_to_delete = []
    for t,triangle in enumerate(surface_triangles):
        if len(np.unique(triangle)) < 3:
            triangles_to_delete.append(t)
        # elif triangle.max() >= len(surface_points):
        #     triangles_to_delete.append(t)
    surface_triangles = np.delete(surface_triangles,triangles_to_delete,0)

    return surface_points, surface_triangles
def quad_topomesh(quads, positions, faces_as_cells=False, **kwargs):
    quads = np.array(quads)
    positions = array_dict(positions)

    edges = array_unique(np.sort(np.concatenate(quads[:,quad_edge_list],axis=0)))

    quad_edges = np.sort(np.concatenate(quads[:,quad_edge_list]))

    start_time = time()
    print "--> Generating quad topomesh"

    quad_edge_matching = vq(quad_edges,edges)[0]

    quad_topomesh = PropertyTopomesh(3)
    for c in np.unique(quads):
        quad_topomesh.add_wisp(0,c)
    for e in edges:
        eid = quad_topomesh.add_wisp(1)
        for pid in e:
            quad_topomesh.link(1,eid,pid)
    for q in quads:
        fid = quad_topomesh.add_wisp(2)
        for eid in quad_edge_matching[4*fid:4*fid+4]:
            quad_topomesh.link(2,fid,eid)
    if not faces_as_cells:
        quad_topomesh.add_wisp(3,0)
        for fid in quad_topomesh.wisps(2):
            quad_topomesh.link(3,0,fid)
    else:
        for fid in quad_topomesh.wisps(2):
            quad_topomesh.add_wisp(3,fid)
            quad_topomesh.link(3,fid,fid)

    quad_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(quads)),keys=np.unique(quads))    

    end_time = time()
    print "<-- Generating quad topomesh [",end_time-start_time,"s]"

    return quad_topomesh
예제 #30
0
def cube_image(size=50):
    img = np.ones((size,size,size),np.uint8)

    points = {}
    points[11] = np.array([1,0,0],float)*size
    points[12] = np.array([0,1,0],float)*size
    points[31] = np.array([0,0,1],float)*size
    points[59] = np.array([1,1,1],float)*size
    points = array_dict(points)

    center = np.array([[size/2,size/2,size/2]],float)

    coords = np.transpose(np.mgrid[0:size,0:size,0:size],(1,2,3,0)).reshape((np.power(size,3),3))
    labels = points.keys()[vq(coords,points.values())[0]]

    ext_coords = coords[vq(coords,center)[1]>size/2.]

    img[tuple(np.transpose(coords))] = labels
    #img[tuple(np.transpose(ext_coords))] = 1
    img = SpatialImage(img,resolution=(1,1,1))

    return img
예제 #31
0
def cube_image(size=50):
    img = np.ones((size, size, size), np.uint8)

    points = {}
    points[11] = np.array([1, 0, 0], float) * size
    points[12] = np.array([0, 1, 0], float) * size
    points[31] = np.array([0, 0, 1], float) * size
    points[59] = np.array([1, 1, 1], float) * size
    points = array_dict(points)

    center = np.array([[size / 2, size / 2, size / 2]], float)

    coords = np.transpose(np.mgrid[0:size, 0:size, 0:size],
                          (1, 2, 3, 0)).reshape((np.power(size, 3), 3))
    labels = points.keys()[vq(coords, points.values())[0]]

    ext_coords = coords[vq(coords, center)[1] > size / 2.]

    img[tuple(np.transpose(coords))] = labels
    #img[tuple(np.transpose(ext_coords))] = 1
    img = SpatialImage(img, voxelsize=(1, 1, 1))

    return img
예제 #32
0
def test_draco():
    n_points = 12
    img = sphere_tissue_image(size=100,n_points=n_points)

    draco = DracoMesh(img)

    assert draco.point_topomesh.nb_wisps(0) == n_points+1

    draco.delaunay_adjacency_complex(surface_cleaning_criteria = [])

    image_tetrahedra = np.sort(draco.image_cell_vertex.keys())
    image_tetrahedra = image_tetrahedra[image_tetrahedra[:,0] != 1]
    draco_tetrahedra = np.sort([list(draco.triangulation_topomesh.borders(3,t,3)) for t in draco.triangulation_topomesh.wisps(3)])
    delaunay_consistency = jaccard_index(image_tetrahedra, draco_tetrahedra)

    draco.adjacency_complex_optimization(n_iterations=2)
    
    assert draco.triangulation_topomesh.nb_region_neighbors(0,2) == n_points

    image_tetrahedra = np.sort(draco.image_cell_vertex.keys())
    image_tetrahedra = image_tetrahedra[image_tetrahedra[:,0] != 1]
    draco_tetrahedra = np.sort([list(draco.triangulation_topomesh.borders(3,t,3)) for t in draco.triangulation_topomesh.wisps(3)])
    draco_consistency = jaccard_index(image_tetrahedra, draco_tetrahedra)

    # print delaunay_consistency,' -> ',draco_consistency

    assert draco_consistency == 1 or (draco_consistency >= 0.9 and draco_consistency > delaunay_consistency)

    triangular = ['star','remeshed','projected','regular','flat']
    image_dual_topomesh = draco.dual_reconstruction(reconstruction_triangulation = triangular, adjacency_complex_degree=3)

    image_volumes = array_dict(nd.sum(np.ones_like(img),img,index=np.unique(img)[1:])*np.prod(img.resolution),np.unique(img)[1:])
    compute_topomesh_property(image_dual_topomesh,'volume',3)
    draco_volumes = image_dual_topomesh.wisp_property('volume',3)

    for c in image_dual_topomesh.wisps(3):
        assert np.isclose(image_volumes[c],draco_volumes[c],0.33)
예제 #33
0
def nuclei_layer(nuclei_positions,
                 nuclei_image,
                 microscope_orientation=1,
                 surface_mode="image",
                 density_voxelsize=1.,
                 return_topomesh=False):

    size = np.array(nuclei_image.shape)
    voxelsize = microscope_orientation * np.array(nuclei_image.voxelsize)

    positions = array_dict(nuclei_positions)

    # if display:
    #     from openalea.core.world import World
    #     world = World()

    # #grid_voxelsize = voxelsize*[12,12,4]
    # grid_voxelsize = np.sign(voxelsize)*[4.,4.,4.]
    # #x,y,z = np.ogrid[0:size[0]*voxelsize[0]:grid_voxelsize[0],0:size[1]*voxelsize[1]:grid_voxelsize[1],0:size[2]*voxelsize[2]:grid_voxelsize[2]]
    # #grid_size = size
    # x,y,z = np.ogrid[-0.5*size[0]*voxelsize[0]:1.5*size[0]*voxelsize[0]:grid_voxelsize[0],-0.5*size[1]*voxelsize[1]:1.5*size[1]*voxelsize[1]:grid_voxelsize[1],-0.5*size[2]*voxelsize[2]:1.5*size[2]*voxelsize[2]:grid_voxelsize[2]]
    # grid_size = 2*size

    # #nuclei_potential = np.array([nuclei_density_function(dict([(p,positions[p])]),cell_radius=8,k=1.0)(x,y,z) for p in positions.keys()])
    # #nuclei_potential = np.transpose(nuclei_potential,(1,2,3,0))
    # #nuclei_density = np.sum(nuclei_potential,axis=3)

    # nuclei_density = nuclei_density_function(positions,cell_radius=5,k=1.0)(x,y,z)

    # surface_topomesh = implicit_surface_topomesh(nuclei_density,grid_size,voxelsize,iso=0.5,center=False)
    # surface_topomesh.update_wisp_property('barycenter',0,array_dict(surface_topomesh.wisp_property('barycenter',0).values() - 0.5*voxelsize*size,surface_topomesh.wisp_property('barycenter',0).keys()))

    # # if display:
    # #     world.add(surface_topomesh,'surface')
    # #     raw_input()
    # #     world.remove('surface')
    # # return None,None,surface_topomesh

    # triangulation_topomesh = delaunay_tetrahedrization_topomesh(positions,clean_surface=False)
    # delaunay_topomesh = deepcopy(triangulation_topomesh)

    # # triangulation_topomesh = tetrahedrization_clean_surface(delaunay_topomesh,surface_cleaning_criteria=['surface','sliver'],surface_topomesh=surface_topomesh)
    # triangulation_topomesh = tetrahedrization_clean_surface(delaunay_topomesh,surface_cleaning_criteria=['surface','distance','sliver'],surface_topomesh=surface_topomesh,maximal_distance=maximal_distance,maximal_eccentricity=maximal_eccentricity)
    # #triangulation_topomesh = tetrahedrization_clean_surface(delaunay_topomesh,surface_cleaning_criteria=['surface','distance','sliver'],surface_topomesh=surface_topomesh,maximal_distance=maximal_distance,maximal_eccentricity=maximal_eccentricity)

    # # if display:
    # #     world.add(triangulation_topomesh,'triangulation')
    # #     raw_input()
    # #     world.remove('triangulation')
    # # return None,triangulation_topomesh,surface_topomesh

    # L1_triangulation_topomesh = epidermis_topomesh(triangulation_topomesh)

    # compute_topomesh_property(L1_triangulation_topomesh,'normal',2,normal_method="density",object_positions=positions)

    # compute_topomesh_vertex_property_from_faces(L1_triangulation_topomesh,'normal',weighting='area',adjacency_sigma=1.2,neighborhood=3)

    # down_facing = L1_triangulation_topomesh.wisp_property('normal',0).values()[:,2] < -0.0
    # L1_triangulation_topomesh.update_wisp_property('downward',0,array_dict(down_facing,keys=list(L1_triangulation_topomesh.wisps(0))))

    # triangle_down_facing = np.any(L1_triangulation_topomesh.wisp_property('downward',0).values(L1_triangulation_topomesh.wisp_property('vertices',2).values(list(L1_triangulation_topomesh.wisps(2)))),axis=1)
    # triangle_down_facing = triangle_down_facing.astype(float)
    # L1_triangulation_topomesh.update_wisp_property('downward',2,array_dict(triangle_down_facing,keys=list(L1_triangulation_topomesh.wisps(2))))

    # for i,t in enumerate(L1_triangulation_topomesh.wisps(2)):
    #     if L1_triangulation_topomesh.wisp_property('downward',2)[t] == 1:
    #         triangle_neighbors = list(L1_triangulation_topomesh.border_neighbors(2,t))
    #         if np.any(L1_triangulation_topomesh.wisp_property('downward',2).values(triangle_neighbors)==0):
    #             triangle_down_facing[i] = 0.5
    # L1_triangulation_topomesh.update_wisp_property('downward',2,array_dict(triangle_down_facing,keys=list(L1_triangulation_topomesh.wisps(2))))

    # triangles_to_remove = np.array(list(L1_triangulation_topomesh.wisps(2)))[L1_triangulation_topomesh.wisp_property('downward',2).values() == 1]
    # for t in triangles_to_remove:
    #     L1_triangulation_topomesh.remove_wisp(2,t)

    # edges_to_remove = np.array(list(L1_triangulation_topomesh.wisps(1)))[np.array([L1_triangulation_topomesh.nb_regions(1,e)==0 for e in L1_triangulation_topomesh.wisps(1)])]
    # for e in edges_to_remove:
    #     L1_triangulation_topomesh.remove_wisp(1,e)

    # vertices_to_remove = np.array(list(L1_triangulation_topomesh.wisps(0)))[np.array([L1_triangulation_topomesh.nb_regions(0,v)==0 for v in L1_triangulation_topomesh.wisps(0)])]
    # for v in vertices_to_remove:
    #     L1_triangulation_topomesh.remove_wisp(0,v)

    # L1_triangulation_topomesh = topomesh_connected_components(L1_triangulation_topomesh)[0]

    # cell_layer = array_dict(np.zeros_like(positions.keys()),positions.keys())
    # for c in L1_triangulation_topomesh.wisps(0):
    #     cell_layer[c] = 1
    # for c in triangulation_topomesh.wisps(0):
    #     if cell_layer[c] != 1:
    #         if np.any(cell_layer.values(list(triangulation_topomesh.region_neighbors(0,c))) == 1):
    #             cell_layer[c] = 2

    if surface_mode == 'density':
        grid_voxelsize = microscope_orientation * np.ones(
            3, float) * density_voxelsize
        x, y, z = np.ogrid[-0.5 * size[0] * voxelsize[0]:1.5 * size[0] *
                           voxelsize[0]:grid_voxelsize[0],
                           -0.5 * size[1] * voxelsize[1]:1.5 * size[1] *
                           voxelsize[1]:grid_voxelsize[1],
                           -0.5 * size[2] * voxelsize[2]:1.5 * size[2] *
                           voxelsize[2]:grid_voxelsize[2]]
        grid_size = 2 * size

        nuclei_density = nuclei_density_function(positions,
                                                 cell_radius=5,
                                                 k=1.0)(x, y, z)

        surface_topomesh = implicit_surface_topomesh(nuclei_density,
                                                     grid_size,
                                                     voxelsize,
                                                     iso=0.5,
                                                     center=False)
        surface_topomesh.update_wisp_property(
            'barycenter', 0,
            array_dict(
                surface_topomesh.wisp_property('barycenter', 0).values() -
                0.5 * voxelsize * size,
                surface_topomesh.wisp_property('barycenter', 0).keys()))
    elif surface_mode == 'image':
        surface_topomesh = nuclei_image_surface_topomesh(
            nuclei_image,
            microscope_orientation=microscope_orientation,
            density_voxelsize=density_voxelsize,
            nuclei_sigma=1,
            maximal_length=6.,
            remeshing_iterations=20)

    top_surface_topomesh = up_facing_surface_topomesh(surface_topomesh,
                                                      nuclei_positions,
                                                      connected=True)
    top_surface_topomesh = topomesh_triangle_split(top_surface_topomesh)

    #world.add(top_surface_topomesh,'top_surface')

    surface_points = top_surface_topomesh.wisp_property(
        'barycenter', 0).values(list(top_surface_topomesh.wisps(0)))
    surface_potential = np.array([
        nuclei_density_function(dict([(p, positions[p])]),
                                cell_radius=5,
                                k=1.0)(surface_points[:, 0],
                                       surface_points[:, 1], surface_points[:,
                                                                            2])
        for p in positions.keys()
    ])
    surface_cells = np.array(positions.keys())[np.argmax(surface_potential,
                                                         axis=0)]

    L1_cells = np.unique(surface_cells)

    cell_layer = array_dict(np.zeros_like(positions.keys()), positions.keys())
    for c in L1_cells:
        cell_layer[c] = 1

    if return_topomesh:
        # triangulation_topomesh.update_wisp_property('layer',0,cell_layer)
        # return cell_layer, triangulation_topomesh, surface_topomesh
        return cell_layer, top_surface_topomesh
    else:
        return cell_layer
def cell_topomesh(input_topomesh, cells=None, copy_properties=False):
    from time import time
    start_time = time()

    #topomesh = PropertyTopomesh(topomesh=input_topomesh)
    topomesh = PropertyTopomesh(3)

    if cells is None:
        cells = set(topomesh.wisps(3))
    else:
        cells = set(cells)

    faces = set()
    for c in cells:
        topomesh._borders[3][c] = deepcopy(input_topomesh._borders[3][c])
        faces = faces.union(set(topomesh._borders[3][c]))

    edges = set()
    for f in faces:
        topomesh._borders[2][f] = deepcopy(input_topomesh._borders[2][f])
        topomesh._regions[2][f] = deepcopy(list(set(input_topomesh._regions[2][f]).intersection(cells)))
        edges = edges.union(set(topomesh._borders[2][f]))

    vertices = set()
    for e in edges:
        topomesh._borders[1][e] = deepcopy(input_topomesh._borders[1][e])
        topomesh._regions[1][e] = deepcopy(list(set(input_topomesh._regions[1][e]).intersection(faces)))
        vertices = vertices.union(set(topomesh._borders[1][e]))

    for v in vertices:
        topomesh._regions[0][v] = deepcopy(list(set(input_topomesh._regions[0][v]).intersection(edges)))


    if copy_properties:
        for degree in xrange(4):
            for property_name in input_topomesh.wisp_property_names(degree):
                input_property = input_topomesh.wisp_property(property_name,degree)
                property_keys = np.intersect1d(input_property.keys(),list(topomesh.wisps(degree)))
                if len(property_keys)>0:
                    topomesh.update_wisp_property(property_name,degree,array_dict(input_topomesh.wisp_property(property_name,degree).values(property_keys),property_keys))

    topomesh.update_wisp_property('barycenter',0,array_dict(input_topomesh.wisp_property('barycenter',0).values(list(vertices)),list(vertices)))

    # cells_to_remove = [c for c in topomesh.wisps(3) if not c in cells]
    # cells_to_remove = list(set(topomesh.wisps(3)).difference(set(cells)))

    # for c in cells_to_remove:
    #     topomesh.remove_wisp(3,c)

    # faces_to_remove = [w for w in topomesh.wisps(2) if topomesh.nb_regions(2,w)==0]
    # for w in faces_to_remove:
    #     topomesh.remove_wisp(2,w)

    # edges_to_remove = [w for w in topomesh.wisps(1) if topomesh.nb_regions(1,w)==0]
    # for w in edges_to_remove:
    #     topomesh.remove_wisp(1,w)
        
    # vertices_to_remove = [w for w in topomesh.wisps(0) if topomesh.nb_regions(0,w)==0]
    # for w in vertices_to_remove:
    #     topomesh.remove_wisp(0,w)

    end_time = time()
    #end_time = time()
    print "<-- Extracting cell topomesh     [",end_time-start_time,"s]"

    return topomesh
def surface_dual_topomesh(topomesh, vertex_placement='center', exterior_vertex=1, exterior_distance=0, face_positions=None, vertices_as_cells=None):
    if vertices_as_cells is None:
        vertices_as_cells = topomesh.nb_wisps(3) != 1

    dual_topomesh = PropertyTopomesh(3)

    for f in topomesh.wisps(2):
        dual_topomesh.add_wisp(0,f)

    for e in topomesh.wisps(1):
        dual_topomesh.add_wisp(1,e)
        for f in topomesh.regions(1,e):
            dual_topomesh.link(1,e,f)

    for v in topomesh.wisps(0):
        if v != exterior_vertex:
            dual_topomesh.add_wisp(2,v)
            for e in topomesh.regions(0,v):
                dual_topomesh.link(2,v,e)

            if vertices_as_cells:
                dual_topomesh.add_wisp(3,v)
                dual_topomesh.link(3,v,v)
            else:
                for c in topomesh.regions(0,v,3):
                    if not dual_topomesh.has_wisp(3,c):
                        dual_topomesh.add_wisp(3,c)
                    dual_topomesh.link(3,c,v)

    for degree in [0,1,2]:
        for property_name in topomesh.wisp_property_names(degree):
            dual_topomesh.update_wisp_property(property_name,2-degree,topomesh.wisp_property(property_name,degree))

    if vertices_as_cells:
        for property_name in topomesh.wisp_property_names(0):
            dual_topomesh.update_wisp_property(property_name,3,topomesh.wisp_property(property_name,0))
    else:
        for property_name in topomesh.wisp_property_names(3):
            dual_topomesh.update_wisp_property(property_name,3,topomesh.wisp_property(property_name,3))


    compute_topomesh_property(topomesh,'barycenter',2)
    face_centers = topomesh.wisp_property('barycenter',2)
    positions = topomesh.wisp_property('barycenter',0)

    if is_triangular(topomesh):
        compute_topomesh_property(topomesh,'vertices',2)
        triangle_ids = np.array(list(topomesh.wisps(2)))
        triangles = topomesh.wisp_property('vertices',2).values(triangle_ids)

        if exterior_vertex is not None:
            exterior_triangle_ids = triangle_ids[np.where(np.any(triangles==exterior_vertex,axis=1))]
            exterior_triangles = triangles[np.where(np.any(triangles==exterior_vertex,axis=1))]
            exterior_edges = [t[t!=exterior_vertex] for t in exterior_triangles]
            exterior_edge_ids = np.concatenate([[e for e in topomesh.borders(2,t) if not exterior_vertex in topomesh.borders(1,e)] for t in exterior_triangle_ids])
            exterior_edge_triangle_ids = np.concatenate([[t for t in topomesh.regions(1,e) if not exterior_vertex in topomesh.borders(2,t,2)] for e in exterior_edge_ids])

            triangle_ids = triangle_ids[np.where(np.all(triangles!=exterior_vertex,axis=1))]
            triangles = triangles[np.where(np.all(triangles!=exterior_vertex,axis=1))]
            
        else:
            exterior_triangles = []
            exterior_triangle_ids = []
            exterior_edges = []
            exterior_edge_triangle_ids = []
            exterior_centers = []

        if vertex_placement == 'voronoi':
            centers = triangle_geometric_features(triangles,positions,['circumscribed_circle_center'])[:,0]
        elif vertex_placement == 'projected_voronoi':
            centers = triangle_geometric_features(triangles,positions,['projected_circumscribed_circle_center'])[:,0]
        elif vertex_placement == 'center':
            centers = triangle_geometric_features(triangles,positions,['barycenter'])[:,0]

        if exterior_vertex is not None:
            exterior_edge_centers = positions.values(exterior_edges).mean(axis=1)
            exterior_face_centers = face_centers.values(exterior_edge_triangle_ids)
            exterior_face_dual_centers = array_dict(centers,triangle_ids).values(exterior_edge_triangle_ids)

            exterior_edge_vectors = np.sign(np.einsum("...ij,...ij->...i",exterior_face_centers-exterior_edge_centers,exterior_face_dual_centers-exterior_edge_centers))[:,np.newaxis]*(exterior_edge_centers-exterior_face_dual_centers)
            print exterior_edge_vectors
            exterior_edge_vectors = exterior_edge_vectors/np.linalg.norm(exterior_edge_vectors,axis=1)[:,np.newaxis]
            exterior_dual_distance = np.linalg.norm(exterior_face_dual_centers-exterior_edge_centers,axis=1)

            #exterior_centers = face_centers.values(exterior_edge_triangle_ids) + exterior_coef*(positions.values(exterior_edges).mean(axis=1)-face_centers.values(exterior_edge_triangle_ids))
            exterior_centers = exterior_face_dual_centers + np.maximum(exterior_distance-exterior_dual_distance,0)[:,np.newaxis]*exterior_edge_vectors

        print list(triangle_ids),list(exterior_triangle_ids)
        print list(topomesh.wisps(2))

        dual_topomesh.update_wisp_property('barycenter',0,array_dict(list(centers)+list(exterior_centers),list(triangle_ids)+list(exterior_triangle_ids)))
    else:
        dual_topomesh.update_wisp_property('barycenter',0,face_centers)

    edges_to_remove = [e for e in dual_topomesh.wisps(1) if dual_topomesh.nb_borders(1,e) != 2]
    for e in edges_to_remove:
        dual_topomesh.remove_wisp(1,e)

    return clean_topomesh(dual_topomesh)
예제 #36
0
                np.ones_like(edited_L1_points[:, 0]),
                np.zeros_like(non_L1_points[:, 0])
            ])))

    signal_values = {}
    for signal_name, compute_ratio in zip(signal_names, compute_ratios):
        signal_img = image_dict[signal_name]
        signal_img = SpatialImage(signal_img, voxelsize=vxs)
        ratio_img = reference_img if compute_ratio else np.ones_like(
            reference_img)
        ratio_img = SpatialImage(ratio_img, voxelsize=vxs)
        signal_values[signal_name] = compute_fluorescence_ratios(
            ratio_img, signal_img, edited_positions)

    edited_positions = array_dict(
        np.array(edited_positions.values()) * microscope_orientation,
        edited_positions.keys()).to_dict()

    edited_topomesh = vertex_topomesh(edited_positions)
    for signal_name in signal_names:
        edited_topomesh.update_wisp_property(signal_name, 0,
                                             signal_values[signal_name])

    edited_topomesh.update_wisp_property('layer', 0, edited_layer)

    topomesh_file = image_dirname + "/" + nomenclature_names[
        filename] + "/" + nomenclature_names[
            filename] + "_nuclei_detection_topomesh_corrected{}.ply".format(
                suffix)
    save_ply_property_topomesh(edited_topomesh,
                               topomesh_file,
def create_CGAL_topomesh(img, mesh_fineness=1.0):
    """
    """

    dirname = str(shared_data(openalea.cgal_meshing).parent.parent+'/')

    start_time = time()
    print "--> Input Image"

    img_graph = graph_from_image(img,spatio_temporal_properties=['volume','barycenter'],ignore_cells_at_stack_margins = False,property_as_real=False)
    img_labels = np.array(list(img_graph.vertices()))
    img_volumes = np.array([img_graph.vertex_property('volume')[v] for v in img_graph.vertices()])
    print "  --> ",img_labels.shape[0]," Objects, ", img_volumes[2:].mean()," microm3 per object"

    facet_distance = np.power(img_volumes[2:].mean(),1/3.)/(4.5*np.pi*mesh_fineness)
    print "  --> Facet Distance : ",facet_distance

    print "  --> Converting to 8bit"
    img_neighbors = np.array([list(img_graph.neighbors(v)) for v in img_graph.vertices()])

    count_labels = np.zeros(256)
    img_graph.add_vertex_property('8bit_labels')

    if img_labels.shape[0] < 255:
        for i,v in enumerate(img_graph.vertices()):
            img_graph.vertex_property('8bit_labels')[v] = i+2
    else:
        for v in img_graph.vertices():
            possible_labels = np.array([])
            select = 0
            while possible_labels.size == 0:
                possible_labels = set(np.arange(2,256))
                possible_labels = possible_labels.difference(set(np.where(count_labels>count_labels[2:].min()+select)[0]))
                #possible_labels = possible_labels.difference(set(np.where(count_labels>count_labels[2:].min()+1)[0]))
                neighbor_labels = set()
                for n in img_graph.neighbors(v):
                    try:
                        neighbor_label = {img_graph.vertex_property('8bit_labels')[n]}
                        for n2 in img_graph.neighbors(n):
                            if n2 != v:
                                try:
                                    neighbor_label = {img_graph.vertex_property('8bit_labels')[n2]}
                                except KeyError:
                                    neighbor_label = set()
                                    pass
                                neighbor_labels = neighbor_labels.union(neighbor_label)
                    except KeyError:
                        neighbor_label = set()
                        pass
                    neighbor_labels = neighbor_labels.union(neighbor_label)
                possible_labels = np.array(list(possible_labels.difference(neighbor_labels)),np.uint8)
                if possible_labels.size == 0:
                    select += 1
                    #print neighbor_labels
            new_label = possible_labels[np.random.randint(possible_labels.size)]
            img_graph.vertex_property('8bit_labels')[v] = new_label
            count_labels[new_label] += 1
            #print v, ' -> ', new_label

        new_labels = np.ones(img.max()+1,np.uint8)
        new_labels[img_labels] = np.array([img_graph.vertex_property('8bit_labels')[v] for v in img_graph.vertices()],np.uint8)

        if np.unique(new_labels).shape[0]<255:
            label_index = np.ones(256)
            label_index[np.unique(new_labels)] = np.arange(new_labels.shape[0])+1
            for v in img_graph.vertices():
                img_graph.vertex_property('8bit_labels')[v] = label_index[img_graph.vertex_property('8bit_labels')[v]]

    new_labels = np.ones(img.max()+1,np.uint8)
    #new_labels[img_labels] = np.array([img_graph.vertex_property('8bit_labels')[v] for v in img_graph.vertices()],np.uint8)
    for v in img_graph.vertices():
        new_labels[v] = img_graph.vertex_property('8bit_labels')[v]

    mod_img = np.array(new_labels[img],np.uint8)
    inrfile = dirname+"tmp/8bit_image.inr.gz"
    imsave(inrfile,SpatialImage(mod_img))

    end_time = time()
    print "<-- Input Image              [",end_time-start_time,"s]"

    facet_angle = 30.0
    facet_size = 40.0
    edge_ratio = 4.0
    cell_size = 60.0

    start_time = time()
    print "--> Building CGAL Mesh"

    outputfile = dirname+"tmp/CGAL_output_mesh.mesh"
    buildCGALMesh(inrfile,outputfile,facet_angle,facet_size,facet_distance,edge_ratio,cell_size)
    end_time = time()
    print "<-- Building CGAL Mesh       [",end_time-start_time,"s]"

    mesh = CGALMesh()
    mesh.createMesh(outputfile)

    start_time = time()
    print "--> Re-Indexing Components"
    mesh.components = np.unique(mesh.tri_subdomains)

    new_mesh = CGALMesh()
    new_mesh.createMesh(outputfile)
    new_mesh.tri_subdomains = np.ones_like(mesh.tri_subdomains)
    new_mesh.tetra_subdomains = np.ones_like(mesh.tetra_subdomains)

    new_mesh.tri_subdomains[np.where(mesh.tri_subdomains == mesh.components[0])] = 1
    new_mesh.tetra_subdomains[np.where(mesh.tetra_subdomains == mesh.components[0])] = 1

    for c in mesh.components[1:]:
        cell_labels = np.where(new_labels == c)[0]
        n_cells = cell_labels.size

        if  n_cells > 0:
            # print "  --> Component ",c," -> ",n_cells," Cells"
            cell_tetrahedra = mesh.tetrahedra[np.where(mesh.tetra_subdomains==c)]

            #if n_cells == 1:
            if False:
                print "  --> Component ",c," ->  1  Object (",n_cells," Cell) : ",cell_labels,"(",img_graph.vertex_property('8bit_labels')[cell_labels[0]],")"
                new_mesh.tetra_subdomains[np.where(mesh.tetra_subdomains == c)] = cell_labels[0]
                new_mesh.tri_subdomains[np.where(mesh.tri_subdomains == c)] = cell_labels[0]
            else:
                cell_tetrahedra_components = np.zeros(cell_tetrahedra.shape[0],int)
                tetrahedra_component_correspondance = {}

                tetra_centers = np.mean(mesh.vertices[cell_tetrahedra],axis=1)

                for t, tetra in enumerate(cell_tetrahedra):
                    if cell_tetrahedra_components[t] == 0:
                        neighbour_tetrahedra = np.unique(np.append(np.where(cell_tetrahedra==tetra[0])[0],np.append(np.where(cell_tetrahedra==tetra[1])[0],np.append(np.where(cell_tetrahedra==tetra[2])[0],np.where(cell_tetrahedra==tetra[3])[0]))))
                        if (cell_tetrahedra_components[neighbour_tetrahedra].max()>0):
                            neighbour_components = cell_tetrahedra_components[neighbour_tetrahedra][np.where(cell_tetrahedra_components[neighbour_tetrahedra]>0)]
                            min_component = np.array([tetrahedra_component_correspondance[component] for component in neighbour_components]).min()
                            for component in neighbour_components:
                                tetrahedra_component_correspondance[tetrahedra_component_correspondance[component]] = min_component
                                tetrahedra_component_correspondance[component] = min_component
                            cell_tetrahedra_components[neighbour_tetrahedra] = min_component
                        else:
                            tetrahedra_component_correspondance[cell_tetrahedra_components.max()+1] = int(cell_tetrahedra_components.max()+1)
                            cell_tetrahedra_components[neighbour_tetrahedra] = int(cell_tetrahedra_components.max()+1)

                for component in tetrahedra_component_correspondance:
                    label = component
                    while label != tetrahedra_component_correspondance[label]:
                        label = tetrahedra_component_correspondance[label]
                        tetrahedra_component_correspondance[component] = tetrahedra_component_correspondance[label]

                component_labels = np.unique([tetrahedra_component_correspondance[component] for component in cell_tetrahedra_components])
                n_objects = component_labels.size

                # if n_objects != n_cells:
                    # print tetrahedra_component_correspondance

                for component in tetrahedra_component_correspondance:
                    tetrahedra_component_correspondance[component] = np.where(component_labels == tetrahedra_component_correspondance[component])[0][0]

                for component in tetrahedra_component_correspondance:
                    cell_tetrahedra_components[np.where(cell_tetrahedra_components == component)] = tetrahedra_component_correspondance[component]

                tetrahedra_object_centers = np.zeros((n_objects,3))

                tetrahedra_object_centers[:,0] = nd.sum(tetra_centers[:,0],cell_tetrahedra_components,index=xrange(n_objects))/nd.sum(np.ones_like(cell_tetrahedra_components),cell_tetrahedra_components,index=xrange(n_objects))
                tetrahedra_object_centers[:,1] = nd.sum(tetra_centers[:,1],cell_tetrahedra_components,index=xrange(n_objects))/nd.sum(np.ones_like(cell_tetrahedra_components),cell_tetrahedra_components,index=xrange(n_objects))
                tetrahedra_object_centers[:,2] = nd.sum(tetra_centers[:,2],cell_tetrahedra_components,index=xrange(n_objects))/nd.sum(np.ones_like(cell_tetrahedra_components),cell_tetrahedra_components,index=xrange(n_objects))

                img_points = np.array([img_graph.vertex_property('barycenter')[v] for v in cell_labels])
                tetrahedra_labels = cell_labels[vq(tetrahedra_object_centers,img_points)[0]]

                # img_points = np.array([img_graph.vertex_property('barycenter')[v] for v in img_labels])
                # tetrahedra_labels = img_labels[vq(tetrahedra_object_centers,img_points)[0]]

                cell_triangles = mesh.triangles[np.where(mesh.tri_subdomains==c)]
                cell_triangles_components = np.array([np.unique(cell_tetrahedra_components[np.where(cell_tetrahedra==tri[0])[0]])[0] for tri in cell_triangles])

                print "  --> Component ",c," -> ",n_objects," Objects (",n_cells," Cells) : ",tetrahedra_labels

                new_mesh.tetra_subdomains[np.where(mesh.tetra_subdomains == c)] = tetrahedra_labels[cell_tetrahedra_components]
                new_mesh.tri_subdomains[np.where(mesh.tri_subdomains == c)] = tetrahedra_labels[cell_triangles_components]

    mesh.tri_subdomains = new_mesh.tri_subdomains
    mesh.tetra_subdomains = new_mesh.tetra_subdomains
            
    mesh.components = np.unique(mesh.tri_subdomains)
    print mesh.vertices.shape[0],"Vertices, ",mesh.triangles.shape[0],"Triangles, ",mesh.tetrahedra.shape[0],"Tetrahedra, ",mesh.components.shape[0]," Components"
    end_time = time()
    print "<-- Re-Indexing Components   [",end_time-start_time,"s]"
    mesh.saveCGALfile(outputfile)

    start_time = time()
    print "--> Creating Topomesh"
    mesh = CGALMesh()
    mesh.createMesh(outputfile)
    mesh.generatePropertyTopomesh()

    positions = array_dict(mesh.vertex_positions.values()*np.array(img.resolution),keys=list(mesh.topo_mesh.wisps(0)))
    compute_topomesh_property(mesh.topo_mesh,'barycenter',degree=0,positions=positions)
    
    end_time = time()
    print "<-- Creating Topomesh        [",end_time-start_time,"s]"

    return mesh.topo_mesh
예제 #38
0
def topomesh_to_vtk_polydata(topomesh,degree=2,positions=None,topomesh_center=None,coef=1):
    import numpy as np
    import vtk
    from time import time
    from openalea.container import array_dict

    if positions is None:
        positions = topomesh.wisp_property('barycenter',0)
        
    if topomesh_center is None:
        topomesh_center = np.mean(positions.values(),axis=0)
#        topomesh_center = np.array([0,0,0])
        print topomesh_center

    vtk_mesh = vtk.vtkPolyData()
    vtk_points = vtk.vtkPoints()
    vtk_edges = vtk.vtkCellArray()
    vtk_triangles = vtk.vtkCellArray()
    vtk_cells = vtk.vtkLongArray()

    start_time = time()
    print "--> Creating VTK PolyData"
    
    if degree == 3:
        for c in topomesh.wisps(3):
            cell_points = []
            cell_center = np.mean([positions[v] for v in topomesh.borders(3,c,3)],axis=0)
            for v in topomesh.borders(3,c,3):
                position = cell_center + coef*(positions[v]-cell_center) - topomesh_center
                position[np.where(np.abs(position)<.001)] =0.
                p = vtk_points.InsertNextPoint(position)
                cell_points.append(p)
            cell_points = array_dict(cell_points,list(topomesh.borders(3,c,3)))

            for t in topomesh.borders(3,c):
                poly = vtk_triangles.InsertNextCell(3)
                for v in topomesh.borders(2,t,2):
                    vtk_triangles.InsertCellPoint(cell_points[v])
                vtk_cells.InsertValue(poly,c)

    elif degree == 2:
        for t in topomesh.wisps(2):
            triangle_points = []
            triangle_center = np.mean([positions[v] for v in topomesh.borders(2,t,2)],axis=0)
            for v in topomesh.borders(2,t,2):
                position = triangle_center + coef*(positions[v]-triangle_center) - topomesh_center
                position[np.where(np.abs(position)<.001)] =0.
                p = vtk_points.InsertNextPoint(position)
                triangle_points.append(p)
            triangle_points = array_dict(triangle_points,list(topomesh.borders(2,t,2)))
            poly = vtk_triangles.InsertNextCell(3)
            for v in topomesh.borders(2,t,2):
                vtk_triangles.InsertCellPoint(triangle_points[v])
            vtk_cells.InsertValue(poly,list(topomesh.regions(2,t))[0])

    elif degree == 1:
        points = []
        for v in topomesh.wisps(0):
            position = positions[v]
            position[np.where(np.abs(position)<.001)] =0.
            p = vtk_points.InsertNextPoint(position)
            points.append(p)
        points = array_dict(points,list(topomesh.wisps(0)))

        for e in topomesh.wisps(1):
            # if topomesh.wisp_property('epidermis',1)[e]:
            # if True:
            if len(list(topomesh.regions(1,e))) > 2:
                c = vtk_edges.InsertNextCell(2)
                for v in topomesh.borders(1,e):
                    vtk_edges.InsertCellPoint(points[v])

    print"  --> Linking Mesh"
    vtk_mesh.SetPoints(vtk_points)
    vtk_mesh.SetPolys(vtk_triangles)
    vtk_mesh.SetLines(vtk_edges)
    vtk_mesh.GetCellData().SetScalars(vtk_cells)

    end_time = time()
    print "<-- Creating VTK PolyData      [",end_time-start_time,"s]"

    return vtk_mesh
예제 #39
0
def compute_topomesh_image(topomesh, img):

    image_start_time = time()
    print "<-- Computing topomesh image"

    polydata_img = np.ones_like(img)
        
    for c in list(topomesh.wisps(3)):
        if len(list(topomesh.borders(3,c))) > 0:
            polydata_start_time = time()
            sub_topomesh = cell_topomesh(topomesh,cells=[c]) 
            
            start_time = time()
            bounding_box = np.array([[0,polydata_img.shape[0]],[0,polydata_img.shape[1]],[0,polydata_img.shape[2]]])
            bounding_box[:,0] = np.floor(sub_topomesh.wisp_property('barycenter',0).values().min(axis=0)/np.array(img.resolution)).astype(int)-1
            bounding_box[:,0] = np.maximum(bounding_box[:,0],0)
            bounding_box[:,1] = np.ceil(sub_topomesh.wisp_property('barycenter',0).values().max(axis=0)/np.array(img.resolution)).astype(int)+1
            bounding_box[:,1] = np.minimum(bounding_box[:,1],np.array(img.shape)-1)
            
            sub_polydata_img = polydata_img[bounding_box[0,0]:bounding_box[0,1],bounding_box[1,0]:bounding_box[1,1],bounding_box[2,0]:bounding_box[2,1]]
            #world.add(sub_polydata_img,"topomesh_image",colormap='glasbey',alphamap='constant',bg_id=1,intensity_range=(0,1))

            reader = matrix_to_image_reader('sub_polydata_image',sub_polydata_img,sub_polydata_img.dtype)
            #reader = matrix_to_image_reader('polydata_image',polydata_img,polydata_img.dtype)

            end_time = time()
            print "  --> Extracting cell sub-image      [",end_time-start_time,"s]"

            start_time = time()
            topomesh_center = bounding_box[:,0]*np.array(img.resolution)
            positions = sub_topomesh.wisp_property('barycenter',0)
            
            polydata = vtk.vtkPolyData()
            vtk_points = vtk.vtkPoints()
            vtk_triangles = vtk.vtkCellArray()
            
            for t in sub_topomesh.wisps(2):
                triangle_points = []
                for v in sub_topomesh.borders(2,t,2):
                    p = vtk_points.InsertNextPoint(positions[v]-topomesh_center)
                    triangle_points.append(p)
                triangle_points = array_dict(triangle_points,list(sub_topomesh.borders(2,t,2)))
                poly = vtk_triangles.InsertNextCell(3)
                for v in sub_topomesh.borders(2,t,2):
                    vtk_triangles.InsertCellPoint(triangle_points[v])

            polydata.SetPoints(vtk_points)
            polydata.SetPolys(vtk_triangles)
            
            end_time = time()
            print "  --> Creating VTK PolyData      [",end_time-start_time,"s]"
            
            start_time = time()
            pol2stenc = vtk.vtkPolyDataToImageStencil()
            pol2stenc.SetTolerance(0)
            pol2stenc.SetOutputOrigin((0,0,0))
            #pol2stenc.SetOutputOrigin(tuple(-bounding_box[:,0]))
            pol2stenc.SetOutputSpacing(img.resolution)
            SetInput(pol2stenc,polydata)
            pol2stenc.Update()
            end_time = time()
            print "  --> Cell ",c," polydata stencil   [",end_time-start_time,"s]"
            
            start_time = time()
            imgstenc = vtk.vtkImageStencil()
            if vtk.VTK_MAJOR_VERSION <= 5:
                imgstenc.SetInput(reader.GetOutput())
                imgstenc.SetStencil(pol2stenc.GetOutput())
            else:
                imgstenc.SetInputData(reader.GetOutput())
                imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
            imgstenc.ReverseStencilOn()
            imgstenc.SetBackgroundValue(c)
            imgstenc.Update()
            end_time = time()
            print "  --> Cell ",c," image stencil   [",end_time-start_time,"s]"

            start_time = time()
            dim = tuple((bounding_box[:,1]-bounding_box[:,0])[::-1])
            array = np.ones(dim, img.dtype)
            export = vtk.vtkImageExport()
            export.SetInputConnection(imgstenc.GetOutputPort())
            export.Export(array)
            end_time = time()
            print "  --> Exporting image       [",end_time-start_time,"s]"
            
            start_time = time()
            array = np.transpose(array,(2,1,0))
            polydata_img[bounding_box[0,0]:bounding_box[0,1],bounding_box[1,0]:bounding_box[1,1],bounding_box[2,0]:bounding_box[2,1]] = array
            end_time = time()
            print "  --> Inserting cell sub-image       [",end_time-start_time,"s]"
            
            polydata_end_time = time()
            print "--> Inserting topomesh cell ",c,"   [",polydata_end_time-polydata_start_time,"s]"
        
    image_end_time = time()
    print "<-- Computing topomesh image   [",image_end_time-image_start_time,"s]"

    return polydata_img
예제 #40
0
def optimize_topomesh(input_topomesh,omega_forces={'regularization':0.00,'laplacian':1.0,'planarization':0.27,'epidermis_planarization':0.07},omega_regularization_max=None,iterations=20,edge_flip=False,**kwargs):
    """
    """

    topomesh = deepcopy(input_topomesh)

    preparation_start_time = time()
    # topomesh.update_wisp_property('barycenter',degree=0,values=initial_vertex_positions,keys=np.array(list(topomesh.wisps(0))))

    compute_topomesh_property(topomesh,'valence',degree=0)
    compute_topomesh_property(topomesh,'borders',degree=1)
    compute_topomesh_property(topomesh,'vertices',degree=1)
    compute_topomesh_property(topomesh,'vertices',degree=2)
    compute_topomesh_property(topomesh,'vertices',degree=3)

    compute_topomesh_property(topomesh,'cells',degree=2)
    compute_topomesh_property(topomesh,'cells',degree=1)
    compute_topomesh_property(topomesh,'cells',degree=0)

    compute_topomesh_property(topomesh,'length',degree=1)

    compute_topomesh_property(topomesh,'barycenter',degree=3)
    compute_topomesh_property(topomesh,'barycenter',degree=2)
    compute_topomesh_property(topomesh,'barycenter',degree=1)
    
    triangular_mesh = kwargs.get('triangular_mesh',True)
    if triangular_mesh:
        compute_topomesh_triangle_properties(topomesh)
        compute_topomesh_property(topomesh,'normal',degree=2)
        compute_topomesh_property(topomesh,'angles',degree=2)

    compute_topomesh_property(topomesh,'epidermis',degree=0)
    compute_topomesh_property(topomesh,'epidermis',degree=1)
    # compute_topomesh_property(topomesh,'epidermis',degree=3)

    if omega_forces.has_key('planarization'):
        start_time = time()
        print "--> Computing interfaces"
        for cid in topomesh.wisps(3):
            for n_cid in topomesh.border_neighbors(3,cid):
                if (n_cid<cid) and (not (n_cid,cid) in topomesh._interface[3].values()):
                    iid = topomesh._interface[3].add((n_cid,cid),None)
        end_time = time()
        print "<-- Computing interfaces[",end_time-start_time,"s]"

    preparation_end_time = time()
    print "--> Preparing topomesh     [",preparation_end_time-preparation_start_time,"s]"

    display = kwargs.get('display',False)
    if display:
        pass

    optimization_start_time = time()

    if omega_forces.has_key('regularization'):
    	if omega_regularization_max is None:
        	omega_regularization_max = omega_forces['regularization']

    gradient_derivatives = kwargs.get("gradient_derivatives",[])

    cell_vertex_motion = kwargs.get("cell_vertex_motion",False)
    if cell_vertex_motion:
        image_cell_vertex = deepcopy(kwargs.get("image_cell_vertex",{}))
        for v in image_cell_vertex.keys():
            image_cell_vertex[v] = image_cell_vertex[v]*np.array(kwargs.get("image_voxelsize",(1.0,1.0,1.0)))
            #image_cell_vertex[v] = image_cell_vertex[v]
    
        compute_topomesh_property(topomesh,'cells',degree=0)
        vertex_cell_neighbours = topomesh.wisp_property('cells',degree=0)

        epidermis_vertices = np.array(list(topomesh.wisps(0)))[np.where(topomesh.wisp_property('epidermis',degree=0).values())]

        start_time = time()
        print "--> Computing mesh cell vertices"
        mesh_cell_vertex = {}
        for v in topomesh.wisps(0):
            if len(vertex_cell_neighbours[v]) == 5:
                for k in xrange(5):
                    vertex_cell_labels = tuple([c for c in vertex_cell_neighbours[v]][:k])+tuple([c for c in vertex_cell_neighbours[v]][k+1:])
                    if not mesh_cell_vertex.has_key(vertex_cell_labels):
                        mesh_cell_vertex[vertex_cell_labels] = v
            if len(vertex_cell_neighbours[v]) == 4:
                vertex_cell_labels = tuple([c for c in vertex_cell_neighbours[v]])
                mesh_cell_vertex[vertex_cell_labels] = v
                if v in epidermis_vertices: 
                # and count_l1_cells(vertex_cell_neighbours[v]) == 4:
                    for k in xrange(4):
                        vertex_cell_labels = (1,) + tuple([c for c in vertex_cell_neighbours[v]][:k])+tuple([c for c in vertex_cell_neighbours[v]][k+1:])
                        if not mesh_cell_vertex.has_key(vertex_cell_labels):
                            mesh_cell_vertex[vertex_cell_labels] = v
            if (len(vertex_cell_neighbours[v]) == 3) and (v in epidermis_vertices):
            # and (count_l1_cells(vertex_cell_neighbours[v]) == 3): 
                vertex_cell_labels = (1,) + tuple([c for c in vertex_cell_neighbours[v]])
                mesh_cell_vertex[vertex_cell_labels] = v
        end_time = time()
        print "<-- Computing mesh cell vertices [",end_time-start_time,"s]"

        cell_vertex_matching = vq(np.sort(array_dict(image_cell_vertex).keys()),np.sort(array_dict(mesh_cell_vertex).keys()))

        matched_image_index = np.where(cell_vertex_matching[1] == 0)[0]
        matched_mesh_index = cell_vertex_matching[0][np.where(cell_vertex_matching[1] == 0)[0]]

        matched_image_cell_vertex = np.array(image_cell_vertex.values())[matched_image_index]
        matched_keys = np.sort(np.array(image_cell_vertex.keys()))[matched_image_index]

        matched_mesh_vertices = np.array(mesh_cell_vertex.values())[cell_vertex_matching[0][np.where(cell_vertex_matching[1] == 0)[0]]]
        matched_keys = np.sort(np.array(mesh_cell_vertex.keys()))[matched_mesh_index]

        initial_vertex_positions = array_dict(topomesh.wisp_property('barycenter',0).values(list(topomesh.wisps(0))),list(topomesh.wisps(0)))

        final_vertex_positions = array_dict()
        fixed_vertex = array_dict(np.array([False for v in topomesh.wisps(0)]),np.array(list(topomesh.wisps(0))))
        for i,v in enumerate(matched_mesh_vertices):
            if not np.isnan(matched_image_cell_vertex[i]).any():
                final_vertex_positions[v] = matched_image_cell_vertex[i]
                # print topomesh.wisp_property('barycenter',0)[v]," -> ",final_vertex_positions[v]
                fixed_vertex[v] = True
        matched_mesh_vertices = final_vertex_positions.keys()

    sigma_deformation_initial = kwargs.get("sigma_deformation",np.sqrt(3)/4.)
    sigma_deformation = sigma_deformation_initial*np.ones_like(np.array(list(topomesh.wisps(0))),float)

    if cell_vertex_motion:
        sigma_deformation[np.where(fixed_vertex.values())[0]] = 0.

    iterations_per_step = kwargs.get('iterations_per_step',1)

    for iteration in xrange(iterations/iterations_per_step+1):

        print "_____________________________"
        print ""
        print "       Iteration ",iteration
        print "_____________________________"
        start_time = time()
        
        gaussian_sigma = kwargs.get('gaussian_sigma',10.0)
        target_areas = kwargs.get('target_areas',None)

        property_topomesh_vertices_deformation(topomesh,iterations=iterations_per_step,omega_forces=omega_forces,sigma_deformation=sigma_deformation,gradient_derivatives=gradient_derivatives,voxelsize=kwargs.get("image_voxelsize",(1.0,1.0,1.0)),gaussian_sigma=gaussian_sigma,target_areas=target_areas)

        if cell_vertex_motion:
            vertex_start_time = time()
            print "--> Moving cell vertices"
            if iteration <= (iterations/iterations_per_step+1)/1.:
                #topomesh.update_wisp_property('barycenter',degree=0,values=((iterations/iterations_per_step+1-(iteration+1))*initial_vertex_positions.values(matched_mesh_vertices) + (iteration+1)*final_vertex_positions.values(matched_mesh_vertices))/(iterations/iterations_per_step+1),keys=matched_mesh_vertices,erase_property=False)
                for v in matched_mesh_vertices:
                    topomesh.wisp_property('barycenter',degree=0)[v] = ((iterations/iterations_per_step+1-(iteration+1))*initial_vertex_positions[v] + (iteration+1)*final_vertex_positions[v])/(iterations/iterations_per_step+1)
            vertex_end_time = time()
            print "<-- Moving cell vertices     [",vertex_end_time-vertex_start_time,"s]"

        compute_topomesh_property(topomesh,'length',degree=1)
        compute_topomesh_property(topomesh,'barycenter',degree=3)
        compute_topomesh_property(topomesh,'barycenter',degree=2)

        if triangular_mesh:
            compute_topomesh_triangle_properties(topomesh)
            compute_topomesh_property(topomesh,'normal',degree=2)

        if edge_flip:
            # property_topomesh_edge_flip_optimization(topomesh,omega_energies=omega_forces,simulated_annealing=True,iterations=15,display=display)
            property_topomesh_edge_flip_optimization(topomesh,omega_energies=omega_forces,simulated_annealing=False,iterations=3,display=display)

            compute_topomesh_property(topomesh,'length',degree=1)
            compute_topomesh_property(topomesh,'barycenter',degree=3)
            compute_topomesh_property(topomesh,'barycenter',degree=2)
            if triangular_mesh:
                compute_topomesh_triangle_properties(topomesh)
                compute_topomesh_property(topomesh,'normal',degree=2)

        sigma_deformation = sigma_deformation_initial*np.power(0.95,(iteration+1)*iterations_per_step)*np.ones_like(np.array(list(topomesh.wisps(0))),float)
        if cell_vertex_motion:
            sigma_deformation[np.where(fixed_vertex.values())[0]] = 0.

        if omega_forces.has_key('regularization'):
            omega_forces['regularization'] = np.minimum(omega_forces['regularization']+(omega_regularization_max*iterations_per_step)/iterations,omega_regularization_max)

        if display:
            pass
            
        end_time = time()
        print "_____________________________"
        print ""
        print "      [",end_time-start_time,"s]"
    #raw_input()
    print "_____________________________"

    optimization_end_time = time()
    print "--> Optimizing Topomesh    [",optimization_end_time - optimization_start_time,"s]"

    return topomesh
예제 #41
0
def nuclei_topomesh_curvature(topomesh,
                              surface_subdivision=1,
                              return_topomesh=False,
                              projection_center=None):
    L1_cells = topomesh.wisp_property(
        'layer', 0).keys()[topomesh.wisp_property('layer', 0).values() == 1]
    cell_barycenters = array_dict(
        topomesh.wisp_property('barycenter', 0).values(L1_cells), L1_cells)

    if projection_center is None:
        center = cell_barycenters.values().mean(axis=0)
        center[2] -= 2. * (cell_barycenters.values() -
                           cell_barycenters.values().mean(axis=0))[:, 2].max()
    else:
        center = np.array(projection_center)

    cell_vectors = cell_barycenters.values() - center
    cell_r = np.linalg.norm(cell_vectors, axis=1)
    cell_rx = np.linalg.norm(cell_vectors[:, np.array([0, 2])], axis=1)
    cell_ry = np.linalg.norm(cell_vectors[:, np.array([1, 2])], axis=1)

    cell_phi = np.sign(cell_vectors[:, 0]) * np.arccos(
        cell_vectors[:, 2] / cell_rx)
    cell_psi = np.sign(cell_vectors[:, 1]) * np.arccos(
        cell_vectors[:, 2] / cell_ry)

    cell_flat_barycenters = deepcopy(cell_barycenters)
    for i, c in enumerate(cell_barycenters.keys()):
        cell_flat_barycenters[c][0] = cell_phi[i]
        cell_flat_barycenters[c][1] = cell_psi[i]
        cell_flat_barycenters[c][2] = 0.

    triangles = np.array(cell_barycenters.keys())[delaunay_triangulation(
        np.array([cell_flat_barycenters[c] for c in cell_barycenters.keys()]))]
    cell_topomesh = triangle_topomesh(triangles, cell_barycenters)

    maximal_length = 15.

    compute_topomesh_property(cell_topomesh, 'length', 1)
    compute_topomesh_property(cell_topomesh, 'triangles', 1)

    boundary_edges = np.array(
        map(len,
            cell_topomesh.wisp_property('triangles', 1).values())) == 1
    distant_edges = cell_topomesh.wisp_property('length',
                                                1).values() > maximal_length
    edges_to_remove = np.array(list(cell_topomesh.wisps(1)))[boundary_edges
                                                             & distant_edges]

    while len(edges_to_remove) > 0:
        triangles_to_remove = np.concatenate(
            cell_topomesh.wisp_property('triangles',
                                        1).values(edges_to_remove))
        for t in triangles_to_remove:
            cell_topomesh.remove_wisp(2, t)

        clean_topomesh(cell_topomesh)

        compute_topomesh_property(cell_topomesh, 'triangles', 1)

        boundary_edges = np.array(
            map(len,
                cell_topomesh.wisp_property('triangles', 1).values())) == 1
        distant_edges = cell_topomesh.wisp_property(
            'length', 1).values() > maximal_length
        edges_to_remove = np.array(list(
            cell_topomesh.wisps(1)))[boundary_edges & distant_edges]

    cell_topomesh = topomesh_connected_components(cell_topomesh)[0]
    property_topomesh_vertices_deformation(cell_topomesh, iterations=5)

    for i in xrange(surface_subdivision):
        cell_topomesh = topomesh_triangle_split(cell_topomesh)
    compute_topomesh_property(cell_topomesh, 'vertices', 2)

    property_topomesh_vertices_deformation(cell_topomesh, iterations=15)

    compute_topomesh_property(cell_topomesh, 'barycenter', 2)
    compute_topomesh_property(cell_topomesh,
                              'normal',
                              2,
                              normal_method='orientation')

    compute_topomesh_vertex_property_from_faces(cell_topomesh,
                                                'normal',
                                                adjacency_sigma=2,
                                                neighborhood=5)
    compute_topomesh_property(cell_topomesh, 'mean_curvature', 2)
    compute_topomesh_vertex_property_from_faces(cell_topomesh,
                                                'mean_curvature',
                                                adjacency_sigma=2,
                                                neighborhood=5)
    compute_topomesh_vertex_property_from_faces(cell_topomesh,
                                                'gaussian_curvature',
                                                adjacency_sigma=2,
                                                neighborhood=5)

    cell_points = cell_barycenters.values()

    for curvature_property in ['mean_curvature', 'gaussian_curvature']:

        surface_curvature = cell_topomesh.wisp_property(
            curvature_property, 0).values(list(cell_topomesh.wisps(0)))

        cell_potential = np.array([
            nuclei_density_function(dict([
                (p, cell_topomesh.wisp_property('barycenter', 0)[p])
            ]),
                                    cell_radius=5,
                                    k=1.0)(cell_points[:, 0],
                                           cell_points[:, 1], cell_points[:,
                                                                          2])
            for p in cell_topomesh.wisps(0)
        ])
        cell_curvature = (cell_potential * surface_curvature[:, np.newaxis]
                          ).sum(axis=0) / cell_potential.sum(axis=0)
        cell_curvature = dict(zip(cell_barycenters.keys(), cell_curvature))
        topomesh.update_wisp_property(
            curvature_property, 0,
            array_dict([
                cell_curvature[c] if c in cell_barycenters.keys() else 0
                for c in topomesh.wisps(0)
            ], list(topomesh.wisps(0))))

    if return_topomesh:
        return cell_topomesh
    else:
        return
예제 #42
0
def link_polydata_triangle_cells(polydata,img,img_graph=None):
    if img_graph is None:
        from openalea.image.algo.graph_from_image   import graph_from_image
        img_graph = graph_from_image(img,spatio_temporal_properties=['barycenter','volume'],ignore_cells_at_stack_margins = False,property_as_real=True)

    polydata_cell_data = polydata.GetCellData().GetArray(0)

    start_time = time()
    print "    --> Listing points"
    polydata_points = np.array([polydata.GetPoints().GetPoint(i) for i in xrange(polydata.GetPoints().GetNumberOfPoints())])
    end_time = time()
    print "    <-- Listing points               [",end_time - start_time,"s]"

    start_time = time()
    print "    --> Merging points"
    point_ids = {}
    for p in xrange(polydata.GetPoints().GetNumberOfPoints()):
        point_ids[tuple(polydata_points[p])] = []
    for p in xrange(polydata.GetPoints().GetNumberOfPoints()):
        point_ids[tuple(polydata_points[p])] += [p]

    unique_points = array_unique(polydata_points)
    n_points = unique_points.shape[0]

    point_unique_id = {}
    for p in xrange(n_points):
        for i in point_ids[tuple(unique_points[p])]:
            point_unique_id[i] = p
    end_time = time()
    print "    <-- Merging points               [",end_time - start_time,"s]"

    triangle_cell_start_time = time()
    print "    --> Listing triangles"
    print "      - ",polydata.GetNumberOfCells()," triangles"
    polydata_triangles = np.sort([[polydata.GetCell(t).GetPointIds().GetId(i) for i in xrange(3)] for t in xrange(polydata.GetNumberOfCells())])   
    print "      - ",array_unique(polydata_triangles).shape[0]," unique triangles"
    # polydata_triangle_points = [polydata.GetCell(t).GetPointIds() for t in xrange(polydata.GetNumberOfCells())]
    # polydata_triangles = np.sort([[triangle_points.GetId(i) for i in xrange(3)] for triangle_points in polydata_triangle_points])   
    polydata_triangles = np.sort(array_dict(point_unique_id).values(polydata_triangles)) 
    print "      - ",array_unique(polydata_triangles).shape[0]," unique triangles (merged vertices)"
    triangle_cell_end_time = time()
    print "    <-- Listing triangles            [",triangle_cell_end_time - triangle_cell_start_time,"s]"
    raw_input()

    triangle_cell_start_time = time()
    print "    --> Initializing triangle cells"
    triangle_cells = {}
    for t in xrange(polydata.GetNumberOfCells()):
        triangle_cells[tuple(polydata_triangles[t])] = []  
        for i in xrange(10):
            if t == (i*polydata.GetNumberOfCells())/10:
                print "     --> Initializing triangle cells (",10*i,"%)"
    triangle_cell_end_time = time()
    print "    <-- Initializing triangle cells  [",triangle_cell_end_time - triangle_cell_start_time,"s]"

    triangle_cell_start_time = time()
    for t in xrange(polydata.GetNumberOfCells()):
        triangle_cells[tuple(polydata_triangles[t])] += list(polydata_cell_data.GetTuple(t))
        for i in xrange(100):
            if t == (i*polydata.GetNumberOfCells())/100:
                triangle_cell_end_time = time()
                print "     --> Listing triangle cells (",i,"%) [",(triangle_cell_end_time-triangle_cell_start_time)/(polydata.GetNumberOfCells()/100.),"s]"
                triangle_cell_start_time = time()

    triangle_cell_start_time = time()
    print "    --> Cleaning triangle cells"
    for t in xrange(polydata.GetNumberOfCells()):
        triangle_cells[tuple(polydata_triangles[t])] = np.unique(triangle_cells[tuple(polydata_triangles[t])])  
        for i in xrange(10):
            if t == (i*polydata.GetNumberOfCells())/10:
                print "     --> Cleaning triangle cells (",10*i,"%)"
    triangle_cell_end_time = time()
    print "    <-- Cleaning triangle cells      [",triangle_cell_end_time - triangle_cell_start_time,"s]"


    # triangle_cell_start_time = time()
    # print "    --> Listing triangle cells"
    # triangle_cell = np.array([polydata_cell_data.GetTuple(t)[0] for t in xrange(polydata.GetNumberOfCells())],np.uint16)
    # triangle_cell_end_time = time()
    # print "    <-- Listing triangle cells     [",triangle_cell_end_time - triangle_cell_start_time,"s]"

    # triangle_cells = {}
    # for t in xrange(polydata.GetNumberOfCells()):
    #     triangle_cells[t] = []

    # for c in considered_cells:
    #     cell_triangles = np.where(triangle_cell == c)[0]
    #     for t in cell_triangles:
    #         triangle_cells[t] += [c]
    #     print "    Cell ",c," : ",cell_triangles.shape[0]," triangles"
    #     neighbor_triangles = where_list(triangle_cell,list(img_graph.neighbors(c)))[0]
    #     neighbor_triangle_matching = vq(polydata_triangles[cell_triangles],polydata_triangles[neighbor_triangles])
    #     cell_double_triangles = neighbor_triangles[neighbor_triangle_matching[0][np.where(neighbor_triangle_matching[1]==0)[0]]]
    #     for t in cell_double_triangles:
    #         triangle_cells[t] += [c]

    # print triangle_cells.values()
    # raw_input()

    # unique_triangles,unique_triangle_rows = array_unique(polydata_triangles,return_index=True)
    # n_triangles = unique_triangles.shape[0]

    # triangle_unique = array_dict(np.arange(n_triangles),unique_triangle_rows)

    # triangle_id = (polydata_triangles * np.array([contour.GetOutput().GetPoints().GetNumberOfPoints(),1,1./contour.GetOutput().GetPoints().GetNumberOfPoints()])).sum(axis=1)
    # unique_triangle_id = (unique_triangles * np.array([contour.GetOutput().GetPoints().GetNumberOfPoints(),1,1./contour.GetOutput().GetPoints().GetNumberOfPoints()])).sum(axis=1)

    # triangle_number = nd.sum(np.ones_like(triangle_id),triangle_id,index=triangle_id)
    # double_triangle_rows = np.where(triangle_number==2)[0]
    # print "    ",double_triangle_rows.shape[0]," double triangles / ",contour.GetOutput().GetNumberOfCells()
    # double_triangles = polydata_triangles[double_triangle_rows]

    # unique_triangle_number = nd.sum(np.ones_like(triangle_id),triangle_id,index=unique_triangle_id)
    # double_unique_triangle_rows = np.where(unique_triangle_number==2)[0]
    # double_unique_triangles = unique_triangles[double_unique_triangle_rows]

    # triangle_triangle_matching = (vq(double_triangles,double_unique_triangles)[0])
    # triangle_triangle_matching = array_dict(double_unique_triangle_rows[triangle_triangle_matching],double_triangle_rows)

    # unique_triangle_cells = {}
    # for t in xrange(n_triangles):
    #     unique_triangle_cells[t] = []
    # for t in xrange(polydata.GetNumberOfCells()):
    #     if triangle_number[t] == 1:
    #         unique_triangle_cells[triangle_unique[t]] += list(polydata_cell_data.GetTuple(t))
    #     elif triangle_number[t] == 2:
    #         unique_triangle_cells[triangle_triangle_matching[t]] += list(polydata_cell_data.GetTuple(t))
    # triangle_cells = {}
    # for t in xrange(polydata.GetNumberOfCells()):
    #     if triangle_number[t] == 1:
    #         triangle_cells[t] = np.array(unique_triangle_cells[triangle_unique[t]],np.uint16)
    #     elif triangle_number[t] == 2:
    #         triangle_cells[t] = np.array(unique_triangle_cells[triangle_triangle_matching[t]],np.uint16)

    cell_data = vtk.vtkFloatArray()
    cell_data.SetNumberOfComponents(2)
    cell_data.SetNumberOfTuples(polydata.GetNumberOfCells())
    for t in xrange(polydata.GetNumberOfCells()):
        triangle_key = tuple(polydata_triangles[t])
        if len(triangle_cells[triangle_key]) == 2:
            cell_data.SetTuple(t,np.sort(triangle_cells[triangle_key]))
        else:
            cell_data.SetTuple(t,np.concatenate([triangle_cells[triangle_key],[1]]))
    polydata.GetCellData().SetScalars(cell_data)

    return triangle_cells
예제 #43
0
def up_facing_surface_topomesh(input_surface_topomesh,
                               normal_method='density',
                               nuclei_positions=None,
                               down_facing_threshold=-0.,
                               connected=True):

    assert (normal_method != 'density') or (nuclei_positions is not None)

    if nuclei_positions is not None:
        positions = array_dict(nuclei_positions)
    else:
        positions = None

    surface_topomesh = deepcopy(input_surface_topomesh)

    compute_topomesh_property(surface_topomesh,
                              'normal',
                              2,
                              normal_method=normal_method,
                              object_positions=positions)
    compute_topomesh_vertex_property_from_faces(surface_topomesh,
                                                'normal',
                                                weighting='area',
                                                adjacency_sigma=1.2,
                                                neighborhood=3)

    down_facing = surface_topomesh.wisp_property(
        'normal', 0).values()[:, 2] < down_facing_threshold
    surface_topomesh.update_wisp_property(
        'downward', 0,
        array_dict(down_facing, keys=list(surface_topomesh.wisps(0))))

    triangle_down_facing = np.any(surface_topomesh.wisp_property(
        'downward', 0).values(
            surface_topomesh.wisp_property('vertices', 2).values(
                list(surface_topomesh.wisps(2)))),
                                  axis=1)
    triangle_down_facing = triangle_down_facing.astype(float)
    surface_topomesh.update_wisp_property(
        'downward', 2,
        array_dict(triangle_down_facing, keys=list(surface_topomesh.wisps(2))))

    for i, t in enumerate(surface_topomesh.wisps(2)):
        if surface_topomesh.wisp_property('downward', 2)[t] == 1:
            triangle_neighbors = np.array(
                list(surface_topomesh.border_neighbors(2, t)), np.uint16)
            if np.any(
                    surface_topomesh.wisp_property('downward', 2).values(
                        triangle_neighbors) == 0):
                triangle_down_facing[i] = 0.5
    surface_topomesh.update_wisp_property(
        'downward', 2,
        array_dict(triangle_down_facing, keys=list(surface_topomesh.wisps(2))))

    triangles_to_remove = np.array(list(surface_topomesh.wisps(2)))[
        surface_topomesh.wisp_property('downward', 2).values() == 1]
    for t in triangles_to_remove:
        surface_topomesh.remove_wisp(2, t)

    edges_to_remove = np.array(list(surface_topomesh.wisps(1)))[np.array([
        surface_topomesh.nb_regions(1, e) == 0
        for e in surface_topomesh.wisps(1)
    ])]
    for e in edges_to_remove:
        surface_topomesh.remove_wisp(1, e)

    vertices_to_remove = np.array(list(surface_topomesh.wisps(0)))[np.array([
        surface_topomesh.nb_regions(0, v) == 0
        for v in surface_topomesh.wisps(0)
    ])]
    for v in vertices_to_remove:
        surface_topomesh.remove_wisp(0, v)

    #top_surface_topomesh = cut_surface_topomesh(surface_topomesh,z_cut=0.8*size[2]*voxelsize[2])
    if connected:
        top_surface_topomesh = topomesh_connected_components(
            surface_topomesh)[0]
    else:
        top_surface_topomesh = surface_topomesh

    return top_surface_topomesh
예제 #44
0
def evaluate_positions_detection(vertex_topomesh, ground_truth_topomesh,
                              max_matching_distance=3.0, outlying_distance=5.0,
                              max_distance=100.):
    """

    Parameters
    ----------
    vertex_topomesh : topomesh
        a topomesh with nuclei/seed coordinates (require wisp_property
        'barycenter') to compare to a ground truth
    ground_truth_topomesh : topomesh
        a topomesh with expertised nuclei/seed coordinates (require
        wisp_property 'barycenter') to be used as reference for evaluation
    max_matching_distance : float

    outlying_distance : float, optional

    max_distance : float, optional


    Returns
    -------
    dictionary of indicators (after matching) such as:
        'True Positive':
        'False Negative':
        'False Positive':
        'Precision':
        'Recall':
        'Jaccard':
        'Dice':

    Notes
    -----
    Requires the Hungarian library : https://github.com/hrldcpr/hungarian
    """
    nuc_ids = vertex_topomesh.wisp_property('barycenter', 0).keys()
    nuc_coords = vertex_topomesh.wisp_property('barycenter', 0).values()
    grt_coords = ground_truth_topomesh.wisp_property('barycenter', 0).values()

    segmentation_ground_truth_matching = vq(nuc_coords, grt_coords)
    ground_truth_segmentation_complete_matching = np.array([vq(nuc_coords, np.array([p]))[1] for p in grt_coords])

    segmentation_outliers = array_dict(segmentation_ground_truth_matching[1] > outlying_distance + 1, nuc_ids)

    cost_matrix = deepcopy(ground_truth_segmentation_complete_matching)
    if cost_matrix.shape[0] < cost_matrix.shape[1]:
        cost_matrix = np.concatenate([cost_matrix, np.ones((cost_matrix.shape[1] - cost_matrix.shape[0], cost_matrix.shape[1])) * max_distance])
    elif cost_matrix.shape[1] < cost_matrix.shape[0]:
        cost_matrix = np.concatenate([cost_matrix, np.ones((cost_matrix.shape[0], cost_matrix.shape[0] - cost_matrix.shape[1])) * max_distance], axis=1)

    cost_matrix[cost_matrix > outlying_distance] = max_distance

    initial_cost_matrix = deepcopy(cost_matrix)

    start_time = time()
    print "--> Hungarian assignment..."
    assignment = lap(cost_matrix)
    end_time = time()
    print "<-- Hungarian assignment     [", end_time - start_time, "s]"

    ground_truth_assignment = np.arange(ground_truth_topomesh.nb_wisps(0))
    segmentation_assignment = assignment[0][:ground_truth_topomesh.nb_wisps(0)]
    assignment_distances = initial_cost_matrix[
        (ground_truth_assignment, segmentation_assignment)]
    # print "Assignment : ",assignment_distances.mean()

    evaluation = {}
    evaluation['True Positive'] = (assignment_distances < max_matching_distance).sum()
    evaluation['False Negative'] = (assignment_distances >= max_matching_distance).sum()
    evaluation['False Positive'] = vertex_topomesh.nb_wisps(0) - segmentation_outliers.values().sum() - evaluation['True Positive']

    evaluation['Precision'] = evaluation['True Positive'] / float(evaluation['True Positive'] + evaluation['False Positive']) if evaluation['True Positive'] + evaluation['False Positive'] > 0 else 100.
    evaluation['Recall'] = evaluation['True Positive'] / float(evaluation['True Positive'] + evaluation['False Negative'])
    evaluation['Jaccard'] = evaluation['True Positive'] / float(evaluation['True Positive'] + evaluation['False Positive'] + evaluation['False Negative'])
    evaluation['Dice'] = 2. * evaluation['True Positive'] / float(2. * evaluation['True Positive'] + evaluation['False Positive'] + evaluation['False Negative'])

    print "Precision ", np.round(100. * evaluation['Precision'], 2), "%, Recall ", np.round(100. * evaluation['Recall'], 2), "%"

    return evaluation
예제 #45
0
def image_to_vtk_polydata(img,considered_cells=None,mesh_center=None,coef=1.0,mesh_fineness=1.0):
    start_time = time()
    print "--> Generating vtk mesh from image"

    vtk_mesh = vtk.vtkPolyData()
    vtk_points = vtk.vtkPoints()
    vtk_triangles = vtk.vtkCellArray()
    vtk_cells = vtk.vtkLongArray()
    
    nx, ny, nz = img.shape
    data_string = img.tostring('F')

    reader = vtk.vtkImageImport()
    reader.CopyImportVoidPointer(data_string, len(data_string))
    if img.dtype == np.uint8:
        reader.SetDataScalarTypeToUnsignedChar()
    else:
        reader.SetDataScalarTypeToUnsignedShort()
    reader.SetNumberOfScalarComponents(1)
    reader.SetDataExtent(0, nx - 1, 0, ny - 1, 0, nz - 1)
    reader.SetWholeExtent(0, nx - 1, 0, ny - 1, 0, nz - 1)
    reader.SetDataSpacing(*img.resolution)

    if considered_cells is None:
        considered_cells = np.unique(img)[1:]

    if mesh_center is None:
        mesh_center = np.array(img.resolution)*np.array(img.shape)/2.

    marching_cube_start_time = time()
    print "  --> Marching Cubes"
    contour = vtk.vtkDiscreteMarchingCubes()
    SetInput(contour,reader.GetOutput())
    contour.ComputeNormalsOn()
    contour.ComputeGradientsOn()
    contour.ComputeScalarsOn()
    for i,label in enumerate(considered_cells):
        contour.SetValue(i,label)
    contour.Update()
    marching_cube_end_time = time()
    print "  <-- Marching Cubes : ",contour.GetOutput().GetPoints().GetNumberOfPoints()," Points,",contour.GetOutput().GetNumberOfCells()," Triangles, ",len(np.unique(img)[1:])," Cells [",marching_cube_end_time - marching_cube_start_time,"s]"

    marching_cubes = contour.GetOutput()

    marching_cubes_cell_data = marching_cubes.GetCellData().GetArray(0)

    triangle_cell_start_time = time()
    print "    --> Listing triangles"
    print "      - ",marching_cubes.GetNumberOfCells()," triangles"
    marching_cubes_triangles = np.sort([[marching_cubes.GetCell(t).GetPointIds().GetId(i) for i in xrange(3)] for t in xrange(marching_cubes.GetNumberOfCells())])   
    triangle_cell_end_time = time()
    print "    <-- Listing triangles            [",triangle_cell_end_time - triangle_cell_start_time,"s]"

    triangle_cell_start_time = time()
    print "    --> Listing triangle cells"
    triangle_cell = np.array([marching_cubes_cell_data.GetTuple(t)[0] for t in xrange(marching_cubes.GetNumberOfCells())],np.uint16)
    triangle_cell_end_time = time()
    print "    <-- Listing triangle cells     [",triangle_cell_end_time - triangle_cell_start_time,"s]"

    triangle_cell_start_time = time()
    print "    --> Updating marching cubes mesh"
    vtk_mesh = vtk.vtkPolyData()
    vtk_points = vtk.vtkPoints()
    vtk_triangles = vtk.vtkCellArray()
    vtk_cells = vtk.vtkLongArray()

    for label in considered_cells:

        # cell_start_time = time()

        cell_marching_cubes_triangles = marching_cubes_triangles[np.where(triangle_cell == label)]

        marching_cubes_point_ids = np.unique(cell_marching_cubes_triangles)

        marching_cubes_points = np.array([marching_cubes.GetPoints().GetPoint(p) for p in marching_cubes_point_ids])
        marching_cubes_center = marching_cubes_points.mean(axis=0)
        marching_cubes_points = marching_cubes_center + coef*(marching_cubes_points-marching_cubes_center) - mesh_center

        cell_points = []
        for p in xrange(marching_cubes_points.shape[0]):
            pid = vtk_points.InsertNextPoint(marching_cubes_points[p])
            cell_points.append(pid)
        cell_points = array_dict(cell_points,marching_cubes_point_ids)

        for t in xrange(cell_marching_cubes_triangles.shape[0]):
            poly = vtk_triangles.InsertNextCell(3)
            for i in xrange(3):
                pid = cell_marching_cubes_triangles[t][i]
                vtk_triangles.InsertCellPoint(cell_points[pid])
            vtk_cells.InsertValue(poly,label)

        # cell_end_time = time()
        # print "  --> Cell",label,":",cell_marching_cubes_triangles.shape[0],"triangles [",cell_end_time-cell_start_time,"s]"

    vtk_mesh.SetPoints(vtk_points)
    vtk_mesh.SetPolys(vtk_triangles)
    vtk_mesh.GetCellData().SetScalars(vtk_cells)

    triangle_cell_end_time = time()
    print "    <-- Updating marching cubes mesh [",triangle_cell_end_time - triangle_cell_start_time,"s]"

    decimation_start_time = time()
    print "  --> Decimation"
    smoother = vtk.vtkWindowedSincPolyDataFilter()
    SetInput(smoother,vtk_mesh)
    smoother.SetFeatureAngle(30.0)
    smoother.SetPassBand(0.05)
    smoother.SetNumberOfIterations(25)
    smoother.NonManifoldSmoothingOn()
    smoother.NormalizeCoordinatesOn()
    smoother.Update()

    decimate = vtk.vtkQuadricClustering()
    SetInput(decimate,smoother.GetOutput())
    decimate.SetNumberOfDivisions(*tuple(mesh_fineness*np.array(np.array(img.shape)*np.array(img.resolution)/2.,np.uint16)))
    decimate.SetFeaturePointsAngle(30.0)
    decimate.CopyCellDataOn()
    decimate.Update()

    decimation_end_time = time()
    print "  <-- Decimation     : ",decimate.GetOutput().GetPoints().GetNumberOfPoints()," Points,",decimate.GetOutput().GetNumberOfCells()," Triangles, ",len(considered_cells)," Cells [",decimation_end_time - decimation_start_time,"s]"

    end_time = time()
    print "<-- Generating vtk mesh from image      [",end_time-start_time,"s]"

    return decimate.GetOutput()
    def update_graph_display(self, world_object, attribute):
        if world_object:

            graph = world_object.data

            if isinstance(graph, TemporalPropertyGraph):
                temporal = True
            else:
                temporal = False

            # labels = list(graph.vertices())

            if world_object['filter_property_name'] == "":
                labels = list(graph.vertices())
            else:
                filter_property = graph.vertex_property(
                    world_object['filter_property_name'])
                labels = [
                    v for v in filter_property.keys() if filter_property[v]
                ]

            labels = [
                v for v in labels
                if graph.vertex_property('barycenter').has_key(v)
            ]

            extent = np.transpose([
                np.array(
                    graph.vertex_property('barycenter').values()).min(axis=0),
                np.array(
                    graph.vertex_property('barycenter').values()).max(axis=0)
            ])
            for dim, axis in enumerate(['x', 'y', 'z']):
                dim_slice = [
                    extent[dim, 0] + s *
                    (extent[dim, 1] - extent[dim, 0]) / 100.
                    for s in world_object[axis + "_slice"]
                ]
                labels = [
                    v for v in labels if
                    graph.vertex_property('barycenter')[v][dim] >= dim_slice[0]
                ]
                labels = [
                    v for v in labels if
                    graph.vertex_property('barycenter')[v][dim] <= dim_slice[1]
                ]

            if temporal:
                if not world_object['all_time_points']:
                    time_point = world_object['time_point']
                    labels = [
                        v for v in labels
                        if graph.vertex_temporal_index(v) == time_point
                    ]

            # if world_object['cell_layer'] == 'L1':
            #     labels = sia.cell_first_layer()
            # elif world_object['cell_layer'] == 'L2':
            #     labels = sia.cell_second_layer()
            # else:
            #     labels = sia.labels()

            for element, element_plural in zip(['vertex', 'edge'],
                                               ['vertices', 'edges']):

                if 'display_' + element_plural in attribute[
                        'name'] or attribute['name'] in [
                            'filter_property_name', 'time_point', 'edge_type',
                            'all_time_points', 'time_offset'
                        ] or '_slice' in attribute['name']:
                    if world_object['display_' + element_plural]:
                        property_name = world_object[element +
                                                     '_property_name']

                        if temporal:
                            edge_type = world_object['edge_type']
                            time_offset = world_object['time_offset']
                            if not world_object['all_time_points']:
                                mesh = property_graph_to_triangular_mesh(
                                    graph,
                                    element,
                                    property_name,
                                    labels,
                                    edge_type=edge_type)
                            else:
                                mesh = property_graph_to_triangular_mesh(
                                    graph,
                                    element,
                                    property_name,
                                    labels,
                                    edge_type=edge_type,
                                    time_offset=time_offset *
                                    (extent[0, 1] - extent[0, 0]))
                        else:
                            mesh = property_graph_to_triangular_mesh(
                                graph, element, property_name, labels)

                        if self.world.has_key(world_object.name + "_" +
                                              element_plural):
                            kwargs = world_kwargs(
                                self.world[world_object.name + "_" +
                                           element_plural])
                        else:
                            kwargs = {}
                            kwargs['colormap'] = (
                                'glasbey' if element == 'vertex' else
                                'grey') if (property_name == '') else 'jet'

                        self._mesh[world_object.name][element] = mesh

                        self.world.add(
                            self._mesh[world_object.name][element],
                            world_object.name + "_" + element_plural, **kwargs)
                    else:
                        self.world.remove(world_object.name + "_" +
                                          element_plural)

                elif element + '_property_name' in attribute['name']:
                    if world_object['display_' + element_plural]:
                        property_name = world_object[element +
                                                     '_property_name']

                        if element == 'vertex':
                            if property_name in graph.vertex_property_names():

                                graph_property = graph.vertex_property(
                                    property_name)
                                property_data = array_dict(
                                    dict(
                                        zip(labels, [
                                            graph_property[l]
                                            if graph_property.has_key(l) else
                                            np.nan for l in labels
                                        ])))
                            else:
                                property_data = array_dict(
                                    dict(zip(labels, labels)))
                            self._mesh[world_object.name][
                                element].point_data = property_data
                        elif element == 'edge':
                            graph_edges = self._mesh[
                                world_object.name][element].edges.keys()
                            if property_name in graph.edge_property_names():
                                graph_property = graph.edge_property(
                                    property_name)
                                property_data = array_dict(
                                    dict(
                                        zip(graph_edges, [
                                            graph_property[e]
                                            if graph_property.has_key(e) else
                                            np.nan for e in graph_edges
                                        ])))
                            else:
                                property_data = array_dict({})
                            self._mesh[world_object.
                                       name][element].edge_data = property_data

                        self.world[world_object.name + "_" +
                                   element_plural].data = self._mesh[
                                       world_object.name][element]
                        if len(property_data) > 1:
                            self.world[world_object.name + "_" +
                                       element_plural].set_attribute(
                                           'intensity_range',
                                           (property_data.values().min(),
                                            property_data.values().max()))

                elif element + '_dataframe' in attribute['name']:
                    if world_object[element + '_dataframe']:

                        property_name = world_object[element +
                                                     '_property_name']

                        df = property_graph_to_dataframe(
                            graph, element, labels)
                        self.world.add(
                            df,
                            world_object.name + "_" + element + "_dataframe")
                        self.world[world_object.name + "_" + element +
                                   "_dataframe"].set_attribute(
                                       'X_variable', property_name)
                        self.world[world_object.name + "_" + element +
                                   "_dataframe"].set_attribute(
                                       'plot', 'cumulative')

                    else:
                        self.world.remove(world_object.name + "_" + element +
                                          "_dataframe")
예제 #47
0
def image_to_vtk_cell_polydata(img,considered_cells=None,mesh_center=None,coef=1.0,mesh_fineness=1.0,smooth_factor=1.0):

    start_time = time()
    print "--> Generating vtk mesh from image"

    vtk_mesh = vtk.vtkPolyData()
    vtk_points = vtk.vtkPoints()
    vtk_triangles = vtk.vtkCellArray()
    vtk_cells = vtk.vtkLongArray()
    
    nx, ny, nz = img.shape
    data_string = img.tostring('F')

    reader = vtk.vtkImageImport()
    reader.CopyImportVoidPointer(data_string, len(data_string))
    if img.dtype == np.uint8:
        reader.SetDataScalarTypeToUnsignedChar()
    else:
        reader.SetDataScalarTypeToUnsignedShort()
    reader.SetNumberOfScalarComponents(1)
    reader.SetDataExtent(0, nx - 1, 0, ny - 1, 0, nz - 1)
    reader.SetWholeExtent(0, nx - 1, 0, ny - 1, 0, nz - 1)
    reader.SetDataSpacing(*img.resolution)
    reader.Update()

    if considered_cells is None:
        considered_cells = np.unique(img)[1:]

    if mesh_center is None:
        #mesh_center = np.array(img.resolution)*np.array(img.shape)/2.
        mesh_center = np.array([0,0,0])

    for label in considered_cells:

        cell_start_time = time()

        cell_volume = (img==label).sum()*np.array(img.resolution).prod()

        # mask_data = vtk.vtkImageThreshold()
        # mask_data.SetInputConnection(reader.GetOutputPort())
        # mask_data.ThresholdBetween(label, label)
        # mask_data.ReplaceInOn()
        # mask_data.SetInValue(label)
        # mask_data.SetOutValue(0)
        contour = vtk.vtkDiscreteMarchingCubes()
        # contour.SetInput(mask_data.GetOutput())
        SetInput(contour,reader.GetOutput())
        contour.ComputeNormalsOn()
        contour.ComputeGradientsOn()
        contour.SetValue(0,label)
        contour.Update()

        # print "    --> Marching Cubes : ",contour.GetOutput().GetPoints().GetNumberOfPoints()," Points,",contour.GetOutput().GetNumberOfCells()," Triangles,  1 Cell"

        # decimate = vtk.vtkDecimatePro()
        # decimate.SetInputConnection(contour.GetOutputPort())
        # # decimate.SetTargetReduction(0.75)
        # decimate.SetTargetReduction(0.66)
        # # decimate.SetTargetReduction(0.5)
        # # decimate.SetMaximumError(2*np.sqrt(3))
        # decimate.Update()

        smooth_iterations = int(np.ceil(smooth_factor*8.))

        smoother = vtk.vtkWindowedSincPolyDataFilter()
        SetInput(smoother,contour.GetOutput())
        smoother.BoundarySmoothingOn()
        # smoother.BoundarySmoothingOff()
        smoother.FeatureEdgeSmoothingOn()
        # smoother.FeatureEdgeSmoothingOff()
        smoother.SetFeatureAngle(120.0)
        # smoother.SetPassBand(1)
        smoother.SetPassBand(0.01)
        smoother.SetNumberOfIterations(smooth_iterations)
        smoother.NonManifoldSmoothingOn()
        smoother.NormalizeCoordinatesOn()
        smoother.Update()

        divisions = int(np.ceil(np.power(cell_volume,1/3.)*mesh_fineness))

        decimate = vtk.vtkQuadricClustering()
        # decimate = vtk.vtkQuadricDecimation()
        # decimate = vtk.vtkDecimatePro()
        # decimate.SetInput(contour.GetOutput())
        SetInput(decimate,smoother.GetOutput())
        # decimate.SetTargetReduction(0.95)
        # decimate.AutoAdjustNumberOfDivisionsOff()
        decimate.SetNumberOfDivisions(divisions,divisions,divisions)
        decimate.SetFeaturePointsAngle(120.0)
        # decimate.AttributeErrorMetricOn()
        # decimate.ScalarsAttributeOn()
        # decimate.PreserveTopologyOn()
        # decimate.CopyCellDataOn()
        # decimate.SetMaximumCost(1.0)
        # decimate.SetMaximumCollapsedEdges(10000.0)
        decimate.Update()

        # print "    --> Decimation     : ",decimate.GetOutput().GetPoints().GetNumberOfPoints()," Points,",decimate.GetOutput().GetNumberOfCells()," Triangles,  1 Cell"

        cell_polydata = decimate.GetOutput()
        # cell_polydata = smoother.GetOutput()

        polydata_points = np.array([cell_polydata.GetPoints().GetPoint(p) for p in xrange(cell_polydata.GetPoints().GetNumberOfPoints())])
        polydata_center = polydata_points.mean(axis=0)
        polydata_points = polydata_center + coef*(polydata_points-polydata_center) - mesh_center

        cell_points = []
        for p in xrange(cell_polydata.GetPoints().GetNumberOfPoints()):
            pid = vtk_points.InsertNextPoint(polydata_points[p])
            cell_points.append(pid)
        cell_points = array_dict(cell_points,np.arange(cell_polydata.GetPoints().GetNumberOfPoints()))

        for t in xrange(cell_polydata.GetNumberOfCells()):
            poly = vtk_triangles.InsertNextCell(3)
            for i in xrange(3):
                pid = cell_polydata.GetCell(t).GetPointIds().GetId(i)
                vtk_triangles.InsertCellPoint(cell_points[pid])
                vtk_cells.InsertValue(poly,label)

        cell_end_time = time()
        print "  --> Cell",label,":",decimate.GetOutput().GetNumberOfCells(),"triangles (",cell_volume," microm3 ) [",cell_end_time-cell_start_time,"s]"

    vtk_mesh.SetPoints(vtk_points)
    vtk_mesh.SetPolys(vtk_triangles)
    vtk_mesh.GetCellData().SetScalars(vtk_cells)

    print "  <-- Cell Mesh      : ",vtk_mesh.GetPoints().GetNumberOfPoints()," Points,",vtk_mesh.GetNumberOfCells()," Triangles, ",len(considered_cells)," Cells"

    end_time = time()
    print "<-- Generating vtk mesh from image      [",end_time-start_time,"s]"

    return vtk_mesh
예제 #48
0
    def compute_image_property(self,
                               property_name,
                               min_contact_area=None,
                               sub_factor=8.):
        """
        """
        computable_properties = [
            'barycenter', 'volume', 'neighborhood_size', 'layer',
            'mean_curvature', 'gaussian_curvature'
        ]
        try:
            assert property_name in computable_properties
        except:
            print "Property \"" + property_name + "\" can not be computed on image"
            print "Try with one of the following :"
            for p in computable_properties:
                print "  * " + p
        else:
            if self._image is not None:
                if property_name in ['barycenter', 'volume']:
                    graph = graph_from_image(
                        self._image,
                        background=self.background,
                        spatio_temporal_properties=[property_name],
                        ignore_cells_at_stack_margins=self.
                        ignore_cells_at_stack_margins)
                    property_dict = graph.vertex_property(property_name)
                elif property_name == 'neighborhood_size':
                    neighbors = [
                        self.image_graph.neighbors(l) for l in self.labels
                    ]
                    property_dict = dict(zip(self.labels, map(len, neighbors)))
                elif property_name == 'layer':
                    if min_contact_area is None:
                        min_contact_area = self.min_contact_area
                    graph = graph_from_image(
                        self._image,
                        background=self.background,
                        spatio_temporal_properties=['L1'],
                        ignore_cells_at_stack_margins=self.
                        ignore_cells_at_stack_margins,
                        min_contact_area=min_contact_area)
                    first_layer = graph.vertex_property('L1')
                    second_layer_cells = [
                        v for v in graph.vertices()
                        if np.any([first_layer[n] for n in graph.neighbors(v)])
                        and not first_layer[v]
                    ]
                    second_layer = dict(
                        zip(list(graph.vertices()), [
                            v in second_layer_cells for v in graph.vertices()
                        ]))
                    property_dict = dict(
                        zip(self.labels, [
                            1
                            if first_layer[l] else 2 if second_layer[l] else 3
                            for l in self.labels
                        ]))
                elif property_name in ['mean_curvature', 'gaussian_curvature']:
                    if not self.has_image_property('barycenter'):
                        self.compute_image_property('barycenter')
                    if not self.has_image_property('layer'):
                        print "--> Computing layer property"
                        self.compute_image_property('layer')

                    cell_centers = self.image_property('barycenter')
                    L1_cells = self.labels[self.image_property(
                        'layer').values() == 1]

                    from openalea.cellcomplex.property_topomesh.utils.implicit_surfaces import implicit_surface_topomesh
                    from openalea.cellcomplex.property_topomesh.property_topomesh_analysis import compute_topomesh_property, compute_topomesh_vertex_property_from_faces
                    from openalea.cellcomplex.property_topomesh.property_topomesh_optimization import property_topomesh_vertices_deformation, topomesh_triangle_split

                    sub_binary_image = (self._image != self.background).astype(
                        float)[::sub_factor, ::sub_factor, ::sub_factor]
                    surface_topomesh = implicit_surface_topomesh(
                        sub_binary_image,
                        np.array(sub_binary_image.shape),
                        sub_factor * np.array(self._image.voxelsize),
                        center=False)
                    property_topomesh_vertices_deformation(surface_topomesh,
                                                           iterations=10)

                    compute_topomesh_property(surface_topomesh, 'barycenter',
                                              2)
                    compute_topomesh_property(surface_topomesh,
                                              'normal',
                                              2,
                                              normal_method='orientation')

                    compute_topomesh_vertex_property_from_faces(
                        surface_topomesh,
                        'normal',
                        adjacency_sigma=2,
                        neighborhood=5)
                    compute_topomesh_property(surface_topomesh,
                                              'mean_curvature', 2)
                    compute_topomesh_vertex_property_from_faces(
                        surface_topomesh,
                        property_name,
                        adjacency_sigma=2,
                        neighborhood=5)

                    surface_cells = L1_cells[vq(
                        surface_topomesh.wisp_property('barycenter',
                                                       0).values(),
                        cell_centers.values(L1_cells))[0]]
                    surface_topomesh.update_wisp_property(
                        'label', 0,
                        array_dict(surface_cells,
                                   list(surface_topomesh.wisps(0))))

                    L1_cell_property = nd.sum(surface_topomesh.wisp_property(
                        property_name, 0).values(),
                                              surface_cells,
                                              index=L1_cells) / nd.sum(
                                                  np.ones_like(surface_cells),
                                                  surface_cells,
                                                  index=L1_cells)
                    L1_cell_property = array_dict(L1_cell_property, L1_cells)
                    property_dict = array_dict([
                        L1_cell_property[l] if (l in L1_cells) and
                        (not np.isnan(L1_cell_property[l])) else 0
                        for l in self.labels
                    ], self.labels)

                property_data = [property_dict[l] for l in self.labels]
                self.update_image_property(property_name, property_data)
예제 #49
0
def nuclei_surface_topomesh(nuclei_topomesh,
                            size,
                            voxelsize,
                            cell_radius=5.0,
                            subsampling=6.,
                            density_k=0.25):

    nuclei_positions = nuclei_topomesh.wisp_property('barycenter', 0)

    from time import time
    start_time = time()

    size_offset = 0.25

    grid_voxelsize = np.sign(voxelsize) * subsampling
    #x,y,z = np.ogrid[0:size[0]*voxelsize[0]:grid_voxelsize[0],0:size[1]*voxelsize[1]:grid_voxelsize[1],0:size[2]*voxelsize[2]:grid_voxelsize[2]]
    #grid_size = size
    x, y, z = np.ogrid[-size_offset * size[0] *
                       voxelsize[0]:(1 + size_offset) * size[0] *
                       voxelsize[0]:grid_voxelsize[0], -size_offset * size[1] *
                       voxelsize[1]:(1 + size_offset) * size[1] *
                       voxelsize[1]:grid_voxelsize[1], -size_offset * size[2] *
                       voxelsize[2]:(1 + size_offset) * size[2] *
                       voxelsize[2]:grid_voxelsize[2]]
    grid_size = (1 + 2. * size_offset) * size

    end_time = time()
    print "--> Generating grid     [", end_time - start_time, "s]"

    start_time = time()
    nuclei_density = nuclei_density_function(nuclei_positions,
                                             cell_radius=cell_radius,
                                             k=density_k)(x, y, z)
    end_time = time()
    print "--> Computing density   [", end_time - start_time, "s]"

    start_time = time()
    surface_topomesh = implicit_surface_topomesh(nuclei_density,
                                                 grid_size,
                                                 voxelsize,
                                                 iso=0.5,
                                                 center=False)
    surface_topomesh.update_wisp_property(
        'barycenter', 0,
        array_dict(
            surface_topomesh.wisp_property('barycenter', 0).values() -
            size_offset * voxelsize * size,
            surface_topomesh.wisp_property('barycenter', 0).keys()))
    surface_topomesh = topomesh_triangle_split(surface_topomesh)
    property_topomesh_vertices_deformation(
        surface_topomesh,
        iterations=20,
        omega_forces=dict(taubin_smoothing=0.65),
        sigma_deformation=2.0)
    end_time = time()
    print "--> Generating topomesh [", end_time - start_time, "s]"

    start_time = time()
    surface_points = surface_topomesh.wisp_property('barycenter', 0).values()
    surface_density, surface_potential = nuclei_density_function(
        nuclei_positions, cell_radius=cell_radius,
        k=density_k)(surface_points[:, 0],
                     surface_points[:, 1],
                     surface_points[:, 2],
                     return_potential=True)
    surface_membership = np.transpose(
        surface_potential) / surface_density[:, np.newaxis]
    end_time = time()
    print "--> Computing surface membership [", end_time - start_time, "s]"

    start_time = time()
    # print np.argmax(surface_membership,axis=1).shape
    # print np.argmax(surface_membership,axis=0).shape
    # print nuclei_topomesh.nb_wisps(0)
    # print surface_topomesh.nb_wisps(0)

    surface_topomesh.update_wisp_property(
        'cell', 0,
        array_dict(
            np.array(nuclei_positions.keys())[np.argmax(surface_membership,
                                                        axis=1)],
            list(surface_topomesh.wisps(0))))
    for property_name in nuclei_topomesh.wisp_property_names(0):
        if not property_name in ['barycenter']:
            #if not property_name in []:
            if nuclei_topomesh.wisp_property(property_name,
                                             0).values().ndim == 1:
                # print (surface_membership*nuclei_topomesh.wisp_property(property_name,0).values()[np.newaxis,:]).sum(axis=1).shape
                surface_topomesh.update_wisp_property(
                    property_name, 0,
                    array_dict(
                        (surface_membership * nuclei_topomesh.wisp_property(
                            property_name, 0).values()[np.newaxis, :]).sum(
                                axis=1), list(surface_topomesh.wisps(0))))
            elif nuclei_topomesh.wisp_property(property_name,
                                               0).values().ndim == 2:
                surface_topomesh.update_wisp_property(
                    property_name, 0,
                    array_dict(
                        (surface_membership[:, :, np.newaxis] *
                         nuclei_topomesh.wisp_property(
                             property_name, 0).values()[np.newaxis, :]).sum(
                                 axis=1), list(surface_topomesh.wisps(0))))
    end_time = time()
    print "--> Updating properties [", end_time - start_time, "s]"

    return surface_topomesh
예제 #50
0
def sphere_tissue_image(size=100, n_points=12, n_layers=1):

    center = np.array([size / 2, size / 2, size / 2], float)

    coords = np.transpose(np.mgrid[0:size, 0:size, 0:size],
                          (1, 2, 3, 0)).reshape((np.power(size,
                                                          3), 3)).astype(int)
    coords_distances = np.linalg.norm(coords - center, axis=1)

    points = {}
    layer_img = {}

    for layer in xrange(n_layers):

        radius = (layer + 1) * size / float(2 * n_layers + 1)

        layer_n_points = n_points * np.power(layer + 1, 2)

        layer_points = {}

        for p in range(layer_n_points):
            theta = np.random.rand() * 2. * np.pi
            phi = np.random.rand() * np.pi - np.pi / 2.

            layer_points[p + np.power(layer, 2) * n_points +
                         3] = center + radius * np.array([
                             np.cos(theta) * np.cos(phi),
                             np.sin(theta) * np.cos(phi),
                             np.sin(phi)
                         ])
            layer_points = array_dict(layer_points)

            point_target_area = 4. * np.pi * np.power(
                radius, 2.) / float(layer_n_points)
            point_target_distance = np.power(point_target_area / np.pi, 0.5)

            sigma_deformation = (size / 100.) * (20. / layer_n_points)
            omega_forces = dict(distance=0.1 * size / 100.,
                                repulsion=100.0 * np.power(size / 100., 2))

            for iterations in xrange(100):
                point_vectors = np.array([
                    layer_points[p] - layer_points.values()
                    for p in layer_points.keys()
                ])
                point_distances = np.array([
                    vq(layer_points.values(), np.array([layer_points[p]]))[1]
                    for p in layer_points.keys()
                ])
                point_vectors = point_vectors / (
                    point_distances[..., np.newaxis] + 1e-7)

                point_distance_forces = omega_forces['distance'] * (
                    (point_distances - point_target_distance)[..., np.newaxis]
                    * point_vectors / point_target_distance).sum(axis=1)

                point_repulsion_forces = omega_forces['repulsion'] * np.power(
                    point_target_distance,
                    2) * (point_vectors / (np.power(point_distances, 2) +
                                           1e-7)[..., np.newaxis]).sum(axis=1)

                point_forces = np.zeros((len(layer_points), 3))
                point_forces += point_distance_forces
                point_forces += point_repulsion_forces

                point_forces = np.minimum(
                    1.0, sigma_deformation / np.linalg.norm(
                        point_forces, axis=1))[:, np.newaxis] * point_forces

                new_points = layer_points.values() + point_forces

                new_points = center + radius * (
                    (new_points - center) / np.linalg.norm(
                        (new_points - center), axis=1)[:, np.newaxis])

                layer_points = array_dict(new_points, layer_points.keys())

            for p in layer_points.keys():
                points[p] = layer_points[p]

            labels = layer_points.keys()[vq(coords, layer_points.values())[0]]

            layer_img[layer + 1] = np.ones((size, size, size), np.uint8)
            layer_img[layer + 1][tuple(np.transpose(coords))] = labels

    points[2] = center
    points = array_dict(points)

    # coords = np.transpose(np.mgrid[0:size,0:size,0:size],(1,2,3,0)).reshape((np.power(size,3),3)).astype(int)
    # labels = points.keys()[vq(coords,points.values())[0]]

    img = np.ones((size, size, size), np.uint8)

    for layer in xrange(n_layers):
        layer_coords = coords[
            (coords_distances > (2 * layer + 1) * size / float(4 *
                                                               (n_layers + 1)))
            & (coords_distances <=
               (2 * layer + 3) * size / float(4 * (n_layers + 1)))]
        img[tuple(np.transpose(layer_coords))] = layer_img[layer + 1][tuple(
            np.transpose(layer_coords))]

    center_coords = coords[coords_distances <= size / float(4 *
                                                            (n_layers + 1))]
    img[tuple(np.transpose(center_coords))] = 2

    ext_coords = coords[coords_distances > (n_layers + 1) * size /
                        float(2 * (n_layers + 2))]
    img[tuple(np.transpose(ext_coords))] = 1
    img = SpatialImage(img, voxelsize=(60. / size, 60. / size, 60. / size))

    return img
예제 #51
0
    def compute_image_adjacency(self):
        """Compute the adjacency relationships between cells in the tissue image.

        By default, the DRACO adjacency complex is set to the cell_vertices tetrahedra (!!NOT A VALID CELL COMPLEX!!)
        !!STRONG RISK OF TOPOLOGICAL ERRORS IF DUALIZING AT THIS STAGE!!

        Updates:
            image_graph (PropertyGraph): adjacency graph connecting adjacent cells by edges
            image_cell_vertex (dict): cell vertices representing 4 co-adjacent cells by the point where they meet
            cell_layer (int): information whether the cell belong to the first layer of cells (L1), the second one (L2) or lower layers (0)
            layer_edge_topomesh (PropertyTopomesh): adjacency graphs restricted to the L1 and L2 layers
            layer_triangle_topomesh (PropertyTopomesh): adjacency triangles between L1 and L2 layers (**TO BE COMPLETED**)
            triangulation_topomesh (PropertyTopomesh): the tetrahedra representing adjacencies between cells 

        Returns:
            None
        """

        self.image_graph = graph_from_image(
            self.segmented_image,
            spatio_temporal_properties=["volume", "barycenter", "L1"],
            ignore_cells_at_stack_margins=False,
            property_as_real=True,
        )
        self.image_labels = np.array(list(self.image_graph.vertices()))
        self.image_cell_volumes = array_dict(
            [self.image_graph.vertex_property("volume")[v] for v in self.image_labels], self.image_labels
        )
        img_center = np.nanmean(self.image_graph.vertex_property("barycenter").values(), axis=0)

        self.positions = array_dict(self.image_graph.vertex_property("barycenter"))
        self.point_topomesh = vertex_topomesh(self.positions)

        img_analysis = SpatialImageAnalysis(self.segmented_image)
        exterior_cells = np.array(list(img_analysis.neighbors(1)))
        self.image_wall_surfaces = img_analysis.wall_areas(real=True)

        self.image_graph.add_vertex(1)
        for c in exterior_cells:
            self.image_graph.add_edge(1, c)

        for v in self.image_cell_vertex.keys():
            self.image_cell_vertex[v] = self.image_cell_vertex[v] * self.resolution
        image_cell_vertex_tetrahedra = np.sort(self.image_cell_vertex.keys())
        image_cell_vertex_tetrahedra = np.delete(
            image_cell_vertex_tetrahedra, np.where(image_cell_vertex_tetrahedra[:, 0] == 1)[0], axis=0
        )
        self.image_cell_vertex_topomesh = tetrahedra_topomesh(image_cell_vertex_tetrahedra, self.positions)
        self.triangulation_topomesh = deepcopy(self.image_cell_vertex_topomesh)

        truncated_image = self.segmented_image[:, :, :]
        truncated_image_graph = graph_from_image(
            truncated_image,
            spatio_temporal_properties=["barycenter", "L1"],
            background=1,
            ignore_cells_at_stack_margins=True,
            property_as_real=True,
        )

        self.cell_layer = array_dict(np.zeros_like(self.positions.keys()), self.positions.keys())
        for c in truncated_image_graph.vertices():
            if c > 1 and truncated_image_graph.vertex_property("L1")[c]:
                self.cell_layer[c] = 1
        for c in self.cell_layer.keys():
            if c > 1 and self.cell_layer[c] == 1:
                for n in truncated_image_graph.neighbors(c):
                    if n > 1 and self.cell_layer[n] != 1:
                        self.cell_layer[n] = 2
        self.point_topomesh.update_wisp_property(
            "layer", 0, self.cell_layer.values(list(self.point_topomesh.wisps(0))), list(self.point_topomesh.wisps(0))
        )

        self.layer_edge_topomesh = {}

        if (self.cell_layer.values() == 1).sum() > 1:
            L1_edges = np.array(
                [
                    [(c, n) for n in self.image_graph.neighbors(c) if n > 1 and self.cell_layer[n] == 1]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] == 1
                ]
            )
            L1_edges = np.concatenate([e for e in L1_edges if len(e) > 0])
            L1_edges = L1_edges[L1_edges[:, 1] > L1_edges[:, 0]]
            L1_edge_topomesh = edge_topomesh(L1_edges, self.positions)
            self.layer_edge_topomesh["L1"] = L1_edge_topomesh

        if (self.cell_layer.values() == 2).sum() > 1:
            L2_edges = np.array(
                [
                    [(c, n) for n in self.image_graph.neighbors(c) if n > 1 and self.cell_layer[n] == 2]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] == 2
                ]
            )
            L2_edges = np.concatenate([e for e in L2_edges if len(e) > 0])
            L2_edges = L2_edges[L2_edges[:, 1] > L2_edges[:, 0]]
            L2_edge_topomesh = edge_topomesh(L2_edges, self.positions)
            self.layer_edge_topomesh["L2"] = L2_edge_topomesh

        self.layer_triangle_topomesh = {}

        if (self.cell_layer.values() == 1).sum() > 1 and (self.cell_layer.values() == 2).sum() > 1:
            L1_L2_edges = np.array(
                [
                    [(c, n) for n in self.image_graph.neighbors(c) if n > 1 and self.cell_layer[n] in [1, 2]]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] in [1, 2]
                ]
            )
            L1_L2_edges = np.concatenate([e for e in L1_L2_edges if len(e) > 0])
            L1_L2_edges = L1_L2_edges[L1_L2_edges[:, 1] > L1_L2_edges[:, 0]]

            L1_L2_additional_edges = np.array(
                [
                    [
                        (c, n)
                        for n in np.unique(
                            np.array(self.image_cell_vertex.keys())[
                                np.where(np.array(self.image_cell_vertex.keys()) == c)[0]
                            ]
                        )
                        if n > 1
                        and n != c
                        and (n not in self.image_graph.neighbors(c))
                        and (self.cell_layer[n] in [1, 2])
                    ]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] in [1, 2]
                ]
            )
            L1_L2_additional_edges = np.concatenate([e for e in L1_L2_additional_edges if len(e) > 0])
            L1_L2_additional_edges = L1_L2_additional_edges[L1_L2_additional_edges[:, 1] > L1_L2_additional_edges[:, 0]]

            self.layer_triangle_topomesh["L1_L2"] = triangle_topomesh(
                triangles_from_adjacency_edges(np.concatenate([L1_L2_edges, L1_L2_additional_edges])), self.positions
            )
예제 #52
0
def layered_tetrahedra_topomesh_construction(layer_triangle_topomesh, positions, cell_layer, omega_criteria = {'distance':1.0,'wall_surface':2.0,'clique':10.0}, **kwargs):
    compute_topomesh_property(layer_triangle_topomesh,'length',1)
    compute_topomesh_property(layer_triangle_topomesh,'borders',2)
    compute_topomesh_property(layer_triangle_topomesh,'perimeter',2)
    
    if omega_criteria.has_key('wall_surface'):
        img_wall_surfaces = kwargs.get('wall_surfaces',None)
        img_volumes = kwargs.get('cell_volumes',dict(zip(positions.keys(),np.ones_like(positions.keys()))))
        assert layer_triangle_topomesh.has_wisp_property('wall_surface',1) or img_wall_surfaces is not None
        if not layer_triangle_topomesh.has_wisp_property('wall_surface',1):
            L1_L2_triangle_edge_vertices = np.array([np.sort([list(layer_triangle_topomesh.borders(1,e)) for e in layer_triangle_topomesh.borders(2,t)]) for t in layer_triangle_topomesh.wisps(2)])
            L1_L2_triangle_edge_wall_surface = np.array([[-1. if tuple(e) not in img_wall_surfaces.keys() else img_wall_surfaces[tuple(e)]/np.power(img_volumes.values(e).mean(),2./3.) for e in t] for t in L1_L2_triangle_edge_vertices])
            layer_triangle_topomesh.update_wisp_property('wall_surface',2,array_dict(L1_L2_triangle_edge_wall_surface.min(axis=1),list(layer_triangle_topomesh.wisps(2))))
            layer_triangle_topomesh = layer_triangle_topomesh

    triangle_weights = np.zeros(layer_triangle_topomesh.nb_wisps(2))
    if omega_criteria.has_key('distance'):
        triangle_weights += omega_criteria['distance']*np.exp(-np.power(layer_triangle_topomesh.wisp_property('length',1).values(layer_triangle_topomesh.wisp_property('borders',2).values()).max(axis=1)/15.0,1))
    if omega_criteria.has_key('wall_surface'):
        triangle_weights += omega_criteria['wall_surface']*layer_triangle_topomesh.wisp_property('wall_surface',2).values() 
    triangle_weights = array_dict(triangle_weights,list(layer_triangle_topomesh.wisps(2)))
        
    triangle_neighbor_edges = [np.concatenate([list(set(layer_triangle_topomesh.region_neighbors(1,e)))+[e] for e in layer_triangle_topomesh.borders(2,t)]) for t in layer_triangle_topomesh.wisps(2)]
    triangle_neighbor_edge_triangles = [np.concatenate([list(layer_triangle_topomesh.regions(1,n_e)) for n_e in n_edges]) for n_edges in triangle_neighbor_edges]
    triangle_tetrahedra_triangles = [np.unique(t)[nd.sum(np.ones_like(t),t,index=np.unique(t))>5] for t in triangle_neighbor_edge_triangles]

    if omega_criteria.has_key('clique'):
        triangle_neighbor_weights = array_dict([triangle_weights.values(t).min() - omega_criteria['clique']*(len(t)-4) for t in triangle_tetrahedra_triangles],list(layer_triangle_topomesh.wisps(2)))
    else:
        triangle_neighbor_weights = array_dict([triangle_weights.values(t).min() for t in triangle_tetrahedra_triangles],list(layer_triangle_topomesh.wisps(2)))
    triangle_tetrahedra_triangles = array_dict(triangle_tetrahedra_triangles,list(layer_triangle_topomesh.wisps(2)))

    tetrahedrization_triangles = np.array(list(layer_triangle_topomesh.wisps(2)))[np.array(map(len,triangle_tetrahedra_triangles))>=4]
        
    constructed_triangulation_topomesh = PropertyTopomesh(3)
    initial_triangle = np.array(list(layer_triangle_topomesh.wisps(2)))[tetrahedrization_triangles][np.argmax(triangle_neighbor_weights.values(tetrahedrization_triangles))]
    free_triangles = [initial_triangle]

    while len(free_triangles) > 0:
        fid_to_add = free_triangles.pop(0)
        print "--> Triangle",list(layer_triangle_topomesh.borders(2,fid_to_add))," : ",triangle_neighbor_weights[fid_to_add]
        
        triangle_vertex_edges = np.concatenate([list(set(layer_triangle_topomesh.regions(0,c)).difference(set(layer_triangle_topomesh.borders(2,fid_to_add)))) for c in layer_triangle_topomesh.borders(2,fid_to_add,2)])
        triangle_vertex_edge_vertices = np.concatenate([c*np.ones(layer_triangle_topomesh.nb_regions(0,c)-2) for c in layer_triangle_topomesh.borders(2,fid_to_add,2)])
        triangle_vertex_edge_neighbor_vertices = np.array([list(set(layer_triangle_topomesh.borders(1,e)).difference({v}))[0] for e,v in zip(triangle_vertex_edges,triangle_vertex_edge_vertices)])

        candidate_tetra_vertices = np.unique(triangle_vertex_edge_neighbor_vertices)[nd.sum(np.ones_like(triangle_vertex_edge_neighbor_vertices),triangle_vertex_edge_neighbor_vertices,index=np.unique(triangle_vertex_edge_neighbor_vertices))==3]
        candidate_tetra_edges = np.array([triangle_vertex_edges[triangle_vertex_edge_neighbor_vertices==c] for c in candidate_tetra_vertices])
        
        candidate_tetra_edge_triangles = [np.concatenate([list(set(layer_triangle_topomesh.regions(1,e)).difference({fid_to_add})) for e in candidate_edges]) for candidate_edges in candidate_tetra_edges]
        candidate_tetra_triangles = np.array([np.concatenate([[fid_to_add],np.unique(t)[nd.sum(np.ones_like(t),t,index=np.unique(t))==2]]) for t in candidate_tetra_edge_triangles])
        
        if len(candidate_tetra_triangles)>0:
            candidate_tetra_free_triangles = np.array([np.sum([t in free_triangles for t in tetra_triangles]) for tetra_triangles in candidate_tetra_triangles])
            candidate_tetra_triangle_weights = triangle_weights.values(candidate_tetra_triangles[:,1:]).min(axis=1)
            
            if (candidate_tetra_free_triangles == candidate_tetra_free_triangles.max()).sum() == 1:
                sorted_candidate_tetra_triangles = candidate_tetra_triangles[np.argsort(-candidate_tetra_free_triangles)]
            else:
                sorted_candidate_tetra_triangles = candidate_tetra_triangles[np.argsort(-candidate_tetra_triangle_weights)]
            
            for tetra_triangles in sorted_candidate_tetra_triangles:
                if np.all(np.array([0 if not constructed_triangulation_topomesh.has_wisp(2,t) else constructed_triangulation_topomesh.nb_regions(2,t) for t in tetra_triangles])<2):
                    tetra_vertices = np.unique([list(layer_triangle_topomesh.borders(2,t,2)) for t in tetra_triangles])
                    tetra_edges = np.unique([list(layer_triangle_topomesh.borders(2,t)) for t in tetra_triangles])
                    if constructed_triangulation_topomesh.nb_wisps(3)!=1 or vq(np.sort([tetra_vertices]),np.sort([list(constructed_triangulation_topomesh.borders(3,t,3)) for t in constructed_triangulation_topomesh.wisps(3)]))[1][0]>0:
                        if len(np.unique(cell_layer.values(tetra_vertices)))==2:
                            #tetra_triangle_tetras = np.unique([list(constructed_triangulation_topomesh.regions(2,t)) for t in tetra_triangles if constructed_triangulation_topomesh.has_wisp(2,t)])
                            tetra_triangle_tetras = np.array(list(constructed_triangulation_topomesh.wisps(3)))
                            if len(tetra_triangle_tetras)>0:
                                tetra_triangle_tetra_edges = np.unique([list(constructed_triangulation_topomesh.borders(3,t,2)) for t in tetra_triangle_tetras])
                                tetra_triangle_points = positions.values(np.array([list(layer_triangle_topomesh.borders(2,t,2)) for t in tetra_triangles]))
                                tetra_triangle_tetra_edge_points = positions.values(np.array([list(layer_triangle_topomesh.borders(1,e)) for e in tetra_triangle_tetra_edges]))
                                tetra_triangle_intersection = np.ravel([intersecting_triangle(edge_points,tetra_triangle_points) for edge_points in tetra_triangle_tetra_edge_points])
                            
                                tetra_triangle_edges = np.unique([list(layer_triangle_topomesh.borders(2,t)) for t in tetra_triangles])
                                tetra_triangle_tetra_triangles = np.unique([list(constructed_triangulation_topomesh.borders(3,t)) for t in tetra_triangle_tetras])
                                tetra_triangle_edge_points = positions.values(np.array([list(layer_triangle_topomesh.borders(1,e)) for e in tetra_triangle_edges]))
                                tetra_triangle_tetra_triangle_points = positions.values(np.array([list(layer_triangle_topomesh.borders(2,t,2)) for t in tetra_triangle_tetra_triangles]))
                                tetra_edge_intersection = np.ravel([intersecting_triangle(edge_points,tetra_triangle_tetra_triangle_points) for edge_points in tetra_triangle_edge_points])
                                tetra_triangle_intersection = np.concatenate([tetra_triangle_intersection,tetra_edge_intersection])
                            else:
                                tetra_triangle_intersection = [False]
                            if not np.any(tetra_triangle_intersection):
                                tid = constructed_triangulation_topomesh.add_wisp(3)
                                print "  --> Tetrahedron",tid,tetra_vertices," : ", triangle_weights.values(tetra_triangles[1:]).min()
                                for c in tetra_vertices:
                                    if not constructed_triangulation_topomesh.has_wisp(0,c):
                                        constructed_triangulation_topomesh.add_wisp(0,c)
                                for e in tetra_edges:
                                    if not constructed_triangulation_topomesh.has_wisp(1,e):
                                        constructed_triangulation_topomesh.add_wisp(1,e)
                                        for c in layer_triangle_topomesh.borders(1,e):
                                            constructed_triangulation_topomesh.link(1,e,c)
                                for t in tetra_triangles:
                                    if not constructed_triangulation_topomesh.has_wisp(2,t):
                                        constructed_triangulation_topomesh.add_wisp(2,t)
                                        for e in layer_triangle_topomesh.borders(2,t):
                                            constructed_triangulation_topomesh.link(2,t,e)
                                    constructed_triangulation_topomesh.link(3,tid,t)
                                    
                                    if constructed_triangulation_topomesh.nb_regions(2,t)<2 and len(np.unique(cell_layer.values(list(constructed_triangulation_topomesh.borders(2,t,2)))))==2:
                                        if not t in free_triangles:
                                            free_triangles.append(t)
                                        
                                        triangle_future_tetra_triangles = list(set(triangle_tetrahedra_triangles[t]).difference(set(constructed_triangulation_topomesh.wisps(2)).difference(set(free_triangles))))
                                        
                                        if omega_criteria.has_key('clique'):
                                            triangle_neighbor_weights[t] = np.min(triangle_weights.values(triangle_future_tetra_triangles)) - omega_criteria['clique']*(len(triangle_future_tetra_triangles)-4)
                                        else:
                                            triangle_neighbor_weights[t] = np.min(triangle_weights.values(triangle_future_tetra_triangles))
        
        # print free_triangles
        if len(free_triangles)>0:
            free_triangles = list(np.array(free_triangles)[np.argsort(-triangle_neighbor_weights.values(free_triangles))])
        constructed_triangulation_topomesh.update_wisp_property('barycenter',0,array_dict(positions.values(list(constructed_triangulation_topomesh.wisps(0))),list(constructed_triangulation_topomesh.wisps(0))))

    return constructed_triangulation_topomesh
 vtx = list(expert_topomesh.wisps(0))
 if 0 in vtx or 1 in vtx:
     # --- Initialise relabelling dictionary:
     relabel = {v: v for v in vtx}
     # --- Change label values for 0 & 1:
     for label in [0, 1]:
         mk = max(relabel.values())
         relabel[label] = mk + 1
     # --- Create a temporary expert topomesh for label edition:
     expert_positions = expert_topomesh.wisp_property('barycenter', 0)
     expert_positions = {relabel[k]: v for k, v in expert_positions.items()}
     tmp_expert_topomesh = vertex_topomesh(expert_positions)
     # --- Relabel all existing properties:
     for ppty in expert_topomesh.wisp_property_names(0):
         ppty_dict = array_dict(expert_topomesh.wisp_property(
             ppty, 0).values(vtx),
                                keys=vtx)
         ppty_dict = {relabel[k]: v for k, v in ppty_dict.items()}
         tmp_expert_topomesh.update_wisp_property(ppty, 0, ppty_dict)
     try:
         assert tmp_expert_topomesh.has_wisp_property('layer', 0, True)
     except AssertionError:
         raise ValueError("Error during relabelling, please check!")
     else:
         expert_topomesh = tmp_expert_topomesh
 # -- Create a seed image from expertised seed positions:
 print "\n# - Creating seed image from EXPERT seed positions..."
 xp_seed_pos = expert_topomesh.wisp_property('barycenter', 0)
 xp_seed_pos = {
     k: v * microscope_orientation
     for k, v in xp_seed_pos.items()
예제 #54
0
def layer_triangle_topomesh_construction(layer_edge_topomesh, positions, omega_criteria = {'distance':1.0,'wall_surface':2.0,'clique':10.0}, **kwargs):

    compute_topomesh_property(layer_edge_topomesh,'length',1)

    edge_weights = np.zeros(layer_edge_topomesh.nb_wisps(1))
    if omega_criteria.has_key('distance'):
        edge_weights += omega_criteria['distance']*np.exp(-np.power(layer_edge_topomesh.wisp_property('length',1).values()/15.0,1))
    
    if omega_criteria.has_key('wall_surface'):
        img_wall_surfaces = kwargs.get('wall_surfaces',None)
        img_volumes = kwargs.get('cell_volumes',dict(zip(positions.keys(),np.ones_like(positions.keys()))))
        assert layer_edge_topomesh.has_wisp_property('wall_surface',1) or img_wall_surfaces is not None
        if not layer_edge_topomesh.has_wisp_property('wall_surface',1):
            layer_edge_vertices = np.sort([list(layer_edge_topomesh.borders(1,e)) for e in layer_edge_topomesh.wisps(1)])
            layer_edge_wall_surface = np.array([img_wall_surfaces[tuple(e)]/np.power(img_volumes.values(e).mean(),2./3.) for e in layer_edge_vertices])
            layer_edge_topomesh.update_wisp_property('wall_surface',1,array_dict(layer_edge_wall_surface,list(layer_edge_topomesh.wisps(1))))
        
        edge_weights += omega_criteria['wall_surface']*layer_edge_topomesh.wisp_property('wall_surface',1).values() 
    
    edge_weights = array_dict(edge_weights,list(layer_edge_topomesh.wisps(1)))
    
    edge_neighbor_vertices = [np.concatenate([list(set(layer_edge_topomesh.region_neighbors(0,c)))+[c] for c in layer_edge_topomesh.borders(1,e)]) for e in layer_edge_topomesh.wisps(1)]
    edge_neighbor_vertices_edges = [np.concatenate([list(layer_edge_topomesh.regions(0,n_v)) for n_v in n_vertices]) for n_vertices in edge_neighbor_vertices]
    edge_triangle_edges = [np.unique(e)[nd.sum(np.ones_like(e),e,index=np.unique(e))>3] for e in edge_neighbor_vertices_edges]
    
    if omega_criteria.has_key('clique'):
        edge_neighbor_weights = array_dict([edge_weights.values(e).min() - omega_criteria['clique']*(len(e)>3) for e in edge_triangle_edges],list(layer_edge_topomesh.wisps(1)))
    else:
        edge_neighbor_weights = array_dict([edge_weights.values(e).min() for e in edge_triangle_edges],list(layer_edge_topomesh.wisps(1)))
    edge_triangle_edges = array_dict(edge_triangle_edges,list(layer_edge_topomesh.wisps(1)))
    
    triangulation_edges = np.array(list(layer_edge_topomesh.wisps(1)))[np.array(map(len,edge_triangle_edges))>=3]
    
    layer_triangulation_topomesh = PropertyTopomesh(3)
    layer_triangulation_topomesh.add_wisp(3,1)
    
    initial_edge = np.array(list(layer_edge_topomesh.wisps(1)))[triangulation_edges][np.argmax(edge_neighbor_weights.values(triangulation_edges))]
    free_edges = [initial_edge]
        
    while len(free_edges) > 0:
        eid_to_add = free_edges.pop(0)
        print "--> Edge",list(layer_edge_topomesh.borders(1,eid_to_add))," : ",edge_neighbor_weights[eid_to_add]
        
        edge_vertex_edges = np.concatenate([list(set(layer_edge_topomesh.regions(0,c)).difference({eid_to_add})) for c in layer_edge_topomesh.borders(1,eid_to_add)])
        edge_vertex_edge_vertices =  np.concatenate([c*np.ones(layer_edge_topomesh.nb_regions(0,c)-1) for c in layer_edge_topomesh.borders(1,eid_to_add)])
        edge_vertex_edge_neighbor_vertices = np.array([list(set(layer_edge_topomesh.borders(1,e)).difference({v}))[0] for e,v in zip(edge_vertex_edges,edge_vertex_edge_vertices)])
    
        candidate_triangle_vertices = np.unique(edge_vertex_edge_neighbor_vertices)[nd.sum(np.ones_like(edge_vertex_edge_neighbor_vertices),edge_vertex_edge_neighbor_vertices,index=np.unique(edge_vertex_edge_neighbor_vertices))==2]
        candidate_triangle_edges = np.array([np.concatenate([[eid_to_add],edge_vertex_edges[edge_vertex_edge_neighbor_vertices==c]]) for c in candidate_triangle_vertices])
        
        if len(candidate_triangle_edges)>0:
            candidate_triangle_free_edges = np.array([np.sum([e in free_edges for e in triangle_edges]) for triangle_edges in candidate_triangle_edges])
            candidate_triangle_edge_weights = edge_weights.values(candidate_triangle_edges[:,1:]).min(axis=1)
            
            if (candidate_triangle_free_edges ==candidate_triangle_free_edges.max()).sum() == 1:
                sorted_candidate_triangle_edges = candidate_triangle_edges[np.argsort(-candidate_triangle_free_edges)]
            else:
                sorted_candidate_triangle_edges = candidate_triangle_edges[np.argsort(-candidate_triangle_edge_weights)]
            
            for triangle_edges in sorted_candidate_triangle_edges:
                if np.all(np.array([0 if not layer_triangulation_topomesh.has_wisp(1,e) else layer_triangulation_topomesh.nb_regions(1,e) for e in triangle_edges])<2):
                    triangle_vertices = np.unique([list(layer_edge_topomesh.borders(1,e)) for e in triangle_edges])
                    if layer_triangulation_topomesh.nb_wisps(2)!=1 or vq(np.sort([triangle_vertices]),np.sort([list(layer_triangulation_topomesh.borders(2,t,2)) for t in layer_triangulation_topomesh.wisps(2)]))[1][0]>0:
                        fid = layer_triangulation_topomesh.add_wisp(2)
                        layer_triangulation_topomesh.link(3,1,fid)
                        print "  --> Triangle",fid,triangle_vertices," : ",edge_weights.values(triangle_edges[1:]).min()
                        for c in triangle_vertices:
                            if not layer_triangulation_topomesh.has_wisp(0,c):
                                layer_triangulation_topomesh.add_wisp(0,c)
                        for e in triangle_edges:
                            if not layer_triangulation_topomesh.has_wisp(1,e):
                                layer_triangulation_topomesh.add_wisp(1,e)
                                for c in layer_edge_topomesh.borders(1,e):
                                    layer_triangulation_topomesh.link(1,e,c)
                            layer_triangulation_topomesh.link(2,fid,e)
                        
                            if layer_triangulation_topomesh.nb_regions(1,e)<2:
                                if not e in free_edges:
                                    free_edges.append(e)
                                edge_future_triangle_edges = list(set(edge_triangle_edges[e]).difference(set(layer_triangulation_topomesh.wisps(1)).difference(set(free_edges))))
                                
                                if omega_criteria.has_key('clique'):
                                    edge_neighbor_weights[e] = np.min(edge_weights.values(edge_future_triangle_edges)) - omega_criteria['clique']*(len(edge_future_triangle_edges)>3)
                                else:
                                    edge_neighbor_weights[e] = np.min(edge_weights.values(edge_future_triangle_edges))
            
            print free_edges
            if len(free_edges)>0:
                free_edges = list(np.array(free_edges)[np.argsort(-edge_neighbor_weights.values(free_edges))])                    
        layer_triangulation_topomesh.update_wisp_property('barycenter',0,array_dict(positions.values(list(layer_triangulation_topomesh.wisps(0))),list(layer_triangulation_topomesh.wisps(0))))
    return layer_triangulation_topomesh
def star_interface_topomesh(topomesh, inner_interfaces=True, verbose=False):
    from time import time

    triangle_edge_list  = np.array([[1, 2],[0, 2],[0, 1]])

    triangular_topomesh = PropertyTopomesh(3)
    triangle_vertex_positions = {}

    for v in topomesh.wisps(0):
        triangular_topomesh.add_wisp(0,v)
        triangle_vertex_positions[v] = topomesh.wisp_property('barycenter',0)[v]

    for e in topomesh.wisps(1):
        triangular_topomesh.add_wisp(1,e)
        for v in topomesh.borders(1,e):
            triangular_topomesh.link(1,e,v)

    for c in topomesh.wisps(3):
        triangular_topomesh.add_wisp(3,c)


    compute_topomesh_property(topomesh,'regions',2)
    compute_topomesh_property(topomesh,'edges',2)
    compute_topomesh_property(topomesh,'vertices',1)
    compute_topomesh_property(topomesh,'vertices',2)

    face_centers = {} 
    face_triangles = {}

    start_time = time()
    print "--> Triangulating Interfaces"
    for interface in topomesh.wisps(2):
        if interface%100 == 0:
            interface_start_time = time()

        if topomesh.nb_borders(2,interface)>0:
            interface_cells = topomesh.wisp_property('regions',2)[interface]
            interface_edges = topomesh.wisp_property('vertices',1).values(topomesh.wisp_property('edges',2)[interface])
            interface_vertices = np.unique(interface_edges)

            if (len(interface_vertices)>2) and (inner_interfaces or (len(interface_cells) == 1)):

                interface_positions = array_dict(topomesh.wisp_property('barycenter',0).values(interface_vertices),interface_vertices)
                interface_center = interface_positions.values().mean(axis=0)

                center_pid = triangular_topomesh.add_wisp(0)
                triangle_vertex_positions[center_pid] = interface_center

                face_centers[interface] = center_pid
                face_triangles[interface] = []

                vertex_center_edges = {}
                for v in interface_vertices:
                    eid = triangular_topomesh.add_wisp(1)
                    triangular_topomesh.link(1,eid,v)
                    triangular_topomesh.link(1,eid,center_pid)
                    vertex_center_edges[v] = eid

                for e in topomesh.borders(2,interface):
                    fid = triangular_topomesh.add_wisp(2)
                    face_triangles[interface] += [fid]
                    triangular_topomesh.link(2,fid,e)
                    for v in topomesh.borders(1,e):
                        triangular_topomesh.link(2,fid,vertex_center_edges[v])
                    for cid in interface_cells:
                        triangular_topomesh.link(3,cid,fid)

            if verbose:
                if interface%100 == 0:
                    interface_end_time = time()
                    # print "  --> Interface ",interface," / ",topomesh.nb_wisps(2),' ',interface_cells,'     [',interface_end_time-interface_start_time,'s]'
                    print "  --> Interface ",interface," / ",topomesh.nb_wisps(2),'     [',(interface_end_time-interface_start_time),'s]'
    end_time = time()

    # for property_name in topomesh.wisp_property_names(0):
    #     try:
    #         center_property = [topomesh.wisp_property(property_name,0).values(topomesh.wisp_property('vertices',2)[f]).mean(axis=0) for f in face_centers.keys()]
    #     except:
    #         center_property = [topomesh.wisp_property(property_name,0).values(topomesh.wisp_property('vertices',2)[f])[0] for f in face_centers.keys()]
    #     vertex_property = array_dict(list(topomesh.wisp_property(property_name,0).values(list(topomesh.wisps(0))))+center_property,list(topomesh.wisps(0))+[face_centers[f] for f in face_centers.keys()])
    #     triangular_topomesh.update_wisp_property(property_name,0,vertex_property)

    for property_name in topomesh.wisp_property_names(2):
        triangle_faces = np.concatenate([[f for t in face_triangles[f]] for f in face_triangles.keys()])
        triangle_keys = np.concatenate([face_triangles[f] for f in face_triangles.keys()])
        triangle_property = array_dict(topomesh.wisp_property(property_name,2).values(triangle_faces),triangle_keys)
        triangular_topomesh.update_wisp_property(property_name,2,triangle_property)


    for property_name in topomesh.wisp_property_names(3):
        triangular_topomesh.update_wisp_property(property_name,3,topomesh.wisp_property(property_name,3))


    print "--> Triangulating Interfaces  [",end_time-start_time,"s]"
    triangular_topomesh.update_wisp_property('barycenter',degree=0,values=triangle_vertex_positions)
    return triangular_topomesh
membrane_img = imread(membrane_image_filename)

mask_filename = image_dirname + "/" + nomenclature_names[
    filename] + "/" + nomenclature_names[filename] + "_mask.inr.gz"
mask_img = imread(mask_filename)
membrane_img[mask_img == 0] = 0

# world.add(membrane_img,'membrane_image',colormap='invert_grey')
#world['membrane_image']['intensity_range'] = (5000,30000)

topomesh_file = image_dirname + "/" + nomenclature_names[
    filename] + "/" + nomenclature_names[
        filename] + "_nuclei_detection_topomesh_corrected.ply"
topomesh = read_ply_property_topomesh(topomesh_file)
positions = topomesh.wisp_property('barycenter', 0)
positions = array_dict(microscope_orientation * positions.values(),
                       positions.keys())

# Create a seed image fro the nuclei barycenters:
seed_img = seed_image_from_points(membrane_img.shape,
                                  membrane_img.voxelsize,
                                  positions,
                                  background_label=0)

# Add the "background seed":
background_threshold = 2000.
smooth_img_bck = linearfilter(membrane_img,
                              param_str_2='-x 0 -y 0 -z 0 -sigma 3.0')
background_img = (smooth_img_bck < background_threshold).astype(np.uint16)
for it in xrange(10):
    background_img = morphology(
        background_img, param_str_2='-operation erosion -iterations 10')
예제 #57
0
def nuclei_image_topomesh(image_dict, reference_name='TagBFP', signal_names=['DIIV','CLV3'], compute_ratios=[True,False], microscope_orientation=1, radius_range=(0.8,1.4), threshold=1000, subsampling=4, surface_voxelsize=1, nuclei_sigma=2.0, compute_layer=True, surface_mode='image', compute_curvature=True, return_surface=False):
    """Compute a point cloud PropertyTopomesh with image nuclei.

    The function runs a nuclei detection on the reference channel of
    the image, and then computes the signal intensities from the other
    channels (ratiometric or not) for each detected point. Additionnally,
    it can estimate the first layer of cells and compute the curvature
    on the surface.


    Args:
        image_dict (dict):
            An SatialImage dictionary with channel names as keys.
        reference_name (str):
            The name of the channel containing nuclei marker.
        signal_names (list):
            A list of the channel names on which to quantify signal.
        compute_ratios (list):
            A list of booleans stating if signal is to be computed 
            as channel intensity (False) or as a ratio between channel
            intensity and reference channel intensity (True) for each
            channel name in signal_names argument.
        microscope_orientation (int):
            1 for an upright microscope, -1 for an inverted one, in
            order to estimate consistently the upper layer of cells.
        radius_range (tuple):
            A tuple of two lengths (in microns) corresponding to the 
            typical size of nuclei to be detected in the image.
        threshold (int):
            A response intensity threshold for the detection, to 
            eliminate weak local maxima of response intensity. 
        subsampling (int):
            A downsampling factor to make the region growing part of 
            the detection faster.
        nuclei_sigma (float):
            The standard deviation (in microns) of the gaussian kernel
            used to quantify the signals.
        compute_layer (bool):
            Whether to estimate the first layer of cells based on the
            point cloud geometry.
        compute_curvature (bool):
            Whether to estimate surface curvature on the epidermal 
            layer of cells (compute_layer must be set to True)

    Returns:
        topomesh (:class:`openaela.mesh.PropertyTopomesh`):
            A point cloud structure with properties defined for each
            quantified signal, cell layer (if compute_layer argument 
            is set to True) and mean and gaussian curvatures (if 
            compute_curvature argument is set to true)
    """

    try:
        assert isinstance(image_dict,dict)
    except:
        print "Image channels should be passed as a Python dictionary with channel names as keys"
        raise
    assert reference_name in image_dict.keys()
    assert np.all([s in image_dict.keys() for s in signal_names])
    assert len(compute_ratios)==len(signal_names)

    reference_img = image_dict[reference_name]
    size = np.array(reference_img.shape)
    voxelsize = microscope_orientation*np.array(reference_img.voxelsize)

    positions = nuclei_detection(reference_img, threshold=threshold, radius_range=radius_range, subsampling=subsampling, microscope_orientation=1)

    signal_values = {}
    for signal_name, compute_ratio in zip(signal_names,compute_ratios):
        signal_img = image_dict[signal_name]

        ratio_img = reference_img if compute_ratio else np.ones_like(reference_img)
        signal_values[signal_name] = compute_fluorescence_ratios(ratio_img,signal_img,positions)
        
    positions = array_dict(positions)
  

    positions = array_dict(positions.values()*microscope_orientation,positions.keys()).to_dict()
    topomesh = vertex_topomesh(positions)
    
    for signal_name in signal_names:
        topomesh.update_wisp_property(signal_name,0,signal_values[signal_name])
    
    # cell_layer, surface_topomesh = nuclei_layer(positions,reference_img,microscope_orientation=microscope_orientation,density_voxelsize=surface_voxelsize,return_topomesh=True) 
    cell_layer, surface_topomesh = nuclei_layer(positions,reference_img,microscope_orientation=microscope_orientation,density_voxelsize=surface_voxelsize,surface_mode=surface_mode,return_topomesh=True) 
    # cell_layer, surface_topomesh = nuclei_layer(positions,size,np.array(reference_img.voxelsize),return_topomesh=True) 
    topomesh.update_wisp_property('layer',0,cell_layer)

    compute_curvature = False
    if compute_curvature:
        triangulation_topomesh = nuclei_topomesh_curvature(topomesh,surface_subdivision=0,return_topomesh=True)

        from copy import deepcopy
        topomesh._borders[1] = deepcopy(triangulation_topomesh._borders[1])
        topomesh._regions[0] = deepcopy(triangulation_topomesh._regions[0])
        for v in cell_layer.keys():
            if not v in topomesh._regions[0]:
                topomesh._regions[0][v] = []
        topomesh._borders[2] = deepcopy(triangulation_topomesh._borders[2])
        topomesh._regions[1] = deepcopy(triangulation_topomesh._regions[1])
        for t in topomesh.wisps(2):
            topomesh._regions[2][t] = []
        topomesh.add_wisps(3,0)
        for t in topomesh.wisps(2):
            topomesh.link(3,0,t)

    if return_surface:
        return topomesh, surface_topomesh
    else:
        return topomesh
예제 #58
0
                                             voxelsize)
# ???
expert_coords = np.maximum(0, np.minimum(size - 1,
                                         expert_coords)).astype(np.uint16)
expert_coords = tuple(np.transpose(expert_coords))

## Mask application :
expert_mask_value = mask_img[expert_coords]
expert_cells_to_remove = expert_positions.keys()[expert_mask_value == 0]
for c in expert_cells_to_remove:
    expert_topomesh.remove_wisp(0, c)
for property_name in expert_topomesh.wisp_property_names(0):
    expert_topomesh.update_wisp_property(
        property_name, 0,
        array_dict(expert_topomesh.wisp_property(property_name, 0).values(
            list(expert_topomesh.wisps(0))),
                   keys=list(expert_topomesh.wisps(0))))

# world.add(expert_topomesh,"expert_seed")
# world["expert_seed"]["property_name_0"] = 'layer'
# world["expert_seed_vertices"]["polydata_colormap"] = load_colormaps()['Greens']

# - Filter L1-corrected seed (ground truth):
L1_expert_topomesh = deepcopy(expert_topomesh)
L1_expert_cells = np.array(list(L1_expert_topomesh.wisps(0)))[
    L1_expert_topomesh.wisp_property('layer', 0).values() == 1]
non_L1_expert_cells = [
    c for c in L1_expert_topomesh.wisps(0) if not c in L1_expert_cells
]
for c in non_L1_expert_cells:
    L1_expert_topomesh.remove_wisp(0, c)