Ejemplo n.º 1
0
    def view_mask(self):
        data = SimpleDataInfo({'Original mask': load_nifti(self.selectedMaskText.text()).get_data(),
                               'Slice mask': load_nifti(self.selectedOutputFileText.text()).get_data()})

        config = MapPlotConfig()
        config.dimension = self.dimensionInput.value()
        config.slice_index = self.sliceInput.value()
        config.maps_to_show = ['Original mask', 'Slice mask']

        start_gui(data=data, config=config, app_exec=False)
Ejemplo n.º 2
0
Archivo: npy.py Proyecto: sudesnac/MDT
def samples_npy_to_nifti(samples_npy_fname,
                         used_mask,
                         nifti_header,
                         nifti_fname=None):
    """Convert a npy file containing sample results to a nifti file.

    Since the sample npy files are stored as a two dimensional matrix (with on the first axis the ROI index number
    and on the second the samples), we need to have the lookup table for the spatial information about the samples.

    Args:
        samples_npy_fname (str): the filename of the samples file to convert
        used_mask (ndarray or str): either an three dimensional matrix with the mask or a path to a nifti file.
        nifti_header (nibabel header): the header to use for writing the nifti file
        nifti_fname (str): the filename of the nifti file. If not given it defaults to the same directory as the
            samples file.
    """
    samples = np.load(samples_npy_fname, mmap_mode='r')

    if isinstance(used_mask, str):
        used_mask = load_nifti(used_mask).get_data()

    if np.count_nonzero(used_mask) != samples.shape[0]:
        raise ValueError(
            'The number of voxels in the mask ({}) does not correspond '
            'with the number of voxels in the samples file ({})'.format(
                np.count_nonzero(used_mask), samples.shape[0]))

    if nifti_fname is None:
        nifti_fname = os.path.join(
            os.path.dirname(samples_npy_fname),
            os.path.splitext(os.path.basename(samples_npy_fname))[0] +
            '.nii.gz')

    volume = restore_volumes(samples, used_mask)
    write_nifti(volume, nifti_fname, nifti_header)
Ejemplo n.º 3
0
def create_write_median_otsu_brain_mask(dwi_info, protocol, output_fname,
                                        **kwargs):
    """Write a brain mask using the given volume and output as the given volume.

    Args:
        dwi_info (string or tuple or ndarray): the filename of the input file or a tuple with as
            first index a ndarray with the DWI and as second index the header or only the image.
        protocol (string or :class:`~mdt.protocols.Protocol`): The filename of the protocol file or a Protocol object
        output_fname (string): the filename of the output file (the extracted brain mask)
            If None, no output is written. If ``dwi_info`` is an ndarray also no file is written
            (we don't have the header).

    Returns:
        ndarray: The created brain mask
    """
    if isinstance(dwi_info, str):
        signal_img = load_nifti(dwi_info)
        dwi = signal_img.get_data()
        header = signal_img.get_header()
    else:
        dwi = dwi_info[0]
        header = dwi_info[1]

    mask = create_median_otsu_brain_mask(dwi, protocol, **kwargs)
    write_nifti(mask, output_fname, header)

    return mask
Ejemplo n.º 4
0
    def run(self, args, extra_args):
        shape = load_nifti(args.mask).shape
        roi_dimension = args.dimension if args.dimension is not None else 2
        if roi_dimension > len(shape) - 1 or roi_dimension < 0:
            print(
                'Error: the given mask has only {0} dimensions with slices {1}.'
                .format(len(shape), shape))
            exit(1)

        roi_slice = args.slice if args.slice is not None else shape[
            roi_dimension] // 2
        if roi_slice > shape[roi_dimension] - 1 or roi_slice < 0:
            print('Error: dimension {0} has only {1} slices.'.format(
                roi_dimension, shape[roi_dimension]))
            exit(1)

        mask_base_name = os.path.splitext(os.path.realpath(args.mask))[0]
        mask_base_name = mask_base_name.replace('.nii', '')

        if args.output_name:
            output_name = os.path.realpath(args.output_name)
        else:
            output_name = mask_base_name + '_{0}_{1}.nii.gz'.format(
                roi_dimension, roi_slice)

        mdt.utils.write_slice_roi(os.path.realpath(args.mask),
                                  roi_dimension,
                                  roi_slice,
                                  output_name,
                                  overwrite_if_exists=True)
Ejemplo n.º 5
0
def create_median_otsu_brain_mask(dwi_info,
                                  protocol,
                                  mask_threshold=0,
                                  fill_holes=True,
                                  **kwargs):
    """Create a brain mask using the given volume.

    Args:
        dwi_info (string or tuple or image): The information about the volume, either:

            - the filename of the input file
            - or a tuple with as first index a ndarray with the DWI and as second index the header
            - or only the image as an ndarray
        protocol (string or :class:`~mdt.protocols.Protocol`): The filename of the protocol file or a Protocol object
        mask_threshold (float): everything below this b-value threshold is masked away (value in s/m^2)
        fill_holes (boolean): if we will fill holes after the median otsu algorithm and before the thresholding
        **kwargs: the additional arguments for median_otsu.

    Returns:
        ndarray: The created brain mask
    """
    logger = logging.getLogger(__name__)
    logger.info('Starting calculating a brain mask')

    if isinstance(dwi_info, str):
        signal_img = load_nifti(dwi_info)
        dwi = signal_img.get_data()
    elif isinstance(dwi_info, (tuple, list)):
        dwi = dwi_info[0]
    else:
        dwi = dwi_info

    if isinstance(protocol, str):
        protocol = load_protocol(protocol)

    if len(dwi.shape) == 4:
        unweighted_ind = protocol.get_unweighted_indices()
        if len(unweighted_ind):
            unweighted = np.mean(dwi[..., unweighted_ind], axis=3)
        else:
            unweighted = np.mean(dwi, axis=3)
    else:
        unweighted = dwi.copy()

    brain_mask = median_otsu(unweighted, **kwargs)
    brain_mask = brain_mask > 0

    if fill_holes:
        brain_mask = binary_fill_holes(brain_mask)

    if mask_threshold:
        brain_mask = np.mean(dwi[..., protocol.get_weighted_indices()],
                             axis=3) * brain_mask > mask_threshold

    logger.info('Finished calculating a brain mask')

    return brain_mask
Ejemplo n.º 6
0
 def update_slice_selector(self):
     if os.path.isfile(self.selectedMaskText.text()):
         dimension_max = load_nifti(self.selectedMaskText.text()).shape[self.dimensionInput.value()]
         self.sliceInput.setMaximum(dimension_max)
         self.sliceInput.setValue(dimension_max // 2.0)
         self.maxSliceLabel.setText(str(dimension_max))
     else:
         self.sliceInput.setValue(0)
         self.maxSliceLabel.setText('x')
Ejemplo n.º 7
0
    def load_maps(map_list):
        tmp = []
        for data in map_list:
            if isinstance(data, str):
                data = load_nifti(data).get_data()

            if len(data.shape) < 4:
                data = data[..., None]

            tmp.append(data)
        return tmp
Ejemplo n.º 8
0
    def run(self, args, extra_args):
        for image in args.images:
            image_path = os.path.realpath(image)

            try:
                image_path = nifti_filepath_resolution(image_path)
                img = load_nifti(image_path)
                header = img.get_header()
                print('{}'.format(image))
                self.print_info(header)
                print('')

            except ValueError:
                warnings.warn('Could not load image "{}"'.format(image_path))
Ejemplo n.º 9
0
    def load_maps(map_list):
        tmp = []
        for data in map_list:
            if isinstance(data, str):
                data = load_nifti(data).get_data()

            if len(data.shape) < 4:
                data = data[..., None]

            if data.shape[3] > 1:
                raise ValueError('Can not sort input volumes where one has more than one items on the 4th dimension.')

            tmp.append(data)
        return tmp
Ejemplo n.º 10
0
def generate_simple_wm_mask(fa_fname,
                            brain_mask_fname,
                            out_fname,
                            fa_threshold=0.3,
                            median_radius=1,
                            numpass=2):
    """Generate a simple white matter mask by thresholding the given FA map.

    Everything below the given FA threshold will be masked (not used). It also applies the regular brain mask to
    only retain values inside the brain.

    Args:
        fa_fname (str): the path to the FA file
        brain_mask_fname (str): the path to the general brain mask in use
        out_fname (str): where to write the outfile.
        fa_threshold (double): the FA threshold. Everything below this threshold is masked (set to 0). To be precise:
            where fa_data < fa_threshold set the value to 0.
        median_radius (int): the radius of the median filter
        numpass (int): the number of passes we apply the median filter
    """
    logger = logging.getLogger(__name__)
    logger.info('Starting calculating a white matter mask using FA.')

    nib_container = load_nifti(fa_fname)
    fa_data = nib_container.get_data()

    fa_data[fa_data < fa_threshold] = 0
    fa_data[fa_data > 0] = 1

    if len(fa_data.shape) > 3:
        fa_data = fa_data[:, :, :, 0]

    filter_footprint = np.zeros((1 + 2 * median_radius, ) * 3)
    filter_footprint[median_radius, median_radius, median_radius] = 1
    filter_footprint[:, median_radius, median_radius] = 1
    filter_footprint[median_radius, :, median_radius] = 1
    filter_footprint[median_radius, median_radius, :] = 1

    mask = load_brain_mask(brain_mask_fname)

    fa_data_masked = np.ma.masked_array(fa_data, mask=mask)
    for ind in range(numpass):
        fa_data_masked = median_filter(fa_data_masked,
                                       footprint=filter_footprint,
                                       mode='constant')

    write_nifti(fa_data_masked, out_fname, nib_container.get_header())
    logger.info('Finished calculating a white matter mask.')
Ejemplo n.º 11
0
def generate_simple_wm_mask(scalar_map,
                            whole_brain_mask,
                            threshold=0.3,
                            median_radius=1,
                            nmr_filter_passes=2):
    """Generate a simple white matter mask by thresholding the given map and smoothing it using a median filter.

    Everything below the given threshold will be masked (not used). It also applies the regular brain mask to
    only retain values inside the brain.

    Args:
        scalar_map (str or ndarray): the path to the FA file
        whole_brain_mask (str or ndarray): the general brain mask used in the FA model fitting
        threshold (double): the FA threshold. Everything below this threshold is masked (set to 0). To be precise:
            where fa_data < fa_threshold set the value to 0.
        median_radius (int): the radius of the median filter
        nmr_filter_passes (int): the number of passes we apply the median filter
    """
    filter_footprint = np.zeros((1 + 2 * median_radius, ) * 3)
    filter_footprint[median_radius, median_radius, median_radius] = 1
    filter_footprint[:, median_radius, median_radius] = 1
    filter_footprint[median_radius, :, median_radius] = 1
    filter_footprint[median_radius, median_radius, :] = 1

    if isinstance(scalar_map, str):
        map_data = load_nifti(scalar_map).get_data()
    else:
        map_data = np.copy(scalar_map)

    map_data[map_data < threshold] = 0
    wm_mask = map_data.astype(np.bool)

    if len(wm_mask.shape) > 3:
        wm_mask = wm_mask[:, :, :, 0]

    wm_mask[np.logical_not(load_brain_mask(whole_brain_mask))] = 0

    if nmr_filter_passes == 0:
        return wm_mask

    mask = load_brain_mask(whole_brain_mask)

    wm_mask_masked = np.ma.masked_array(wm_mask, mask=mask)
    for ind in range(nmr_filter_passes):
        wm_mask_masked = median_filter(wm_mask_masked,
                                       footprint=filter_footprint,
                                       mode='constant')
    return wm_mask_masked
Ejemplo n.º 12
0
    def view_mask(self):
        mask = np.expand_dims(load_brain_mask(self.selectedOutputText.text()),
                              axis=3)
        image_data = load_nifti(self.selectedImageText.text()).get_data()
        masked_image = image_data * mask

        data = SimpleDataInfo({
            'Masked': masked_image,
            'DWI': image_data,
            'Mask': mask
        })

        config = MapPlotConfig()
        config.dimension = 2
        config.slice_index = image_data.shape[2] // 2
        config.maps_to_show = ['DWI', 'Masked', 'Mask']

        start_gui(data=data, config=config, app_exec=False)
Ejemplo n.º 13
0
    def directory_updated(self, folder):
        if os.path.isfile(folder):
            folder = os.path.dirname(folder)

        self._folder = folder
        result_files = glob.glob(os.path.join(folder, '*.nii*'))

        def get_name(img_path):
            return split_image_path(os.path.basename(img_path))[1]

        self._parameter_files = {
            get_name(f): get_name(f)
            for f in result_files
        }

        items_list = sorted(self._parameter_files.keys())
        selected_items = results_preselection_names(
            sorted(self._parameter_files.keys()))

        self.selectMaps.clear()
        self.selectMaps.addItems(items_list)

        for item in [
                self.selectMaps.item(index)
                for index in range(self.selectMaps.count())
        ]:
            if item.text() in selected_items:
                item.setSelected(True)

        if items_list:
            shape = load_nifti(result_files[0]).shape
            maximum = shape[self.initialDimensionChooser.value()]
            self.initialSliceChooser.setMaximum(maximum)

            if self.initialSliceChooser.value(
            ) == 0 or self.initialSliceChooser.value() >= maximum:
                self.initialSliceChooser.setValue(maximum // 2.0)

            self.maximumIndexLabel.setText(str(maximum))
Ejemplo n.º 14
0
 def _get_gradient_deviations(self):
     if self._gradient_deviations is not None:
         return load_nifti(self._gradient_deviations).get_data()
     return None