def relabel(self, path_to_input_segmentation, path_to_output_segmentation=None, list_old_labels=(), list_new_labels=(), path_to_input_labels_descriptor=None, path_to_output_labels_descriptor=None): """ Masks of :func:`labels_manager.tools.manipulations.relabeller.relabeller` using filenames """ pfi_in, pfi_out = get_pfi_in_pfi_out(path_to_input_segmentation, path_to_output_segmentation, self.pfo_in, self.pfo_out) im_labels = nib.load(pfi_in) data_labels = im_labels.get_data() data_relabelled = relabeller(data_labels, list_old_labels=list_old_labels, list_new_labels=list_new_labels) im_relabelled = set_new_data(im_labels, data_relabelled) nib.save(im_relabelled, pfi_out) if path_to_input_labels_descriptor is not None: pfi_in_ld = connect_path_tail_head(self.pfo_in, path_to_input_labels_descriptor) ldm_input = LdM(pfi_in_ld, labels_descriptor_convention=self.labels_descriptor_convention) ldm_relabelled = ldm_input.relabel(list_old_labels=list_old_labels, list_new_labels=list_new_labels) if path_to_output_labels_descriptor is None: ldm_relabelled.save_label_descriptor(pfi_in_ld) else: pfi_out_ld = connect_path_tail_head(self.pfo_out, path_to_output_labels_descriptor) ldm_relabelled.save_label_descriptor(pfi_out_ld) print('Relabelled image {0} saved in {1}.'.format(pfi_in, pfi_out)) return pfi_out
def binarise_and_adjust_mask_from_segmentation_path(pfi_segm_input, pfi_mask_output, pfo_temp, subject_name, labels_to_exclude=(), dil_factor=1, ero_factor=1): """ Sequence of topological operation to pass from the manual segmentation to a single binary mask covering the brain tissue and excluding the skull. :param pfi_segm_input: :param pfi_mask_output: :param pfo_temp: :param subject_name: :param labels_to_exclude: :param dil_factor: dilation factor before erosion :param ero_factor: erosion factor after dilation :return: """ pfi_intermediate = jph(pfo_temp, '{}_tmp_binarisation.nii.gz'.format(subject_name)) print_and_run('cp {} {}'.format(pfi_segm_input, pfi_intermediate)) if len(labels_to_exclude) > 0: im_segm = nib.load(pfi_intermediate) array_segm_new_data = relabeller(im_segm.get_data(), list_old_labels=labels_to_exclude, list_new_labels=[ 0, ] * len(labels_to_exclude)) im_segm_new = set_new_data(im_segm, array_segm_new_data) nib.save(im_segm_new, pfi_intermediate) print_and_run('seg_maths {0} -bin {0}'.format(pfi_intermediate)) # fill and dil the binarised segmentation print_and_run('seg_maths {0} -fill {1}'.format(pfi_intermediate, pfi_intermediate)) print_and_run('seg_maths {0} -dil {1} {0}'.format(pfi_intermediate, dil_factor)) print_and_run('seg_maths {0} -ero {1} {0}'.format(pfi_intermediate, ero_factor)) # print_and_run('seg_maths {0} -fill {0}'.format(pfi_intermediate)) print_and_run('seg_maths {0} -fill {1}'.format(pfi_intermediate, pfi_mask_output))
def island_for_label(array_segm, label, m=0, special_label=-1): """ As ndimage.label, with output ordered by the size of the connected component. :param array_segm: :param label: :param m: integer. If m = 0 the n connected components will be numbered from 1 (biggest) to n (smallest). If m > 0, from the m-th largest components, all the components are set to the special special_label. :param special_label: value used if m > 0. :return: segmentation with the components sorted. ----- e.g. array_segm has 4 components of for the input label. If m = 0 it returns the components labelled from 1 to 4, where 1 is the biggest. if m = 2 the first two largest components are numbered 1 and 2, and the remaining 2 are labelled with special_label. """ if label not in array_segm: print('Label {} not in the provided array.'.format(label)) return array_segm binary_segm_comp, num_comp = ndimage.label(array_segm == label) if num_comp == 1: return binary_segm_comp voxels_per_components = np.array( [np.count_nonzero(binary_segm_comp == l + 1) for l in range(num_comp)]) scores = voxels_per_components.argsort()[::-1] + 1 new_labels = np.arange(num_comp) + 1 binary_segm_components_sorted = relabeller(binary_segm_comp, scores, new_labels, verbose=1) if m > 0: binary_segm_components_sorted[ binary_segm_components_sorted > m] = special_label return binary_segm_components_sorted
# data: fin_punt_seg_original = 'punt_seg.nii.gz' fin_punt_seg_new = 'punt_seg_relabelled.nii.gz' list_old_labels = [1, 2, 3, 4, 5, 6] list_new_labels = [2, 3, 4, 5, 6, 7] # Using the manager: lt.manipulate_labels.relabel(fin_punt_seg_original, fin_punt_seg_new, list_old_labels, list_new_labels) # Without the managers: loading the data and applying the relabeller im_seg = nib.load(jph(root_dir, 'data_examples', fin_punt_seg_original)) data_seg = im_seg.get_data() data_seg_new = rel.relabeller(data_seg, list_old_labels, list_new_labels) im_relabelled = set_new_data(im_seg, data_seg_new) # Results comparison: nib_seg_new = nib.load(jph(root_dir, 'data_output', fin_punt_seg_new)) nib_seg_new_data = nib_seg_new.get_data() np.testing.assert_array_equal(data_seg_new, nib_seg_new_data) if open_figures: # figure before: cmd = 'itksnap -g {0} -s {1}'.format( jph(root_dir, 'data_examples', 'punt.nii.gz'), jph(root_dir, 'data_examples', fin_punt_seg_original)) os.system(cmd) # figure after
def test_relabeller_basic(): data = np.array(range(10)).reshape(2, 5) relabelled_data = relabeller(data, range(10), range(10)[::-1]) np.testing.assert_array_equal(relabelled_data, np.array(range(10)[::-1]).reshape(2,5))
def test_relabeller_wrong_input(): data = np.array(range(10)).reshape(2, 5) with np.testing.assert_raises(IOError): relabeller(data, [1, 2], [3, 4, 4])
def test_relabeller_one_element_not_in_array(): data = np.array(range(10)).reshape(2, 5) relabelled_data = relabeller(data, 15, 1, verbose=1) np.testing.assert_array_equal(relabelled_data, data)
def test_relabeller_one_element(): data = np.array(range(10)).reshape(2, 5) relabelled_data = relabeller(data, 0, 1, verbose=1) expected_output = data[:] expected_output[0, 0] = 1 np.testing.assert_array_equal(relabelled_data, expected_output)
def symmetrise_with_registration(self, filename_anatomy, filename_segmentation, list_labels_input, result_img_path, results_folder_path=None, list_labels_transformed=None, coord='z', reuse_registration=False): """ Symmetrise a segmentation with registration: it uses NiftyReg. The old side is symmetrised in the new side, with new relabelling. Method based on paths even if in tools :param filename_anatomy: Path to File anatomical image :param filename_segmentation: Path to File segmentation of the anatomical image :param results_folder_path: Path to FOlder where intermediate results are stored :param result_img_path: Path to File symmetrised segmentation :param list_labels_input: labels that will be taken into account in the symmetrisation from the old side. :param list_labels_transformed: corresponding labels in the same order. If None, labels of the new side will be kept with the same numbering in the new side. :param reuse_registration: if a registration is already present in the pfo_results, and you only need to change the labels value, it will spare you some time when set to True. :param coord: coordinate of the registration: in RAS, 'z' will symmetrise Left on Right. :return: symmetrised segmentation. --- NOTE: requires niftyreg. """ pfi_in_anatomy = connect_path_tail_head(self.pfo_in, filename_anatomy) pfi_in_segmentation = connect_path_tail_head(self.pfo_in, filename_segmentation) if results_folder_path is None: if self.pfo_out is not None: results_folder_path = self.pfo_out else: results_folder_path = self.pfo_in else: results_folder_path = os.path.dirname(pfi_in_segmentation) pfi_out_segmentation = connect_path_tail_head(results_folder_path, result_img_path) def flip_data_path(input_im_path, output_im_path, axis='x'): # wrap flip data, having path for inputs and outputs. if not os.path.isfile(input_im_path): raise IOError('input image file does not exist.') im_labels = nib.load(input_im_path) data_labels = im_labels.get_data() data_flipped = flip_data(data_labels, axis_direction=axis) im_relabelled = set_new_data(im_labels, data_flipped) nib.save(im_relabelled, output_im_path) # side A is the input, side B is the one where we want to symmetrise. # --- Initialisation --- # # check input: if not os.path.isfile(pfi_in_anatomy): raise IOError('input image file {} does not exist.'.format(pfi_in_anatomy)) if not os.path.isfile(pfi_in_segmentation): raise IOError('input segmentation file {} does not exist.'.format(pfi_in_segmentation)) # erase labels that are not in the list from image and descriptor out_labels_side_A_path = os.path.join(results_folder_path, 'z_labels_side_A.nii.gz') labels_im = nib.load(pfi_in_segmentation) labels_data = labels_im.get_data() labels_to_erase = list(set(labels_data.flat) - set(list_labels_input + [0])) # Relabel: from pfi_segmentation to out_labels_side_A_path im_pfi_segmentation = nib.load(pfi_in_segmentation) segmentation_data_relabelled = relabeller(im_pfi_segmentation.get_data(), list_old_labels=labels_to_erase, list_new_labels=[0, ] * len(labels_to_erase)) nib_labels_side_A_path = set_new_data(im_pfi_segmentation, segmentation_data_relabelled) nib.save(nib_labels_side_A_path, out_labels_side_A_path) # --- Create side B --- # # flip anatomical image and register it over the non flipped out_anatomical_flipped_path = os.path.join(results_folder_path, 'z_anatomical_flipped.nii.gz') flip_data_path(pfi_in_anatomy, out_anatomical_flipped_path, axis=coord) # flip the labels out_labels_flipped_path = os.path.join(results_folder_path, 'z_labels_flipped.nii.gz') flip_data_path(out_labels_side_A_path, out_labels_flipped_path, axis=coord) # register anatomical flipped over non flipped out_anatomical_flipped_warped_path = os.path.join(results_folder_path, 'z_anatomical_flipped_warped.nii.gz') out_affine_transf_path = os.path.join(results_folder_path, 'z_affine_transformation.txt') if not reuse_registration: cmd = 'reg_aladin -ref {0} -flo {1} -aff {2} -res {3}'.format(pfi_in_anatomy, out_anatomical_flipped_path, out_affine_transf_path, out_anatomical_flipped_warped_path) print('Registration started!\n') os.system(cmd) # propagate the registration to the flipped labels out_labels_side_B_path = os.path.join(results_folder_path, 'z_labels_side_B.nii.gz') cmd = 'reg_resample -ref {0} -flo {1} ' \ '-res {2} -trans {3} -inter {4}'.format(out_labels_side_A_path, out_labels_flipped_path, out_labels_side_B_path, out_affine_transf_path, 0) print('Resampling started!\n') os.system(cmd) else: out_labels_side_B_path = os.path.join(results_folder_path, 'z_labels_side_B.nii.gz') # update labels of the side B if necessarily if list_labels_transformed is not None: print('relabelling step!') assert len(list_labels_transformed) == len(list_labels_input) # relabel from out_labels_side_B_path to out_labels_side_B_path im_segmentation_side_B = nib.load(out_labels_side_B_path) data_segmentation_side_B_new = relabeller(im_segmentation_side_B.get_data(), list_old_labels=list_labels_input, list_new_labels=list_labels_transformed) nib_segmentation_side_B_new = set_new_data(im_segmentation_side_B, data_segmentation_side_B_new) nib.save(nib_segmentation_side_B_new, out_labels_side_B_path) # --- Merge side A and side B in a single volume according to a criteria --- # # out_labels_side_A_path, out_labels_side_B_path --> result_path.nii.gz nib_side_A = nib.load(out_labels_side_A_path) nib_side_B = nib.load(out_labels_side_B_path) data_side_A = nib_side_A.get_data() data_side_B = nib_side_B.get_data() symmetrised_data = np.zeros_like(data_side_A) # To manage the intersections of labels between old and new side. Vectorize later... dims = data_side_A.shape print('Pointwise symmetrisation started!') for z in range(dims[0]): for x in range(dims[1]): for y in range(dims[2]): if (data_side_A[z, x, y] == 0 and data_side_B[z, x, y] != 0) or \ (data_side_A[z, x, y] != 0 and data_side_B[z, x, y] == 0): symmetrised_data[z, x, y] = np.max([data_side_A[z, x, y], data_side_B[z, x, y]]) elif data_side_A[z, x, y] != 0 and data_side_B[z, x, y] != 0: if data_side_A[z, x, y] == data_side_B[z, x, y]: symmetrised_data[z, x, y] = data_side_A[z, x, y] else: symmetrised_data[z, x, y] = 255 # devil label! im_symmetrised = set_new_data(nib_side_A, symmetrised_data) nib.save(im_symmetrised, pfi_out_segmentation)
def process_T1_per_subject(sj, steps): print('\nProcessing T1 {} started.\n'.format(sj)) if sj not in list_all_subjects(pfo_subjects_parameters): raise IOError('Subject parameters not known. Subject {}'.format(sj)) sj_parameters = pickle.load(open(jph(pfo_subjects_parameters, sj), 'r')) study = sj_parameters['study'] category = sj_parameters['category'] options_T1 = sj_parameters['options_T1'] suffix_T1_architecture = sj_parameters['names_architecture'][ 'T1'] # default is 3D pfo_input_sj_3D = jph(root_study_rabbits, '02_nifti', study, category, sj, sj + '_' + suffix_T1_architecture) pfo_output_sj = jph(root_study_rabbits, 'A_data', study, category, sj) # select appropriate atlas: if study == 'ACS' or study == 'PTB' or study == 'TestStudy': pfo_atlas = root_atlas elif study == 'W8': pfo_atlas = root_atlas_W8 else: raise IOError('Parameter **study** not included in the current logic.') # input sanity check: if not os.path.exists(pfo_input_sj_3D): raise IOError('Input folder nifti data T1 does not exist. {}'.format( pfo_input_sj_3D)) # -- Generate intermediate and output folder pfo_mod = jph(pfo_output_sj, 'mod') pfo_segm = jph(pfo_output_sj, 'segm') pfo_mask = jph(pfo_output_sj, 'masks') pfo_tmp = jph(pfo_output_sj, 'z_tmp', 'z_T1' + suffix_T1_architecture) print_and_run('mkdir -p {}'.format(pfo_output_sj)) print_and_run('mkdir -p {}'.format(pfo_mod)) print_and_run('mkdir -p {}'.format(pfo_segm)) print_and_run('mkdir -p {}'.format(pfo_mask)) print_and_run('mkdir -p {}'.format(pfo_tmp)) reference_subject = options_T1['pivot'] # If the element is in template retrieve the original roi mask and reg mask if sj_parameters['in_atlas']: reference_subject = sj # turn off all the not useful stuff: options_T1['roi_mask'] = '' steps['adjust_mask'] = False steps['create_lesion_maks'] = False if steps['orient_to_standard']: print('- orient to standard {}'.format(sj)) pfi_input_original = jph(pfo_input_sj_3D, sj + '_3D.nii.gz') assert check_path_validity(pfi_input_original) pfi_std = jph(pfo_tmp, sj + '_to_std.nii.gz') orient2std(pfi_input_original, pfi_std) del pfi_input_original, pfi_std if steps['create_roi_masks']: pfi_std = jph(pfo_tmp, '{}_to_std.nii.gz'.format(sj)) assert check_path_validity(pfi_std) # --- Get the reference masks from the stereotaxic orientation --- # reference subject: pfi_sj_ref_coord_system = jph(pfo_atlas, reference_subject, 'mod', '{}_T1.nii.gz'.format(reference_subject)) # original mask pfi_reference_roi_mask = jph( pfo_atlas, reference_subject, 'masks', '{}_roi_mask.nii.gz'.format(reference_subject)) pfi_reference_reg_mask = jph( pfo_atlas, reference_subject, 'masks', '{}_reg_mask.nii.gz'.format(reference_subject)) assert check_path_validity(pfi_sj_ref_coord_system) assert check_path_validity(pfi_reference_roi_mask) assert check_path_validity(pfi_reference_reg_mask) # --- Get the angle difference from histological (template) to bicommissural (data) and orient header --- if isinstance(sj_parameters['angles'][0], list): angles = sj_parameters['angles'][0] else: angles = sj_parameters['angles'] angle_parameter = angles[1] print('Get initial roi mask using the pivot.') pfi_sj_ref_coord_system_hd_oriented = jph( pfo_tmp, 'reference_for_mask_registration.nii.gz') pfi_reference_roi_mask_hd_oriented = jph( pfo_tmp, 'reference_for_mask_roi_mask.nii.gz') pfi_reference_reg_mask_hd_oriented = jph( pfo_tmp, 'reference_for_mask_reg_mask.nii.gz') nis_app = nis.App() nis_app.header.apply_small_rotation( pfi_sj_ref_coord_system, pfi_sj_ref_coord_system_hd_oriented, angle=angle_parameter, principal_axis='pitch') nis_app.header.apply_small_rotation(pfi_reference_roi_mask, pfi_reference_roi_mask_hd_oriented, angle=angle_parameter, principal_axis='pitch') nis_app.header.apply_small_rotation(pfi_reference_reg_mask, pfi_reference_reg_mask_hd_oriented, angle=angle_parameter, principal_axis='pitch') # set translational part to zero nis_app.header.modify_translational_part( pfi_sj_ref_coord_system_hd_oriented, pfi_sj_ref_coord_system_hd_oriented, np.array([0, 0, 0])) nis_app.header.modify_translational_part( pfi_reference_roi_mask_hd_oriented, pfi_reference_roi_mask_hd_oriented, np.array([0, 0, 0])) nis_app.header.modify_translational_part( pfi_reference_reg_mask_hd_oriented, pfi_reference_reg_mask_hd_oriented, np.array([0, 0, 0])) assert check_path_validity(pfi_sj_ref_coord_system_hd_oriented) assert check_path_validity(pfi_reference_roi_mask_hd_oriented) pfi_affine_transformation_ref_on_subject = jph( pfo_tmp, 'aff_ref_on_' + sj + '.txt') pfi_3d_warped_ref_on_subject = jph(pfo_tmp, 'warp_ref_on_' + sj + '.nii.gz') cmd = 'reg_aladin -ref {0} -flo {1} -fmask {2} -aff {3} -res {4} -omp {5} -speeeeed '.format( # -rigOnly pfi_std, pfi_sj_ref_coord_system_hd_oriented, pfi_reference_roi_mask_hd_oriented, pfi_affine_transformation_ref_on_subject, pfi_3d_warped_ref_on_subject, num_cores_run) print_and_run(cmd) print('- propagate affine registration T1 to roi masks {}'.format(sj)) pfi_roi_mask_not_adjusted = jph( pfo_tmp, sj + '_T1_roi_mask_not_adjusted.nii.gz') cmd = 'reg_resample -ref {0} -flo {1} -trans {2} -res {3} -inter 0'.format( pfi_std, pfi_reference_roi_mask_hd_oriented, pfi_affine_transformation_ref_on_subject, pfi_roi_mask_not_adjusted) print_and_run(cmd) print('- propagate affine registration T1 to reg masks {}'.format(sj)) pfi_reg_mask_not_adjusted = jph( pfo_tmp, sj + '_T1_reg_mask_not_adjusted.nii.gz') cmd = 'reg_resample -ref {0} -flo {1} -trans {2} -res {3} -inter 0'.format( pfi_std, pfi_reference_reg_mask_hd_oriented, pfi_affine_transformation_ref_on_subject, pfi_reg_mask_not_adjusted) print_and_run(cmd) if sj_parameters['in_atlas']: # if sj is in multi-atlas just copy the masks as they are in the destination, and then manipulate pfi_roi_mask = jph(pfo_mask, '{}_T1_roi_mask.nii.gz'.format(sj)) # pfi_reg_mask = jph(pfo_mask, '{}_T1_reg_mask.nii.gz'.format(sj)) cmd = 'cp {} {}'.format(pfi_roi_mask_not_adjusted, pfi_roi_mask) print_and_run(cmd) # cmd = 'cp {} {}'.format(pfi_reg_mask_not_adjusted, pfi_reg_mask) # print_and_run(cmd) del pfi_std, pfi_sj_ref_coord_system, pfi_reference_roi_mask, \ angle_parameter, angles, pfi_sj_ref_coord_system_hd_oriented, pfi_reference_roi_mask_hd_oriented, \ pfi_affine_transformation_ref_on_subject, pfi_3d_warped_ref_on_subject, cmd if steps['adjust_mask']: print('- adjust mask {}'.format(sj)) # Input: pfi_roi_mask_not_adjusted = jph( pfo_tmp, sj + '_T1_roi_mask_not_adjusted.nii.gz') assert os.path.exists( pfi_roi_mask_not_adjusted), pfi_roi_mask_not_adjusted # Parameters: dilation_param = options_T1['mask_dilation'] # Main output: pfi_roi_mask = jph(pfo_mask, '{}_T1_roi_mask.nii.gz'.format(sj)) if dilation_param < 0: # if negative, erode. cmd = 'seg_maths {0} -ero {1} {2}'.format( pfi_roi_mask_not_adjusted, -1 * dilation_param, pfi_roi_mask) elif dilation_param > 0: cmd = 'seg_maths {0} -dil {1} {2}'.format( pfi_roi_mask_not_adjusted, dilation_param, pfi_roi_mask) else: cmd = 'cp {} {}'.format(pfi_roi_mask_not_adjusted, pfi_roi_mask) del dilation_param, pfi_roi_mask_not_adjusted print_and_run(cmd) del pfi_roi_mask, cmd if steps['cut_masks']: if options_T1['crop_roi']: print('- cut masks {}'.format(sj)) pfi_std = jph(pfo_tmp, sj + '_to_std.nii.gz') pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz') assert check_path_validity(pfi_std) assert check_path_validity(pfi_roi_mask) pfi_3d_cropped_roi = jph(pfo_tmp, sj + '_cropped.nii.gz') cmd = 'seg_maths {0} -mul {1} {2}'.format(pfi_std, pfi_roi_mask, pfi_3d_cropped_roi) print '\nCutting newly-created ciccione mask on the subject: subject {0}.\n'.format( sj) print_and_run(cmd) del pfi_std, pfi_roi_mask, pfi_3d_cropped_roi, cmd else: pfi_std = jph(pfo_tmp, sj + '_to_std.nii.gz') assert check_path_validity(pfi_std) pfi_3d_cropped_roi = jph(pfo_tmp, sj + '_cropped.nii.gz') cmd = 'cp {0} {1}'.format(pfi_std, pfi_3d_cropped_roi) print_and_run(cmd) if steps['step_bfc']: print('- step bfc {}'.format(sj)) pfi_3d_cropped_roi = jph(pfo_tmp, sj + '_cropped.nii.gz') assert check_path_validity(pfi_3d_cropped_roi) pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz') bfc_param = sj_parameters['bias_field_parameters'] pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz') bias_field_correction(pfi_3d_cropped_roi, pfi_3d_bias_field_corrected, pfi_mask=pfi_roi_mask, prefix='', convergenceThreshold=bfc_param[0], maximumNumberOfIterations=bfc_param[1], biasFieldFullWidthAtHalfMaximum=bfc_param[2], wienerFilterNoise=bfc_param[3], numberOfHistogramBins=bfc_param[4], numberOfControlPoints=bfc_param[5], splineOrder=bfc_param[6], print_only=False) del pfi_3d_cropped_roi, pfi_3d_bias_field_corrected, bfc_param, pfi_roi_mask if steps['create_lesion_maks']: print('Extract lesion mask: Subject {}'.format(sj)) # output: pfi_lesion_mask = jph(pfo_mask, sj + '_T1_lesion_mask.nii.gz') if options_T1['lesion_mask_method'] == 0: percentile = sj_parameters['options_T1']['window_percentile'] median_filter = sj_parameters['options_T1']['median_filter'] print( 'remove percentiles, values added manually: percentile {}, median filter {}' .format(percentile, median_filter)) pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz') pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz') assert check_path_validity(pfi_3d_bias_field_corrected) assert check_path_validity(pfi_roi_mask) percentile_lesion_mask_extractor( im_input_path=pfi_3d_bias_field_corrected, im_output_path=pfi_lesion_mask, im_mask_foreground_path=pfi_roi_mask, percentiles=percentile, safety_on=False, median_filter=median_filter, pfo_tmp=pfo_tmp) elif options_T1['lesion_mask_method'] > 0: K = options_T1['lesion_mask_method'] print( 'remove the first (not background) and the last gaussians after MoG fitting, with K = {}.' .format(K)) pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz') pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz') assert os.path.exists(pfi_3d_bias_field_corrected) assert check_path_validity(pfi_roi_mask) pfi_mog_segm = jph(pfo_tmp, '{}_mog_segm.nii.gz'.format(sj)) pfi_T1_bfc = nib.load(pfi_3d_bias_field_corrected) pfi_roi_mask = nib.load(pfi_roi_mask) im_T1_bfc = nib.load(pfi_T1_bfc) im_roi_mask = nib.load(pfi_T1_bfc) c_array, p_array = MoG_array(im_T1_bfc.get_data(), K=K, pre_process_median_filter=True, mask_array=im_roi_mask.get_data(), pre_process_only_interquartile=True) c = set_new_data(im_T1_bfc, c_array) p = set_new_data(im_T1_bfc, p_array) nib.save(c, '/Users/sebastiano/Desktop/zzz.nii.gz') old_labels = list(range(K)) # [0, 1, 2, 3, 4] new_labels = [ 1, ] * len(old_labels) new_labels[0], new_labels[1], new_labels[-1] = 0, 0, 0 im_crisp = set_new_data(c, np.copy( relabeller(c.get_data(), old_labels, new_labels)), new_dtype=np.uint8) nib.save(im_crisp, pfi_mog_segm) # final tuning: cmd0 = 'seg_maths {0} -ero 3 {0}'.format(pfi_mog_segm, pfi_mog_segm) cmd1 = 'seg_maths {0} -fill {0}'.format(pfi_mog_segm) cmd2 = 'seg_maths {0} -dil 3 {0}'.format(pfi_mog_segm) cmd3 = 'seg_maths {0} -fill {0}'.format(pfi_mog_segm) print_and_run(cmd0) print_and_run(cmd1) print_and_run(cmd2) print_and_run(cmd3) # pfi_lesion_mask IS pfi_roi_mask - pfi_mog_segm pfi_mog_segm_and_roi = jph(pfo_tmp, '{}_T1_MoGsegm_and_roi.nii.gz') cmd11 = 'seg_maths {0} -mul {1} {2}'.format( pfi_roi_mask, pfi_mog_segm, pfi_mog_segm_and_roi) print_and_run(cmd11) cmd22 = 'seg_maths {0} -sub {1} {2}'.format( pfi_roi_mask, pfi_mog_segm_and_roi, pfi_lesion_mask) print_and_run(cmd22) if steps['create_reg_mask']: if sj_parameters['in_atlas']: print('Get registration mask: Subject {} is in atlas'.format(sj)) pfi_reg_mask_not_adjusted = jph( pfo_tmp, '{}_T1_reg_mask_not_adjusted.nii.gz'.format(sj)) assert os.path.exists(pfi_reg_mask_not_adjusted), \ 'Processing T1, subject {}. Run the step create_roi_mask first'.format(sj) pfi_reg_mask = jph(pfo_mask, '{}_T1_reg_mask.nii.gz'.format(sj)) cmd = 'cp {} {}'.format(pfi_reg_mask_not_adjusted, pfi_reg_mask) print_and_run(cmd) else: print('Create registration mask: Subject {}'.format(sj)) # output: pfi_reg_mask = jph(pfo_mask, sj + '_T1_reg_mask.nii.gz') # registration mask is defined as the difference between roi_mask and lesion_mask pfi_roi_mask = jph(pfo_mask, sj + '_T1_roi_mask.nii.gz') pfi_lesion_mask = jph(pfo_mask, sj + '_T1_lesion_mask.nii.gz') assert os.path.exists(pfi_roi_mask), pfi_roi_mask assert os.path.exists(pfi_lesion_mask), pfi_lesion_mask pfi_roi_mask_and_lesion_mask = jph( pfo_tmp, '{}_T1_ROI_and_LM.nii.gz'.format(sj)) cmd11 = 'seg_maths {0} -mul {1} {2}'.format( pfi_roi_mask, pfi_lesion_mask, pfi_roi_mask_and_lesion_mask) print_and_run(cmd11) cmd22 = 'seg_maths {0} -sub {1} {2}'.format( pfi_roi_mask, pfi_roi_mask_and_lesion_mask, pfi_reg_mask) print_and_run(cmd22) if steps['save_results']: print('- save results {}'.format(sj)) pfi_3d_bias_field_corrected = jph(pfo_tmp, sj + '_bfc.nii.gz') assert check_path_validity(pfi_3d_bias_field_corrected) pfi_3d_final_destination = jph(pfo_mod, sj + '_T1.nii.gz') cmd = 'cp {0} {1}'.format(pfi_3d_bias_field_corrected, pfi_3d_final_destination) print_and_run(cmd) del pfi_3d_bias_field_corrected, pfi_3d_final_destination, cmd