def add_label_stats_to_dataframe(input_dataframe: pd.DataFrame,
                                 dataset_root_directory: Path,
                                 target_label_names: List[str]) -> pd.DataFrame:
    """
    Loops through all available subject IDs, generates ground-truth label statistics and updates input dataframe
    with the computed stats by adding new columns. In particular, it checks the overlapping regions between
    different structures and volume of labels.

    :param input_dataframe: Input Pandas dataframe object containing subjectIds and label names
    :param dataset_root_directory: Path to dataset root directory
    :param target_label_names: A list of label names that are used in label stat computations
    """
    dataset_sources = load_dataset_sources(input_dataframe,
                                           local_dataset_root_folder=dataset_root_directory,
                                           image_channels=["ct"],
                                           ground_truth_channels=target_label_names,
                                           mask_channel=None)

    # Iterate over subjects and check overlapping labels
    for subject_id in [*dataset_sources.keys()]:
        labels = io_util.load_labels_from_dataset_source(dataset_sources[subject_id])
        overlap_stats = metrics_util.get_label_overlap_stats(labels=labels[1:, ...],
                                                             label_names=target_label_names)

        header = io_util.load_nifti_image(dataset_sources[subject_id].ground_truth_channels[0]).header
        volume_stats = metrics_util.get_label_volume(labels=labels[1:, ...],
                                                     label_names=target_label_names,
                                                     label_spacing=header.spacing)

        # Log the extracted label statistics
        for col_name, col_stats in zip(("LabelOverlap", "LabelVolume (mL)"), (overlap_stats, volume_stats)):
            input_dataframe.loc[input_dataframe.subject == subject_id, col_name] = \
                input_dataframe.loc[input_dataframe.subject == subject_id, "channel"].map(col_stats)

    return input_dataframe
Exemple #2
0
def test_get_label_volume() -> None:
    """
    Tests computation of label volumes.
    """
    test_data = {'spleen': np.array([[0, 1, 0], [1, 1, 0]]),
                 'liver': np.array([[0, 0, 0], [0, 0, 0]])}
    label_overlap_stats = get_label_volume(labels=np.stack(test_data.values()),
                                           label_names=list(test_data.keys()),
                                           label_spacing=(1.00, 2.00, 3.00))

    assert label_overlap_stats['spleen'] == pytest.approx(3 * 6 / 1000.0, 1e-6)
    assert label_overlap_stats['liver'] == pytest.approx(0.0, 1e-6)