Esempio n. 1
0
def bundle_sum_distance(t, static, moving, num_threads=None):
    """ MDF distance optimization function (SUM)

    We minimize the distance between moving streamlines as they align
    with the static streamlines.

    Parameters
    -----------
    t : ndarray
        t is a vector of affine transformation parameters with
        size at least 6.
        If the size is 6, t is interpreted as translation + rotation.
        If the size is 7, t is interpreted as translation + rotation +
        isotropic scaling.
        If size is 12, t is interpreted as translation + rotation +
        scaling + shearing.

    static : list
        Static streamlines

    moving : list
        Moving streamlines. These will be transformed to align with
        the static streamlines

    Returns
    -------
    cost: float

    """

    aff = compose_matrix44(t)
    moving = transform_streamlines(moving, aff)
    d01 = distance_matrix_mdf(static, moving)
    return np.sum(d01)
Esempio n. 2
0
def bundle_sum_distance(t, static, moving, num_threads=None):
    """ MDF distance optimization function (SUM)

    We minimize the distance between moving streamlines as they align
    with the static streamlines.

    Parameters
    -----------
    t : ndarray
        t is a vector of of affine transformation parameters with
        size at least 6.
        If size is 6, t is interpreted as translation + rotation.
        If size is 7, t is interpreted as translation + rotation +
        isotropic scaling.
        If size is 12, t is interpreted as translation + rotation +
        scaling + shearing.

    static : list
        Static streamlines

    moving : list
        Moving streamlines. These will be transform to align with
        the static streamlines

    Returns
    -------
    cost: float

    """

    aff = compose_matrix44(t)
    moving = transform_streamlines(moving, aff)
    d01 = distance_matrix_mdf(static, moving)
    return np.sum(d01)
Esempio n. 3
0
def bundle_min_distance(t, static, moving):
    """ MDF-based pairwise distance optimization function (MIN).

    We minimize the distance between moving streamlines as they align
    with the static streamlines.

    Parameters
    ----------
    t : ndarray
        t is a vector of affine transformation parameters with
        size at least 6.
        If size is 6, t is interpreted as translation + rotation.
        If size is 7, t is interpreted as translation + rotation +
        isotropic scaling.
        If size is 12, t is interpreted as translation + rotation +
        scaling + shearing.

    static : list
        Static streamlines

    moving : list
        Moving streamlines.

    Returns
    -------
    cost: float

    """
    aff = compose_matrix44(t)
    moving = transform_streamlines(moving, aff)
    d01 = distance_matrix_mdf(static, moving)

    rows, cols = d01.shape
    return 0.25 * (np.sum(np.min(d01, axis=0)) / float(cols) +
                   np.sum(np.min(d01, axis=1)) / float(rows))**2
Esempio n. 4
0
def bundle_min_distance(t, static, moving):
    """ MDF-based pairwise distance optimization function (MIN)

    We minimize the distance between moving streamlines as they align
    with the static streamlines.

    Parameters
    -----------
    t : ndarray
        t is a vector of of affine transformation parameters with
        size at least 6.
        If size is 6, t is interpreted as translation + rotation.
        If size is 7, t is interpreted as translation + rotation +
        isotropic scaling.
        If size is 12, t is interpreted as translation + rotation +
        scaling + shearing.

    static : list
        Static streamlines

    moving : list
        Moving streamlines.

    Returns
    -------
    cost: float

    """
    aff = compose_matrix44(t)
    moving = transform_streamlines(moving, aff)
    d01 = distance_matrix_mdf(static, moving)

    rows, cols = d01.shape
    return 0.25 * (np.sum(np.min(d01, axis=0)) / float(cols) +
                   np.sum(np.min(d01, axis=1)) / float(rows)) ** 2
def bundles_distances_endpoints_fastest(S_A, S_B):
    """Distance between lists/arrays or streamlines, based on
    endpoints. Returns the distance matrix between the related
    groups streamlines.
    Fastest implementation based on distance_matrix_mdf().
    """
    tmp_S_A = np.array([[s_A[0], s_A[-1]] for s_A in S_A])
    tmp_S_B = np.array([[s_B[0], s_B[-1]] for s_B in S_B])
    return 2.0 * distance_matrix_mdf(tmp_S_A, tmp_S_B)
Esempio n. 6
0
def remove_similar_streamlines(streamlines, threshold=5):
    """ Remove similar streamlines, shuffling streamlines will impact the
    results.
    Only provide a small set of streamlines (below 2000 if possible).

    Parameters
    ----------
    streamlines : list of numpy.ndarray
        Input streamlines to remove duplicates from.
    threshold : float
        Distance threshold to consider two streamlines similar, in mm.

    Returns
    -------
    streamlines : list of numpy.ndarray
    """
    if len(streamlines) == 1:
        return streamlines

    sample_20_streamlines = set_number_of_points(streamlines, 20)
    distance_matrix = distance_matrix_mdf(sample_20_streamlines,
                                          sample_20_streamlines)

    current_indice = 0
    while True:
        sim_indices = np.where(distance_matrix[current_indice] < threshold)[0]

        pop_count = 0
        # Every streamlines similar to yourself (excluding yourself)
        # should be deleted from the set of desired streamlines
        for ind in sim_indices:
            if not current_indice == ind:
                streamlines.pop(ind - pop_count)

                distance_matrix = np.delete(distance_matrix,
                                            ind - pop_count,
                                            axis=0)
                distance_matrix = np.delete(distance_matrix,
                                            ind - pop_count,
                                            axis=1)
                pop_count += 1

        current_indice += 1
        # Once you reach the end of the remaining streamlines
        if current_indice >= len(distance_matrix):
            break

    return streamlines
Esempio n. 7
0
def remove_similar_streamlines(streamlines, removal_distance=2.):
    """ Computes a distance matrix using all streamlines, then removes streamlines closer than `removal_distance`.

    Parameters
    -----------
    streamlines : `ArraySequence` object or list of 3D arrays
        Streamlines to downsample
    removal_distance : float
        Distance for which streamlines are considered 'similar' and should be removed

    Returns
    -------
    `ArraySequence` object
        Downsampled streamlines
    """
    # Simple trick to make it faster than using 40-60 points
    sample_10_streamlines = set_number_of_points(streamlines, 10)
    distance_matrix = distance_matrix_mdf(sample_10_streamlines,
                                          sample_10_streamlines)

    current_id = 0
    while True:
        indices = np.where(distance_matrix[current_id] < removal_distance)[0]

        it = 0
        if len(indices) > 1:
            for k in indices:
                # Every streamlines similar to yourself (excluding yourself)
                # should be deleted from the set of desired streamlines
                if not current_id == k:
                    streamlines.pop(k - it)
                    distance_matrix = np.delete(distance_matrix,
                                                k - it,
                                                axis=0)
                    distance_matrix = np.delete(distance_matrix,
                                                k - it,
                                                axis=1)
                    it += 1

        current_id += 1
        # Once you reach the end of the remaining streamlines
        if current_id >= len(streamlines):
            break

    return streamlines
Esempio n. 8
0
def test_efficient_bmd():

    a = np.array([[1, 1, 1],
                  [2, 2, 2],
                  [3, 3, 3]])

    streamlines = [a, a + 2, a + 4]

    points, offsets = unlist_streamlines(streamlines)
    points = points.astype(np.double)
    points2 = points.copy()

    D = np.zeros((len(offsets), len(offsets)), dtype='f8')

    _bundle_minimum_distance_matrix(points, points2,
                                    len(offsets), len(offsets),
                                    a.shape[0], D)

    assert_equal(np.sum(np.diag(D)), 0)

    points2 += 2

    _bundle_minimum_distance_matrix(points, points2,
                                    len(offsets), len(offsets),
                                    a.shape[0], D)

    streamlines2 = relist_streamlines(points2, offsets)
    D2 = distance_matrix_mdf(streamlines, streamlines2)

    assert_array_almost_equal(D, D2)

    cols = D2.shape[1]
    rows = D2.shape[0]

    dist = 0.25 * (np.sum(np.min(D2, axis=0)) / float(cols) +
                   np.sum(np.min(D2, axis=1)) / float(rows)) ** 2

    dist2 = _bundle_minimum_distance(points, points2,
                                     len(offsets), len(offsets),
                                     a.shape[0])
    assert_almost_equal(dist, dist2)
Esempio n. 9
0
def remove_similar_streamlines(streamlines, threshold=5, do_avg=False):
    """ Remove similar streamlines, shuffling streamlines will impact the 
    results.
    Only provide a small set of streamlines (below 2000 if possible).

    Parameters
    ----------
    streamlines : list of numpy.ndarray
        Input streamlines to remove duplicates from.
    threshold : float
        Distance threshold to consider two streamlines similar, in mm.
    do_avg : bool
        Instead of removing similar streamlines, average all similar streamlines
        as a single smoother streamline.

    Returns
    -------
    streamlines : list of numpy.ndarray
    """
    if len(streamlines) == 1:
        return streamlines

    sample_20_streamlines = set_number_of_points(streamlines, 20)
    distance_matrix = distance_matrix_mdf(sample_20_streamlines,
                                          sample_20_streamlines)

    current_indice = 0
    avg_streamlines = []
    while True:
        sim_indices = np.where(distance_matrix[current_indice] < threshold)[0]

        pop_count = 0
        if do_avg:
            avg_streamline_list = []

        # Every streamlines similar to yourself (excluding yourself)
        # should be deleted from the set of desired streamlines
        for ind in sim_indices:
            if not current_indice == ind:
                streamlines.pop(ind-pop_count)

                distance_matrix = np.delete(distance_matrix, ind-pop_count,
                                            axis=0)
                distance_matrix = np.delete(distance_matrix, ind-pop_count,
                                            axis=1)
                pop_count += 1

            if do_avg:
                kicked_out = sample_20_streamlines[ind]
                avg_streamline_list.append(kicked_out)

        if do_avg:
            if len(avg_streamline_list) > 1:
                metric = AveragePointwiseEuclideanMetric()
                qb = QuickBundles(threshold=100, metric=metric)
                clusters = qb.cluster(avg_streamline_list)
                avg_streamlines.append(clusters.centroids[0])
            else:
                avg_streamlines.append(avg_streamline_list[0])

        current_indice += 1
        # Once you reach the end of the remaining streamlines
        if current_indice >= len(distance_matrix):
            break

    if do_avg:
        return avg_streamlines
    else:
        return streamlines