Example #1
0
def parcellate_voronoi_vol(mask, nb_parcels, seeds=None):
    """
    Produce a parcellation from a Voronoi diagram built on random seeds.
    The number of seeds is equal to the nb of parcels.
    Seed are randomly placed within the mask, expect on edge positions

    Args:
        - mask (numpy.ndarray): binary 3D array of valid position to parcellate
        - nb_parcels (int): the required number of parcels
        - seeds: TODO

    Return:
        - the parcellation (numpy.ndarray): a 3D array of integers
        -
    """
    parcellation = np.zeros(mask.shape, dtype=int)
    nvox = (mask !=0).sum()
    for cc_mask in mg.split_mask_into_cc_iter(mask!=0):
        # compute the required number of parcels within the current CC:
        size_cc = cc_mask.sum()
        cc_np = max(int(np.round(nb_parcels * size_cc / (nvox*1.))), 1)
        pyhrf.verbose(2, 'Treating a connected component (CC) of %d positions' \
                          %cc_mask.sum())
        if cc_mask.sum() < 6:
            continue
        if seeds is None:
            # perform voronoi on random seeds

            eroded_mask = peelVolume3D(cc_mask)
            eroded_mask_size = eroded_mask.sum()
            if eroded_mask_size < nb_parcels: #do no erode, mask too small
                eroded_mask_size = nvox
                eroded_mask = mask.copy()
            cc_seeds = np.random.randint(0,eroded_mask_size, cc_np)
            mask_for_seed = np.zeros(eroded_mask_size, dtype=int)
            mask_for_seed[cc_seeds] = 1
            mask_for_seed  = expand_array_in_mask(mask_for_seed, eroded_mask)
        else:
            mask_for_seed = seeds * cc_mask

        pyhrf.verbose(2, 'Nb of seeds in current CC: %d' \
                          %mask_for_seed.sum())
        cc_parcellation = voronoi(np.vstack(np.where(cc_mask)).T,
                                  np.vstack(np.where(mask_for_seed)).T) + 1
        pyhrf.verbose(3, 'CC parcellation labels: %s' \
                          %str(np.unique(cc_parcellation)))
        maxp = parcellation.max()
        parcellation += expand_array_in_mask(cc_parcellation + maxp, cc_mask)
        pyhrf.verbose(3, 'Current parcellation labels: %s' \
                          %str(np.unique(parcellation)))
    pyhrf.verbose(1, 'voronoi parcellation: %s, %s' \
                      %(str(parcellation.shape), str(parcellation.dtype)))

    return parcellation
Example #2
0
def parcellate_voronoi_vol(mask, nb_parcels, seeds=None):
    """
    Produce a parcellation from a Voronoi diagram built on random seeds.
    The number of seeds is equal to the nb of parcels.
    Seed are randomly placed within the mask, expect on edge positions

    Args:
        - mask (numpy.ndarray): binary 3D array of valid position to parcellate
        - nb_parcels (int): the required number of parcels
        - seeds: TODO

    Return:
        - the parcellation (numpy.ndarray): a 3D array of integers
        -
    """
    parcellation = np.zeros(mask.shape, dtype=int)
    nvox = (mask != 0).sum()
    for cc_mask in mg.split_mask_into_cc_iter(mask != 0):
        # compute the required number of parcels within the current CC:
        size_cc = cc_mask.sum()
        cc_np = max(int(np.round(nb_parcels * size_cc / (nvox * 1.))), 1)
        logger.info('Treating a connected component (CC) of %d positions',
                    cc_mask.sum())
        if cc_mask.sum() < 6:
            continue
        if seeds is None:
            # perform voronoi on random seeds

            eroded_mask = peelVolume3D(cc_mask)
            eroded_mask_size = eroded_mask.sum()
            if eroded_mask_size < nb_parcels:  # do no erode, mask too small
                eroded_mask_size = nvox
                eroded_mask = mask.copy()
            cc_seeds = np.random.randint(0, eroded_mask_size, cc_np)
            mask_for_seed = np.zeros(eroded_mask_size, dtype=int)
            mask_for_seed[cc_seeds] = 1
            mask_for_seed = expand_array_in_mask(mask_for_seed, eroded_mask)
        else:
            mask_for_seed = seeds * cc_mask

        logger.info('Nb of seeds in current CC: %d', mask_for_seed.sum())
        cc_parcellation = voronoi(
            np.vstack(np.where(cc_mask)).T,
            np.vstack(np.where(mask_for_seed)).T) + 1
        logger.info('CC parcellation labels: %s',
                    str(np.unique(cc_parcellation)))
        maxp = parcellation.max()
        parcellation += expand_array_in_mask(cc_parcellation + maxp, cc_mask)
        logger.info('Current parcellation labels: %s',
                    str(np.unique(parcellation)))
    logger.info('voronoi parcellation: %s, %s', str(parcellation.shape),
                str(parcellation.dtype))

    return parcellation
Example #3
0
def parcellate_balanced_vol(mask, nb_parcels):
    """
    Performs a balanced partitioning on the input mask using a balloon patroling
     algorithm [Eurol 2009]. Values with 0 are discarded position in the mask.

    Args:
        - mask (numpy.ndarray): binary 3D array of valid position to parcellate
        - nb_parcels (int): the required number of parcels

    Return:
        - the parcellation (numpy.ndarray): a 3D array of integers
    """

    parcellation = np.zeros(mask.shape, dtype=int)
    nvox = (mask != 0).sum()

    # Iterate over connected components in the input mask
    for cc_mask in mg.split_mask_into_cc_iter(mask != 0):
        logger.info('Treating a connected component (CC) of %d positions',
                    cc_mask.sum())
        g = mg.graph_from_lattice(cc_mask)
        size_cc = cc_mask.sum()
        # compute the required number of parcels within the current CC:
        cc_np = max(int(np.round(nb_parcels * size_cc / (nvox * 1.))), 1)

        logger.info('Split (CC) into %d parcels', cc_np)

        cc_labels = np.ones(cc_mask.sum(), dtype=int)
        if cc_np > 1:
            split_parcel(cc_labels, {1: g},
                         1,
                         cc_np,
                         inplace=True,
                         verbosity=2,
                         balance_tolerance='draft')
        else:  # only one parcel expected, CC must be too small to be splited
            cc_labels[:] = 1
        logger.info('Split done!')

        # accumulate parcellation result
        maxp = parcellation.max()
        parcellation += expand_array_in_mask(cc_labels + maxp, cc_mask > 0)

    return parcellation
Example #4
0
def parcellate_balanced_vol(mask, nb_parcels):
    """
    Performs a balanced partitioning on the input mask using a balloon patroling
     algorithm [Eurol 2009]. Values with 0 are discarded position in the mask.

    Args:
        - mask (numpy.ndarray): binary 3D array of valid position to parcellate
        - nb_parcels (int): the required number of parcels

    Return:
        - the parcellation (numpy.ndarray): a 3D array of integers
    """

    parcellation = np.zeros(mask.shape, dtype=int)
    nvox = (mask != 0).sum()

    # Iterate over connected components in the input mask
    for cc_mask in mg.split_mask_into_cc_iter(mask != 0):
        pyhrf.verbose(2, 'Treating a connected component (CC) of %d positions' \
                          %cc_mask.sum())
        g = mg.graph_from_lattice(cc_mask)
        size_cc = cc_mask.sum()
        # compute the required number of parcels within the current CC:
        cc_np = max(int(np.round(nb_parcels * size_cc / (nvox*1.))), 1)

        pyhrf.verbose(2, 'Split (CC) into %d parcels' %cc_np)

        cc_labels = np.ones(cc_mask.sum(), dtype=int)
        if cc_np > 1:
            split_parcel(cc_labels, {1:g}, 1, cc_np, inplace=True,
                         verbosity=2, balance_tolerance='draft')
        else: #only one parcel expected, CC must be too small to be splited
            cc_labels[:] = 1
        pyhrf.verbose(2, 'Split done!')

        # accumulate parcellation result
        maxp = parcellation.max()
        parcellation += expand_array_in_mask(cc_labels + maxp, cc_mask>0)

    return parcellation