示例#1
0
def create_edge_indices(positions):
    n = len(positions)
    nodes = np.arange(n)
    
    simplices = Delaunay(positions).simplices
    simplices.sort()
    edges = set()
    for s in simplices:
        edges |= set(itertools.combinations(s, 2))
    edges = np.array(list(edges))
    return edges
示例#2
0
def medialaxis(boundary):

    # Function:       medialaxis(boundary)
    # Description:    given sorted boundary points, outputs a matrix medial data: medial points, radii and triangles
    # Input:          bounday - a vector of sorted complex valued boundary points.
    # Output:         medialdata[m r triin] - m is the collection of points on the medial axis, r is the associated radii, and triin is the delaunay triangulation of the boundary corresponding to triangles entirely inside the boundary.

    if np.dot(np.squeeze(boundary.real - np.roll(boundary.real, -1)),
              np.squeeze(boundary.imag + np.roll(boundary.imag, -1))) > 0:
        boundary = np.flipud(boundary)

    coordinates = []
    for i in boundary:
        coordinates.append([int(i.real), int(i.imag)])

    points = np.array(coordinates)

    tri = Delaunay(points)
    # '''
    plt.triplot(points[:, 0], points[:, 1], tri.simplices)
    # plt.plot(points.real, points.imag, 'o')
    # plt.show()
    # '''
    tri = np.array(tri.simplices)
    tri.sort(axis=1)

    u = boundary[tri[:, 0]]
    v = boundary[tri[:, 1]]
    w = boundary[tri[:, 2]]
    dot = (u - w) * np.conj(v - w)

    m = (u + v + 1j * (u - v) * dot.real / dot.imag) / 2
    r = abs(u - m)

    inside = dot.imag > 0
    triin = tri[inside, :]
    m = m[inside]
    r = r[inside]

    plt.plot(m.real, m.imag, 'o')
    plt.show()

    result = []
    result.append(m)
    result.append(r)
    result.append(triin)

    return result
def adjacency(positions,
              em_indices,
              edges=None,
              direction_weight=False,
              em_weight=100.0,
              dbscan_weight=0.02,
              dbscan_eps=10):
    n = len(positions)
    nodes = np.arange(n)

    simplices = Delaunay(positions).simplices
    simplices.sort()
    edges = set()
    for s in simplices:
        edges |= set(itertools.combinations(s, 2))
    edges = np.array(list(edges))
    #     print('# of edges', len(edges))

    #     edges = np.vstack(np.triu_indices(n, k=1)).T

    dists = dist_metric(positions[edges[:, 0]], positions[edges[:, 1]])
    weights = dists
    #     print('distance weights', weights)
    if direction_weight:
        directions = direction_metric(edges, positions, dists)
        weights = directions * dists
#     print('directions', directions)

# create adjacency matrix where weights are nonzero
#     on_edges = np.where(weights != 0)
#     edges = edges[on_edges]
#     print('Fraction of edges turned on:', len(edges)/len(weights))
#     weights = weights[on_edges]

# this is only upper triangular
    A_upper_half = coo_matrix((weights, (edges[:, 0], edges[:, 1])),
                              shape=(n, n),
                              dtype=weights.dtype).tocsc()
    A_lower_half = coo_matrix((weights, (edges[:, 1], edges[:, 0])),
                              shape=(n, n),
                              dtype=weights.dtype).tocsc()
    A = A_upper_half + A_lower_half

    # add DBSCAN bias
    # closely attach EM primaries to their DBSCAN cluster, repulse different EM primary clusters
    clusters = DBSCAN(eps=dbscan_eps, min_samples=2).fit(positions).labels_
    primary_clusters = clusters[em_indices]
    dbscan_indices = []
    dbscan_weights = []
    for i in range(np.amax(clusters)):
        same_cluster = np.zeros(n)
        dbscan_filter = np.where(clusters == i)[0]
        if i in primary_clusters:
            # sparsely repulse all other primary clusters
            for j in primary_clusters:
                if j != i:
                    db_filter = np.where(clusters == j)[0]
                    sparse_indices = cartesian_product(db_filter,
                                                       dbscan_filter)
                    #                     print('sparse_indices', len(sparse_indices))
                    dbscan_indices.extend(sparse_indices)
                    dbscan_weights.extend(
                        len(sparse_indices) * [-1 * em_weight])
        indices = list(itertools.combinations(dbscan_filter, 2))
        dbscan_indices.extend(indices)
        dbscan_weights.extend(len(indices) * [dbscan_weight])
    dbscan_indices = np.array(dbscan_indices)
    dbscan_weights = np.array(dbscan_weights)
    if len(dbscan_weights) > 0:
        A += coo_matrix(
            (dbscan_weights, (dbscan_indices[:, 0], dbscan_indices[:, 1])),
            shape=(n, n),
            dtype=weights.dtype).tocsc()
        A += coo_matrix(
            (dbscan_weights, (dbscan_indices[:, 1], dbscan_indices[:, 0])),
            shape=(n, n),
            dtype=weights.dtype).tocsc()


#     print('DBSCAN processed')

#     indices = np.array(list(itertools.combinations(em_indices, 2)))
#     if len(indices) > 0:
#         D_vec = np.array(A.sum(axis=1)).flatten()
#         em_repulsion = -10.0 * np.ones(len(indices))
#         A += coo_matrix((em_repulsion, (indices[:, 0], indices[:, 1])), shape=(n, n), dtype=weights.dtype).tocsc()
#         A += coo_matrix((em_repulsion, (indices[:, 1], indices[:, 0])), shape=(n, n), dtype=weights.dtype).tocsc()

    D_vec = np.abs(np.array(A.sum(axis=1)).flatten())
    D_norm_vec = 1 / np.sqrt(D_vec)
    D = diags(D_vec)
    D_norm = diags(D_norm_vec)

    A_norm = D_norm * A * D_norm
    #     print('A normalized')

    return A_norm