Esempio n. 1
0
    def load_unit(self, unit_id):
        """Loads the image data for display."""

        image1_path, image2_path = self.path_getter_inputs(unit_id)
        self.image_one = read_image(image1_path, error_msg='first image')
        self.image_two = read_image(image2_path, error_msg='second image')

        skip_subject = False
        if np.count_nonzero(self.image_one) == 0:
            skip_subject = True
            print('image {} of {} is empty!'.format(self.image1_name,
                                                    self.current_unit_id))

        if np.count_nonzero(self.image_two) == 0:
            skip_subject = True
            print('image {} of {} is empty!'.format(self.image2_name,
                                                    self.current_unit_id))

        if not skip_subject:
            # crop and rescale
            self.image_one, self.image_two = crop_to_seg_extents(
                self.image_one, self.image_two, self.padding)
            self.image_one = scale_0to1(self.image_one)
            self.image_two = scale_0to1(self.image_two)

            self.slices = pick_slices(self.image_one, self.views,
                                      self.num_slices_per_view)
            # flag to keep track of whether data has been changed.
            self._histogram_updated = False

        # # where to save the visualization to
        # out_vis_path = pjoin(self.out_dir, 'visual_qc_{}_{}'.format(self.vis_type, unit_id))

        return skip_subject
Esempio n. 2
0
    def load_unit(self, unit_id):
        """Loads the image data for display."""

        t1_mri_path = get_freesurfer_mri_path(self.in_dir, unit_id,
                                              self.mri_name)
        fs_seg_path = get_freesurfer_mri_path(self.in_dir, unit_id,
                                              self.seg_name)

        temp_t1_mri = read_image(t1_mri_path, error_msg='T1 mri')
        temp_fs_seg = read_image(fs_seg_path, error_msg='segmentation')

        if temp_t1_mri.shape != temp_fs_seg.shape:
            raise ValueError('size mismatch! MRI: {} Seg: {}\n'
                             'Size must match in all dimensions.'.format(
                                 self.current_t1_mri.shape, temp_fs_seg.shape))

        skip_subject = False
        if self.vis_type in ('cortical_volumetric', 'cortical_contour'):
            temp_seg_uncropped, roi_set_is_empty = void_subcortical_symmetrize_cortical(
                temp_fs_seg)
        elif self.vis_type in ('labels_volumetric', 'labels_contour'):
            if self.label_set is not None:
                # TODO same colors for same labels is not guaranteed
                #   if one subject fewer labels than others
                #   due to remapping of labels for each subject
                temp_seg_uncropped, roi_set_is_empty = get_label_set(
                    temp_fs_seg, self.label_set)
            else:
                raise ValueError(
                    '--label_set must be specified for visualization types: '
                    ' labels_volumetric and labels_contour')
        else:
            raise NotImplementedError(
                'Invalid visualization type - '
                'choose from: {}'.format(
                    cfg.visualization_combination_choices))

        if roi_set_is_empty:
            skip_subject = True
            print('segmentation image for {} '
                  'does not contain requested label set!'.format(unit_id))
            return skip_subject

        # T1 mri must be rescaled - to avoid strange distributions skewing plots
        rescaled_t1_mri = scale_0to1(temp_t1_mri, cfg.max_cmap_range_t1_mri)
        self.current_t1_mri, self.current_seg = crop_to_seg_extents(
            rescaled_t1_mri, temp_seg_uncropped, self.padding)

        out_vis_path = pjoin(
            self.out_dir, 'visual_qc_{}_{}_{}'.format(self.vis_type,
                                                      self.suffix, unit_id))

        return skip_subject
Esempio n. 3
0
def overlay_images(qcw, mri, seg,
                   subject_id=None,
                   annot=None,
                   figsize=None,
                   padding=default_padding,
                   output_path=None):
    """Backend engine for overlaying a given seg on MRI with freesurfer label."""

    num_rows_per_view, num_slices_per_view, padding = check_params(qcw.num_rows, qcw.num_slices, padding)
    mri, seg = crop_to_seg_extents(mri, seg, padding)

    surf_vis = dict()  # empty - no vis to include
    # TODO broaden this to include subcortical structures as well
    if 'cortical' in qcw.vis_type:
        if qcw.in_dir is not None and subject_id is not None and qcw.out_dir is not None:
            surf_vis = make_vis_pial_surface(qcw.in_dir, subject_id, qcw.out_dir)
    num_surf_vis = len(surf_vis)

    # TODO calculation below is redundant, if surf vis does not fail
    # i.e. if num_surf_vis is fixed, no need to recompute for every subject
    num_views = len(qcw.views)
    num_rows = num_rows_per_view * num_views
    slices = pick_slices(seg, qcw.views, num_slices_per_view)
    num_volumetric_slices = len(slices)
    total_num_panels = num_volumetric_slices + num_surf_vis
    num_rows_for_surf_vis = 1 if num_surf_vis > 0 else 0
    num_rows = num_rows + num_rows_for_surf_vis
    num_cols = check_layout(total_num_panels, num_views, num_rows_per_view, num_rows_for_surf_vis)

    plt.style.use('dark_background')

    if figsize is None:
        # figsize = [min(15,4*num_rows), min(12,4*num_cols)] # max (15,12)
        figsize = [4 * num_rows, 2* num_cols]
    fig, ax = plt.subplots(num_rows, num_cols, figsize=figsize)

    display_params_mri = dict(interpolation='none', aspect='equal', origin='lower',
                              alpha=qcw.alpha_mri)
    display_params_seg = dict(interpolation='none', aspect='equal', origin='lower',
                              alpha=qcw.alpha_seg)

    normalize_labels = colors.Normalize(vmin=seg.min(), vmax=seg.max(), clip=True)
    fs_cmap = get_freesurfer_cmap(qcw.vis_type)
    seg_mapper = cm.ScalarMappable(norm=normalize_labels, cmap=fs_cmap)

    normalize_mri = colors.Normalize(vmin=mri.min(), vmax=mri.max(), clip=True)
    mri_mapper = cm.ScalarMappable(norm=normalize_mri, cmap='gray')

    # deciding colors for the whole image
    unique_labels = np.unique(seg)
    # removing background - 0 stays 0
    unique_labels = np.delete(unique_labels, 0)
    if len(unique_labels) == 1:
        color4label = [qcw.contour_color]
    else:
        color4label = seg_mapper.to_rgba(unique_labels)

    handles_seg = list()
    handles_mri = list()

    ax = ax.flatten()
    # display surfaces
    for sf_counter, ((hemi, view), spath) in enumerate(surf_vis.items()):
        plt.sca(ax[sf_counter])
        img = mpimg.imread(spath)
        # img = crop_image(img)
        plt.imshow(img)
        ax[sf_counter].text(0, 0, '{} {}'.format(hemi, view))
        plt.axis('off')

    # display slices
    for ax_counter, (dim_index, slice_num) in enumerate(slices):
        plt.sca(ax[ax_counter + num_surf_vis])

        slice_mri = get_axis(mri, dim_index, slice_num)
        slice_seg = get_axis(seg, dim_index, slice_num)

        # display MRI
        mri_rgb = mri_mapper.to_rgba(slice_mri)
        h_mri = plt.imshow(mri_rgb, **display_params_mri)

        if 'volumetric' in qcw.vis_type:
            seg_rgb = seg_mapper.to_rgba(slice_seg)
            h_seg = plt.imshow(seg_rgb, **display_params_seg)
        elif 'contour' in qcw.vis_type:
            h_seg = plot_contours_in_slice(slice_seg, unique_labels, color4label)

        plt.axis('off')

        # # encoding the souce of the object (image/line) being displayed
        # handle_seg.set_label('seg {} {}'.format(dim_index, slice_num))
        # handle_mri.set_label('mri {} {}'.format(dim_index, slice_num))

        handles_mri.append(h_mri)
        if len(h_seg) >= 1:
            handles_seg.extend(h_seg)
        else:
            handles_seg.append(h_seg)

    # hiding unused axes
    for ua in range(total_num_panels, len(ax)):
        ax[ua].set_visible(False)

    if annot is not None:
        h_annot = fig.suptitle(annot, **cfg.annot_text_props)
        h_annot.set_position(cfg.position_annot_text)

    fig.set_size_inches(figsize)

    if output_path is not None:
        # no space left unused
        plt.subplots_adjust(**cfg.no_blank_area)
        output_path = output_path.replace(' ', '_')
        layout_str = 'v{}_ns{}_{}x{}'.format(''.join([ str(v) for v in qcw.views]),num_slices_per_view,num_rows,num_cols)
        fig.savefig(output_path + '_{}.png'.format(layout_str), bbox_inches='tight')

    # leaving some space on the right for review elements
    plt.subplots_adjust(**cfg.review_area)

    return fig, handles_mri, handles_seg, figsize
Esempio n. 4
0
def aseg_on_mri(mri_spec,
                aseg_spec,
                alpha_mri=1.0,
                alpha_seg=1.0,
                num_rows=2,
                num_cols=6,
                rescale_method='global',
                aseg_cmap='freesurfer',
                sub_cortical=False,
                annot=None,
                padding=5,
                bkground_thresh=0.05,
                output_path=None,
                figsize=None,
                **kwargs):
    "Produces a collage of various slices from different orientations in the given 3D image"

    num_rows, num_cols, padding = check_params(num_rows, num_cols, padding)

    mri = read_image(mri_spec, bkground_thresh=bkground_thresh)
    seg = read_image(aseg_spec, bkground_thresh=0)
    mri, seg = crop_to_seg_extents(mri, seg, padding)

    num_slices_per_view = num_rows * num_cols
    slices = pick_slices(seg, num_slices_per_view)

    plt.style.use('dark_background')

    num_axes = 3
    if figsize is None:
        figsize = [5 * num_axes * num_rows, 5 * num_cols]
    fig, ax = plt.subplots(num_axes * num_rows, num_cols, figsize=figsize)

    # displaying some annotation text if provided
    if annot is not None:
        fig.suptitle(annot, backgroundcolor='black', color='g')

    display_params_mri = dict(interpolation='none',
                              aspect='equal',
                              origin='lower',
                              cmap='gray',
                              alpha=alpha_mri,
                              vmin=mri.min(),
                              vmax=mri.max())
    display_params_seg = dict(interpolation='none',
                              aspect='equal',
                              origin='lower',
                              alpha=alpha_seg)

    normalize_labels = colors.Normalize(vmin=seg.min(),
                                        vmax=seg.max(),
                                        clip=True)
    fs_cmap = get_freesurfer_cmap(sub_cortical)
    label_mapper = cm.ScalarMappable(norm=normalize_labels, cmap=fs_cmap)

    ax = ax.flatten()
    ax_counter = 0
    for dim_index in range(3):
        for slice_num in slices[dim_index]:
            plt.sca(ax[ax_counter])
            ax_counter = ax_counter + 1

            slice_mri = get_axis(mri, dim_index, slice_num)
            slice_seg = get_axis(seg, dim_index, slice_num)

            # # masking data to set no-value pixels to transparent
            # seg_background = np.isclose(slice_seg, 0.0)
            # slice_seg = np.ma.masked_where(seg_background, slice_seg)
            # slice_mri = np.ma.masked_where(np.logical_not(seg_background), slice_mri)

            seg_rgb = label_mapper.to_rgba(slice_seg)
            plt.imshow(seg_rgb, **display_params_seg)
            plt.imshow(slice_mri, **display_params_mri)
            plt.axis('off')

    # plt.subplots_adjust(wspace=0.0, hspace=0.0)
    plt.subplots_adjust(left=0.01,
                        right=0.99,
                        bottom=0.01,
                        top=0.99,
                        wspace=0.05,
                        hspace=0.02)
    # fig.tight_layout()

    if output_path is not None:
        output_path = output_path.replace(' ', '_')
        fig.savefig(output_path + '.png', bbox_inches='tight')

    # plt.close()

    return fig