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 = msct_image.zeros_like(self.image_input) 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(np.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(np.round(coord.value)) image_output_ref.absolutepath = self.fname_output[1] image_output_ref.save('minimize_int') self.fname_output = self.fname_output[0] return image_output
def visualize_warp(im_warp: Image, im_grid: Image = None, step=3, rm_tmp=True): fname_warp = im_warp.absolutepath() if im_grid: fname_grid = im_grid.absolutepath() else: from numpy import zeros tmp_dir = tmp_create() status, out = run_proc(['fslhd', fname_warp]) curdir = os.getcwd() os.chdir(tmp_dir) dim1 = 'dim1 ' dim2 = 'dim2 ' dim3 = 'dim3 ' nx = int(out[out.find(dim1):][len(dim1):out[out.find(dim1):].find('\n')]) ny = int(out[out.find(dim2):][len(dim2):out[out.find(dim2):].find('\n')]) nz = int(out[out.find(dim3):][len(dim3):out[out.find(dim3):].find('\n')]) sq = zeros((step, step)) sq[step - 1] = 1 sq[:, step - 1] = 1 dat = zeros((nx, ny, nz)) for i in range(0, dat.shape[0], step): for j in range(0, dat.shape[1], step): for k in range(dat.shape[2]): if dat[i:i + step, j:j + step, k].shape == (step, step): dat[i:i + step, j:j + step, k] = sq fname_grid = 'grid_' + str(step) + '.nii.gz' im_grid = Image(param=dat) grid_hdr = im_warp.hdr im_grid.hdr = grid_hdr im_grid.absolutepath = fname_grid im_grid.save() fname_grid_resample = add_suffix(fname_grid, '_resample') run_proc(['sct_resample', '-i', fname_grid, '-f', '3x3x1', '-x', 'nn', '-o', fname_grid_resample]) fname_grid = os.path.join(tmp_dir, fname_grid_resample) os.chdir(curdir) path_warp, file_warp, ext_warp = extract_fname(fname_warp) grid_warped = os.path.join(path_warp, extract_fname(fname_grid)[1] + '_' + file_warp + ext_warp) run_proc(['sct_apply_transfo', '-i', fname_grid, '-d', fname_grid, '-w', fname_warp, '-o', grid_warped]) if rm_tmp: rmtree(tmp_dir)
def visualize_warp(fname_warp, fname_grid=None, step=3, rm_tmp=True): if fname_grid is None: from numpy import zeros tmp_dir = sct.tmp_create() im_warp = Image(fname_warp) curdir = os.getcwd() os.chdir(tmp_dir) assert len(im_warp.data.shape ) == 5, 'ERROR: Warping field does bot have 5 dimensions...' nx, ny, nz, nt, ndimwarp = im_warp.data.shape # nx, ny, nz, nt, px, py, pz, pt = im_warp.dim # This does not work because dimensions of a warping field are not correctly read : it would be 1,1,1,1,1,1,1,1 sq = zeros((step, step)) sq[step - 1] = 1 sq[:, step - 1] = 1 dat = zeros((nx, ny, nz)) for i in range(0, dat.shape[0], step): for j in range(0, dat.shape[1], step): for k in range(dat.shape[2]): if dat[i:i + step, j:j + step, k].shape == (step, step): dat[i:i + step, j:j + step, k] = sq fname_grid = 'grid_' + str(step) + '.nii.gz' im_grid = Image(param=dat) grid_hdr = im_warp.hdr im_grid.hdr = grid_hdr im_grid.absolutepath = fname_grid im_grid.save() fname_grid_resample = sct.add_suffix(fname_grid, '_resample') sct.run([ 'sct_resample', '-i', fname_grid, '-f', '3x3x1', '-x', 'nn', '-o', fname_grid_resample ]) fname_grid = os.path.join(tmp_dir, fname_grid_resample) os.chdir(curdir) path_warp, file_warp, ext_warp = sct.extract_fname(fname_warp) grid_warped = os.path.join(path_warp, 'grid_warped_gm' + ext_warp) sct.run([ 'sct_apply_transfo', '-i', fname_grid, '-d', fname_grid, '-w', fname_warp, '-o', grid_warped ]) if rm_tmp: sct.rmtree(tmp_dir) return grid_warped
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 sct.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 sct.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 sct.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.absolutepath = fname_labeled_seg_new im_label.save()
def visualize_warp(fname_warp, fname_grid=None, step=3, rm_tmp=True): if fname_grid is None: from numpy import zeros tmp_dir = sct.tmp_create() im_warp = Image(fname_warp) status, out = sct.run(['fslhd', fname_warp]) curdir = os.getcwd() os.chdir(tmp_dir) dim1 = 'dim1 ' dim2 = 'dim2 ' dim3 = 'dim3 ' nx = int(out[out.find(dim1):][len(dim1):out[out.find(dim1):].find('\n')]) ny = int(out[out.find(dim2):][len(dim2):out[out.find(dim2):].find('\n')]) nz = int(out[out.find(dim3):][len(dim3):out[out.find(dim3):].find('\n')]) sq = zeros((step, step)) sq[step - 1] = 1 sq[:, step - 1] = 1 dat = zeros((nx, ny, nz)) for i in range(0, dat.shape[0], step): for j in range(0, dat.shape[1], step): for k in range(dat.shape[2]): if dat[i:i + step, j:j + step, k].shape == (step, step): dat[i:i + step, j:j + step, k] = sq fname_grid = 'grid_' + str(step) + '.nii.gz' im_grid = Image(param=dat) grid_hdr = im_warp.hdr im_grid.hdr = grid_hdr im_grid.absolutepath = fname_grid im_grid.save() fname_grid_resample = sct.add_suffix(fname_grid, '_resample') sct.run(['sct_resample', '-i', fname_grid, '-f', '3x3x1', '-x', 'nn', '-o', fname_grid_resample]) fname_grid = os.path.join(tmp_dir, fname_grid_resample) os.chdir(curdir) path_warp, file_warp, ext_warp = sct.extract_fname(fname_warp) grid_warped = os.path.join(path_warp, sct.extract_fname(fname_grid)[1] + '_' + file_warp + ext_warp) sct.run(['sct_apply_transfo', '-i', fname_grid, '-d', fname_grid, '-w', fname_warp, '-o', grid_warped]) if rm_tmp: sct.rmtree(tmp_dir)
def crop_with_gui(self): import matplotlib.pyplot as plt import matplotlib.image as mpimg # Initialization fname_data = self.input_filename suffix_out = '_crop' remove_temp_files = self.rm_tmp_files verbose = self.verbose # Check file existence sct.printv('\nCheck file existence...', verbose) sct.check_file_exist(fname_data, verbose) # Get dimensions of data sct.printv('\nGet dimensions of data...', verbose) nx, ny, nz, nt, px, py, pz, pt = Image(fname_data).dim sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), verbose) # check if 4D data if not nt == 1: sct.printv('\nERROR in ' + os.path.basename(__file__) + ': Data should be 3D.\n', 1, 'error') sys.exit(2) # sct.printv(arguments) sct.printv('\nCheck parameters:') sct.printv(' data ................... ' + fname_data) # Extract path/file/extension path_data, file_data, ext_data = sct.extract_fname(fname_data) path_out, file_out, ext_out = '', file_data + suffix_out, ext_data path_tmp = sct.tmp_create() + "/" # copy files into tmp folder from sct_convert import convert sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose) convert(fname_data, os.path.join(path_tmp, "data.nii")) # go to tmp folder curdir = os.getcwd() os.chdir(path_tmp) # change orientation sct.printv('\nChange orientation to RPI...', verbose) Image('data.nii').change_orientation("RPI").save('data_rpi.nii') # get image of medial slab sct.printv('\nGet image of medial slab...', verbose) image_array = nibabel.load('data_rpi.nii').get_data() nx, ny, nz = image_array.shape scipy.misc.imsave('image.jpg', image_array[math.floor(nx / 2), :, :]) # Display the image sct.printv('\nDisplay image and get cropping region...', verbose) fig = plt.figure() # fig = plt.gcf() # ax = plt.gca() ax = fig.add_subplot(111) img = mpimg.imread("image.jpg") implot = ax.imshow(img.T) implot.set_cmap('gray') plt.gca().invert_yaxis() # mouse callback ax.set_title('Left click on the top and bottom of your cropping field.\n Right click to remove last point.\n Close window when your done.') line, = ax.plot([], [], 'ro') # empty line cropping_coordinates = LineBuilder(line) plt.show() # disconnect callback # fig.canvas.mpl_disconnect(line) # check if user clicked two times if len(cropping_coordinates.xs) != 2: sct.printv('\nERROR: You have to select two points. Exit program.\n', 1, 'error') sys.exit(2) # convert coordinates to integer zcrop = [int(i) for i in cropping_coordinates.ys] # sort coordinates zcrop.sort() # crop image sct.printv('\nCrop image...', verbose) nii = Image('data_rpi.nii') data_crop = nii.data[:, :, zcrop[0]:zcrop[1]] nii.data = data_crop nii.absolutepath = 'data_rpi_crop.nii' nii.save() # come back os.chdir(curdir) sct.printv('\nGenerate output files...', verbose) sct.generate_output_file(os.path.join(path_tmp, "data_rpi_crop.nii"), os.path.join(path_out, file_out + ext_out)) # Remove temporary files if remove_temp_files == 1: sct.printv('\nRemove temporary files...') sct.rmtree(path_tmp) sct.display_viewer_syntax(files=[os.path.join(path_out, file_out + ext_out)])
def crop_with_gui(self): import matplotlib.pyplot as plt import matplotlib.image as mpimg # Initialization fname_data = self.input_filename suffix_out = '_crop' remove_temp_files = self.rm_tmp_files verbose = self.verbose # Check file existence sct.printv('\nCheck file existence...', verbose) sct.check_file_exist(fname_data, verbose) # Get dimensions of data sct.printv('\nGet dimensions of data...', verbose) nx, ny, nz, nt, px, py, pz, pt = Image(fname_data).dim sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), verbose) # check if 4D data if not nt == 1: sct.printv( '\nERROR in ' + os.path.basename(__file__) + ': Data should be 3D.\n', 1, 'error') sys.exit(2) # sct.printv(arguments) sct.printv('\nCheck parameters:') sct.printv(' data ................... ' + fname_data) # Extract path/file/extension path_data, file_data, ext_data = sct.extract_fname(fname_data) path_out, file_out, ext_out = '', file_data + suffix_out, ext_data path_tmp = sct.tmp_create() + "/" # copy files into tmp folder from sct_convert import convert sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose) convert(fname_data, os.path.join(path_tmp, "data.nii")) # go to tmp folder curdir = os.getcwd() os.chdir(path_tmp) # change orientation sct.printv('\nChange orientation to RPI...', verbose) Image('data.nii').change_orientation("RPI").save('data_rpi.nii') # get image of medial slab sct.printv('\nGet image of medial slab...', verbose) image_array = nibabel.load('data_rpi.nii').get_data() nx, ny, nz = image_array.shape scipy.misc.imsave('image.jpg', image_array[math.floor(nx / 2), :, :]) # Display the image sct.printv('\nDisplay image and get cropping region...', verbose) fig = plt.figure() # fig = plt.gcf() # ax = plt.gca() ax = fig.add_subplot(111) img = mpimg.imread("image.jpg") implot = ax.imshow(img.T) implot.set_cmap('gray') plt.gca().invert_yaxis() # mouse callback ax.set_title( 'Left click on the top and bottom of your cropping field.\n Right click to remove last point.\n Close window when your done.' ) line, = ax.plot([], [], 'ro') # empty line cropping_coordinates = LineBuilder(line) plt.show() # disconnect callback # fig.canvas.mpl_disconnect(line) # check if user clicked two times if len(cropping_coordinates.xs) != 2: sct.printv( '\nERROR: You have to select two points. Exit program.\n', 1, 'error') sys.exit(2) # convert coordinates to integer zcrop = [int(i) for i in cropping_coordinates.ys] # sort coordinates zcrop.sort() # crop image sct.printv('\nCrop image...', verbose) nii = Image('data_rpi.nii') data_crop = nii.data[:, :, zcrop[0]:zcrop[1]] nii.data = data_crop nii.absolutepath = 'data_rpi_crop.nii' nii.save() # come back os.chdir(curdir) sct.printv('\nGenerate output files...', verbose) sct.generate_output_file(os.path.join(path_tmp, "data_rpi_crop.nii"), os.path.join(path_out, file_out + ext_out)) # Remove temporary files if remove_temp_files == 1: sct.printv('\nRemove temporary files...') sct.rmtree(path_tmp) sct.display_viewer_syntax( files=[os.path.join(path_out, file_out + ext_out)])
def main(argv=None): parser = get_parser() arguments = parser.parse_args(argv) verbose = arguments.v set_global_loglevel(verbose=verbose) param = Param() if param.debug: printv('\n*** WARNING: DEBUG MODE ON ***\n') else: input_fname = arguments.i input_second_fname = '' output_fname = 'hausdorff_distance.txt' resample_to = 0.1 if arguments.d is not None: input_second_fname = arguments.d if arguments.thinning is not None: param.thinning = bool(arguments.thinning) if arguments.resampling is not None: resample_to = arguments.resampling if arguments.o is not None: output_fname = arguments.o param.verbose = verbose tmp_dir = tmp_create() im1_name = "im1.nii.gz" copy(input_fname, os.path.join(tmp_dir, im1_name)) if input_second_fname != '': im2_name = 'im2.nii.gz' copy(input_second_fname, os.path.join(tmp_dir, im2_name)) else: im2_name = None curdir = os.getcwd() os.chdir(tmp_dir) # now = time.time() input_im1 = Image( resample_image(im1_name, binary=True, thr=0.5, npx=resample_to, npy=resample_to)) input_im1.absolutepath = os.path.basename(input_fname) if im2_name is not None: input_im2 = Image( resample_image(im2_name, binary=True, thr=0.5, npx=resample_to, npy=resample_to)) input_im2.absolutepath = os.path.basename(input_second_fname) else: input_im2 = None computation = ComputeDistances(input_im1, im2=input_im2, param=param) # TODO change back the orientatin of the thinned image if param.thinning: computation.thinning1.thinned_image.save( os.path.join( curdir, add_suffix(os.path.basename(input_fname), '_thinned'))) if im2_name is not None: computation.thinning2.thinned_image.save( os.path.join( curdir, add_suffix(os.path.basename(input_second_fname), '_thinned'))) os.chdir(curdir) res_fic = open(output_fname, 'w') res_fic.write(computation.res) res_fic.write('\n\nInput 1: ' + input_fname) res_fic.write('\nInput 2: ' + input_second_fname) res_fic.close()
im2_name = 'im2.nii.gz' sct.copy(input_second_fname, os.path.join(tmp_dir, im2_name)) else: im2_name = None curdir = os.getcwd() os.chdir(tmp_dir) # now = time.time() input_im1 = Image( resample_image(im1_name, binary=True, thr=0.5, npx=resample_to, npy=resample_to)) input_im1.absolutepath = os.path.basename(input_fname) if im2_name is not None: input_im2 = Image( resample_image(im2_name, binary=True, thr=0.5, npx=resample_to, npy=resample_to)) input_im2.absolutepath = os.path.basename(input_second_fname) else: input_im2 = None computation = ComputeDistances(input_im1, im2=input_im2, param=param) # TODO change back the orientatin of the thinned image if param.thinning:
tmp_dir = sct.tmp_create() im1_name = "im1.nii.gz" sct.copy(input_fname, os.path.join(tmp_dir, im1_name)) if input_second_fname != '': im2_name = 'im2.nii.gz' sct.copy(input_second_fname, os.path.join(tmp_dir, im2_name)) else: im2_name = None curdir = os.getcwd() os.chdir(tmp_dir) # now = time.time() input_im1 = Image(resample_image(im1_name, binary=True, thr=0.5, npx=resample_to, npy=resample_to)) input_im1.absolutepath = os.path.basename(input_fname) if im2_name is not None: input_im2 = Image(resample_image(im2_name, binary=True, thr=0.5, npx=resample_to, npy=resample_to)) input_im2.absolutepath = os.path.basename(input_second_fname) else: input_im2 = None computation = ComputeDistances(input_im1, im2=input_im2, param=param) # TODO change back the orientatin of the thinned image if param.thinning: computation.thinning1.thinned_image.save(os.path.join(curdir, sct.add_suffix(os.path.basename(input_fname), '_thinned'))) if im2_name is not None: computation.thinning2.thinned_image.save(os.path.join(curdir, sct.add_suffix(os.path.basename(input_second_fname), '_thinned'))) os.chdir(curdir)
def find_centerline(algo, image_fname, contrast_type, brain_bool, folder_output, remove_temp_files, centerline_fname): """ Assumes RPI orientation :param algo: :param image_fname: :param contrast_type: :param brain_bool: :param folder_output: :param remove_temp_files: :param centerline_fname: :return: """ im = Image(image_fname) ctl_absolute_path = sct.add_suffix(im.absolutepath, "_ctr") # isct_spine_detect requires nz > 1 if im.dim[2] == 1: im = concat_data([im, im], dim=2) im.hdr['dim'][3] = 2 # Needs to be change manually since dim not updated during concat_data bool_2d = True else: bool_2d = False # TODO: maybe change 'svm' for 'optic', because this is how we call it in sct_get_centerline if algo == 'svm': # run optic on a heatmap computed by a trained SVM+HoG algorithm # optic_models_fname = os.path.join(path_sct, 'data', 'optic_models', '{}_model'.format(contrast_type)) # # TODO: replace with get_centerline(method=optic) im_ctl, _, _, _ = get_centerline(im, ParamCenterline(algo_fitting='optic', contrast=contrast_type)) elif algo == 'cnn': # CNN parameters dct_patch_ctr = {'t2': {'size': (80, 80), 'mean': 51.1417, 'std': 57.4408}, 't2s': {'size': (80, 80), 'mean': 68.8591, 'std': 71.4659}, 't1': {'size': (80, 80), 'mean': 55.7359, 'std': 64.3149}, 'dwi': {'size': (80, 80), 'mean': 55.744, 'std': 45.003}} dct_params_ctr = {'t2': {'features': 16, 'dilation_layers': 2}, 't2s': {'features': 8, 'dilation_layers': 3}, 't1': {'features': 24, 'dilation_layers': 3}, 'dwi': {'features': 8, 'dilation_layers': 2}} # load model ctr_model_fname = os.path.join(sct.__sct_dir__, 'data', 'deepseg_sc_models', '{}_ctr.h5'.format(contrast_type)) ctr_model = nn_architecture_ctr(height=dct_patch_ctr[contrast_type]['size'][0], width=dct_patch_ctr[contrast_type]['size'][1], channels=1, classes=1, features=dct_params_ctr[contrast_type]['features'], depth=2, temperature=1.0, padding='same', batchnorm=True, dropout=0.0, dilation_layers=dct_params_ctr[contrast_type]['dilation_layers']) ctr_model.load_weights(ctr_model_fname) # compute the heatmap im_heatmap, z_max = heatmap(im=im, model=ctr_model, patch_shape=dct_patch_ctr[contrast_type]['size'], mean_train=dct_patch_ctr[contrast_type]['mean'], std_train=dct_patch_ctr[contrast_type]['std'], brain_bool=brain_bool) im_ctl, _, _, _ = get_centerline(im_heatmap, ParamCenterline(algo_fitting='optic', contrast=contrast_type)) if z_max is not None: sct.printv('Cropping brain section.') im_ctl.data[:, :, z_max:] = 0 elif algo == 'viewer': im_labels = _call_viewer_centerline(im) im_ctl, _, _, _ = get_centerline(im_labels, param=ParamCenterline()) elif algo == 'file': im_ctl = Image(centerline_fname) im_ctl.change_orientation('RPI') else: logger.error('The parameter "-centerline" is incorrect. Please try again.') sys.exit(1) # TODO: for some reason, when algo == 'file', the absolutepath is changed to None out of the method find_centerline im_ctl.absolutepath = ctl_absolute_path if bool_2d: im_ctl = split_data(im_ctl, dim=2)[0] if algo != 'viewer': im_labels = None # TODO: remove unecessary return params return "dummy_file_name", im_ctl, im_labels
def validation(self, fname_manual_gmseg, fname_sc_seg): path_manual_gmseg, file_manual_gmseg, ext_manual_gmseg = sct.extract_fname( fname_manual_gmseg) path_sc_seg, file_sc_seg, ext_sc_seg = sct.extract_fname(fname_sc_seg) # Create tmp folder and copy files in it tmp_dir = sct.tmp_create() sct.copy(fname_manual_gmseg, os.path.join(tmp_dir, file_manual_gmseg + ext_manual_gmseg)) sct.copy(fname_sc_seg, os.path.join(tmp_dir, file_sc_seg + ext_sc_seg)) sct.copy( os.path.join(self.param.output_folder, self.fname_warp_template2gm), os.path.join(tmp_dir, self.fname_warp_template2gm)) curdir = os.getcwd() os.chdir(tmp_dir) cmd = [ 'sct_warp_template', '-d', fname_manual_gmseg, '-w', self.fname_warp_template2gm, '-a', '0' ] if self.param.path_qc is not None and os.environ.get( "SCT_RECURSIVE_QC", None) == "1": cmd += ["-qc", self.param.path_qc] sct.run(cmd) if 'MNI-Poly-AMU_GM.nii.gz' in os.listdir( os.path.join('label', 'template')): im_new_template_gm = Image( os.path.join('label', 'template', 'MNI-Poly-AMU_GM.nii.gz')) im_new_template_wm = Image( os.path.join('label', 'template', 'MNI-Poly-AMU_WM.nii.gz')) else: im_new_template_gm = Image( os.path.join('label', 'template', 'PAM50_gm.nii.gz')) im_new_template_wm = Image( os.path.join('label', 'template', 'PAM50_wm.nii.gz')) im_new_template_gm = thr_im(im_new_template_gm, self.param.thr, self.param.thr) im_new_template_wm = thr_im(im_new_template_wm, self.param.thr, self.param.thr) self.im_template_gm = thr_im(self.im_template_gm, self.param.thr, self.param.thr) self.im_template_wm = thr_im(self.im_template_wm, self.param.thr, self.param.thr) fname_new_template_gm = 'new_template_gm.nii.gz' im_new_template_gm.absolutepath = fname_new_template_gm im_new_template_gm.save() fname_new_template_wm = 'new_template_wm.nii.gz' im_new_template_wm.absolutepath = fname_new_template_wm im_new_template_wm.save() fname_old_template_wm = 'old_template_wm.nii.gz' self.im_template_wm.absolutepath = fname_old_template_wm self.im_template_wm.save() fname_old_template_gm = 'old_template_gm.nii.gz' self.im_template_gm.absolutepath = fname_old_template_gm self.im_template_gm.save() fname_manual_wmseg = 'target_manual_wmseg.nii.gz' sct.run([ 'sct_maths', '-i', file_sc_seg + ext_sc_seg, '-sub', file_manual_gmseg + ext_manual_gmseg, '-o', fname_manual_wmseg ]) # Compute Hausdorff distance status, output_old_hd = sct.run([ 'sct_compute_hausdorff_distance', '-i', fname_old_template_gm, '-r', file_manual_gmseg + ext_manual_gmseg, '-t', '1', '-v', '1' ]) status, output_new_hd = sct.run([ 'sct_compute_hausdorff_distance', '-i', fname_new_template_gm, '-r', file_manual_gmseg + ext_manual_gmseg, '-t', '1', '-v', '1' ]) hd_name = 'hd_md_multilabel_reg.txt' hd_fic = open(hd_name, 'w') hd_fic.write( 'The "diff" columns are comparisons between regular template registration and corrected template registration according to SC internal structure\n' 'Diff = metric_regular_reg - metric_corrected_reg\n') hd_fic.write('#Slice, HD, HD diff, MD, MD diff\n') no_ref_slices = [] init_hd = "Hausdorff's distance - First relative Hausdorff's distance median - Second relative Hausdorff's distance median(all in mm)\n" old_gm_hd = output_old_hd[output_old_hd.find(init_hd) + len(init_hd):].split('\n') new_gm_hd = output_new_hd[output_new_hd.find(init_hd) + len(init_hd):].split('\n') for i in range(len(old_gm_hd) - 3): # last two lines are informations i_old, val_old = old_gm_hd[i].split(':') i_new, val_new = new_gm_hd[i].split(':') i_old = int(i_old[-2:]) i_new = int(i_new[-2:]) assert i == i_old == i_new, 'ERROR: when comparing Hausdorff distances, slice numbers differs.' hd_old, med1_old, med2_old = val_old.split('-') hd_new, med1_new, med2_new = val_new.split('-') if float(hd_old) == 0.0: no_ref_slices.append(i) hd_fic.write(str(i) + ', NO MANUAL SEGMENTATION\n') else: md_new = max(float(med1_new), float(med2_new)) md_old = max(float(med1_old), float(med2_old)) hd_fic.write( str(i) + ', ' + hd_new + ', ' + str(float(hd_old) - float(hd_new)) + ', ' + str(md_new) + ', ' + str(md_old - md_new) + '\n') hd_fic.close() # Compute Dice coefficient # --- DC old template try: status_old_gm, output_old_gm = sct.run([ 'sct_dice_coefficient', '-i', file_manual_gmseg + ext_manual_gmseg, '-d', fname_old_template_gm, '-2d-slices', '2' ]) except Exception: # put the result and the reference in the same space using a registration with ANTs with no iteration: corrected_manual_gmseg = file_manual_gmseg + '_in_old_template_space' + ext_manual_gmseg # TODO sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[' + fname_old_template_gm + ',' + file_manual_gmseg + ext_manual_gmseg + ',1,16] -o [reg_ref_to_res,' + corrected_manual_gmseg + '] -n BSpline[3] -c 0 -f 1 -s 0') # sct.run('sct_maths -i '+corrected_manual_gmseg+' -thr 0.1 -o '+corrected_manual_gmseg) sct.run([ 'sct_maths', '-i', corrected_manual_gmseg, '-bin', '0.1', '-o', corrected_manual_gmseg ]) status_old_gm, output_old_gm = sct.run([ 'sct_dice_coefficient', '-i', corrected_manual_gmseg, '-d', fname_old_template_gm, '-2d-slices', '2' ]) try: status_old_wm, output_old_wm = sct.run([ 'sct_dice_coefficient', '-i', fname_manual_wmseg, '-d', fname_old_template_wm, '-2d-slices', '2' ]) except Exception: # put the result and the reference in the same space using a registration with ANTs with no iteration: path_manual_wmseg, file_manual_wmseg, ext_manual_wmseg = sct.extract_fname( fname_manual_wmseg) corrected_manual_wmseg = file_manual_wmseg + '_in_old_template_space' + ext_manual_wmseg # TODO sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[' + fname_old_template_wm + ',' + fname_manual_wmseg + ',1,16] -o [reg_ref_to_res,' + corrected_manual_wmseg + '] -n BSpline[3] -c 0 -f 1 -s 0') # sct.run('sct_maths -i '+corrected_manual_wmseg+' -thr 0.1 -o '+corrected_manual_wmseg) sct.run('sct_maths -i ' + corrected_manual_wmseg + ' -bin 0.1 -o ' + corrected_manual_wmseg) status_old_wm, output_old_wm = sct.run([ 'sct_dice_coefficient', '-i', corrected_manual_wmseg, '-d', fname_old_template_wm, '-2d-slices', '2' ]) # --- DC new template try: status_new_gm, output_new_gm = sct.run([ 'sct_dice_coefficient', '-i', file_manual_gmseg + ext_manual_gmseg, '-d', fname_new_template_gm, '-2d-slices', '2' ]) except Exception: # put the result and the reference in the same space using a registration with ANTs with no iteration: corrected_manual_gmseg = file_manual_gmseg + '_in_new_template_space' + ext_manual_gmseg # TODO sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[' + fname_new_template_gm + ',' + file_manual_gmseg + ext_manual_gmseg + ',1,16] -o [reg_ref_to_res,' + corrected_manual_gmseg + '] -n BSpline[3] -c 0 -f 1 -s 0') # sct.run('sct_maths -i '+corrected_manual_gmseg+' -thr 0.1 -o '+corrected_manual_gmseg) sct.run([ 'sct_maths', '-i', corrected_manual_gmseg, '-bin', '0.1', '-o', corrected_manual_gmseg ]) status_new_gm, output_new_gm = sct.run([ 'sct_dice_coefficient', '-i', corrected_manual_gmseg, '-d', fname_new_template_gm, '-2d-slices', '2' ]) try: status_new_wm, output_new_wm = sct.run([ 'sct_dice_coefficient', '-i', fname_manual_wmseg, '-d', fname_new_template_wm, '-2d-slices', '2' ]) except Exception: # put the result and the reference in the same space using a registration with ANTs with no iteration: path_manual_wmseg, file_manual_wmseg, ext_manual_wmseg = sct.extract_fname( fname_manual_wmseg) corrected_manual_wmseg = file_manual_wmseg + '_in_new_template_space' + ext_manual_wmseg sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[' + fname_new_template_wm + ',' + fname_manual_wmseg + ',1,16] -o [reg_ref_to_res,' + corrected_manual_wmseg + '] -n BSpline[3] -c 0 -f 1 -s 0') # sct.run('sct_maths -i '+corrected_manual_wmseg+' -thr 0.1 -o '+corrected_manual_wmseg) sct.run([ 'sct_maths', '-i', corrected_manual_wmseg, '-bin', '0.1', '-o', corrected_manual_wmseg ]) status_new_wm, output_new_wm = sct.run([ 'sct_dice_coefficient', '-i', corrected_manual_wmseg, '-d', fname_new_template_wm, '-2d-slices', '2' ]) dice_name = 'dice_multilabel_reg.txt' dice_fic = open(dice_name, 'w') dice_fic.write( 'The "diff" columns are comparisons between regular template registration and corrected template registration according to SC internal structure\n' 'Diff = metric_corrected_reg - metric_regular_reg\n') dice_fic.write('#Slice, WM DC, WM diff, GM DC, GM diff\n') init_dc = '2D Dice coefficient by slice:\n' old_gm_dc = output_old_gm[output_old_gm.find(init_dc) + len(init_dc):].split('\n') old_wm_dc = output_old_wm[output_old_wm.find(init_dc) + len(init_dc):].split('\n') new_gm_dc = output_new_gm[output_new_gm.find(init_dc) + len(init_dc):].split('\n') new_wm_dc = output_new_wm[output_new_wm.find(init_dc) + len(init_dc):].split('\n') for i in range(len(old_gm_dc)): if i not in no_ref_slices: i_new_gm, val_new_gm = new_gm_dc[i].split(' ') i_new_wm, val_new_wm = new_wm_dc[i].split(' ') i_old_gm, val_old_gm = old_gm_dc[i].split(' ') i_old_wm, val_old_wm = old_wm_dc[i].split(' ') assert i == int(i_new_gm) == int(i_new_wm) == int( i_old_gm ) == int( i_old_wm ), 'ERROR: when comparing Dice coefficients, slice numbers differs.' dice_fic.write( str(i) + ', ' + val_new_wm + ', ' + str(float(val_new_wm) - float(val_old_wm)) + ', ' + val_new_gm + ', ' + str(float(val_new_gm) - float(val_old_gm)) + '\n') else: dice_fic.write(str(i) + ', NO MANUAL SEGMENTATION\n') dice_fic.close() os.chdir(curdir) sct.generate_output_file( os.path.join(tmp_dir, hd_name), os.path.join(self.param.output_folder, hd_name)) sct.generate_output_file( os.path.join(tmp_dir, dice_name), os.path.join(self.param.output_folder, dice_name)) if self.param.remove_tmp: sct.rmtree(tmp_dir)