Beispiel #1
0
def compute_centroids(patient):
    """Function for computing per-class centroid of a patient.

    This function takes a Patient object as an argument and,
    using its corresponding labelmap(s) [TODO: support multiple
    labelmaps], extracts centroid information for each class.

    This centroid information comes in three flavors, each an
    element of the corresponding label's dict:
     * 'voxel': centroid given as index of voxel
     * 'real': centroid given as real position in mm
     * 'relative': voxel centroid normalized in the volume
    
    Attributes
    ----------
    patient : :obj:`Patient`
        Patient object to extract centroid from.

    Returns
    -------
    centroids : `dict`
        dict of centroid information, keyed by label
    """
    # Acquiring the first labelmap of the patient (TODO: multiple labelmap support)
    labelmap = next(iter(patient.labelmaps.values()))  #patient.labelmaps['t2']
    volume = next(iter(patient.volumes.values()))  #patient.volumes['t2']

    # get sorted labels and center-of-mass for each label
    labels = np.unique(labelmap.data)
    centers_of_mass = measure_center_of_mass(np.ones_like(labelmap.data),
                                             labels=labelmap.data,
                                             index=labels)

    # building centroid attribute list
    centroids = {}
    for label, centroid in zip(labels, centers_of_mass):
        centroids[label] = {
            "voxel":
            list(centroid),
            "real": [(centroid[i] * volume.header["spacings"][i]) +
                     volume.header["initial_position"][i]
                     for i in range(len(centroid))],
            "relative":
            [centroid[i] / volume.data.shape[i] for i in range(len(centroid))]
        }

    # normalize to mean 0, stddev 1
    for flavor in ["voxel", "real", "relative"]:
        for index in range(3):
            mean, stddev = np.mean([
                element[flavor][index] for element in centroids.values()
            ]), np.std(
                [element[flavor][index] for element in centroids.values()])
            for element in centroids.values():
                element[flavor][index] = (element[flavor][index] -
                                          mean) / stddev

    return centroids
Beispiel #2
0
def compute_centroids(volume, labelmap, specific_label=None):
    """Computes centroids for each label in a volume.

    Returns
    -------
    centroids : `2darray`
        Array with `num_labels` lines and 3 columns. Each line contains
        the normalized, real x, y, and z of each label.
    """
    # get sorted labels and center-of-mass for each label
    if specific_label is None:
        labels = np.unique(labelmap.data)
        centroids = measure_center_of_mass(np.ones_like(labelmap.data),
                                           labels=labelmap.data,
                                           index=labels)
    else:  # specific label only
        centroids = measure_center_of_mass(labelmap.data == specific_label)
    centroids = np.array(centroids)

    # multiply voxel value by voxel size to get real centroid
    centroids *= volume.header["spacings"]

    return centroids
def compute_attributes(volume, labelmap, attribute):
    """Computes an specific attribute for an entire volume"""
    if attribute == "centroid":
        labels = np.unique(labelmap)
        centroids = measure_center_of_mass(np.ones_like(labelmap), labels=labelmap, index=labels)
        centroids = np.array(centroids)
        return centroids
    elif attribute == "intensity":
        labels, indexes = np.unique(labelmap, return_inverse=True)
        intensities = np.empty(len(labels))
        for i, label in enumerate(labels):
            intensities[i] = np.mean(volume.flatten()[indexes==i])
        return intensities
    elif attribute == "size":
        labels,voxel_count_per_labels = np.unique(labelmap, return_counts=True)
        sizes = voxel_count_per_labels
        return sizes
    else:
        raise Exception("{} is not a supported attribute".format(attribute))