예제 #1
0
def save_pat_objects(pat_id, phase_id, segmentation, seg_errors, uncertainties, aleatoric,
                     type_of_map, spacing,
                     output_dirs, new_spacing=None, do_resample=False, direction=None, origin=None,
                     pred_probs=None):
    if do_resample and new_spacing is None:
        raise ValueError("ERROR - if resample tue then new_spacing cannot be None")
    if phase_id is not None:
        f_prefix = '{}_{}'.format(pat_id, phase_id)
    else:
        f_prefix = '{}'.format(pat_id)
    fname = path.join(output_dirs['pred_labels'], f_prefix + '.nii.gz')
    if do_resample:
        segmentation = apply_2d_zoom_3d(segmentation.astype(np.int16), spacing, order=0, do_blur=False,
                                        as_type=np.int16, new_spacing=new_spacing)
        # print("Resample segmentations ", o_shape, segmentation.shape)

    save_nifty(segmentation.astype(np.int16), new_spacing if do_resample else spacing, fname,
               direction=direction, origin=origin)
    print("INFO - Saved auto mask to {} (sp/new_sp)".format(fname), spacing, new_spacing)
    fname = path.join(output_dirs['umaps'], f_prefix + '_{}.nii.gz'.format(type_of_map))
    if do_resample:
        uncertainties = apply_2d_zoom_3d(uncertainties.astype(np.float32), spacing, do_blur=True,
                                         new_spacing=new_spacing)
        # print("Resample uncertainties ", o_shape, uncertainties.shape)
    save_nifty(uncertainties.astype(np.float32), new_spacing if do_resample else spacing, fname, direction=direction,
               origin=origin)
    if seg_errors is not None:
        fname = path.join(output_dirs['errors'], f_prefix + '.nii.gz')
        if do_resample:
            seg_errors = apply_2d_zoom_3d(seg_errors.astype(np.int16), spacing, order=0, do_blur=False,
                                          as_type=np.int16, new_spacing=new_spacing)
        save_nifty(seg_errors.astype(np.int16), new_spacing if do_resample else spacing, fname, direction=direction,
                   origin=origin)
    if aleatoric is not None:
        fname = path.join(output_dirs['umaps'], f_prefix + '_aleatoric.nii.gz')
        if do_resample:
            aleatoric = apply_2d_zoom_3d(aleatoric.astype(np.float32), spacing, do_blur=True, new_spacing=new_spacing)
        save_nifty(aleatoric.astype(np.float32), new_spacing if do_resample else spacing, fname, direction=direction,
                   origin=origin)

    if pred_probs is not None:
        fname = path.join(output_dirs['pred_probs'], f_prefix + '.nii.gz')
        pred_new_spacing = np.array([new_spacing[0], 1, new_spacing[1], new_spacing[2]])
        pred_spacing = np.array([spacing[0], 1, spacing[1], spacing[2]])
        if do_resample:
            nclasses = pred_probs.shape[1]
            resampled_probs = np.zeros((segmentation.shape[0], pred_probs.shape[1], segmentation.shape[1],
                                        segmentation.shape[2]))
            for cls_idx in np.arange(nclasses):
                resampled_probs[:, cls_idx] = apply_2d_zoom_3d(pred_probs[:, cls_idx].astype(np.float32), spacing,
                                                               do_blur=False, new_spacing=new_spacing)
            pred_probs = resampled_probs
        print("WARNING do resample ", do_resample)
        save_nifty(pred_probs.astype(np.float32), pred_new_spacing if do_resample else pred_spacing, fname, direction=direction,
                   origin=origin)
예제 #2
0
 def _do_resample(self, img, gt_lbl, sp):
     img = apply_2d_zoom_3d(img,
                            sp,
                            do_blur=True,
                            new_spacing=self.new_spacing)
     gt_lbl = apply_2d_zoom_3d(gt_lbl,
                               sp,
                               order=0,
                               do_blur=False,
                               as_type=np.int,
                               new_spacing=self.new_spacing)
     return img, gt_lbl
예제 #3
0
def save_segmentations(segmentation,
                       pat_id,
                       output_dirs,
                       spacing,
                       do_resample,
                       new_spacing=None,
                       frame_id=None,
                       direction=None,
                       origin=None):

    if frame_id is not None:
        f_prefix = '{}_{:02d}'.format(pat_id, frame_id)
    else:
        f_prefix = '{}'.format(pat_id)
    fname = path.join(output_dirs['pred_labels'], f_prefix + '.nii.gz')
    if do_resample:
        if segmentation.ndim == 3:
            segmentation = apply_2d_zoom_3d(segmentation.astype(np.int16),
                                            spacing,
                                            order=0,
                                            do_blur=False,
                                            as_type=np.int16,
                                            new_spacing=new_spacing)
        else:
            # assuming 4d data
            num_time_points = segmentation.shape[0]
            resized_segs = None
            for t in np.arange(num_time_points):
                seg = segmentation[t]
                new_seg = apply_2d_zoom_3d(seg.astype(np.int16),
                                           spacing,
                                           order=0,
                                           do_blur=False,
                                           as_type=np.int16,
                                           new_spacing=new_spacing)
                if resized_segs is None:
                    resized_segs = np.expand_dims(new_seg, axis=0)
                else:
                    resized_segs = np.vstack(
                        (resized_segs, np.expand_dims(new_seg, axis=0)))

        # print("Resample segmentations ", o_shape, segmentation.shape)

    save_nifty(segmentation.astype(np.int16),
               new_spacing if do_resample else spacing,
               fname,
               direction=direction,
               origin=origin)
예제 #4
0
def get_pred_probs(src_data_path,
                   cardiac_phase,
                   mc_dropout=False,
                   patient_id=None,
                   meta_info=True):
    """
    returns softmax probabilities as numpy array of shape [z, nclasses, y, x] and spacing
    """

    search_path = get_search_mask(src_data_path, "pred_probs", cardiac_phase,
                                  mc_dropout, patient_id)

    pred_probs = {}
    file_list = glob.glob(search_path)
    if len(file_list) == 0:
        raise ValueError("ERROR - No search result for {}".format(search_path))
    file_list.sort()

    for fname in file_list:
        pat_id, _ = (os.path.splitext(os.path.basename(fname))[0]).split("_")
        img = sitk.ReadImage(fname)
        org_sp = img.GetSpacing()[::-1]
        softmax_probs = sitk.GetArrayFromImage(img).astype(np.float32)

        # We store pred probs in the original spacing (according to the image info).
        # Nevertheless, in case the spacing of x, y is below 1mm we resample to 1.4 isotropic. We do the same
        # in the ACDC dataset object
        if org_sp[-1] < 1.:
            nclasses = softmax_probs.shape[1]
            t_sp = np.array([org_sp[0], 1.4, 1.4]).astype(np.float64)
            t_org_sp = np.array([org_sp[0], org_sp[2],
                                 org_sp[3]]).astype(np.float64)
            spacing = np.array([org_sp[0], org_sp[1], 1.4,
                                1.4]).astype(np.float64)
            resampled_probs = []
            for cls_idx in np.arange(nclasses):
                resampled_probs.append(
                    apply_2d_zoom_3d(softmax_probs[:,
                                                   cls_idx].astype(np.float32),
                                     t_org_sp,
                                     do_blur=False,
                                     new_spacing=t_sp))
            softmax_probs = np.concatenate(
                ([arr[:, None] for arr in resampled_probs]), axis=1)

        else:
            spacing = org_sp

        if meta_info:
            pred_probs[pat_id] = {
                'pred_probs': softmax_probs,
                'spacing': spacing,
                'original_spacing': org_sp
            }
        else:
            pred_probs[pat_id] = softmax_probs
        del softmax_probs

    return pred_probs
예제 #5
0
def get_images_nifti(data_src_dir, patid=None, resample=False, rescale=False):

    if patid is None:
        search_path = os.path.join(data_src_dir, "*.nii.gz")
    else:
        search_path = os.path.join(data_src_dir, patid + "*.nii.gz")
    file_list = glob.glob(search_path)
    if len(file_list) == 0:
        raise ValueError("ERROR - No search result for {}".format(search_path))
    else:
        print("INFO - Found {} nifti files in {}".format(
            len(file_list), data_src_dir))
    file_list.sort()

    for fname in file_list:
        img = sitk.ReadImage(fname)
        img_arr = sitk.GetArrayFromImage(img).astype(np.float32)
        pat_id, _ = (os.path.splitext(os.path.basename(fname))[0]).split(".")
        if img_arr.ndim == 4:
            num_of_frames = img_arr.shape[0]
            spacing = img.GetSpacing()[::-1][1:]
            original_spacing = img.GetSpacing()[::-1][1:]
        else:
            num_of_frames = 1
            img_arr = np.expand_dims(img_arr, axis=0)
            spacing = img.GetSpacing()[::-1]
            original_spacing = img.GetSpacing()[::-1]
        print("INFO - Processing patid {}, #frames {}".format(
            pat_id, num_of_frames))
        if resample or spacing[-1] < 1.:
            do_resample = True
            new_spacing = np.array([original_spacing[0], 1.4,
                                    1.4]).astype(np.float32)
            spacing = new_spacing
        else:
            do_resample = False
            new_spacing = None

        for frame_id in range(num_of_frames):
            img_np = img_arr[frame_id]
            if do_resample:
                img_np = apply_2d_zoom_3d(img_np,
                                          original_spacing,
                                          new_spacing,
                                          do_blur=True)
            if rescale:
                img_np = rescale_intensities(img_np).astype(np.float32)

            yield {
                'image': img_np,
                'spacing': spacing,
                'reference': img_np,
                'patient_id': pat_id,
                'frame_id': frame_id,
                'cardiac_phase': 'none',
                'structures': [],
                'original_spacing': original_spacing,
                'num_of_frames': num_of_frames
            }
예제 #6
0
def acdc_validation_fold_image4d(fold,
                                 root_dir,
                                 patid=None,
                                 resample=False,
                                 rescale=False,
                                 file_suffix='4d.nii.gz'):
    if isinstance(patid, str):
        patid = int(patid.strip('patient'))

    print("acdc_validation_fold_image4d ", fold)
    allpatnumbers = np.arange(1, 101)
    foldmask = np.tile(np.arange(4)[::-1].repeat(5), 5)
    validation_nums = allpatnumbers[foldmask == fold]
    if patid is not None:
        validation_nums = [pid for pid in validation_nums if patid == pid]
        if len(validation_nums) == 0:
            raise ValueError(
                "ERROR - acdc validation fold - patid {} not found in validation set"
                .format(patid))

    for patnum in validation_nums:
        img = ACDCImage(patnum,
                        root_dir=root_dir,
                        resample=True,
                        scale_intensities=False,
                        resample_zaxis=False,
                        file_suffix=file_suffix)
        img4d_arr = img.image4d()
        num_of_frames = img4d_arr.shape[0]
        spacing = img.voxel_spacing()[1:]
        original_spacing = img.voxel_spacing()[1:]

        for frame_id in range(num_of_frames):
            img_np = img4d_arr[frame_id]
            if resample:
                print("WARNING - Resampling")
                spacing = np.array([
                    original_spacing[0], ACDCImage.new_spacing[1],
                    ACDCImage.new_spacing[2]
                ]).astype(np.float32)
                img_np = apply_2d_zoom_3d(img_np,
                                          spacing,
                                          do_blur=True,
                                          new_spacing=img.new_spacing)
            if rescale:
                img_np = rescale_intensities(img_np).astype(np.float32)

            yield {
                'image': img_np,
                'spacing': spacing,
                'reference': img_np,
                'patient_id': img.patient_id,
                'frame_id': frame_id,
                'cardiac_phase': 'ED',
                'structures': [],
                'original_spacing': original_spacing,
                'num_of_frames': num_of_frames
            }
예제 #7
0
def get_umaps(src_data_path, cardiac_phase, mc_dropout=False, patient_id=None):
    """
    returns uncertainty map (e- or b-map) as numpy array of shape [z, y, x] and spacing
    """

    if mc_dropout:
        input_dir = "_bmap" + file_ext
    else:
        input_dir = "_emap" + file_ext
    if patient_id is None:
        input_dir = os.path.sep + "*_{}".format(cardiac_phase) + input_dir
    else:
        input_dir = os.path.sep + patient_id + "_{}".format(
            cardiac_phase) + input_dir
    search_path = src_data_path + os.sep + OUTPUT_DIRS[
        'umaps'] + os.sep + input_dir

    umaps = {}
    file_list = glob.glob(search_path)
    if len(file_list) == 0:
        raise ValueError("ERROR - No search result for {}".format(search_path))
    file_list.sort()

    for fname in file_list:
        pat_id, _, _ = (os.path.splitext(
            os.path.basename(fname))[0]).split("_")

        img = sitk.ReadImage(fname)
        org_sp = img.GetSpacing()[::-1]
        data = sitk.GetArrayFromImage(img).astype(np.float32)
        # hacky!!! For entropy maps it happens that some voxels have tiny negative values e-08.
        # But we need to make sure these are zero
        # data[data < 0] = 0
        # We store pred labels (and uncertainty maps) in the original spacing (according to the image info).
        # Nevertheless, in case the spacing of x, y is below 1mm we resample to 1.4 isotropic. We do the same
        # in the ACDC dataset object
        if org_sp[-1] < 1.:
            spacing = np.array([org_sp[0], 1.4, 1.4]).astype(np.float64)
            data = apply_2d_zoom_3d(data,
                                    org_sp,
                                    do_blur=True,
                                    new_spacing=spacing)
        else:
            spacing = org_sp
        umaps[pat_id] = {
            'umap': data,
            'spacing': spacing,
            'original_spacing': org_sp
        }
        del data

    return umaps
예제 #8
0
def get_pred_labels(src_data_path,
                    cardiac_phase,
                    mc_dropout=False,
                    patient_id=None,
                    one_hot=False,
                    meta_info=True):
    """
    returns predicted labels as numpy array of shape [z, y, x] and spacing
    """

    search_path = get_search_mask(src_data_path, "pred_labels", cardiac_phase,
                                  mc_dropout, patient_id)

    pred_labels = {}
    file_list = glob.glob(search_path)
    if len(file_list) == 0:
        raise ValueError("ERROR - No search result for {}".format(search_path))
    file_list.sort()

    for fname in file_list:
        pat_id, _ = (os.path.splitext(os.path.basename(fname))[0]).split("_")

        img = sitk.ReadImage(fname)
        org_sp = img.GetSpacing()[::-1]
        predictions = sitk.GetArrayFromImage(img).astype(np.long)
        # We store pred labels (and uncertainty maps) in the original spacing (according to the image info).
        # Nevertheless, in case the spacing of x, y is below 1mm we resample to 1.4 isotropic. We do the same
        # in the ACDC dataset object
        if org_sp[-1] < 1.:
            spacing = np.array([org_sp[0], 1.4, 1.4]).astype(np.float64)
            predictions = apply_2d_zoom_3d(predictions,
                                           org_sp,
                                           order=0,
                                           do_blur=False,
                                           as_type=np.int,
                                           new_spacing=spacing)
        else:
            spacing = org_sp

        if one_hot:
            predictions = one_hot_encoding(predictions)
        if meta_info:
            pred_labels[pat_id] = {
                'pred_labels': predictions,
                'spacing': spacing,
                'original_spacing': org_sp
            }
        else:
            pred_labels[pat_id] = predictions
        del predictions

    return pred_labels
예제 #9
0
def save_pred_probs(pat_id, phase_id, pred_probs, spacing,
                    output_dirs, new_spacing=None, do_resample=False, direction=None, origin=None):
    if phase_id is not None:
        f_prefix = '{}_{}'.format(pat_id, phase_id)
    else:
        f_prefix = '{}'.format(pat_id)

    fname = path.join(output_dirs['pred_probs'], f_prefix + '.nii.gz')
    pred_new_spacing = np.array([new_spacing[0], 1, new_spacing[1], new_spacing[2]])
    pred_spacing = np.array([spacing[0], 1, spacing[1], spacing[2]])
    if do_resample:
        nclasses = pred_probs.shape[1]
        resampled_probs = None
        for cls_idx in np.arange(nclasses):
            new_probs = apply_2d_zoom_3d(pred_probs[:, cls_idx].astype(np.float32), spacing,
                                                           do_blur=False, new_spacing=new_spacing)
            if resampled_probs is None:
                resampled_probs = np.zeros((new_probs.shape[0], pred_probs.shape[1], new_probs.shape[1],
                                            new_probs.shape[2]))
            resampled_probs[:, cls_idx] = new_probs
        pred_probs = resampled_probs

    save_nifty(pred_probs.astype(np.float32), pred_new_spacing if do_resample else pred_spacing, fname, direction=direction,
               origin=origin)