示例#1
0
def multicomponent_merge(fname_list):
    from numpy import zeros, reshape
    # WARNING: output multicomponent is not optimal yet, some issues may be related to the use of this function

    im_0 = Image(fname_list[0])
    new_shape = list(im_0.data.shape)
    if len(new_shape) == 3:
        new_shape.append(1)
    new_shape.append(len(fname_list))
    new_shape = tuple(new_shape)

    data_out = zeros(new_shape)
    for i, fname in enumerate(fname_list):
        im = Image(fname)
        dat = im.data
        if len(dat.shape) == 2:
            data_out[:, :, 0, 0, i] = dat.astype('float32')
        elif len(dat.shape) == 3:
            data_out[:, :, :, 0, i] = dat.astype('float32')
        elif len(dat.shape) == 4:
            data_out[:, :, :, :, i] = dat.astype('float32')
        del im
        del dat
    im_out = im_0.copy()
    im_out.data = data_out.astype('float32')
    im_out.hdr.set_intent('vector', (), '')
    im_out.setFileName(im_out.file_name+'_multicomponent'+im_out.ext)
    return im_out
示例#2
0
def load_level(list_slices_target, fname_level):
    verbose = 1
    path_level, file_level, ext_level = extract_fname(fname_level)

    #  ####### Check if the level file is an image or a text file
    # Level file is an image
    if ext_level in ['.nii', '.nii.gz']:
        im_level = Image(fname_level)
        im_level.change_orientation('IRP')

        list_level = []
        list_med_level = []
        for slice_level in im_level.data:
            try:
                # vertebral level of the slice
                l = np.mean(slice_level[slice_level > 0])
                # median of the vertebral level of the slice: if all voxels are int, med will be an int.
                med = np.median(slice_level[slice_level > 0])
                # change med in int if it is an int
                med = int(med) if int(med)==med else med
            except Exception, e:
                printv('WARNING: ' + str(e) + '\nNo level label found. Level will be set to 0 for this slice', verbose, 'warning')
                l = 0
                med = 0
            list_level.append(l)
            list_med_level.append(med)

        # if all median of level are int for all slices : consider level as int
        if all([isinstance(med, int) for med in list_med_level]):
            # level as int are placed in the middle of each vertebra (that's why there is a "+0.5")
            list_level = [int(round(l))+0.5 for l in list_level]
示例#3
0
def set_orientation(im, orientation, data_inversion=False, filename=False, fname_out=''):
    """
    Set orientation on image
    :param im: either Image object or file name. Carefully set param filename.
    :param orientation:
    :param data_inversion:
    :param filename:
    :return:
    """

    if fname_out:
        pass
    elif filename:
        path, fname, ext = extract_fname(im)
        fname_out = fname+'_'+orientation+ext
    else:
        fname_out = im.file_name+'_'+orientation+im.ext

    if not data_inversion:
        from sct_utils import run
        if filename:
            run('isct_orientation3d -i '+im+' -orientation '+orientation+' -o '+fname_out, 0)
            im_out = fname_out
        else:
            run('isct_orientation3d -i '+im.absolutepath+' -orientation '+orientation+' -o '+fname_out, 0)
            im_out = Image(fname_out)
    else:
        im_out = im.copy()
        im_out.change_orientation(orientation, True)
        im_out.setFileName(fname_out)
    return im_out
示例#4
0
    def remove_label(self, symmetry=False):
        """
        Compare two label images and remove any labels in input image that are not in reference image.
        The symmetry option enables to remove labels from reference image that are not in input image
        """
        # image_output = Image(self.image_input.dim, orientation=self.image_input.orientation, hdr=self.image_input.hdr, verbose=self.verbose)
        image_output = Image(self.image_input, verbose=self.verbose)
        image_output.data *= 0  # put all voxels to 0

        result_coord_input, result_coord_ref = self.remove_label_coord(self.image_input.getNonZeroCoordinates(coordValue=True),
                                                                       self.image_ref.getNonZeroCoordinates(coordValue=True), symmetry)

        for coord in result_coord_input:
            image_output.data[int(coord.x), int(coord.y), int(coord.z)] = int(round(coord.value))

        if symmetry:
            # image_output_ref = Image(self.image_ref.dim, orientation=self.image_ref.orientation, hdr=self.image_ref.hdr, verbose=self.verbose)
            image_output_ref = Image(self.image_ref, verbose=self.verbose)
            for coord in result_coord_ref:
                image_output_ref.data[int(coord.x), int(coord.y), int(coord.z)] = int(round(coord.value))
            image_output_ref.setFileName(self.fname_output[1])
            image_output_ref.save('minimize_int')

            self.fname_output = self.fname_output[0]

        return image_output
def savePredictions(predictions, path_output, list_images, segmentation_image_size):
    number_of_images = len(list_images)
    predictions = numpy.reshape(predictions, [number_of_images, segmentation_image_size, segmentation_image_size, NUM_LABELS])
    predictions = predictions[:, :, :, 1]
    for i, pref in enumerate(predictions):
        im_pred = Image(pref)
        im_pred.setFileName(path_output+sct.add_suffix(list_images[i], '_pred'))
        im_pred.save()
示例#6
0
    def continuous_vertebral_levels(self):
        """
        This function transforms the vertebral levels file from the template into a continuous file.
        Instead of having integer representing the vertebral level on each slice, a continuous value that represents
        the position of the slice in the vertebral level coordinate system.
        The image must be RPI
        :return:
        """
        im_input = Image(self.image_input, self.verbose)
        im_output = Image(self.image_input, self.verbose)
        im_output.data *= 0

        # 1. extract vertebral levels from input image
        #   a. extract centerline
        #   b. for each slice, extract corresponding level
        nx, ny, nz, nt, px, py, pz, pt = im_input.dim
        from sct_straighten_spinalcord import smooth_centerline
        x_centerline_fit, y_centerline_fit, z_centerline_fit, x_centerline_deriv, y_centerline_deriv, z_centerline_deriv = smooth_centerline(self.image_input, algo_fitting='nurbs', verbose=0)
        value_centerline = np.array([im_input.data[int(x_centerline_fit[it]), int(y_centerline_fit[it]), int(z_centerline_fit[it])] for it in range(len(z_centerline_fit))])

        # 2. compute distance for each vertebral level --> Di for i being the vertebral levels
        vertebral_levels = {}
        for slice_image, level in enumerate(value_centerline):
            if level not in vertebral_levels:
                vertebral_levels[level] = slice_image

        length_levels = {}
        for level in vertebral_levels:
            indexes_slice = np.where(value_centerline == level)
            length_levels[level] = np.sum([math.sqrt(((x_centerline_fit[indexes_slice[0][index_slice + 1]] - x_centerline_fit[indexes_slice[0][index_slice]])*px)**2 +
                                                     ((y_centerline_fit[indexes_slice[0][index_slice + 1]] - y_centerline_fit[indexes_slice[0][index_slice]])*py)**2 +
                                                     ((z_centerline_fit[indexes_slice[0][index_slice + 1]] - z_centerline_fit[indexes_slice[0][index_slice]])*pz)**2)
                                           for index_slice in range(len(indexes_slice[0]) - 1)])

        # 2. for each slice:
        #   a. identify corresponding vertebral level --> i
        #   b. calculate distance of slice from upper vertebral level --> d
        #   c. compute relative distance in the vertebral level coordinate system --> d/Di
        continuous_values = {}
        for it, iz in enumerate(z_centerline_fit):
            level = value_centerline[it]
            indexes_slice = np.where(value_centerline == level)
            indexes_slice = indexes_slice[0][indexes_slice[0] >= it]
            distance_from_level = np.sum([math.sqrt(((x_centerline_fit[indexes_slice[index_slice + 1]] - x_centerline_fit[indexes_slice[index_slice]]) * px * px) ** 2 +
                                                    ((y_centerline_fit[indexes_slice[index_slice + 1]] - y_centerline_fit[indexes_slice[index_slice]]) * py * py) ** 2 +
                                                    ((z_centerline_fit[indexes_slice[index_slice + 1]] - z_centerline_fit[indexes_slice[index_slice]]) * pz * pz) ** 2)
                                          for index_slice in range(len(indexes_slice) - 1)])
            continuous_values[iz] = level + 2.0 * distance_from_level / float(length_levels[level])

        # 3. saving data
        # for each slice, get all non-zero pixels and replace with continuous values
        coordinates_input = self.image_input.getNonZeroCoordinates()
        im_output.changeType('float32')
        # for all points in input, find the value that has to be set up, depending on the vertebral level
        for i, coord in enumerate(coordinates_input):
            im_output.data[int(coord.x), int(coord.y), int(coord.z)] = continuous_values[coord.z]

        return im_output
 def next(self):
     if self.iteration <= self.num_of_frames:
         result = Image(self)
         print "Iteration #" + str(self.iteration)
         result.data *= float(self.iteration) / float(self.num_of_frames)
         result.file_name = "tmp."+result.file_name+"_" + str(self.iteration)
         self.iteration += 1
         return result, self.iteration
     else:
         raise StopIteration()
示例#8
0
    def plan_ref(self):
        """
        Generate a plane in the reference space for each label present in the input image
        """

        image_output = Image(self.image_ref, self.verbose)
        image_output.data *= 0

        image_input_neg = Image(self.image_input, self.verbose).copy()
        image_input_pos = Image(self.image_input, self.verbose).copy()
        image_input_neg.data *=0
        image_input_pos.data *=0
        X, Y, Z = (self.image_input.data< 0).nonzero()
        for i in range(len(X)):
            image_input_neg.data[X[i], Y[i], Z[i]] = -self.image_input.data[X[i], Y[i], Z[i]] # in order to apply getNonZeroCoordinates
        X_pos, Y_pos, Z_pos = (self.image_input.data> 0).nonzero()
        for i in range(len(X_pos)):
            image_input_pos.data[X_pos[i], Y_pos[i], Z_pos[i]] = self.image_input.data[X_pos[i], Y_pos[i], Z_pos[i]]

        coordinates_input_neg = image_input_neg.getNonZeroCoordinates()
        coordinates_input_pos = image_input_pos.getNonZeroCoordinates()

        image_output.changeType('float32')
        for coord in coordinates_input_neg:
            image_output.data[:, :, int(coord.z)] = -coord.value #PB: takes the int value of coord.value
        for coord in coordinates_input_pos:
            image_output.data[:, :, int(coord.z)] = coord.value

        return image_output
示例#9
0
def resample_image(fname,
                   suffix='_resampled.nii.gz',
                   binary=False,
                   npx=0.3,
                   npy=0.3,
                   thr=0.0,
                   interpolation='spline'):
    """
    Resampling function: add a padding, resample, crop the padding
    :param fname: name of the image file to be resampled
    :param suffix: suffix added to the original fname after resampling
    :param binary: boolean, image is binary or not
    :param npx: new pixel size in the x direction
    :param npy: new pixel size in the y direction
    :param thr: if the image is binary, it will be thresholded at thr (default=0) after the resampling
    :param interpolation: type of interpolation used for the resampling
    :return: file name after resampling (or original fname if it was already in the correct resolution)
    """
    im_in = Image(fname)
    orientation = get_orientation_3d(im_in)
    if orientation != 'RPI':
        im_in = set_orientation(im_in, 'RPI')
        im_in.save()
        fname = im_in.absolutepath
    nx, ny, nz, nt, px, py, pz, pt = im_in.dim

    if round(px, 2) != round(npx, 2) or round(py, 2) != round(npy, 2):
        name_resample = sct.extract_fname(fname)[1] + suffix
        if binary:
            interpolation = 'nn'

        sct.run('sct_resample -i ' + fname + ' -mm ' + str(npx) + 'x' +
                str(npy) + 'x' + str(pz) + ' -o ' + name_resample + ' -x ' +
                interpolation)

        if binary:
            # sct.run('sct_maths -i ' + name_resample + ' -thr ' + str(thr) + ' -o ' + name_resample)
            sct.run('sct_maths -i ' + name_resample + ' -bin ' + str(thr) +
                    ' -o ' + name_resample)

        if orientation != 'RPI':
            im_resample = Image(name_resample)
            im_resample = set_orientation(im_resample, orientation)
            im_resample.save()
            name_resample = im_resample.absolutepath
        return name_resample
    else:
        if orientation != 'RPI':
            im_in = set_orientation(im_in, orientation)
            im_in.save()
            fname = im_in.absolutepath
        sct.printv('Image resolution already ' + str(npx) + 'x' + str(npy) +
                   'xpz')
        return fname
示例#10
0
def concat_data(fname_in_list, dim, pixdim=None):
    """
    Concatenate data
    :param im_in_list: list of images.
    :param dim: dimension: 0, 1, 2, 3.
    :param pixdim: pixel resolution to join to image header
    :return im_out: concatenated image
    """
    # WARNING: calling concat_data in python instead of in command line causes a non understood issue (results are different with both options)
    from numpy import concatenate, expand_dims, squeeze

    dat_list = []
    data_concat_list = []

    # check if shape of first image is smaller than asked dim to concatenate along
    data0 = Image(fname_in_list[0]).data
    if len(data0.shape) <= dim:
        expand_dim = True
    else:
        expand_dim = False

    for i, fname in enumerate(fname_in_list):
        # if there is more than 100 images to concatenate, then it does it iteratively to avoid memory issue.
        if i != 0 and i % 100 == 0:
            data_concat_list.append(concatenate(dat_list, axis=dim))
            im = Image(fname)
            dat = im.data
            if expand_dim:
                dat = expand_dims(dat, dim)
            dat_list = [dat]
            del im
            del dat
        else:
            im = Image(fname)
            dat = im.data
            if expand_dim:
                dat = expand_dims(dat, dim)
            dat_list.append(dat)
            del im
            del dat
    if data_concat_list:
        data_concat_list.append(concatenate(dat_list, axis=dim))
        data_concat = concatenate(data_concat_list, axis=dim)
    else:
        data_concat = concatenate(dat_list, axis=dim)
    # write file
    im_out = Image(fname_in_list[0]).copy()
    im_out.data = data_concat
    im_out.setFileName(im_out.file_name+'_concat'+im_out.ext)

    if pixdim is not None:
        im_out.hdr['pixdim'] = pixdim

    return im_out
 def next(self):
     if self.iteration <= self.num_of_frames:
         result = Image(self)
         sct.printv("Iteration #" + str(self.iteration))
         result.data *= float(self.iteration) / float(self.num_of_frames)
         result.file_name = "tmp." + result.file_name + "_" + str(
             self.iteration)
         self.iteration += 1
         return result, self.iteration
     else:
         raise StopIteration()
示例#12
0
    def extract_slices(self):
        # open image and re-orient it to RPI if needed
        im, seg = Image(self.param.fname_im), Image(self.param.fname_seg)
        if self.orientation_im != self.orientation_extraction:
            im, seg = set_orientation(
                im, self.orientation_extraction), set_orientation(
                    seg, self.orientation_extraction)

        # extract axial slices in self.dct_im_seg
        self.dct_im_seg['im'], self.dct_im_seg['seg'] = [
            im.data[:, :, z] for z in range(im.dim[2])
        ], [seg.data[:, :, z] for z in range(im.dim[2])]
    def __init__(self, fname_label, fname_output=None, fname_ref=None, cross_radius=5, dilate=False,
                 coordinates=None, verbose='1'):
        self.image_input = Image(fname_label)

        if fname_ref is not None:
            self.image_ref = Image(fname_ref)

        self.fname_output = fname_output
        self.cross_radius = cross_radius
        self.dilate = dilate
        self.coordinates = coordinates
        self.verbose = verbose
    def label_lesion(self):
        printv('\nLabel connected regions of the masked image...',
               self.verbose, 'normal')
        im = Image(self.fname_mask)
        im_2save = im.copy()
        im_2save.data = label(im.data, connectivity=2)
        im_2save.setFileName(self.fname_label)
        im_2save.save()

        self.measure_pd['label'] = [l for l in np.unique(im_2save.data) if l]
        printv('Lesion count = ' + str(len(self.measure_pd['label'])),
               self.verbose, 'info')
    def compute(self):

        fname_data = self.fmri

        # # create temporary folder
        # sct.printv('\nCreate temporary folder...', self.param.verbose)
        # path_tmp = 'tmp.'+time.strftime("%y%m%d%H%M%S/")
        # status, output = sct.run('mkdir '+path_tmp, self.param.verbose)

        # # motion correct the fmri data
        # # sct.printv('\nMotion correct the fMRI data...', self.param.verbose, 'normal')
        # path_fmri, fname_fmri, ext_fmri = sct.extract_fname(self.fmri)
        # fname_fmri_moco = fname_fmri
        # # print sct.slash_at_the_end(path_fmri) + fname_fmri
        # # sct.run('mcflirt -in ' + sct.slash_at_the_end(path_fmri, 1) + fname_fmri + ' -out ' + fname_fmri_moco)

        # compute tsnr
        sct.printv('\nCompute the tSNR...', self.param.verbose, 'normal')
        fname_data_mean = sct.add_suffix(fname_data, '_mean.nii')
        sct.run('sct_maths -i ' + fname_data + ' -o ' + fname_data_mean +
                ' -mean t')
        # if not average_data_across_dimension(fname_data, fname_data_mean, 3):
        #     sct.printv('ERROR in average_data_across_dimension', 1, 'error')
        # sct.run('fslmaths ' + fname_data + ' -Tmean ' + fname_data_mean)
        fname_data_std = sct.add_suffix(fname_data, '_std.nii')
        sct.run('sct_maths -i ' + fname_data + ' -o ' + fname_data_std +
                ' -mean t')
        # if not average_data_across_dimension(fname_data, fname_data_std, 3, 1):
        #     sct.printv('ERROR in average_data_across_dimension', 1, 'error')
        # sct.run('fslmaths ' + fname_data + ' -Tstd ' + fname_data_std)
        fname_tsnr = sct.add_suffix(fname_data, '_tsnr')
        from msct_image import Image
        nii_mean = Image(fname_data_mean)
        data_mean = nii_mean.data
        data_std = Image(fname_data_std).data
        data_tsnr = data_mean / data_std
        nii_tsnr = nii_mean
        nii_tsnr.data = data_tsnr
        nii_tsnr.setFileName(fname_tsnr)
        nii_tsnr.save()
        # sct.run('fslmaths ' + fname_data_mean + ' -div ' + fname_data_std + ' ' + fname_tsnr)

        # Remove temp files
        sct.printv('\nRemove temporary files...', self.param.verbose, 'normal')
        import os
        os.remove(fname_data_mean)
        os.remove(fname_data_std)

        # to view results
        sct.printv('\nDone! To view results, type:', self.param.verbose,
                   'normal')
        sct.printv('fslview ' + fname_tsnr + ' &\n', self.param.verbose,
                   'info')
示例#16
0
def centerline2roi(fname_image, folder_output='./', verbose=0):
    """
    Tis method converts a binary centerline image to a .roi centerline file

    Args:
        fname_image: filename of the binary centerline image, in RPI orientation
        folder_output: path to output folder where to copy .roi centerline
        verbose: adjusts the verbosity of the logging.

    Returns: filename of the .roi centerline that has been created

    """
    path_data, file_data, ext_data = sct.extract_fname(fname_image)
    fname_output = file_data + '.roi'

    date_now = datetime.now()
    ROI_TEMPLATE = 'Begin Marker ROI\n' \
                   '  Build version="7.0_33"\n' \
                   '  Annotation=""\n' \
                   '  Colour=0\n' \
                   '  Image source="{fname_segmentation}"\n' \
                   '  Created  "{creation_date}" by Operator ID="SCT"\n' \
                   '  Slice={slice_num}\n' \
                   '  Begin Shape\n' \
                   '    X={position_x}; Y={position_y}\n' \
                   '  End Shape\n' \
                   'End Marker ROI\n'

    im = Image(fname_image)
    nx, ny, nz, nt, px, py, pz, pt = im.dim
    coordinates_centerline = im.getNonZeroCoordinates(sorting='z')

    f = open(fname_output, "w")
    sct.printv('\nWriting ROI file...', verbose)

    for coord in coordinates_centerline:
        coord_phys_center = im.transfo_pix2phys([[(nx - 1) / 2.0,
                                                  (ny - 1) / 2.0, coord.z]])[0]
        coord_phys = im.transfo_pix2phys([[coord.x, coord.y, coord.z]])[0]
        f.write(
            ROI_TEMPLATE.format(
                fname_segmentation=fname_image,
                creation_date=date_now.strftime("%d %B %Y %H:%M:%S.%f %Z"),
                slice_num=coord.z + 1,
                position_x=coord_phys_center[0] - coord_phys[0],
                position_y=coord_phys_center[1] - coord_phys[1]))

    f.close()

    if os.path.abspath(folder_output) != os.getcwd():
        shutil.copy(fname_output, folder_output)

    return fname_output
示例#17
0
    def get_im_from_list(self, data):
        im = Image(data)
        # set pix dimension
        im.hdr.structarr['pixdim'][1] = self.param_data.axial_res
        im.hdr.structarr['pixdim'][2] = self.param_data.axial_res
        # set the correct orientation
        im.setFileName('im_to_orient.nii.gz')
        im.save()
        im = set_orientation(im, 'IRP')
        im = set_orientation(im, 'PIL', data_inversion=True)

        return im
def register_seg(seg_input, seg_dest):
    """Slice-by-slice registration by translation of two segmentations.

    For each slice, we estimate the translation vector by calculating the difference of position of the two centers of
    mass.
    The segmentations can be of different sizes but the output segmentation must be smaller than the input segmentation.

    input:
        seg_input: name of moving segmentation file (type: string)
        seg_dest: name of fixed segmentation file (type: string)

    output:
        x_displacement: list of translation along x axis for each slice (type: list)
        y_displacement: list of translation along y axis for each slice (type: list)

    """
    seg_input_img = Image(seg_input)
    seg_dest_img = Image(seg_dest)
    seg_input_data = seg_input_img.data
    seg_dest_data = seg_dest_img.data

    x_center_of_mass_input = [0 for i in range(seg_dest_data.shape[2])]
    y_center_of_mass_input = [0 for i in range(seg_dest_data.shape[2])]
    print "\nGet center of mass of the input segmentation for each slice (corresponding to a slice in the output segmentation)..."  # different if size of the two seg are different
    # TO DO: select only the slices corresponding to the output segmentation
    coord_origin_dest = seg_dest_img.transfo_pix2phys([[0, 0, 0]])
    [[x_o, y_o, z_o]] = seg_input_img.transfo_phys2pix(coord_origin_dest)
    for iz in xrange(seg_dest_data.shape[2]):
        x_center_of_mass_input[iz], y_center_of_mass_input[iz] = ndimage.measurements.center_of_mass(
            array(seg_input_data[:, :, z_o + iz])
        )

    x_center_of_mass_output = [0 for i in range(seg_dest_data.shape[2])]
    y_center_of_mass_output = [0 for i in range(seg_dest_data.shape[2])]
    print "\nGet center of mass of the output segmentation for each slice ..."
    for iz in xrange(seg_dest_data.shape[2]):
        x_center_of_mass_output[iz], y_center_of_mass_output[iz] = ndimage.measurements.center_of_mass(
            array(seg_dest_data[:, :, iz])
        )

    x_displacement = [0 for i in range(seg_input_data.shape[2])]
    y_displacement = [0 for i in range(seg_input_data.shape[2])]
    print "\nGet displacement by voxel..."
    for iz in xrange(seg_dest_data.shape[2]):
        x_displacement[iz] = -(
            x_center_of_mass_output[iz] - x_center_of_mass_input[iz]
        )  # WARNING: in ITK's coordinate system, this is actually Tx and not -Tx
        y_displacement[iz] = (
            y_center_of_mass_output[iz] - y_center_of_mass_input[iz]
        )  # This is Ty in ITK's and fslview' coordinate systems

    return x_displacement, y_displacement
    def coregister_model_data(self):
        # get mean image
        im_mean = Image(param=self.mean_image)

        # register all slices WM on mean WM
        for dic_slice in self.slices:
            # create a directory to get the warping fields
            warp_dir = 'wf_slice' + str(dic_slice.id)
            if not os.path.exists(warp_dir):
                os.mkdir(warp_dir)

            # get slice mean WM image
            im_slice = Image(param=dic_slice.im)
            # register slice image on mean dic image
            im_slice_reg, fname_src2dest, fname_dest2src = register_data(
                im_src=im_slice,
                im_dest=im_mean,
                param_reg=self.param_data.register_param,
                path_copy_warp=warp_dir)
            shape = im_slice_reg.data.shape

            # use forward warping field to register all slice wm
            list_wmseg_reg = []
            for wm_seg in dic_slice.wm_seg:
                im_wmseg = Image(param=wm_seg)
                im_wmseg_reg = apply_transfo(im_src=im_wmseg,
                                             im_dest=im_mean,
                                             warp=warp_dir + '/' +
                                             fname_src2dest,
                                             interp='nn')

                list_wmseg_reg.append(im_wmseg_reg.data.reshape(shape))

            # use forward warping field to register gm seg
            list_gmseg_reg = []
            for gm_seg in dic_slice.gm_seg:
                im_gmseg = Image(param=gm_seg)
                im_gmseg_reg = apply_transfo(im_src=im_gmseg,
                                             im_dest=im_mean,
                                             warp=warp_dir + '/' +
                                             fname_src2dest,
                                             interp='nn')
                list_gmseg_reg.append(im_gmseg_reg.data.reshape(shape))

            # set slice attributes with data registered into the model space
            dic_slice.set(im_m=im_slice_reg.data)
            dic_slice.set(wm_seg_m=list_wmseg_reg)
            dic_slice.set(gm_seg_m=list_gmseg_reg)

            # remove warping fields directory
            if self.param.rm_tmp:
                shutil.rmtree(warp_dir)
示例#20
0
def test_integrity(param_test):
    """
    Test integrity of function
    """
    # initializations
    mse_detection = float('nan')

    # extract name of output centerline: data_centerline_optic.nii.gz
    file_ctr = os.path.join(
        param_test.path_output,
        sct.add_suffix(param_test.file_input, '_centerline_optic'))

    # open output segmentation
    im_ctr = Image(file_ctr)

    # open ground truth
    im_seg_manual = Image(param_test.fname_gt)
    im_ctr_manual = im_seg_manual.copy()  # Create Ctr GT from SC seg GT

    if im_ctr_manual.orientation != 'RPI':
        im_ctr_manual.change_orientation('RPI')

    im_ctr_manua_data = im_ctr_manual.data

    # Compute center of mass of the SC seg on each axial slice.
    center_of_mass_x_y_z_lst = [[
        int(center_of_mass(im_ctr_manua_data[:, :, zz])[0]),
        int(center_of_mass(im_ctr_manua_data[:, :, zz])[1]), zz
    ] for zz in range(im_ctr_manual.dim[2])]

    im_ctr_manual.data *= 0
    for x_y_z in center_of_mass_x_y_z_lst:
        im_ctr_manual.data[x_y_z[0], x_y_z[1], x_y_z[2]] = 1

    # compute MSE between generated ctr and ctr from database
    mse_detection = compute_mse(im_ctr, im_ctr_manual)

    param_test.output += 'Computed MSE: ' + str(mse_detection)
    param_test.output += 'MSE threshold (if computed MSE higher: fail): ' + str(
        param_test.mse_threshold)

    if mse_detection > param_test.mse_threshold:
        param_test.status = 99
        param_test.output += '--> FAILED'
    else:
        param_test.output += '--> PASSED'

    # update Panda structure
    param_test.results['mse_detection'] = mse_detection

    return param_test
示例#21
0
def check_if_same_space(fname_1, fname_2):
    from msct_image import Image
    from numpy import min, nonzero, all, around
    from numpy import abs as np_abs
    from numpy import log10 as np_log10

    im_1 = Image(fname_1)
    im_2 = Image(fname_2)
    q1 = im_1.hdr.get_qform()
    q2 = im_2.hdr.get_qform()

    dec = int(np_abs(round(np_log10(min(np_abs(q1[nonzero(q1)]))))) + 1)
    dec = 4 if dec > 4 else dec
    return all(around(q1, dec) == around(q2, dec))
def scad_propseg_validation(folder_input, contrast):
    from sct_get_centerline import ind2sub
    import time
    import math
    import numpy
    import sct_convert as cnv

    t0 = time.time()

    current_folder = os.getcwd()
    os.chdir(folder_input)

    try:
        patients = next(os.walk('.'))[1]
        for i in patients:
            directory = i + "/" + str(contrast)
            try:
                os.chdir(directory)
            except Exception, e:
                print str(i)+" : "+contrast+" directory not found"
            try:
                if os.path.isfile(i+"_"+contrast+".nii.gz"):
                    raw_image = Image(i+"_"+contrast+".nii.gz")
                elif os.path.isfile(contrast+".nii.gz"):
                    raw_image = Image(contrast+".nii.gz")
                else:
                    raise Exception("Patient scan not found")

                if os.path.isfile(i+"_"+contrast+"_manual_segmentation.nii.gz"):
                    manual_segmentation  = i+"_"+contrast+"_manual_segmentation.nii.gz"
                    # Using propseg default
                    sct.run("sct_propseg -i "+raw_image.absolutepath+" -t "+contrast)
                    cnv.convert(raw_image.file_name+"_seg.nii.gz", "propseg_default.nii.gz")
                    # Using scad
                    scad = SCAD(raw_image, contrast=contrast, rm_tmp_file=1, verbose=1)
                    scad.execute()
                    # Using propseg with scad
                    sct.run("sct_propseg -i "+raw_image.absolutepath+" -t "+contrast+" -init-centerline "+scad.output_filename)
                    cnv.convert(raw_image.file_name+"_seg.nii.gz", "propseg_scad.nii.gz")
                    # Calculate dice of propseg_default
                    sct.run("sct_dice_coefficient propseg_default.nii.gz "+manual_segmentation+" -o propseg_default_result.txt")
                    # Calculate dice of propseg_scad
                    sct.run("sct_dice_coefficient propseg_scad.nii.gz "+manual_segmentation+" -o propseg_scad_result.txt")
                else:
                    printv("Cannot find the manual segmentation", type="warning")

            except Exception, e:
                print e.message

            os.chdir(folder_input)
示例#23
0
    def orient2pir(self):
        """Orient input data to PIR orientation."""
        if self.orientation_im != 'PIR':  # open image and re-orient it to PIR if needed
            im_tmp = Image(self.fname_im)
            set_orientation(im_tmp,
                            'PIR',
                            fname_out=''.join(
                                sct.extract_fname(self.fname_im)[1:]))

            if self.fname_seg is not None:
                set_orientation(Image(self.fname_seg),
                                'PIR',
                                fname_out=''.join(
                                    sct.extract_fname(self.fname_seg)[1:]))
示例#24
0
def concat_data(fname_in, fname_out, dim):
    """
    Concatenate data
    :param fname_in: list of file names.
    :param fname_out:
    :param dim: dimension: 0, 1, 2, 3.
    :return: none
    """
    # create empty list
    list_data = []

    # loop across files
    for i in range(len(fname_in)):
        # append data to list
        list_data.append(Image(fname_in[i]).data)

    # expand dimension of all elements in the list if necessary
    if dim > list_data[0].ndim - 1:
        list_data = [expand_dims(i, dim) for i in list_data]
    # concatenate
    try:
        data_concat = concatenate(list_data, axis=dim)
    except Exception as e:
        sct.printv(
            '\nERROR: Concatenation on line {}'.format(
                sys.exc_info()[-1].tb_lineno) + '\n' + str(e) + '\n', 1,
            'error')

    # write file
    im = Image(fname_in[0])
    im.data = data_concat
    im.setFileName(fname_out)
    im.save()
示例#25
0
    def crop_from_mask_with_background(self):
        from numpy import asarray, einsum
        image_in = Image(self.input_filename)
        data_array = asarray(image_in.data)
        data_mask = asarray(Image(self.mask).data)
        assert data_array.shape == data_mask.shape

        # Element-wise matrix multiplication:
        new_data = None
        dim = len(data_array.shape)
        if dim == 3:
            new_data = einsum('ijk,ijk->ijk', data_mask, data_array)
        elif dim == 2:
            new_data = einsum('ij,ij->ij', data_mask, data_array)

        if self.background != 0:
            from sct_maths import get_data_or_scalar
            data_background = get_data_or_scalar(str(self.background),
                                                 data_array)
            data_mask_inv = data_mask.max() - data_mask
            if dim == 3:
                data_background = einsum('ijk,ijk->ijk', data_mask_inv,
                                         data_background)
            elif dim == 2:
                data_background = einsum('ij,ij->ij', data_mask_inv,
                                         data_background)
            new_data += data_background

        # set image out
        image_in.setFileName(self.output_filename)
        image_in.data = new_data
        image_in.save()
    def angle_correction(self):
        # Empty arrays in which angle for each z slice will be stored
        self.angles = np.zeros(Image(self.fname_mask).dim[2])

        if self.fname_sc is not None:
            im_seg = Image(self.fname_sc)
            data_seg = im_seg.data
            X, Y, Z = (data_seg > 0).nonzero()
            min_z_index, max_z_index = min(Z), max(Z)

            # fit centerline, smooth it and return the first derivative (in physical space)
            x_centerline_fit, y_centerline_fit, z_centerline, x_centerline_deriv, y_centerline_deriv, z_centerline_deriv = smooth_centerline(
                self.fname_sc,
                algo_fitting='hanning',
                type_window='hanning',
                window_length=80,
                nurbs_pts_number=3000,
                phys_coordinates=True,
                verbose=self.verbose,
                all_slices=False)
            centerline = Centerline(x_centerline_fit, y_centerline_fit,
                                    z_centerline, x_centerline_deriv,
                                    y_centerline_deriv, z_centerline_deriv)

            # average centerline coordinates over slices of the image
            x_centerline_deriv_rescorr, y_centerline_deriv_rescorr, z_centerline_deriv_rescorr = centerline.average_coordinates_over_slices(
                im_seg)[3:]

            # compute Z axis of the image, in physical coordinate
            axis_Z = im_seg.get_directions()[2]

            # for iz in xrange(min_z_index, max_z_index + 1):
            for zz in range(im_seg.dim[2]):
                if zz >= min_z_index and zz <= max_z_index:
                    # in the case of problematic segmentation (e.g., non continuous segmentation often at the extremities), display a warning but do not crash
                    try:  # normalize the tangent vector to the centerline (i.e. its derivative)
                        tangent_vect = self._normalize(
                            np.array([
                                x_centerline_deriv_rescorr[zz],
                                y_centerline_deriv_rescorr[zz],
                                z_centerline_deriv_rescorr[zz]
                            ]))
                        # compute the angle between the normal vector of the plane and the vector z
                        self.angles[zz] = np.arccos(
                            np.vdot(tangent_vect, axis_Z))
                    except IndexError:
                        printv(
                            'WARNING: Your segmentation does not seem continuous, which could cause wrong estimations at the problematic slices. Please check it, especially at the extremities.',
                            type='warning')
示例#27
0
def concat_data(fname_in_list, dim, pixdim=None):
    """
    Concatenate data
    :param im_in_list: list of images.
    :param dim: dimension: 0, 1, 2, 3.
    :param pixdim: pixel resolution to join to image header
    :return im_out: concatenated image
    """
    # WARNING: calling concat_data in python instead of in command line causes a non understood issue (results are different with both options)
    from numpy import concatenate, expand_dims

    dat_list = []
    data_concat_list = []

    # check if shape of first image is smaller than asked dim to concatenate along
    data0 = Image(fname_in_list[0]).data
    if len(data0.shape) <= dim:
        expand_dim = True
    else:
        expand_dim = False

    for i, fname in enumerate(fname_in_list):
        # if there is more than 100 images to concatenate, then it does it iteratively to avoid memory issue.
        if i != 0 and i % 100 == 0:
            data_concat_list.append(concatenate(dat_list, axis=dim))
            im = Image(fname)
            dat = im.data
            if expand_dim:
                dat = expand_dims(dat, dim)
            dat_list = [dat]
            del im
            del dat
        else:
            im = Image(fname)
            dat = im.data
            if expand_dim:
                dat = expand_dims(dat, dim)
            dat_list.append(dat)
            del im
            del dat
    if data_concat_list:
        data_concat_list.append(concatenate(dat_list, axis=dim))
        data_concat = concatenate(data_concat_list, axis=dim)
    else:
        data_concat = concatenate(dat_list, axis=dim)
    # write file
    im_out = Image(fname_in_list[0]).copy()
    im_out.data = data_concat
    im_out.setFileName(im_out.file_name + '_concat' + im_out.ext)

    if pixdim is not None:
        im_out.hdr['pixdim'] = pixdim

    return im_out
    def compute(self):

        fname_data = self.fmri

        # # create temporary folder
        # sct.printv('\nCreate temporary folder...', self.param.verbose)
        # path_tmp = 'tmp.'+time.strftime("%y%m%d%H%M%S/")
        # status, output = sct.run('mkdir '+path_tmp, self.param.verbose)

        # # motion correct the fmri data
        # # sct.printv('\nMotion correct the fMRI data...', self.param.verbose, 'normal')
        # path_fmri, fname_fmri, ext_fmri = sct.extract_fname(self.fmri)
        # fname_fmri_moco = fname_fmri
        # # print sct.slash_at_the_end(path_fmri) + fname_fmri
        # # sct.run('mcflirt -in ' + sct.slash_at_the_end(path_fmri, 1) + fname_fmri + ' -out ' + fname_fmri_moco)

        # compute mean
        fname_data_mean = sct.add_suffix(fname_data, '_mean')
        sct_maths.main(
            args=['-i', fname_data, '-o', fname_data_mean, '-mean', 't'])

        # compute STD
        fname_data_std = sct.add_suffix(fname_data, '_std')
        sct_maths.main(
            args=['-i', fname_data, '-o', fname_data_std, '-std', 't'])

        # compute tSNR
        fname_tsnr = sct.add_suffix(fname_data, '_tsnr')
        from msct_image import Image
        nii_mean = Image(fname_data_mean)
        data_mean = nii_mean.data
        data_std = Image(fname_data_std).data
        data_tsnr = data_mean / data_std
        nii_tsnr = nii_mean
        nii_tsnr.data = data_tsnr
        nii_tsnr.setFileName(fname_tsnr)
        nii_tsnr.save()

        # Remove temp files
        sct.printv('\nRemove temporary files...', self.param.verbose, 'normal')
        import os
        os.remove(fname_data_mean)
        os.remove(fname_data_std)

        # to view results
        sct.printv('\nDone! To view results, type:', self.param.verbose,
                   'normal')
        sct.printv('fslview ' + fname_tsnr + ' &\n', self.param.verbose,
                   'info')
示例#29
0
def generate_qc(fn_in, fn_seg, args, path_qc):
    """Generate a QC entry allowing to quickly review the segmentation process."""
    import spinalcordtoolbox.reports.qc as qc
    import spinalcordtoolbox.reports.slice as qcslice

    qc.add_entry(
        src=fn_in,
        process="sct_deepseg_sc",
        args=args,
        path_qc=path_qc,
        plane='Axial',
        qcslice=qcslice.Axial([Image(fn_in), Image(fn_seg)]),
        qcslice_operations=[qc.QcImage.listed_seg],
        qcslice_layout=lambda x: x.mosaic(),
    )
示例#30
0
    def symmetrizer(self, side='left'):
        """
        This function symmetrize the input image. One side of the image will be copied on the other side. We assume a
        RPI orientation.
        :param side: string 'left' or 'right'. Side that will be copied on the other side.
        :return:
        """
        image_output = Image(self.image_input, self.verbose)

        image_output[0:]

        """inspiration: (from atlas creation matlab script)
        temp_sum = temp_g + temp_d;
        temp_sum_flip = temp_sum(end:-1:1,:);
        temp_sym = (temp_sum + temp_sum_flip) / 2;

        temp_g(1:end / 2,:) = 0;
        temp_g(1 + end / 2:end,:) = temp_sym(1 + end / 2:end,:);
        temp_d(1:end / 2,:) = temp_sym(1:end / 2,:);
        temp_d(1 + end / 2:end,:) = 0;

        tractsHR
        {label_l}(:,:, num_slice_ref) = temp_g;
        tractsHR
        {label_r}(:,:, num_slice_ref) = temp_d;
        """

        return image_output
    def __init__(self, param=None, param_glcm=None):
        self.param = param if param is not None else Param()
        self.param_glcm = param_glcm if param_glcm is not None else ParamGLCM()

        # create tmp directory
        self.tmp_dir = tmp_create(verbose=self.param.verbose)  # path to tmp directory

        if self.param.dim == 'ax':
            self.orientation_extraction = 'RPI'
        elif self.param.dim == 'sag':
            self.orientation_extraction = 'IPR'
        else:
            self.orientation_extraction = 'IRP'

        # metric_lst=['property_distance_angle']
        self.metric_lst = []
        for m in list(itertools.product(self.param_glcm.feature.split(','), self.param_glcm.angle.split(','))):
            text_name = m[0] if m[0].upper() != 'asm'.upper() else m[0].upper()
            self.metric_lst.append(text_name + '_' + str(self.param_glcm.distance) + '_' + str(m[1]))

        # dct_im_seg{'im': list_of_axial_slice, 'seg': list_of_axial_masked_slice}
        self.dct_im_seg = {'im': None, 'seg': None}

        # to re-orient the data at the end if needed
        self.orientation_im = get_orientation(Image(self.param.fname_im))

        self.fname_metric_lst = {}
def load_manual_gmseg(list_slices_target,
                      list_fname_manual_gmseg,
                      tmp_dir,
                      im_sc_seg_rpi,
                      new_res,
                      square_size_size_mm,
                      for_model=False,
                      fname_mask=None):
    if isinstance(list_fname_manual_gmseg, str):
        # consider fname_manual_gmseg as a list of file names to allow multiple manual GM segmentation
        list_fname_manual_gmseg = [list_fname_manual_gmseg]

    for fname_manual_gmseg in list_fname_manual_gmseg:
        os.chdir('..')
        shutil.copy(fname_manual_gmseg, tmp_dir)
        # change fname level to only file name (path = tmp dir now)
        path_gm, file_gm, ext_gm = extract_fname(fname_manual_gmseg)
        fname_manual_gmseg = file_gm + ext_gm
        os.chdir(tmp_dir)

        im_manual_gmseg = Image(fname_manual_gmseg)

        # reorient to RPI
        im_manual_gmseg = set_orientation(im_manual_gmseg, 'RPI')

        if fname_mask is not None:
            fname_gmseg_crop = add_suffix(im_manual_gmseg.absolutepath,
                                          '_pre_crop')
            crop_im = ImageCropper(input_file=im_manual_gmseg.absolutepath,
                                   output_file=fname_gmseg_crop,
                                   mask=fname_mask)
            im_manual_gmseg_crop = crop_im.crop()
            im_manual_gmseg = im_manual_gmseg_crop

        # assert gmseg has the right number of slices
        assert im_manual_gmseg.data.shape[2] == len(
            list_slices_target
        ), 'ERROR: the manual GM segmentation has not the same number of slices than the image.'

        # interpolate gm to reference image
        nz_gmseg, nx_gmseg, ny_gmseg, nt_gmseg, pz_gmseg, px_gmseg, py_gmseg, pt_gmseg = im_manual_gmseg.dim

        list_im_gm = interpolate_im_to_ref(im_manual_gmseg,
                                           im_sc_seg_rpi,
                                           new_res=new_res,
                                           sq_size_size_mm=square_size_size_mm,
                                           interpolation_mode=0)

        # load gm seg in list of slices
        n_poped = 0
        for im_gm, slice_im in zip(list_im_gm, list_slices_target):
            if im_gm.data.max() == 0 and for_model:
                list_slices_target.pop(slice_im.id - n_poped)
                n_poped += 1
            else:
                slice_im.gm_seg.append(im_gm.data)
                wm_slice = (slice_im.im > 0) - im_gm.data
                slice_im.wm_seg.append(wm_slice)

    return list_slices_target
示例#33
0
    def __init__(self, fname_im, contrast, fname_seg, path_out, verbose):

        self.fname_im = fname_im
        self.contrast = contrast

        self.fname_seg = fname_seg

        self.path_out = path_out

        self.verbose = verbose

        self.tmp_dir = sct.tmp_create(
            verbose=self.verbose)  # path to tmp directory

        self.orientation_im = get_orientation(Image(
            self.fname_im))  # to re-orient the data at the end

        self.slice2D_im = sct.extract_fname(
            self.fname_im
        )[1] + '_midSag.nii'  # file used to do the detection, with only one slice
        self.dection_map_pmj = sct.extract_fname(
            self.fname_im)[1] + '_map_pmj'  # file resulting from the detection

        # path to the pmj detector
        path_sct = os.environ.get("SCT_DIR",
                                  os.path.dirname(os.path.dirname(__file__)))
        self.pmj_model = os.path.join(path_sct, 'data', 'pmj_models',
                                      '{}_model'.format(self.contrast))

        self.threshold = -0.75 if self.contrast == 't1' else 0.8  # detection map threshold, depends on the contrast

        self.fname_out = sct.extract_fname(self.fname_im)[1] + '_pmj.nii.gz'

        self.fname_qc = 'qc_pmj.png'
def apply_transfo(im_src, im_dest, warp, interp='spline', rm_tmp=True):
    # create tmp dir and go in it
    tmp_dir = sct.tmp_create()
    # copy warping field to tmp dir
    sct.copy(warp, tmp_dir)
    warp = ''.join(extract_fname(warp)[1:])
    # go to tmp dir
    curdir = os.getcwd()
    os.chdir(tmp_dir)
    # save image and seg
    fname_src = 'src.nii.gz'
    im_src.setFileName(fname_src)
    im_src.save()
    fname_dest = 'dest.nii.gz'
    im_dest.setFileName(fname_dest)
    im_dest.save()
    # apply warping field
    fname_src_reg = add_suffix(fname_src, '_reg')
    sct_apply_transfo.main(
        args=['-i', fname_src, '-d', fname_dest, '-w', warp, '-x', interp])

    im_src_reg = Image(fname_src_reg)
    # get out of tmp dir
    os.chdir(curdir)
    if rm_tmp:
        # remove tmp dir
        sct.rmtree(tmp_dir)
    # return res image
    return im_src_reg
def use_viewer_to_define_labels(fname_data, first_label, nb_of_slices_to_mean):
    from sct_viewer import ClickViewerGroundTruth
    from msct_image import Image
    import sct_image

    image_input = Image(fname_data)

    image_input_orientation = sct_image.orientation(image_input,
                                                    get=True,
                                                    verbose=False)
    reoriented_image_filename = 'reoriented_image_source.nii.gz'
    path_tmp_viewer = sct.tmp_create(verbose=False)
    cmd_image = 'sct_image -i "%s" -o "%s" -setorient SAL -v 0' % (
        fname_data, reoriented_image_filename)
    sct.run(cmd_image, verbose=False)

    im_input_SAL = prepare_input_image_for_viewer(fname_data)
    viewer = ClickViewerGroundTruth(im_input_SAL,
                                    first_label,
                                    orientation_subplot=['sag', 'ax'])
    set_viewer_parameters(viewer, nb_of_slices_to_mean)

    mask_points = viewer.start()
    if not mask_points and viewer.closed:
        mask_points = viewer.list_points_useful_notation
    make_labels_image_from_list_points(mask_points, reoriented_image_filename,
                                       image_input_orientation)
def test_integrity(param_test):
    """
    Test integrity of function
    """
    path_data = os.path.join(param_test.path_data, param_test.contrast,
                             param_test.file_input)
    integrity_value = 1.0

    # open output segmentation
    try:
        im_seg_manual = Image(path_data)
    except:
        param_test.output += 'ERROR: Cannot open ground truth segmentation: ' + path_data
        param_test.status = 99
        return param_test

    # compute dice coefficient between generated image and image from database
    dice_segmentation = compute_dice(im_seg_manual,
                                     im_seg_manual,
                                     mode='3d',
                                     zboundaries=False)

    param_test.output += 'Computed dice: ' + str(dice_segmentation)

    if dice_segmentation != integrity_value:
        param_test.output += '\nERROR: Dice coefficient should be : ' + str(
            integrity_value)
        param_test.status = 99

    return param_test
示例#37
0
    def compute(self):

        fname_data = self.fmri

        # open data
        nii_data = Image(fname_data)
        data = nii_data.data

        # compute mean
        data_mean = np.mean(data, 3)
        # compute STD
        data_std = np.std(data, 3, ddof=1)
        # compute TSNR
        data_tsnr = data_mean / data_std

        # save TSNR
        fname_tsnr = sct.add_suffix(fname_data, '_tsnr')
        nii_tsnr = nii_data
        nii_tsnr.data = data_tsnr
        nii_tsnr.setFileName(fname_tsnr)
        nii_tsnr.save(type='float32')

        # to view results
        sct.printv('\nDone! To view results, type:', self.param.verbose, 'normal')
        sct.printv('fslview ' + fname_tsnr + ' &\n', self.param.verbose, 'info')
示例#38
0
def viewer_centerline(image_fname, interslice_gap, verbose):
    image_input_reoriented = Image(image_fname)
    nx, ny, nz, nt, px, py, pz, pt = image_input_reoriented.dim
    viewer = ClickViewerPropseg(image_input_reoriented)

    viewer.gap_inter_slice = int(
        interslice_gap /
        px)  # px because the image is supposed to be SAL orientation
    viewer.number_of_slices = 0
    viewer.calculate_list_slices()

    # start the viewer that ask the user to enter a few points along the spinal cord
    mask_points = viewer.start()

    if not mask_points and viewer.closed:
        mask_points = viewer.list_points_useful_notation

    if mask_points:
        # create the mask containing either the three-points or centerline mask for initialization
        mask_filename = sct.add_suffix(image_fname, "_mask_viewer")
        sct.run("sct_label_utils -i " + image_fname + " -create " +
                mask_points + " -o " + mask_filename,
                verbose=False)

        fname_output = mask_filename

    else:
        sct.printv(
            '\nERROR: the viewer has been closed before entering all manual points. Please try again.',
            1,
            type='error')
        fname_output = None

    return fname_output
def pad_im(fname_im, nx_full, ny_full, nz_full, xi, xf, yi, yf, zi, zf):
    fname_im_pad = sct.add_suffix(fname_im, '_pad')
    pad_xi = str(xi)
    pad_xf = str(nx_full - (xf + 1))
    pad_yi = str(yi)
    pad_yf = str(ny_full - (yf + 1))
    pad_zi = str(zi)
    pad_zf = str(nz_full - (zf + 1))
    pad = ','.join([pad_xi, pad_xf, pad_yi, pad_yf, pad_zi, pad_zf])
    if len(Image(fname_im).data.shape) == 5:
        status, output = sct.run('sct_image -i ' + fname_im + ' -mcs')
        s = 'Created file(s):\n-->'
        output_fnames = output[output.find(s) +
                               len(s):].split('\n')[0].split("'")
        fname_comp_list = [
            output_fnames[i] for i in range(1, len(output_fnames), 2)
        ]
        fname_comp_pad_list = []
        for fname_comp in fname_comp_list:
            fname_comp_pad = sct.add_suffix(fname_comp, '_pad')
            sct.run('sct_image -i ' + fname_comp + ' -pad-asym ' + pad +
                    ' -o ' + fname_comp_pad)
            fname_comp_pad_list.append(fname_comp_pad)
        components = ','.join(fname_comp_pad_list)
        sct.run('sct_image -i ' + components + ' -omc -o ' + fname_im_pad)
        sct.check_file_exist(fname_im_pad, verbose=1)
    else:
        sct.run('sct_image -i ' + fname_im + ' -pad-asym ' + pad + ' -o ' +
                fname_im_pad)
    return fname_im_pad
示例#40
0
def compute_mtsat_from_file(fname_mt, fname_pd, fname_t1, tr_mt, tr_pd, tr_t1, fa_mt, fa_pd, fa_t1, fname_b1map=None,
                            fname_mtsat=None, fname_t1map=None, verbose=1):
    """
    Compute MTsat and T1map.
    :param fname_mt:
    :param fname_pd:
    :param fname_t1:
    :param tr_mt:
    :param tr_pd:
    :param tr_t1:
    :param fa_mt:
    :param fa_pd:
    :param fa_t1:
    :param fname_b1map:
    :param fname_mtsat:
    :param fname_t1map:
    :param verbose:
    :return: fname_mtsat: file name for MTsat map
    :return: fname_t1map: file name for T1 map
    """
    # load data
    sct.printv('Load data...', verbose)
    nii_mt = Image(fname_mt)
    nii_pd = Image(fname_pd)
    nii_t1 = Image(fname_t1)
    if fname_b1map is None:
        nii_b1map = None
    else:
        nii_b1map = Image(fname_b1map)

    # compute MTsat
    nii_mtsat, nii_t1map = compute_mtsat(nii_mt, nii_pd, nii_t1, tr_mt, tr_pd, tr_t1, fa_mt, fa_pd, fa_t1,
                                         nii_b1map=nii_b1map, verbose=verbose)

    # Output MTsat and T1 maps
    # by default, output in the same directory as the input images
    sct.printv('Generate output files...', verbose)
    if fname_mtsat is None:
        fname_mtsat = os.path.join(nii_mt.path, "mtsat.nii.gz")
    nii_mtsat.setFileName(fname_mtsat)
    nii_mtsat.save()
    if fname_t1map is None:
        fname_t1map = os.path.join(nii_mt.path, "t1map.nii.gz")
    nii_t1map.setFileName(fname_t1map)
    nii_t1map.save()

    return fname_mtsat, fname_t1map
def label_segmentation(fname_seg, list_disc_z, list_disc_value, verbose=1):
    """
    Label segmentation image
    :param fname_seg: fname of the segmentation
    :param list_disc_z: list of z that correspond to a disc
    :param list_disc_value: list of associated disc values
    :param verbose:
    :return:
    """
    # open segmentation
    seg = Image(fname_seg)
    dim = seg.dim
    ny = dim[1]
    nz = dim[2]
    # loop across z
    for iz in range(nz):
        # get index of the disc right above iz
        try:
            ind_above_iz = max(
                [i for i in range(len(list_disc_z)) if list_disc_z[i] > iz])
        except ValueError:
            # if ind_above_iz is empty, attribute value 0
            vertebral_level = 0
        else:
            # assign vertebral level (add one because iz is BELOW the disk)
            vertebral_level = list_disc_value[ind_above_iz] + 1
            # sct.printv(vertebral_level)
        # get voxels in mask
        ind_nonzero = np.nonzero(seg.data[:, :, iz])
        seg.data[ind_nonzero[0], ind_nonzero[1], iz] = vertebral_level
        if verbose == 2:
            import matplotlib
            matplotlib.use('Agg')
            import matplotlib.pyplot as plt
            plt.figure(50)
            plt.scatter(int(round(ny / 2)),
                        iz,
                        c=vertebral_level,
                        vmin=min(list_disc_value),
                        vmax=max(list_disc_value),
                        cmap='prism',
                        marker='_',
                        s=200)
    # write file
    seg.file_name += '_labeled'
    seg.save()
def get_minimum_path_nii(fname):
    from msct_image import Image
    data = Image(fname)
    vesselness_data = data.data
    raw_orient = data.change_orientation()
    result, J1, J2 = get_minimum_path(data.data, invert=1)
    data.data = result
    data.change_orientation(raw_orient)
    data.file_name += '_minimalpath'
    data.save()
示例#43
0
    def execute(self):
        """
        This method executes the symmetry detection
        :return: returns the symmetry data
        """
        img = Image(self.input_image)
        raw_orientation = img.change_orientation()
        data = np.squeeze(img.data)
        dim = data.shape
        section_length = dim[1]/self.nb_sections

        result = np.zeros(dim)

        for i in range(0, self.nb_sections):
            if (i+1)*section_length > dim[1]:
                y_length = (i+1)*section_length - ((i+1)*section_length - dim[1])
                result[:, i*section_length:i*section_length + y_length, :] = symmetry_detector_right_left(data[:, i*section_length:i*section_length + y_length, :],  cropped_xy=self.crop_xy)
            sym = symmetry_detector_right_left(data[:, i*section_length:(i+1)*section_length, :], cropped_xy=self.crop_xy)
            result[:, i*section_length:(i+1)*section_length, :] = sym

        result_image = Image(img)
        if len(result_image.data) == 4:
            result_image.data = result[:,:,:,np.newaxis]
        else:
            result_image.data = result

        result_image.change_orientation(raw_orientation)

        return result_image.data
示例#44
0
    def __init__(self, fname_label, fname_output=None, fname_ref=None, cross_radius=5, dilate=False,
                 coordinates=None, verbose=1):
        self.image_input = Image(fname_label, verbose=verbose)

        if fname_ref is not None:
            self.image_ref = Image(fname_ref, verbose=verbose)

        if isinstance(fname_output, list):
            if len(fname_output) == 1:
                self.fname_output = fname_output[0]
            else:
                self.fname_output = fname_output
        else:
            self.fname_output = fname_output
        self.cross_radius = cross_radius
        self.dilate = dilate
        self.coordinates = coordinates
        self.verbose = verbose
示例#45
0
def get_minimum_path_nii(fname):
    from msct_image import Image
    data=Image(fname)
    vesselness_data = data.data
    raw_orient=data.change_orientation()
    data.data=get_minimum_path(data.data, invert=1)
    data.change_orientation(raw_orient)
    data.file_name += '_minimalpath'
    data.save()
示例#46
0
def label_segmentation(fname_seg, list_disc_z, list_disc_value, verbose=1):
    """
    Label segmentation image
    :param fname_seg: fname of the segmentation
    :param list_disc_z: list of z that correspond to a disc
    :param list_disc_value: list of associated disc values
    :param verbose:
    :return:
    """
    # open segmentation
    seg = Image(fname_seg)
    dim = seg.dim
    ny = dim[1]
    nz = dim[2]
    # open labeled discs
    im_discs = Image(fname_seg)
    # loop across z
    for iz in range(nz):
        # get index of the disc right above iz
        try:
            ind_above_iz = max([i for i in range(len(list_disc_z)) if list_disc_z[i] > iz])
        except ValueError:
            # if ind_above_iz is empty, attribute value 0
            vertebral_level = 0
        else:
            # assign vertebral level (add one because iz is BELOW the disk)
            vertebral_level = list_disc_value[ind_above_iz] + 1
            # print vertebral_level
        # get voxels in mask
        ind_nonzero = np.nonzero(seg.data[:, :, iz])
        seg.data[ind_nonzero[0], ind_nonzero[1], iz] = vertebral_level
        if verbose == 2:
            import matplotlib
            matplotlib.use('Agg')
            import matplotlib.pyplot as plt
            plt.figure(50)
            plt.scatter(int(round(ny/2)), iz, c=vertebral_level, vmin=min(list_disc_value), vmax=max(list_disc_value), cmap='prism', marker='_', s=200)
    # write file
    seg.file_name += '_labeled'
    seg.save()
    def __init__(self, target_fname, sc_seg_fname, t2_data=None, denoising=True):

        self.t2star = 't2star.nii.gz'
        self.sc_seg = 't2star_sc_seg.nii.gz'
        self.t2 = 't2.nii.gz'
        self.t2_seg = 't2_seg.nii.gz'
        self.t2_landmarks = 't2_landmarks.nii.gz'
        self.resample_to = 0.3

        sct.run('cp ../' + target_fname + ' ./' + self.t2star)
        sct.run('cp ../' + sc_seg_fname + ' ./' + self.sc_seg)

        nx, ny, nz, nt, self.original_px, self.original_py, pz, pt = sct.get_dimension(self.t2star)

        if round(self.original_px, 2) != self.resample_to or round(self.original_py, 2) != self.resample_to:
            self.t2star = resample_image(self.t2star, npx=self.resample_to, npy=self.resample_to)
            self.sc_seg = resample_image(self.sc_seg, binary=True, npx=self.resample_to, npy=self.resample_to)

        t2star_im = Image(self.t2star)
        if denoising:
            t2star_im.denoise_ornlm()
            t2star_im.save()
            self.t2star = t2star_im.file_name + t2star_im.ext
        '''
        status, t2_star_orientation = sct.run('sct_orientation -i ' + self.t2star)
        self.original_orientation = t2_star_orientation[4:7]
        '''
        self.original_orientation = t2star_im.orientation

        self.square_mask = crop_t2_star(self.t2star, self.sc_seg, box_size=75)

        self.treated_target = sct.extract_fname(self.t2star)[1] + '_seg_in_croped.nii.gz'

        self.level_fname = None
        if t2_data is not None:
            sct.run('cp ../' + t2_data[0] + ' ./' + self.t2)
            sct.run('cp ../' + t2_data[1] + ' ./' + self.t2_seg)
            sct.run('cp ../' + t2_data[2] + ' ./' + self.t2_landmarks)

            self.level_fname = compute_level_file(self.t2star, self.sc_seg, self.t2, self.t2_seg, self.t2_landmarks)
def concat_data(fname_in, fname_out, dim):
    """
    Concatenate data
    :param fname_in: list of file names.
    :param fname_out:
    :param dim: dimension: 0, 1, 2, 3.
    :return: none
    """
    # create empty list
    list_data = []

    # loop across files
    for i in range(len(fname_in)):
        # append data to list
        list_data.append(Image(fname_in[i]).data)

    # expand dimension of all elements in the list if necessary
    if dim > list_data[0].ndim-1:
        list_data = [expand_dims(i, dim) for i in list_data]
    # concatenate
    try:
        data_concat = concatenate(list_data, axis=dim)
    except Exception as e:
        sct.printv('\nERROR: Concatenation on line {}'.format(sys.exc_info()[-1].tb_lineno)+'\n'+str(e)+'\n', 1, 'error')

    # write file
    im = Image(fname_in[0])
    im.data = data_concat
    im.setFileName(fname_out)
    im.save()
示例#49
0
    def crop_from_mask_with_background(self):
        from numpy import asarray, einsum
        image_in = Image(self.input_filename)
        data_array = asarray(image_in.data)
        data_mask = asarray(Image(self.mask).data)
        assert data_array.shape == data_mask.shape

        # Element-wise matrix multiplication:
        new_data = None
        dim = len(data_array.shape)
        if dim == 3:
            new_data = einsum('ijk,ijk->ijk', data_mask, data_array)
        elif dim == 2:
            new_data = einsum('ij,ij->ij', data_mask, data_array)

        if self.background != 0:
            from sct_maths import get_data_or_scalar
            data_background = get_data_or_scalar(str(self.background), data_array)
            data_mask_inv = data_mask.max() - data_mask
            if dim == 3:
                data_background = einsum('ijk,ijk->ijk', data_mask_inv, data_background)
            elif dim == 2:
                data_background = einsum('ij,ij->ij', data_mask_inv, data_background)
            new_data += data_background

        # set image out
        image_in.setFileName(self.output_filename)
        image_in.data = new_data
        image_in.save()
def main(args = None):

    dim_list = ['x', 'y', 'z', 't']

    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])
    fname_in = arguments["-i"]
    fname_out = arguments["-o"]
    verbose = int(arguments['-v'])

    # Build fname_out
    if fname_out == '':
        path_in, file_in, ext_in = extract_fname(fname_in)
        fname_out = path_in+file_in+'_mean'+ext_in

    # Open file.
    nii = Image(fname_in)
    data = nii.data

    # run command
    if '-otsu' in arguments:
        param = arguments['-otsu']
        data_out = otsu(data, param)
    elif '-otsu_adap' in arguments:
        param = arguments['-otsu_adap']
        data_out = otsu_adap(data, param[0], param[1])
    elif '-otsu_median' in arguments:
        param = arguments['-otsu_median']
        data_out = otsu_median(data, param[0], param[1])
    elif '-thr' in arguments:
        param = arguments['-thr']
        data_out = threshold(data, param)
    elif '-percent' in arguments:
        param = arguments['-percent']
        data_out = perc(data, param)
    elif '-mean' in arguments:
        dim = dim_list.index(arguments['-mean'])
        data_out = compute_mean(data, dim)
    elif '-std' in arguments:
        dim = dim_list.index(arguments['-std'])
        data_out = compute_std(data, dim)
    elif '-dilate' in arguments:
        data_out = dilate(data, arguments['-dilate'])
    elif '-erode' in arguments:
        data_out = erode(data, arguments['-dilate'])
    else:
        printv('No process applied.', 1, 'warning')
        return

    # Write output
    nii.data = data_out
    nii.setFileName(fname_out)
    nii.save()

    # display message
    printv('Created file:\n--> '+fname_out+'\n', verbose, 'info')
示例#51
0
def clean_labeled_segmentation(fname_labeled_seg, fname_seg, fname_labeled_seg_new):
    """
    Clean labeled segmentation by:
      (i)  removing voxels in segmentation_labeled that are not in segmentation and
      (ii) adding voxels in segmentation that are not in segmentation_labeled
    :param fname_labeled_seg:
    :param fname_seg:
    :param fname_labeled_seg_new: output
    :return: none
    """
    # remove voxels in segmentation_labeled that are not in segmentation
    run('sct_maths -i '+fname_labeled_seg+' -mul '+fname_seg+' -o segmentation_labeled_mul.nii.gz')
    # add voxels in segmentation that are not in segmentation_labeled
    run('sct_maths -i '+fname_labeled_seg+' -dilate 2 -o segmentation_labeled_dilate.nii.gz')  # dilate labeled segmentation
    data_label_dilate = Image('segmentation_labeled_dilate.nii.gz').data
    run('sct_maths -i segmentation_labeled_mul.nii.gz -bin 0 -o segmentation_labeled_mul_bin.nii.gz')
    data_label_bin = Image('segmentation_labeled_mul_bin.nii.gz').data
    data_seg = Image(fname_seg).data
    data_diff = data_seg - data_label_bin
    ind_nonzero = np.where(data_diff)
    im_label = Image('segmentation_labeled_mul.nii.gz')
    for i_vox in range(len(ind_nonzero[0])):
        # assign closest label value for this voxel
        ix, iy, iz = ind_nonzero[0][i_vox], ind_nonzero[1][i_vox], ind_nonzero[2][i_vox]
        im_label.data[ix, iy, iz] = data_label_dilate[ix, iy, iz]
    # save new label file (overwrite)
    im_label.setFileName(fname_labeled_seg_new)
    im_label.save()
def set_orientation(fname_in, orientation, fname_out, inversion=False):
    if not inversion:
        sct.run('isct_orientation3d -i '+fname_in+' -orientation '+orientation+' -o '+fname_out, 0)
    else:
        from msct_image import Image
        input_image = Image(fname_in)
        input_image.change_orientation(orientation, True)
        input_image.setFileName(fname_out)
        input_image.save()
    # return full path
    return os.path.abspath(fname_out)
示例#53
0
    def __init__(self, fname):
        self.image = Image(fname)

        self.pretreated_im = self.pretreat()

        self.result_im = self.image.copy()
        self.result_im.file_name = self.image.file_name + '_vessel_mask'
        self.result_im.path = './'

        self.hess = hessian(self.pretreated_im.data)
        self.vessel_mask = self.compute_vessel_mask()

        self.result_im.data = self.vessel_mask
        self.result_im.save()
    def __init__(
        self,
        fname_gm,
        fname_wm,
        path_template,
        fname_warp_template2target,
        param=None,
        fname_warp_target2template=None,
        apply_warp_template=0,
    ):
        if param is None:
            self.param = Param()
        else:
            self.param = param
        self.im_gm = Image(fname_gm)
        self.im_wm = Image(fname_wm)
        self.path_template = sct.slash_at_the_end(path_template, 1)
        if "MNI-Poly-AMU_GM.nii.gz" in os.listdir(self.path_template + "template/"):
            self.im_template_gm = Image(self.path_template + "template/MNI-Poly-AMU_GM.nii.gz")
            self.im_template_wm = Image(self.path_template + "template/MNI-Poly-AMU_WM.nii.gz")
            self.template = "MNI-Poly-AMU"
        else:
            self.im_template_gm = Image(self.path_template + "template/PAM50_gm.nii.gz")
            self.im_template_wm = Image(self.path_template + "template/PAM50_wm.nii.gz")
            self.template = "PAM50"

        # Previous warping fields:
        self.fname_warp_template2target = fname_warp_template2target
        self.fname_warp_target2template = fname_warp_target2template

        # new warping fields:
        self.fname_warp_template2gm = ""
        self.fname_wwarp_gm2template = ""

        # temporary fix - related to issue #871
        self.apply_warp_template = apply_warp_template
    def segment(self):
        before = time.time()
        sct.run('mkdir ' + self.tmp_dir)

        self.segmentation_pipeline()

        # Generate output files:
        for res_fname in self.res_names.values():
            sct.generate_output_file(self.tmp_dir+res_fname, self.seg_param.output_path+res_fname)
        if self.ref_gm_seg_fname is not None:
            sct.generate_output_file(self.tmp_dir+self.dice_name, self.seg_param.output_path+self.dice_name)
            sct.generate_output_file(self.tmp_dir+self.hausdorff_name, self.seg_param.output_path+self.hausdorff_name)
        if compute_ratio:
            sct.generate_output_file(self.tmp_dir+self.ratio_name, self.seg_param.output_path+self.ratio_name)

        after = time.time()
        sct.printv('Done! (in ' + str(after-before) + ' sec) \nTo see the result, type :')
        if self.seg_param.res_type == 'binary':
            wm_col = 'Red'
            gm_col = 'Blue'
            b = '0,1'
        else:
            wm_col = 'Blue-Lightblue'
            gm_col = 'Red-Yellow'
            b = '0.3,1'
        sct.printv('fslview ' + self.target_fname + ' '+self.seg_param.output_path+self.res_names['wm_seg']+' -l '+wm_col+' -t 0.4 -b '+b+' '+self.seg_param.output_path+self.res_names['gm_seg']+' -l '+gm_col+' -t 0.4  -b '+b+' &', self.seg_param.verbose, 'info')

        if self.seg_param.qc:
            # output QC image
            im = Image(self.target_fname)
            im_gmseg = Image(self.seg_param.output_path+self.res_names['gm_seg'])
            im.save_quality_control(plane='axial', n_slices=5, seg=im_gmseg, thr=float(b.split(',')[0]), cmap_col='red-yellow', path_output=self.seg_param.output_path)

        if self.seg_param.remove_tmp:
            sct.printv('Remove temporary folder ...', self.seg_param.verbose, 'normal')
            sct.run('rm -rf '+self.tmp_dir)
def register_seg(seg_input, seg_dest):
    seg_input_img = Image(seg_input)
    seg_dest_img = Image(seg_dest)
    seg_input_data = seg_input_img.data
    seg_dest_data = seg_dest_img.data

    x_center_of_mass_input = [0 for i in range(seg_dest_data.shape[2])]
    y_center_of_mass_input = [0 for i in range(seg_dest_data.shape[2])]
    print "\nGet center of mass of the input segmentation for each slice (corresponding to a slice in the output segmentation)..."  # different if size of the two seg are different
    # TO DO: select only the slices corresponding to the output segmentation
    coord_origin_dest = seg_dest_img.transfo_pix2phys([[0, 0, 0]])
    [[x_o, y_o, z_o]] = seg_input_img.transfo_phys2pix(coord_origin_dest)
    for iz in xrange(seg_dest_data.shape[2]):
        print iz
        x_center_of_mass_input[iz], y_center_of_mass_input[iz] = ndimage.measurements.center_of_mass(
            array(seg_input_data[:, :, z_o + iz])
        )

    x_center_of_mass_output = [0 for i in range(seg_dest_data.shape[2])]
    y_center_of_mass_output = [0 for i in range(seg_dest_data.shape[2])]
    print "\nGet center of mass of the output segmentation for each slice ..."
    for iz in xrange(seg_dest_data.shape[2]):
        x_center_of_mass_output[iz], y_center_of_mass_output[iz] = ndimage.measurements.center_of_mass(
            array(seg_dest_data[:, :, iz])
        )

    x_displacement = [0 for i in range(seg_input_data.shape[2])]
    y_displacement = [0 for i in range(seg_input_data.shape[2])]
    print "\nGet displacement by voxel..."
    for iz in xrange(seg_dest_data.shape[2]):
        x_displacement[iz] = -(
            x_center_of_mass_output[iz] - x_center_of_mass_input[iz]
        )  # strangely, this is the inverse of x_displacement when the same equation defines y_displacement
        y_displacement[iz] = y_center_of_mass_output[iz] - y_center_of_mass_input[iz]

    return x_displacement, y_displacement
示例#57
0
def resample_image(fname, suffix='_resampled.nii.gz', binary=False, npx=0.3, npy=0.3, thr=0.0, interpolation='spline'):
    """
    Resampling function: add a padding, resample, crop the padding
    :param fname: name of the image file to be resampled
    :param suffix: suffix added to the original fname after resampling
    :param binary: boolean, image is binary or not
    :param npx: new pixel size in the x direction
    :param npy: new pixel size in the y direction
    :param thr: if the image is binary, it will be thresholded at thr (default=0) after the resampling
    :param interpolation: type of interpolation used for the resampling
    :return: file name after resampling (or original fname if it was already in the correct resolution)
    """
    im_in = Image(fname)
    orientation = get_orientation_3d(im_in)
    if orientation != 'RPI':
        im_in = set_orientation(im_in, 'RPI')
        im_in.save()
        fname = im_in.absolutepath
    nx, ny, nz, nt, px, py, pz, pt = im_in.dim

    if round(px, 2) != round(npx, 2) or round(py, 2) != round(npy, 2):
        name_resample = sct.extract_fname(fname)[1] + suffix
        if binary:
            interpolation = 'nn'

        sct.run('sct_resample -i '+fname+' -mm '+str(npx)+'x'+str(npy)+'x'+str(pz)+' -o '+name_resample+' -x '+interpolation)

        if binary:
            # sct.run('sct_maths -i ' + name_resample + ' -thr ' + str(thr) + ' -o ' + name_resample)
            sct.run('sct_maths -i ' + name_resample + ' -bin ' + str(thr) + ' -o ' + name_resample)

        if orientation != 'RPI':
            im_resample = Image(name_resample)
            im_resample = set_orientation(im_resample, orientation)
            im_resample.save()
            name_resample = im_resample.absolutepath
        return name_resample
    else:
        if orientation != 'RPI':
            im_in = set_orientation(im_in, orientation)
            im_in.save()
            fname = im_in.absolutepath
        sct.printv('Image resolution already ' + str(npx) + 'x' + str(npy) + 'xpz')
        return fname
def copy_header(fname_src, fname_dest):
    """
    Copy header
    :param fname_src: source file name
    :param fname_dest: destination file name
    :return:
    """
    nii_src = Image(fname_src)
    data_dest = Image(fname_dest).data
    nii_src.setFileName(fname_dest)
    nii_src.data = data_dest
    nii_src.save()
示例#59
0
def convert(fname_in, fname_out, squeeze_data=True, type=None, verbose=1):
    """
    Convert data
    :return True/False
    """
    from msct_image import Image
    from sct_utils import printv
    printv('sct_convert -i '+fname_in+' -o '+fname_out, verbose, 'code')
    # Open file
    im = Image(fname_in)
    # Save file
    im.setFileName(fname_out)
    if type is not None:
        im.changeType(type=type)
    im.save(squeeze_data=squeeze_data)
    return im
 def output_debug_file(self, img, data, file_name):
     """
     This method writes a nifti file that corresponds to a step in the algorithm for easy debug.
     The new nifti file uses the header from the the image passed as parameter
     :param data: data to be written to file
     :param file_name: filename...
     :return: None
     """
     if self.verbose == 2:
         current_folder = os.getcwd()
         # os.chdir(self.path_tmp)
         try:
             img = Image(img)
             img.data = data
             img.change_orientation(self.raw_orientation)
             img.file_name = file_name
             img.save()
         except Exception, e:
             print e