def validation(self):
        name_ref_gm_seg = sct.extract_fname(self.ref_gm_seg)
        im_ref_gm_seg = Image('../' + self.ref_gm_seg)

        res_gm_seg_bin = Image('../' + self.res_names['gm_seg'])
        res_wm_seg_bin = Image('../' + self.res_names['wm_seg'])

        sct.run('cp ../' + self.ref_gm_seg + ' ./ref_gm_seg.nii.gz')
        im_ref_wm_seg = inverse_gmseg_to_wmseg(im_ref_gm_seg, Image('../' + self.sc_seg_fname), 'ref_gm_seg')
        im_ref_wm_seg.file_name = 'ref_wm_seg'
        im_ref_wm_seg.ext = '.nii.gz'
        im_ref_wm_seg.save()

        if self.param.res_type == 'prob':
            res_gm_seg_bin.data = np.asarray((res_gm_seg_bin.data >= 0.5).astype(int))
            res_wm_seg_bin.data = np.asarray((res_wm_seg_bin.data >= 0.50001).astype(int))

        res_gm_seg_bin.path = './'
        res_gm_seg_bin.file_name = 'res_gm_seg_bin'
        res_gm_seg_bin.ext = '.nii.gz'
        res_gm_seg_bin.save()
        res_wm_seg_bin.path = './'
        res_wm_seg_bin.file_name = 'res_wm_seg_bin'
        res_wm_seg_bin.ext = '.nii.gz'
        res_wm_seg_bin.save()
        try:
            status_gm, output_gm = sct.run('sct_dice_coefficient ref_gm_seg.nii.gz res_gm_seg_bin.nii.gz  -2d-slices 2', error_exit='warning', raise_exception=True)
        except Exception:
            sct.run('c3d res_gm_seg_bin.nii.gz  ref_gm_seg.nii.gz -reslice-identity -o ref_in_res_space_gm.nii.gz ')
            status_gm, output_gm = sct.run('sct_dice_coefficient ref_in_res_space_gm.nii.gz res_gm_seg_bin.nii.gz  -2d-slices 2', error_exit='warning')
        try:
            status_wm, output_wm = sct.run('sct_dice_coefficient ref_wm_seg.nii.gz res_wm_seg_bin.nii.gz  -2d-slices 2', error_exit='warning', raise_exception=True)
        except Exception:
            sct.run('c3d res_wm_seg_bin.nii.gz  ref_wm_seg.nii.gz -reslice-identity -o ref_in_res_space_wm.nii.gz ')
            status_wm, output_wm = sct.run('sct_dice_coefficient ref_in_res_space_wm.nii.gz res_wm_seg_bin.nii.gz  -2d-slices 2', error_exit='warning')
        dice_name = 'dice_' + self.param.res_type + '.txt'
        dice_fic = open('../' + dice_name, 'w')
        if self.param.res_type == 'prob':
            dice_fic.write('WARNING : the probabilistic segmentations were binarized with a threshold at 0.5 to compute the dice coefficient \n')
        dice_fic.write('\n--------------------------------------------------------------\nDice coefficient on the Gray Matter segmentation:\n')
        dice_fic.write(output_gm)
        dice_fic.write('\n\n--------------------------------------------------------------\nDice coefficient on the White Matter segmentation:\n')
        dice_fic.write(output_wm)
        dice_fic.close()
        # sct.run(' mv ./' + dice_name + ' ../')

        return dice_name
 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()
 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()
 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
 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.produce_output:
         current_folder = os.getcwd()
         os.chdir(self.debug_folder)
         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
         os.chdir(current_folder)
    def execute(self):
        print 'Execution of the SCAD algorithm in ' + str(os.getcwd())

        original_name = self.input_image.file_name
        vesselness_file_name = "imageVesselNessFilter.nii.gz"
        raw_file_name = "raw.nii"

        self.setup_debug_folder()

        if self.debug:
            import matplotlib.pyplot as plt  # import for debug purposes

        # create tmp and copy input
        path_tmp = self.create_temporary_path()
        conv.convert(self.input_image.absolutepath, path_tmp + raw_file_name)

        if self.vesselness_provided:
            sct.run('cp ' + vesselness_file_name + ' ' + path_tmp +
                    vesselness_file_name)
        os.chdir(path_tmp)

        # get input image information
        img = Image(raw_file_name)

        # save original orientation and change image to RPI
        self.raw_orientation = img.change_orientation()

        # get body symmetry
        if self.enable_symmetry:
            from msct_image import change_data_orientation
            sym = SymmetryDetector(raw_file_name, self.contrast, crop_xy=0)
            self.raw_symmetry = sym.execute()
            img.change_orientation(self.raw_orientation)
            self.output_debug_file(img, self.raw_symmetry, "body_symmetry")
            img.change_orientation()

        # vesselness filter
        if not self.vesselness_provided:
            sct.run('isct_vesselness -i ' + raw_file_name + ' -t ' +
                    self._contrast + " -radius " + str(self.spinalcord_radius))

        # load vesselness filter data and perform minimum path on it
        img = Image(vesselness_file_name)
        self.output_debug_file(img, img.data, "Vesselness_Filter")
        img.change_orientation()
        self.minimum_path_data, self.J1_min_path, self.J2_min_path = get_minimum_path(
            img.data, invert=1, debug=1)
        self.output_debug_file(img, self.minimum_path_data, "minimal_path")
        self.output_debug_file(img, self.J1_min_path, "J1_minimal_path")
        self.output_debug_file(img, self.J2_min_path, "J2_minimal_path")

        # Apply an exponent to the minimum path
        self.minimum_path_powered = np.power(self.minimum_path_data,
                                             self.minimum_path_exponent)
        self.output_debug_file(
            img, self.minimum_path_powered,
            "minimal_path_power_" + str(self.minimum_path_exponent))

        # Saving in Image since smooth_minimal_path needs pixel dimensions
        img.data = self.minimum_path_powered

        # smooth resulting minimal path
        self.smoothed_min_path = smooth_minimal_path(img)
        self.output_debug_file(img, self.smoothed_min_path.data,
                               "minimal_path_smooth")

        # normalise symmetry values between 0 and 1
        if self.enable_symmetry:
            normalised_symmetry = normalize_array_histogram(self.raw_symmetry)
            self.output_debug_file(img, self.smoothed_min_path.data,
                                   "minimal_path_smooth")

            # multiply normalised symmetry data with the minimum path result
            from msct_image import change_data_orientation
            self.spine_detect_data = np.multiply(
                self.smoothed_min_path.data,
                change_data_orientation(
                    np.power(normalised_symmetry, self.symmetry_exponent),
                    self.raw_orientation, "RPI"))
            self.output_debug_file(img, self.spine_detect_data,
                                   "symmetry_x_min_path")
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(
                self.spine_detect_data, self.spine_detect_data.shape)
        else:
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(
                self.smoothed_min_path.data, self.smoothed_min_path.data.shape)
        self.output_debug_file(img, self.centerline_with_outliers,
                               "centerline_with_outliers")

        # saving centerline with outliers to have
        img.data = self.centerline_with_outliers
        img.change_orientation()
        img.file_name = "centerline_with_outliers"
        img.save()

        # use a b-spline to smooth out the centerline
        x, y, z, dx, dy, dz = smooth_centerline(
            "centerline_with_outliers.nii.gz")

        # save the centerline
        nx, ny, nz, nt, px, py, pz, pt = img.dim
        img.data = np.zeros((nx, ny, nz))
        for i in range(0, np.size(x) - 1):
            img.data[int(x[i]), int(y[i]), int(z[i])] = 1

        self.output_debug_file(img, img.data, "centerline")
        img.change_orientation(self.raw_orientation)
        img.file_name = "centerline"
        img.save()

        # copy back centerline
        os.chdir('../')
        conv.convert(path_tmp + img.file_name + img.ext, self.output_filename)
        if self.rm_tmp_file == 1:
            import shutil
            shutil.rmtree(path_tmp)

        print "To view the output with FSL :"
        sct.printv(
            "fslview " + self.input_image.absolutepath + " " +
            self.output_filename + " -l Red", self.verbose, "info")
    def validation(self):
        ext = '.nii.gz'
        validation_dir = 'validation'
        sct.run('mkdir ' + validation_dir)

        # loading the images
        im_ref_gm_seg = Image('../' + self.ref_gm_seg_fname)
        im_ref_wm_seg = inverse_gmseg_to_wmseg(
            im_ref_gm_seg,
            Image('../' + self.sc_seg_fname),
            im_ref_gm_seg.path + im_ref_gm_seg.file_name,
            save=False)

        res_gm_seg_bin = self.gm_seg.res_gm_seg.copy()
        res_wm_seg_bin = self.gm_seg.res_wm_seg.copy()

        if self.param.res_type == 'prob':
            res_gm_seg_bin.data = np.asarray(
                (res_gm_seg_bin.data >= 0.5).astype(int))
            res_wm_seg_bin.data = np.asarray(
                (res_wm_seg_bin.data >= 0.50001).astype(int))

        mask = Image(self.preprocessed.square_mask)

        # doing the validation
        os.chdir(validation_dir)

        im_ref_gm_seg.path = './'
        im_ref_gm_seg.file_name = 'ref_gm_seg'
        im_ref_gm_seg.ext = ext
        im_ref_gm_seg.save()
        ref_gm_seg_new_name = resample_image(im_ref_gm_seg.file_name + ext,
                                             npx=self.preprocessed.resample_to,
                                             npy=self.preprocessed.resample_to,
                                             binary=True)
        im_ref_gm_seg = Image(ref_gm_seg_new_name)
        sct.run('rm ' + ref_gm_seg_new_name)

        im_ref_wm_seg.path = './'
        im_ref_wm_seg.file_name = 'ref_wm_seg'
        im_ref_wm_seg.ext = ext
        im_ref_wm_seg.save()
        ref_wm_seg_new_name = resample_image(im_ref_wm_seg.file_name + ext,
                                             npx=self.preprocessed.resample_to,
                                             npy=self.preprocessed.resample_to,
                                             binary=True)
        im_ref_wm_seg = Image(ref_wm_seg_new_name)
        sct.run('rm ' + ref_wm_seg_new_name)

        ref_orientation = im_ref_gm_seg.orientation
        im_ref_gm_seg.change_orientation('IRP')
        im_ref_wm_seg.change_orientation('IRP')

        im_ref_gm_seg.crop_and_stack(mask, save=False)
        im_ref_wm_seg.crop_and_stack(mask, save=False)

        im_ref_gm_seg.change_orientation('RPI')
        im_ref_wm_seg.change_orientation('RPI')

        # saving the images to call the validation functions
        res_gm_seg_bin.path = './'
        res_gm_seg_bin.file_name = 'res_gm_seg_bin'
        res_gm_seg_bin.ext = ext
        res_gm_seg_bin.save()

        res_wm_seg_bin.path = './'
        res_wm_seg_bin.file_name = 'res_wm_seg_bin'
        res_wm_seg_bin.ext = ext
        res_wm_seg_bin.save()

        im_ref_gm_seg.path = './'
        im_ref_gm_seg.file_name = 'ref_gm_seg'
        im_ref_gm_seg.ext = ext
        im_ref_gm_seg.save()

        im_ref_wm_seg.path = './'
        im_ref_wm_seg.file_name = 'ref_wm_seg'
        im_ref_wm_seg.ext = ext
        im_ref_wm_seg.save()

        sct.run('sct_orientation -i ' + res_gm_seg_bin.file_name + ext +
                ' -s RPI')
        res_gm_seg_bin.file_name += '_RPI'
        sct.run('sct_orientation -i ' + res_wm_seg_bin.file_name + ext +
                ' -s RPI')
        res_wm_seg_bin.file_name += '_RPI'

        res_gm_seg_bin = Image(res_gm_seg_bin.file_name + ext)
        im_ref_gm_seg.hdr.set_zooms(
            res_gm_seg_bin.hdr.get_zooms())  # correcting the pix dimension
        im_ref_gm_seg.save()

        res_wm_seg_bin = Image(res_wm_seg_bin.file_name + ext)
        im_ref_wm_seg.hdr.set_zooms(
            res_wm_seg_bin.hdr.get_zooms())  # correcting the pix dimension
        im_ref_wm_seg.save()

        # Dice
        try:
            status_gm, output_gm = sct.run(
                'sct_dice_coefficient ' + im_ref_gm_seg.file_name + ext + ' ' +
                res_gm_seg_bin.file_name + ext + '  -2d-slices 2',
                error_exit='warning',
                raise_exception=True)
        except Exception:
            sct.run('c3d ' + res_gm_seg_bin.file_name + ext + ' ' +
                    im_ref_gm_seg.file_name + ext + ' -reslice-identity -o ' +
                    im_ref_gm_seg.file_name + '_in_res_space' + ext)
            sct.run('fslmaths ' + im_ref_gm_seg.file_name + '_in_res_space' +
                    ext + ' -thr 0.1 ' + im_ref_gm_seg.file_name +
                    '_in_res_space' + ext)
            sct.run('fslmaths ' + im_ref_gm_seg.file_name + '_in_res_space' +
                    ext + ' -bin ' + im_ref_gm_seg.file_name +
                    '_in_res_space' + ext)
            status_gm, output_gm = sct.run(
                'sct_dice_coefficient ' + im_ref_gm_seg.file_name +
                '_in_res_space' + ext + ' ' + res_gm_seg_bin.file_name + ext +
                '  -2d-slices 2',
                error_exit='warning')
        try:
            status_wm, output_wm = sct.run(
                'sct_dice_coefficient ' + im_ref_wm_seg.file_name + ext + ' ' +
                res_wm_seg_bin.file_name + ext + '  -2d-slices 2',
                error_exit='warning',
                raise_exception=True)
        except Exception:
            sct.run('c3d ' + res_wm_seg_bin.file_name + ext + ' ' +
                    im_ref_wm_seg.file_name + ext + ' -reslice-identity -o ' +
                    im_ref_wm_seg.file_name + '_in_res_space' + ext)
            sct.run('fslmaths ' + im_ref_wm_seg.file_name + '_in_res_space' +
                    ext + ' -thr 0.1 ' + im_ref_wm_seg.file_name +
                    '_in_res_space' + ext)
            sct.run('fslmaths ' + im_ref_wm_seg.file_name + '_in_res_space' +
                    ext + ' -bin ' + im_ref_wm_seg.file_name +
                    '_in_res_space' + ext)
            status_wm, output_wm = sct.run(
                'sct_dice_coefficient ' + im_ref_wm_seg.file_name +
                '_in_res_space' + ext + ' ' + res_wm_seg_bin.file_name + ext +
                '  -2d-slices 2',
                error_exit='warning')

        dice_name = 'dice_' + sct.extract_fname(
            self.target_fname)[1] + '_' + self.param.res_type + '.txt'
        dice_fic = open('../../' + dice_name, 'w')
        if self.param.res_type == 'prob':
            dice_fic.write(
                'WARNING : the probabilistic segmentations were binarized with a threshold at 0.5 to compute the dice coefficient \n'
            )
        dice_fic.write(
            '\n--------------------------------------------------------------\n'
            'Dice coefficient on the Gray Matter segmentation:\n')
        dice_fic.write(output_gm)
        dice_fic.write(
            '\n\n--------------------------------------------------------------\n'
            'Dice coefficient on the White Matter segmentation:\n')
        dice_fic.write(output_wm)
        dice_fic.close()
        # sct.run(' mv ./' + dice_name + ' ../')

        hd_name = 'hd_' + sct.extract_fname(
            self.target_fname)[1] + '_' + self.param.res_type + '.txt'
        sct.run('sct_compute_hausdorff_distance.py -i ' +
                res_gm_seg_bin.file_name + ext + ' -r ' +
                im_ref_gm_seg.file_name + ext + ' -t 1 -o ' + hd_name +
                ' -v ' + str(self.param.verbose))
        sct.run('mv ./' + hd_name + ' ../../')

        os.chdir('..')
        return dice_name, hd_name
Exemple #8
0
    def execute(self):
        print 'Execution of the SCAD algorithm'

        vesselness_file_name = "imageVesselNessFilter.nii.gz"
        raw_file_name = "raw.nii"

        if self.debug:
            import matplotlib.pyplot as plt # import for debug purposes

        # create tmp and copy input
        path_tmp = sct.tmp_create()
        sct.tmp_copy_nifti(self.input_image.absolutepath, path_tmp, raw_file_name)

        if self.vesselness_provided:
            sct.run('cp '+vesselness_file_name+' '+path_tmp+vesselness_file_name)
        os.chdir(path_tmp)

        # get input image information
        img = Image(raw_file_name)

        # save original orientation and change image to RPI
        self.raw_orientation = img.change_orientation()

        # get body symmetry
        sym = SymmetryDetector(raw_file_name, self.contrast, crop_xy=1)
        self.raw_symmetry = sym.execute()

        # vesselness filter
        if not self.vesselness_provided:
            sct.run('sct_vesselness -i '+raw_file_name+' -t ' + self._contrast)

        # load vesselness filter data and perform minimum path on it
        img = Image(vesselness_file_name)
        raw_orientation = img.change_orientation()
        self.minimum_path_data, self.J1_min_path, self.J2_min_path = get_minimum_path(img.data, invert=1, debug=1, smooth_factor=1)

        # Apply an exponent to the minimum path
        self.minimum_path_powered = np.power(self.minimum_path_data, self.minimum_path_exponent)

        # Saving in Image since smooth_minimal_path needs pixel dimensions
        img.data = self.minimum_path_powered

        # smooth resulting minimal path
        self.smoothed_min_path = smooth_minimal_path(img)

        # normalise symmetry values between 0 and 1
        normalised_symmetry = equalize_array_histogram(self.raw_symmetry)

        # multiply normalised symmetry data with the minimum path result
        self.spine_detect_data = np.multiply(self.smoothed_min_path.data, normalised_symmetry)

        # extract the centerline from the minimal path image
        centerline_with_outliers = get_centerline(self.spine_detect_data, self.spine_detect_data.shape)
        img.data = centerline_with_outliers
        img.change_orientation()
        img.file_name = "centerline_with_outliers"
        img.save()

        # use a b-spline to smooth out the centerline
        x, y, z, dx, dy, dz = smooth_centerline("centerline_with_outliers.nii.gz")

        # save the centerline
        centerline_dim = img.dim
        img.data = np.zeros(centerline_dim)
        for i in range(0, np.size(x)-1):
            img.data[int(x[i]), int(y[i]), int(z[i])] = 1

        img.change_orientation(raw_orientation)
        img.file_name = "centerline"
        img.save()

        # copy back centerline
        os.chdir('../')
        sct.tmp_copy_nifti(path_tmp + 'centerline.nii.gz',self.input_image.path,self.input_image.file_name+'_centerline'+self.input_image.ext)

        if self.rm_tmp_file == 1:
            import shutil
            shutil.rmtree(path_tmp)

        if self.produce_output:
            self.produce_output_files()
    def execute(self):
        print 'Execution of the SCAD algorithm in '+str(os.getcwd())

        original_name = self.input_image.file_name
        vesselness_file_name = "imageVesselNessFilter.nii.gz"
        raw_file_name = "raw.nii"

        self.setup_debug_folder()

        if self.debug:
            import matplotlib.pyplot as plt # import for debug purposes

        # create tmp and copy input
        path_tmp = self.create_temporary_path()
        conv.convert(self.input_image.absolutepath, path_tmp+raw_file_name)

        if self.vesselness_provided:
            sct.run('cp '+vesselness_file_name+' '+path_tmp+vesselness_file_name)
        os.chdir(path_tmp)

        # get input image information
        img = Image(raw_file_name)

        # save original orientation and change image to RPI
        self.raw_orientation = img.change_orientation()

        # get body symmetry
        if self.enable_symmetry:
            from msct_image import change_data_orientation
            sym = SymmetryDetector(raw_file_name, self.contrast, crop_xy=0)
            self.raw_symmetry = sym.execute()
            img.change_orientation(self.raw_orientation)
            self.output_debug_file(img, self.raw_symmetry, "body_symmetry")
            img.change_orientation()

        # vesselness filter
        if not self.vesselness_provided:
            sct.run('sct_vesselness -i '+raw_file_name+' -t ' + self._contrast+" -radius "+str(self.spinalcord_radius))

        # load vesselness filter data and perform minimum path on it
        img = Image(vesselness_file_name)
        img.change_orientation()
        self.minimum_path_data, self.J1_min_path, self.J2_min_path = get_minimum_path(img.data, invert=1, debug=1)
        self.output_debug_file(img, self.minimum_path_data, "minimal_path")
        self.output_debug_file(img, self.J1_min_path, "J1_minimal_path")
        self.output_debug_file(img, self.J2_min_path, "J2_minimal_path")

        # Apply an exponent to the minimum path
        self.minimum_path_powered = np.power(self.minimum_path_data, self.minimum_path_exponent)
        self.output_debug_file(img, self.minimum_path_powered, "minimal_path_power_"+str(self.minimum_path_exponent))

        # Saving in Image since smooth_minimal_path needs pixel dimensions
        img.data = self.minimum_path_powered

        # smooth resulting minimal path
        self.smoothed_min_path = smooth_minimal_path(img)
        self.output_debug_file(img, self.smoothed_min_path.data, "minimal_path_smooth")

        # normalise symmetry values between 0 and 1
        if self.enable_symmetry:
            normalised_symmetry = normalize_array_histogram(self.raw_symmetry)
            self.output_debug_file(img, self.smoothed_min_path.data, "minimal_path_smooth")

        # multiply normalised symmetry data with the minimum path result
            from msct_image import change_data_orientation
            self.spine_detect_data = np.multiply(self.smoothed_min_path.data, change_data_orientation(np.power(normalised_symmetry, self.symmetry_exponent), self.raw_orientation, "RPI"))
            self.output_debug_file(img, self.spine_detect_data, "symmetry_x_min_path")
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(self.spine_detect_data, self.spine_detect_data.shape)
        else:
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(self.smoothed_min_path.data, self.smoothed_min_path.data.shape)
        self.output_debug_file(img, self.centerline_with_outliers, "centerline_with_outliers")

        # saving centerline with outliers to have
        img.data = self.centerline_with_outliers
        img.change_orientation()
        img.file_name = "centerline_with_outliers"
        img.save()

        # use a b-spline to smooth out the centerline
        x, y, z, dx, dy, dz = smooth_centerline("centerline_with_outliers.nii.gz")

        # save the centerline
        nx, ny, nz, nt, px, py, pz, pt = img.dim
        img.data = np.zeros((nx, ny, nz))
        for i in range(0, np.size(x)-1):
            img.data[int(x[i]), int(y[i]), int(z[i])] = 1

        self.output_debug_file(img, img.data, "centerline")
        img.change_orientation(self.raw_orientation)
        img.file_name = "centerline"
        img.save()

        # copy back centerline
        os.chdir('../')
        conv.convert(path_tmp+img.file_name+img.ext, self.output_filename)
        if self.rm_tmp_file == 1:
            import shutil
            shutil.rmtree(path_tmp)
    if nt > 1:
        sct.log.error('ERROR: your input image needs to be 3D in order to be segmented.')

    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    # if centerline or mask is asked using viewer
    if use_viewer:
        from spinalcordtoolbox.gui.base import AnatomicalParams
        from spinalcordtoolbox.gui.centerline import launch_centerline_dialog

        params = AnatomicalParams()
        params.num_points = 3
        image = Image(fname_data)
        tmp_output_file = Image(image)
        tmp_output_file.data *= 0
        tmp_output_file.file_name = os.path.join(folder_output, file_data + 'manually_seg' + ext_data)
        controller = launch_centerline_dialog(image, tmp_output_file, params)
        try:
            controller.as_niftii(tmp_output_file.file_name)
            # add mask filename to parameters string
            if use_viewer == "centerline":
                cmd += " -init-centerline " + tmp_output_file.file_name
            elif use_viewer == "mask":
                cmd += " -init-mask " + tmp_output_file.file_name
        except ValueError:
            sct.log.error('the viewer has been closed before entering all manual points. Please try again.')

    # If using OptiC, enabled by default
    elif use_optic:
        path_script = os.path.dirname(__file__)
        path_sct = os.path.dirname(path_script)
    def validation(self):
        name_ref_gm_seg = sct.extract_fname(self.ref_gm_seg)
        im_ref_gm_seg = Image("../" + self.ref_gm_seg)

        res_gm_seg_bin = Image("../" + self.res_names["gm_seg"])
        res_wm_seg_bin = Image("../" + self.res_names["wm_seg"])

        sct.run("cp ../" + self.ref_gm_seg + " ./ref_gm_seg.nii.gz")
        im_ref_wm_seg = inverse_gmseg_to_wmseg(im_ref_gm_seg, Image("../" + self.sc_seg_fname), "ref_gm_seg")
        im_ref_wm_seg.file_name = "ref_wm_seg"
        im_ref_wm_seg.ext = ".nii.gz"
        im_ref_wm_seg.save()

        if self.param.res_type == "prob":
            res_gm_seg_bin.data = np.asarray((res_gm_seg_bin.data >= 0.5).astype(int))
            res_wm_seg_bin.data = np.asarray((res_wm_seg_bin.data >= 0.50001).astype(int))

        res_gm_seg_bin.path = "./"
        res_gm_seg_bin.file_name = "res_gm_seg_bin"
        res_gm_seg_bin.ext = ".nii.gz"
        res_gm_seg_bin.save()
        res_wm_seg_bin.path = "./"
        res_wm_seg_bin.file_name = "res_wm_seg_bin"
        res_wm_seg_bin.ext = ".nii.gz"
        res_wm_seg_bin.save()
        try:
            status_gm, output_gm = sct.run(
                "sct_dice_coefficient ref_gm_seg.nii.gz res_gm_seg_bin.nii.gz  -2d-slices 2",
                error_exit="warning",
                raise_exception=True,
            )
        except Exception:
            sct.run("c3d res_gm_seg_bin.nii.gz  ref_gm_seg.nii.gz -reslice-identity -o ref_in_res_space_gm.nii.gz ")
            status_gm, output_gm = sct.run(
                "sct_dice_coefficient ref_in_res_space_gm.nii.gz res_gm_seg_bin.nii.gz  -2d-slices 2",
                error_exit="warning",
            )
        try:
            status_wm, output_wm = sct.run(
                "sct_dice_coefficient ref_wm_seg.nii.gz res_wm_seg_bin.nii.gz  -2d-slices 2",
                error_exit="warning",
                raise_exception=True,
            )
        except Exception:
            sct.run("c3d res_wm_seg_bin.nii.gz  ref_wm_seg.nii.gz -reslice-identity -o ref_in_res_space_wm.nii.gz ")
            status_wm, output_wm = sct.run(
                "sct_dice_coefficient ref_in_res_space_wm.nii.gz res_wm_seg_bin.nii.gz  -2d-slices 2",
                error_exit="warning",
            )
        dice_name = "dice_" + self.param.res_type + ".txt"
        dice_fic = open("../" + dice_name, "w")
        if self.param.res_type == "prob":
            dice_fic.write(
                "WARNING : the probabilistic segmentations were binarized with a threshold at 0.5 to compute the dice coefficient \n"
            )
        dice_fic.write(
            "\n--------------------------------------------------------------\nDice coefficient on the Gray Matter segmentation:\n"
        )
        dice_fic.write(output_gm)
        dice_fic.write(
            "\n\n--------------------------------------------------------------\nDice coefficient on the White Matter segmentation:\n"
        )
        dice_fic.write(output_wm)
        dice_fic.close()
        # sct.run(' mv ./' + dice_name + ' ../')

        return dice_name
def resample():
    # extract resampling factor
    sct.printv('\nParse resampling factor...', param.verbose)
    factor_split = param.factor.split('x')
    factor = [float(factor_split[i]) for i in range(len(factor_split))]
    # check if it has three values
    if not len(factor) == 3:
        sct.printv('\nERROR: factor should have three dimensions. E.g., 2x2x1.\n', 1, 'error')
    else:
        fx, fy, fz = [float(factor_split[i]) for i in range(len(factor_split))]

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_out, file_out, ext_out = path_data, file_data, ext_data
    if param.fname_out != '':
        file_out = sct.extract_fname(param.fname_out)[1]
    else:
        file_out.append(param.file_suffix)

    input_im = Image(param.fname_data)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = input_im.dim
    sct.printv('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), param.verbose)
    dim = 4  # by default, will be adjusted later
    if nt == 1:
        dim = 3
    if nz == 1:
        dim = 2
        #TODO : adapt for 2D too or change description
        sct.run('ERROR (sct_resample): Dimension of input data is different from 3 or 4. Exit program', param.verbose, 'error')

    # Calculate new dimensions
    sct.printv('\nCalculate new dimensions...', param.verbose)
    nx_new = int(round(nx*fx))
    ny_new = int(round(ny*fy))
    nz_new = int(round(nz*fz))
    px_new = px/fx
    py_new = py/fy
    pz_new = pz/fz
    sct.printv('  ' + str(nx_new) + ' x ' + str(ny_new) + ' x ' + str(nz_new)+ ' x ' + str(nt), param.verbose)


    zooms = input_im.hdr.get_zooms()[:3]
    affine = input_im.hdr.get_base_affine()
    new_zooms = (px_new, py_new, pz_new)

    if type(param.interpolation) == int:
        order = param.interpolation
    elif type(param.interpolation) == str and param.interpolation in param.x_to_order.keys():
        order = param.x_to_order[param.interpolation]
    else:
        order = 1
        sct.printv('WARNING: wrong input for the interpolation. Using default value = trilinear', param.verbose, 'warning')

    new_data, new_affine = dp_iso.reslice(input_im.data, affine, zooms, new_zooms, mode=param.mode, order=order)

    new_im = Image(param=new_data)
    new_im.absolutepath = path_out+file_out+ext_out
    new_im.path = path_out
    new_im.file_name = file_out
    new_im.ext = ext_out

    zooms_to_set = list(new_zooms)
    if dim == 4:
        zooms_to_set.append(nt)

    new_im.hdr = input_im.hdr
    new_im.hdr.set_zooms(zooms_to_set)
    new_im.save()

    # to view results
    sct.printv('\nDone! To view results, type:', param.verbose)
    sct.printv('fslview '+param.fname_out+' &', param.verbose, 'info')
    print
def resample():
    # extract resampling factor
    sct.printv('\nParse resampling factor...', param.verbose)
    factor_split = param.factor.split('x')
    factor = [float(factor_split[i]) for i in range(len(factor_split))]
    # check if it has three values
    if not len(factor) == 3:
        sct.printv(
            '\nERROR: factor should have three dimensions. E.g., 2x2x1.\n', 1,
            'error')
    else:
        fx, fy, fz = [float(factor_split[i]) for i in range(len(factor_split))]

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_out, file_out, ext_out = path_data, file_data, ext_data
    if param.fname_out != '':
        file_out = sct.extract_fname(param.fname_out)[1]
    else:
        file_out.append(param.file_suffix)

    input_im = Image(param.fname_data)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = input_im.dim
    sct.printv(
        '  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt),
        param.verbose)
    dim = 4  # by default, will be adjusted later
    if nt == 1:
        dim = 3
    if nz == 1:
        dim = 2
        #TODO : adapt for 2D too or change description
        sct.run(
            'ERROR (sct_resample): Dimension of input data is different from 3 or 4. Exit program',
            param.verbose, 'error')

    # Calculate new dimensions
    sct.printv('\nCalculate new dimensions...', param.verbose)
    nx_new = int(round(nx * fx))
    ny_new = int(round(ny * fy))
    nz_new = int(round(nz * fz))
    px_new = px / fx
    py_new = py / fy
    pz_new = pz / fz
    sct.printv(
        '  ' + str(nx_new) + ' x ' + str(ny_new) + ' x ' + str(nz_new) +
        ' x ' + str(nt), param.verbose)

    zooms = input_im.hdr.get_zooms()[:3]
    affine = input_im.hdr.get_base_affine()
    new_zooms = (px_new, py_new, pz_new)

    if type(param.interpolation) == int:
        order = param.interpolation
    elif type(param.interpolation
              ) == str and param.interpolation in param.x_to_order.keys():
        order = param.x_to_order[param.interpolation]
    else:
        order = 1
        sct.printv(
            'WARNING: wrong input for the interpolation. Using default value = trilinear',
            param.verbose, 'warning')

    new_data, new_affine = dp_iso.reslice(input_im.data,
                                          affine,
                                          zooms,
                                          new_zooms,
                                          mode=param.mode,
                                          order=order)

    new_im = Image(param=new_data)
    new_im.absolutepath = path_out + file_out + ext_out
    new_im.path = path_out
    new_im.file_name = file_out
    new_im.ext = ext_out

    zooms_to_set = list(new_zooms)
    if dim == 4:
        zooms_to_set.append(nt)

    new_im.hdr = input_im.hdr
    new_im.hdr.set_zooms(zooms_to_set)
    new_im.save()

    # to view results
    sct.printv('\nDone! To view results, type:', param.verbose)
    sct.printv('fslview ' + param.fname_out + ' &', param.verbose, 'info')
    print
def resample():
    # extract resampling factor
    sct.printv('\nParse resampling factor...', param.verbose)
    new_size_split = param.new_size.split('x')
    new_size = [float(new_size_split[i]) for i in range(len(new_size_split))]
    # check if it has three values
    if not len(new_size) == 3:
        sct.printv('\nERROR: new size should have three dimensions. E.g., 2x2x1.\n', 1, 'error')
    else:
        ns_x, ns_y, ns_z = new_size

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_out, file_out, ext_out = '', file_data, ext_data
    if param.fname_out != '':
        path_out, file_out, ext_out = sct.extract_fname(param.fname_out)
    else:
        file_out += param.file_suffix
    param.fname_out = path_out+file_out+ext_out

    input_im = Image(param.fname_data)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = input_im.dim
    sct.printv('  ' + str(px) + ' x ' + str(py) + ' x ' + str(pz)+ ' x ' + str(pt)+'mm', param.verbose)
    dim = 4  # by default, will be adjusted later
    if nt == 1:
        dim = 3
    if nz == 1:
        dim = 2
        sct.run('ERROR (sct_resample): Dimension of input data is different from 3 or 4. Exit program', param.verbose, 'error')

    # Calculate new dimensions
    sct.printv('\nCalculate new dimensions...', param.verbose)
    if param.new_size_type == 'factor':
        px_new = px/ns_x
        py_new = py/ns_y
        pz_new = pz/ns_z
    elif param.new_size_type == 'vox':
        px_new = px*nx/ns_x
        py_new = py*ny/ns_y
        pz_new = pz*nz/ns_z
    else:
        px_new = ns_x
        py_new = ns_y
        pz_new = ns_z

    sct.printv('  ' + str(px_new) + ' x ' + str(py_new) + ' x ' + str(pz_new)+ ' x ' + str(pt)+'mm', param.verbose)

    zooms = (px, py, pz)  # input_im.hdr.get_zooms()[:3]
    affine = input_im.hdr.get_qform()  # get_base_affine()
    new_zooms = (px_new, py_new, pz_new)

    if type(param.interpolation) == int:
        order = param.interpolation
    elif type(param.interpolation) == str and param.interpolation in param.x_to_order.keys():
        order = param.x_to_order[param.interpolation]
    else:
        order = 1
        sct.printv('WARNING: wrong input for the interpolation. Using default value = linear', param.verbose, 'warning')

    new_data, new_affine = dp_iso.reslice(input_im.data, affine, zooms, new_zooms, mode=param.mode, order=order)

    new_im = Image(param=new_data)
    new_im.absolutepath = param.fname_out
    new_im.path = path_out
    new_im.file_name = file_out
    new_im.ext = ext_out

    zooms_to_set = list(new_zooms)
    if dim == 4:
        zooms_to_set.append(nt)

    new_im.hdr = input_im.hdr
    new_im.hdr.set_zooms(zooms_to_set)

    # Set the new sform and qform:
    new_im.hdr.set_sform(new_affine)
    new_im.hdr.set_qform(new_affine)

    new_im.save()

    # to view results
    sct.printv('\nDone! To view results, type:', param.verbose)
    sct.printv('fslview '+param.fname_out+' &', param.verbose, 'info')
    def validation(self):
        ext = '.nii.gz'
        validation_dir = 'validation'
        sct.run('mkdir ' + validation_dir)

        # loading the images
        im_ref_gm_seg = Image('../' + self.ref_gm_seg_fname)
        im_ref_wm_seg = inverse_gmseg_to_wmseg(im_ref_gm_seg, Image('../' + self.sc_seg_fname), im_ref_gm_seg.path + im_ref_gm_seg.file_name, save=False)

        res_gm_seg_bin = self.gm_seg.res_gm_seg.copy()
        res_wm_seg_bin = self.gm_seg.res_wm_seg.copy()

        if self.param.res_type == 'prob':
            res_gm_seg_bin.data = np.asarray((res_gm_seg_bin.data >= 0.5).astype(int))
            res_wm_seg_bin.data = np.asarray((res_wm_seg_bin.data >= 0.50001).astype(int))

        mask = Image(self.preprocessed.square_mask)

        # doing the validation
        os.chdir(validation_dir)

        im_ref_gm_seg.path = './'
        im_ref_gm_seg.file_name = 'ref_gm_seg'
        im_ref_gm_seg.ext = ext
        im_ref_gm_seg.save()
        ref_gm_seg_new_name = resample_image(im_ref_gm_seg.file_name + ext, npx=self.preprocessed.resample_to, npy=self.preprocessed.resample_to, binary=True)
        im_ref_gm_seg = Image(ref_gm_seg_new_name)
        sct.run('rm ' + ref_gm_seg_new_name)

        im_ref_wm_seg.path = './'
        im_ref_wm_seg.file_name = 'ref_wm_seg'
        im_ref_wm_seg.ext = ext
        im_ref_wm_seg.save()
        ref_wm_seg_new_name = resample_image(im_ref_wm_seg.file_name + ext, npx=self.preprocessed.resample_to, npy=self.preprocessed.resample_to, binary=True)
        im_ref_wm_seg = Image(ref_wm_seg_new_name)
        sct.run('rm ' + ref_wm_seg_new_name)

        ref_orientation = im_ref_gm_seg.orientation
        im_ref_gm_seg.change_orientation('IRP')
        im_ref_wm_seg.change_orientation('IRP')

        im_ref_gm_seg.crop_and_stack(mask, save=False)
        im_ref_wm_seg.crop_and_stack(mask, save=False)

        im_ref_gm_seg.change_orientation('RPI')
        im_ref_wm_seg.change_orientation('RPI')

        # saving the images to call the validation functions
        res_gm_seg_bin.path = './'
        res_gm_seg_bin.file_name = 'res_gm_seg_bin'
        res_gm_seg_bin.ext = ext
        res_gm_seg_bin.save()

        res_wm_seg_bin.path = './'
        res_wm_seg_bin.file_name = 'res_wm_seg_bin'
        res_wm_seg_bin.ext = ext
        res_wm_seg_bin.save()

        im_ref_gm_seg.path = './'
        im_ref_gm_seg.file_name = 'ref_gm_seg'
        im_ref_gm_seg.ext = ext
        im_ref_gm_seg.save()

        im_ref_wm_seg.path = './'
        im_ref_wm_seg.file_name = 'ref_wm_seg'
        im_ref_wm_seg.ext = ext
        im_ref_wm_seg.save()

        sct.run('sct_orientation -i ' + res_gm_seg_bin.file_name + ext + ' -s RPI')
        res_gm_seg_bin.file_name += '_RPI'
        sct.run('sct_orientation -i ' + res_wm_seg_bin.file_name + ext + ' -s RPI')
        res_wm_seg_bin.file_name += '_RPI'

        res_gm_seg_bin = Image(res_gm_seg_bin.file_name + ext)
        im_ref_gm_seg.hdr.set_zooms(res_gm_seg_bin.hdr.get_zooms())  # correcting the pix dimension
        im_ref_gm_seg.save()

        res_wm_seg_bin = Image(res_wm_seg_bin.file_name + ext)
        im_ref_wm_seg.hdr.set_zooms(res_wm_seg_bin.hdr.get_zooms())  # correcting the pix dimension
        im_ref_wm_seg.save()

        # Dice
        try:
            status_gm, output_gm = sct.run('sct_dice_coefficient ' + im_ref_gm_seg.file_name + ext + ' ' + res_gm_seg_bin.file_name + ext + '  -2d-slices 2', error_exit='warning', raise_exception=True)
        except Exception:
            sct.run('c3d ' + res_gm_seg_bin.file_name + ext + ' ' + im_ref_gm_seg.file_name + ext + ' -reslice-identity -o ' + im_ref_gm_seg.file_name + '_in_res_space' + ext)
            sct.run('fslmaths ' + im_ref_gm_seg.file_name + '_in_res_space' + ext + ' -thr 0.1 ' + im_ref_gm_seg.file_name + '_in_res_space' + ext )
            sct.run('fslmaths ' + im_ref_gm_seg.file_name + '_in_res_space' + ext + ' -bin ' + im_ref_gm_seg.file_name + '_in_res_space' + ext )
            status_gm, output_gm = sct.run('sct_dice_coefficient ' + im_ref_gm_seg.file_name + '_in_res_space' + ext + ' ' + res_gm_seg_bin.file_name + ext + '  -2d-slices 2', error_exit='warning')
        try:
            status_wm, output_wm = sct.run('sct_dice_coefficient ' + im_ref_wm_seg.file_name + ext + ' ' + res_wm_seg_bin.file_name + ext + '  -2d-slices 2', error_exit='warning', raise_exception=True)
        except Exception:
            sct.run('c3d ' + res_wm_seg_bin.file_name + ext + ' ' + im_ref_wm_seg.file_name + ext + ' -reslice-identity -o ' + im_ref_wm_seg.file_name + '_in_res_space' + ext)
            sct.run('fslmaths ' + im_ref_wm_seg.file_name + '_in_res_space' + ext + ' -thr 0.1 ' + im_ref_wm_seg.file_name + '_in_res_space' + ext)
            sct.run('fslmaths ' + im_ref_wm_seg.file_name + '_in_res_space' + ext + ' -bin ' + im_ref_wm_seg.file_name + '_in_res_space' + ext)
            status_wm, output_wm = sct.run('sct_dice_coefficient ' + im_ref_wm_seg.file_name + '_in_res_space' + ext + ' ' + res_wm_seg_bin.file_name + ext + '  -2d-slices 2', error_exit='warning')

        dice_name = 'dice_' + sct.extract_fname(self.target_fname)[1] + '_' + self.param.res_type + '.txt'
        dice_fic = open('../../' + dice_name, 'w')
        if self.param.res_type == 'prob':
            dice_fic.write('WARNING : the probabilistic segmentations were binarized with a threshold at 0.5 to compute the dice coefficient \n')
        dice_fic.write('\n--------------------------------------------------------------\n'
                       'Dice coefficient on the Gray Matter segmentation:\n')
        dice_fic.write(output_gm)
        dice_fic.write('\n\n--------------------------------------------------------------\n'
                       'Dice coefficient on the White Matter segmentation:\n')
        dice_fic.write(output_wm)
        dice_fic.close()
        # sct.run(' mv ./' + dice_name + ' ../')

        hd_name = 'hd_' + sct.extract_fname(self.target_fname)[1] + '_' + self.param.res_type + '.txt'
        sct.run('sct_compute_hausdorff_distance.py -i ' + res_gm_seg_bin.file_name + ext + ' -r ' + im_ref_gm_seg.file_name + ext + ' -t 1 -o ' + hd_name + ' -v ' + str(self.param.verbose))
        sct.run('mv ./' + hd_name + ' ../../')

        os.chdir('..')
        return dice_name, hd_name