Example #1
0
def lung_fill_hole(data_folder, data, type_im, cn, ext='.mha', mha_folder_name='mha'):
    lung_initial_folder_name = 'Lung_Initial'
    lung_filled_folder_name = 'Lung_Filled'
    if data == 'DIR-Lab_4D':
        type_im_list = ['T00', 'T10', 'T20', 'T30', 'T40', 'T50', 'T60', 'T70', 'T80', 'T90']
        data_folder_sub = data_folder + 'DIR-Lab/4DCT/'
        lung_initial_folder = data_folder_sub+mha_folder_name+'/case'+str(cn)+'/'+lung_initial_folder_name+'/'
        lung_filled_folder = data_folder_sub+mha_folder_name+'/case'+str(cn)+'/'+lung_filled_folder_name+'/'
        lung_initial_address = lung_initial_folder+'case'+str(cn)+'_'+type_im_list[type_im]+'_'+lung_initial_folder_name+ext
        lung_filled_address = lung_filled_folder+'case'+str(cn)+'_'+type_im_list[type_im]+'_'+lung_filled_folder_name+ext

    elif data == 'DIR-Lab_COPD':
        type_im_list = ['i', 'e']
        data_folder_sub = data_folder + 'DIR-Lab/COPDgene/'
        lung_initial_folder = data_folder_sub+mha_folder_name+'/'+lung_initial_folder_name+'/'
        lung_filled_folder = data_folder_sub+mha_folder_name+'/'+lung_filled_folder_name+'/'
        lung_initial_address = lung_initial_folder+'copd'+str(cn)+'_'+type_im_list[type_im]+'BHCT'+ext
        lung_filled_address = lung_filled_folder+'copd'+str(cn)+'_'+type_im_list[type_im]+'BHCT'+ext

    else:
        raise ValueError('Data='+data+", it should be in ['DIR-Lab_4D', 'DIR-Lab_COPD']")

    if not os.path.isdir(lung_filled_folder):
        os.makedirs(lung_filled_folder)

    lung_initial_sitk = sitk.ReadImage(lung_initial_address)
    lung_initial = sitk.GetArrayFromImage(lung_initial_sitk)
    lung_initial = lung_initial > 0
    structure = np.ones([3, 3, 3], dtype=np.bool)
    lung_filled = (ndimage.morphology.binary_closing(lung_initial, structure=structure)).astype(np.int8)
    sitk.WriteImage(ip.array_to_sitk(lung_filled, im_ref=lung_initial_sitk), lung_filled_address)
Example #2
0
def cylinder_mask(setting, cn=None, overwrite=False):
    cylinder_folder = su.address_generator(setting,
                                           'Cylinder',
                                           cn=cn,
                                           type_im=0).rsplit('/',
                                                             maxsplit=1)[0]
    if not os.path.isdir(cylinder_folder):
        os.makedirs(cylinder_folder)
    for type_im in range(len(setting['types'])):
        cylinder_mask_address = su.address_generator(setting,
                                                     'Cylinder',
                                                     cn=cn,
                                                     type_im=type_im)
        if (not os.path.isfile(cylinder_mask_address)) or overwrite:
            image_sitk = sitk.ReadImage(
                su.address_generator(setting, 'Im', cn=cn, type_im=type_im))
            cylinder_mask_sitk = sitk.BinaryThreshold(
                image_sitk,
                lowerThreshold=setting['defaultPixelValue'] - 1,
                upperThreshold=setting['defaultPixelValue'] + 0.01,
                insideValue=0,
                outsideValue=1)
            structure = np.ones((1, 3, 3))
            # erosion with ndimage is 5 times faster than SimpleITK
            cylinder_mask_eroded = (ndimage.binary_erosion(
                sitk.GetArrayFromImage(cylinder_mask_sitk),
                structure=structure,
                iterations=2)).astype(np.int8)
            cylinder_mask_eroded_sitk = ip.array_to_sitk(cylinder_mask_eroded,
                                                         im_ref=image_sitk)
            sitk.WriteImage(cylinder_mask_eroded_sitk, cylinder_mask_address)
            logging.debug(cylinder_mask_address + ' is done')
Example #3
0
def lung_fill_hole_erode(setting, cn=None):
    folder = su.address_generator(setting, 'Lung_Filled_Erode', cn=cn, type_im=0).rsplit('/', maxsplit=1)[0]
    if not os.path.isdir(folder):
        os.makedirs(folder)
    for type_im in range(len(setting['types'])):
        lung_raw_filled_sitk = sitk.ReadImage(su.address_generator(setting, 'Lung_Filled', cn=cn, type_im=type_im))
        lung_raw_filled = sitk.GetArrayFromImage(lung_raw_filled_sitk)

        lung_raw_filled = lung_raw_filled > 0
        structure = np.ones([3, 3, 3], dtype=np.bool)
        lung_filled_erode = (ndimage.morphology.binary_dilation(lung_raw_filled, structure=structure)).astype(np.int8)
        sitk.WriteImage(ip.array_to_sitk(lung_filled_erode, im_ref=lung_raw_filled_sitk),
                        su.address_generator(setting, 'Lung_Filled_Erode', cn=cn, type_im=type_im))
Example #4
0
def jac(setting, cn=None):
    time_before = time.time()
    dvf_sitk = sitk.ReadImage(
        su.address_generator(setting, 'DVF_nonRigid_composed', cn=cn, out=0))
    jac = ip.calculate_jac(sitk.GetArrayFromImage(dvf_sitk),
                           dvf_sitk.GetSpacing())
    sitk.WriteImage(
        sitk.Cast(ip.array_to_sitk(jac, im_ref=dvf_sitk),
                  sitk.sitkVectorFloat32),
        su.address_generator(setting, 'Jac', cn=cn))
    time_after = time.time()
    logging.debug(
        'multi_registration: calculating Jac cn={} is done in {:.2f}'.format(
            cn, time_after - time_before))
Example #5
0
def image_normalization(setting, cn=None, mask_name='Lung_Filled_Erode'):
    normalized_folder = su.address_generator(
        setting, 'originalImageFolder') + 'Normalized/'
    if not os.path.isdir(normalized_folder):
        os.makedirs(normalized_folder)
    normalized_erode_folder = su.address_generator(
        setting, 'originalImageFolder') + 'Masked_Normalized/'
    if not os.path.isdir(normalized_erode_folder):
        os.makedirs(normalized_erode_folder)
    for type_im in range(len(setting['types'])):
        im_sitk = sitk.ReadImage(
            su.address_generator(setting, 'Im', type_im=type_im, cn=cn))
        im = sitk.GetArrayFromImage(im_sitk)
        mask = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(setting,
                                     mask_name,
                                     type_im=type_im,
                                     cn=cn)))
        im_masked = im * mask
        min_im = np.min(im_masked)
        max_im = np.max(im_masked)
        slop = 1.0 / (max_im - min_im)
        intercept = -min_im / (max_im - min_im)
        im_masked_normalized = 1 - (im_masked - min_im) / (max_im - min_im)
        im_masked_normalized = im_masked_normalized * mask
        im_masked_normalized_sitk = ip.array_to_sitk(im_masked_normalized,
                                                     im_ref=im_sitk)
        sitk.WriteImage(
            im_masked_normalized_sitk,
            su.address_generator(setting,
                                 'Im_Masked_Normalized',
                                 type_im=type_im,
                                 cn=cn))
        print('writing ' + su.address_generator(setting,
                                                'Im_Masked_Normalized',
                                                type_im=type_im,
                                                cn=cn,
                                                print_mode=True))
        print('slop: {:.6f}, intercept: {:.6f}'.format(slop, intercept))
Example #6
0
def std_t(setting, cn=None, max_number_of_registration=None, mode='initial'):
    """
    This function writes stdT, E_T or stdT_final, E_T_final. mode can be chosen between 'initial' and 'final'
    mode = 'initial' ---->>  write stdT, E_T
    mode = 'final' ---->>  write stdT_final, E_T_final

    :param setting: setting dictionary
    :param cn:  number of the case
    :param max_number_of_registration:  maximum number of registration. By default it is supposed to be written in the setting dict.
    :param mode:   'initial' or 'final'
    :return: write stdT, E_T or stdT_final, E_T_final
    """

    time_before = time.time()
    all_dvf_available = True
    if mode == 'initial':
        name_ext = ''  # no extentension in the naming of initial mode, for eg: DVF_nonRigid_composed, stdT
        if max_number_of_registration is None:
            max_number_of_registration = setting['out_max']
        if os.path.isfile(
                su.address_generator(setting, 'stdT' + name_ext, cn=cn)):
            logging.debug(
                'multi_registration.std_t: already exists: ' +
                su.address_generator(
                    setting, 'stdT' + name_ext, cn=cn, print_mode=True))
            return 1
        else:
            for out in range(1, max_number_of_registration + 1):
                all_dvf_available = all_dvf_available & os.path.isfile(
                    su.address_generator(setting,
                                         'DVF_nonRigid_composed' + name_ext,
                                         cn=cn,
                                         out=out))
    elif mode == 'final':
        name_ext = '_final'  # _final extentension in the naming of final mode, , for eg: DVF_nonRigid_composed_final, stdT_final
        if max_number_of_registration is None:
            max_number_of_registration = setting['out_max_final']
        if os.path.isfile(
                su.address_generator(setting, 'stdT' + name_ext, cn=cn)):
            logging.debug(
                'multi_registration.std_t: already exists: ' +
                su.address_generator(
                    setting, 'stdT' + name_ext, cn=cn, print_mode=True))
            return 1
        else:
            for outfinal in range(1, max_number_of_registration + 1):
                all_dvf_available = all_dvf_available & os.path.isfile(
                    su.address_generator(setting,
                                         'DVF_nonRigid_composed' + name_ext,
                                         cn=cn,
                                         outfinal=outfinal))
    else:
        raise ValueError('mode is set to ' + mode +
                         ' but is should be either "initial" or "final"')

    if all_dvf_available:
        logging.debug('multi_registration.stdT: start calculating stdT' +
                      name_ext + ' IN={}'.format(cn))
        dimension = setting['dimension']

        dvf0 = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(setting,
                                     'DVF_nonRigid_composed',
                                     cn=cn,
                                     out=0)))
        dvf_all = [None] * dimension
        dvf_var = [None] * dimension
        dvf_mean = [None] * dimension
        for dim in range(3):
            dvf_all[dim] = np.empty(np.r_[np.shape(dvf0)[:-1],
                                          max_number_of_registration],
                                    dtype=np.float32)
        for out in range(1, max_number_of_registration + 1):
            if mode == 'initial':
                dvf_ = sitk.GetArrayFromImage(
                    sitk.ReadImage(
                        su.address_generator(setting,
                                             'DVF_nonRigid_composed' +
                                             name_ext,
                                             cn=cn,
                                             out=out)))
                logging.debug('multi_registration.stdT: reading: ' +
                              su.address_generator(setting,
                                                   'DVF_nonRigid_composed' +
                                                   name_ext,
                                                   cn=cn,
                                                   out=out,
                                                   print_mode=True))
            elif mode == 'final':
                dvf_ = sitk.GetArrayFromImage(
                    sitk.ReadImage(
                        su.address_generator(setting,
                                             'DVF_nonRigid_composed' +
                                             name_ext,
                                             cn=cn,
                                             outfinal=out)))
                logging.debug('multi_registration.stdT: reading: ' +
                              su.address_generator(setting,
                                                   'DVF_nonRigid_composed' +
                                                   name_ext,
                                                   cn=cn,
                                                   outfinal=out,
                                                   print_mode=True))
            for dim in range(dimension):
                dvf_all[dim][:, :, :, out - 1] = dvf_[:, :, :, dim]

        for dim in range(dimension):
            dvf_var[dim] = (np.var(dvf_all[dim],
                                   axis=dimension)).astype(np.float32)
            dvf_mean[dim] = (np.mean(dvf_all[dim],
                                     axis=dimension)).astype(np.float32)

        std_t = np.sqrt(sum(dvf_var))
        E_T = (np.sqrt(
            np.sum(np.square([
                dvf_mean[dim] - dvf0[:, :, :, dim] for dim in range(dimension)
            ]),
                   axis=0))).astype(np.float32)
        fixed_image_sitk = sitk.ReadImage(
            su.address_generator(setting, 'Im', cn=cn, type_im=0))
        sitk.WriteImage(
            ip.array_to_sitk(std_t, im_ref=fixed_image_sitk),
            su.address_generator(setting, 'stdT' + name_ext, cn=cn))
        sitk.WriteImage(ip.array_to_sitk(E_T, im_ref=fixed_image_sitk),
                        su.address_generator(setting, 'E_T' + name_ext, cn=cn))
        time_after = time.time()
        logging.debug(
            'multi_registration.stdT: calculating stdT' + name_ext +
            ' IN={} is done in {:.2f}'.format(cn, time_after - time_before))
    else:
        logging.debug('multi_registration.std_t: all dvf are not available: ' +
                      su.address_generator(
                          setting, 'stdT' + name_ext, cn=cn, print_mode=True))
Example #7
0
def compute_error(setting, cn=None, write_error_image=True):
    if (os.path.isfile(su.address_generator(setting, 'errorImage', cn=cn))
            & os.path.isfile(
                su.address_generator(setting, 'errorImageAffine', cn=cn))
            & os.path.isfile(
                su.address_generator(setting, 'errorImageMask', cn=cn))):
        logging.debug(setting['current_experiment'] + ' cn:' + str(cn) +
                      ' all error images exist')
        return 1

    if not (os.path.isfile(
            su.address_generator(
                setting, 'DVF_nonRigid_composed', cn=cn, out=0))):
        logging.debug(setting['current_experiment'] + ' cn:' + str(cn) +
                      ' deformation field not found')
        return 2

    fixed_indices = np.loadtxt(su.address_generator(setting,
                                                    'landmarkIndex_tr',
                                                    cn=cn,
                                                    type_im=0),
                               dtype=np.int)
    fixed_points = np.loadtxt(
        su.address_generator(setting, 'landmarkPoint_tr', cn=cn, type_im=0))
    moving_points = np.loadtxt(
        su.address_generator(setting, 'landmarkPoint_tr', cn=cn, type_im=1))
    if setting['registration_output'] == 'DVF':
        if 'affine_experiment_step' in setting.keys():
            affine_step = setting['affine_experiment_step']
        elif 'AffineParameter' in setting.keys():
            affine_step = len(setting['AffineParameter']) - 1
        else:
            affine_step = 0
        dvf_nonrigid = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(setting,
                                     'DVF_nonRigid_composed',
                                     cn=cn,
                                     out=0)))
        dvf_affine = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(
                    setting,
                    'affineDVF',
                    cn=cn,
                    current_experiment=setting['affine_experiment'],
                    reg_step=affine_step)))
        fixed_nonrigid_transformed_points = np.empty(np.shape(fixed_points))
        fixed_affine_transformed_points = np.empty(np.shape(fixed_points))
        for p in range(len(fixed_nonrigid_transformed_points)):
            fixed_nonrigid_transformed_points[p, :] = fixed_points[p, :] + [
                dvf_nonrigid[fixed_indices[p, 2], fixed_indices[p, 1],
                             fixed_indices[p, 0], 0],
                dvf_nonrigid[fixed_indices[p, 2], fixed_indices[p, 1],
                             fixed_indices[p, 0], 1],
                dvf_nonrigid[fixed_indices[p, 2], fixed_indices[p, 1],
                             fixed_indices[p, 0], 2]
            ]
            fixed_affine_transformed_points[p, :] = fixed_points[p, :] + [
                dvf_affine[fixed_indices[p, 2], fixed_indices[p, 1],
                           fixed_indices[p, 0], 0],
                dvf_affine[fixed_indices[p, 2], fixed_indices[p, 1],
                           fixed_indices[p, 0], 1],
                dvf_affine[fixed_indices[p, 2], fixed_indices[p, 1],
                           fixed_indices[p, 0], 2]
            ]
    elif setting['registration_output'] == 'elastix_transform_parameters':
        fixed_points_elx_address = su.address_generator(setting,
                                                        'landmarkIndex_elx',
                                                        cn=cn,
                                                        type_im=0)
        elxpy.transformix(
            parameter_file=su.address_generator(setting,
                                                'DVF_nonRigid_composed',
                                                cn=cn,
                                                out=0),
            output_directory=su.address_generator(setting,
                                                  'nonRigidFolder',
                                                  cn=cn,
                                                  out=0),
            points=fixed_points_elx_address,
            transformixPath='transformix')
        raise ValueError('not implemented yet')

    TRE_before_registration = (np.sum(
        (fixed_affine_transformed_points - moving_points)**2, axis=1))**0.5
    TRE = (np.sum((fixed_nonrigid_transformed_points - moving_points)**2,
                  axis=1))**0.5

    if write_error_image:
        logging.debug('compute_error: writing: ' + su.address_generator(
            setting, 'errorImage', cn=cn, print_mode=True))
        fixed_image_sitk = sitk.ReadImage(
            su.address_generator(setting, 'Im', cn=cn, type_im=0))
        error_image_nonrigid = np.zeros(fixed_image_sitk.GetSize()[::-1])
        error_image_affine = np.zeros(fixed_image_sitk.GetSize()[::-1])
        error_mask = np.zeros(fixed_image_sitk.GetSize()[::-1], dtype=np.int8)
        r = setting['neighborhood_radius']
        for p in range(len(fixed_indices)):
            error_image_affine[fixed_indices[p, 2] - r:fixed_indices[p, 2] +
                               r + 1, fixed_indices[p, 1] -
                               r:fixed_indices[p, 1] + r + 1,
                               fixed_indices[p, 0] - r:fixed_indices[p, 0] +
                               r + 1] = TRE_before_registration[p]
            error_image_nonrigid[fixed_indices[p, 2] - r:fixed_indices[p, 2] +
                                 r + 1, fixed_indices[p, 1] -
                                 r:fixed_indices[p, 1] + r + 1,
                                 fixed_indices[p, 0] - r:fixed_indices[p, 0] +
                                 r + 1] = TRE[p]
            error_mask[fixed_indices[p, 2] - r:fixed_indices[p, 2] + r + 1,
                       fixed_indices[p, 1] - r:fixed_indices[p, 1] + r + 1,
                       fixed_indices[p, 0] - r:fixed_indices[p, 0] + r + 1] = 1
        sitk.WriteImage(
            sitk.Cast(
                ip.array_to_sitk(error_image_nonrigid,
                                 im_ref=fixed_image_sitk), sitk.sitkFloat32),
            su.address_generator(setting, 'errorImage', cn=cn))
        sitk.WriteImage(
            sitk.Cast(
                ip.array_to_sitk(error_image_affine, im_ref=fixed_image_sitk),
                sitk.sitkFloat32),
            su.address_generator(setting, 'errorImageAffine', cn=cn))
        sitk.WriteImage(
            sitk.Cast(ip.array_to_sitk(error_mask, im_ref=fixed_image_sitk),
                      sitk.sitkInt8),
            su.address_generator(setting, 'errorImageMask', cn=cn))
    return 0
Example #8
0
def img_converter(data_folder,
                  data,
                  type_im,
                  cn,
                  ext='.mha',
                  mha_folder_name='mha',
                  point_folder_name='points'):
    """
    convert img images to mha.
    reading image:
    1) Size and voxel spacing of the images are available at https://www.dir-lab.com/ReferenceData.html
    2) The superior-inferior axis needs to be flipped
    3) Empty slices will be removed
        copd1_eBHCT.mha slice 0:1
        copd2_eBHCT.mha slice 0:6
        copd3_eBHCT.mha slice 0:9
        copd4_eBHCT.mha slice 0:9
        copd5_eBHCT.mha slice NA
        copd6_eBHCT.mha slice 0:2
        copd7_eBHCT.mha slice 0:9
        copd8_eBHCT.mha slice 0:7
        copd9_eBHCT.mha slice 0:19
        copd10_iBHCT.mah slice 0
    4) Index modification:
        4a) The superior-inferior axis needs to be flipped
        4b) The indices start at 1. We like them to start at 0.
        4c) change indices of landmarks based on the removed slices

    5) Normalize the intensity by subtracting by -1024
    6) Set the outside value to -2048

    :param ext
    :param cn:
    :param type_im
    :param data_folder
    :param data
    :param mha_folder_name
    :param point_folder_name
    :return:
    """

    if data == 'DIR-Lab_4D':
        type_im_list = [
            'T00', 'T10', 'T20', 'T30', 'T40', 'T50', 'T60', 'T70', 'T80',
            'T90'
        ]
        data_folder_sub = data_folder + 'DIR-Lab/4DCT/'
        if cn < 6:
            im_img_name = 'Images/case' + str(
                cn) + '_' + type_im_list[type_im] + '_s.img'
        else:
            im_img_name = 'Images/case' + str(
                cn) + '_' + type_im_list[type_im] + '.img'
        im_img_folder = data_folder_sub + 'Case' + str(cn) + 'Pack/'
        if cn == 8:
            im_img_folder = data_folder_sub + 'Case' + str(cn) + 'Deploy/'
        im_mha_name = 'case' + str(cn) + '_' + type_im_list[type_im] + ext
        im_mha_folder = data_folder_sub + mha_folder_name + '/case' + str(
            cn) + '/'
        point_folder = data_folder_sub + point_folder_name + '/case' + str(
            cn) + '/'
        index_tr_old_address_list = [
            im_img_folder + '/Sampled4D/case' + str(cn) + '_4D-75_' +
            type_im_list[type_im] + '.txt',
            im_img_folder + '/ExtremePhases/case' + str(cn) + '_300_' +
            type_im_list[type_im] + '_xyz.txt'
        ]
        index_tr_new_address_list = [
            point_folder + '/case' + str(cn) + '_4D-75_' +
            type_im_list[type_im] + '_xyz_tr.txt', point_folder + '/case' +
            str(cn) + '_300_' + type_im_list[type_im] + '_xyz_tr.txt'
        ]
        index_elx_new_address_list = [
            point_folder + '/case' + str(cn) + '_4D-75_' +
            type_im_list[type_im] + '_xyz_elx.txt', point_folder + '/case' +
            str(cn) + '_300_' + type_im_list[type_im] + '_xyz_elx.txt'
        ]
        point_tr_new_address_list = [
            point_folder + '/case' + str(cn) + '_4D-75_' +
            type_im_list[type_im] + '_world_tr.txt', point_folder + '/case' +
            str(cn) + '_300_' + type_im_list[type_im] + '_world_tr.txt'
        ]
        point_elx_new_address_list = [
            point_folder + '/case' + str(cn) + '_4D-75_' +
            type_im_list[type_im] + '_world_elx.txt', point_folder + '/case' +
            str(cn) + '_300_' + type_im_list[type_im] + '_world_elx.txt'
        ]
        dirlab_header = dirlab_4dct_header()

    elif data == 'DIR-Lab_COPD':
        type_im_list = ['i', 'e']
        data_folder_sub = data_folder + 'DIR-Lab/COPDgene/'
        im_img_name = 'copd' + str(
            cn) + '_' + type_im_list[type_im] + 'BHCT.img'
        im_img_folder = data_folder_sub + 'copd' + str(cn) + '/'
        im_mha_name = 'copd' + str(
            cn) + '_' + type_im_list[type_im] + 'BHCT' + ext
        im_mha_folder = data_folder_sub + mha_folder_name + '/'
        point_folder = data_folder_sub + point_folder_name
        index_tr_old_address_list = [
            im_img_folder + 'copd' + str(cn) + '_300_' +
            type_im_list[type_im] + 'BH_xyz_r1.txt'
        ]
        index_tr_new_address_list = [
            point_folder + '/copd' + str(cn) + '_300_' +
            type_im_list[type_im] + 'BH_xyz_r1_tr.txt'
        ]
        index_elx_new_address_list = [
            point_folder + '/copd' + str(cn) + '_300_' +
            type_im_list[type_im] + 'BH_xyz_r1_elx.txt'
        ]
        point_tr_new_address_list = [
            point_folder + '/copd' + str(cn) + '_300_' +
            type_im_list[type_im] + 'BH_world_r1_tr.txt'
        ]
        point_elx_new_address_list = [
            point_folder + '/copd' + str(cn) + '_300_' +
            type_im_list[type_im] + 'BH_world_r1_elx.txt'
        ]
        dirlab_header = dirlab_copd_header()

    else:
        raise ValueError('Data=' + data +
                         ", it should be in ['DIR-Lab_4D', 'DIR-Lab_COPD']")

    if not os.path.isdir(im_mha_folder):
        os.makedirs(im_mha_folder)
    if not os.path.isdir(point_folder):
        os.makedirs(point_folder)
    im_img_address = im_img_folder + im_img_name
    im_mha_address = im_mha_folder + im_mha_name
    if not os.path.isfile(im_mha_address):
        # 1,2) reading image:----------------------------------------------------------------
        fid = open(im_img_address, 'rb')
        im_data = np.fromfile(fid, np.int16)
        image_old = im_data.reshape(dirlab_header['case' +
                                                  str(cn)]['Size'][::-1])
        image_old = np.flip(
            image_old,
            axis=0)  # The superior-inferior axis needs to be flipped
        origin = [0, 0, 0]
        image = copy.deepcopy(image_old)
        # reading landmarks:
        for ii, index_tr_old_address in enumerate(index_tr_old_address_list):
            index_tr_new_address = index_tr_new_address_list[ii]
            index_elx_new_address = index_elx_new_address_list[ii]
            point_tr_new_address = point_tr_new_address_list[ii]
            point_elx_new_address = point_elx_new_address_list[ii]
            if os.path.isfile(index_tr_old_address):
                index_tr_old_raw = np.loadtxt(index_tr_old_address)
                # 4a&b) The superior-inferior axis is flipped. be careful about that indices start at 1. after converting to zero-start,
                #  there is no -1 in the SI direction.

                index_tr_old = np.array([[
                    index_tr_old_raw[i, 0] - 1, index_tr_old_raw[i, 1] - 1,
                    image_old.shape[0] - index_tr_old_raw[i, 2]
                ] for i in range(index_tr_old_raw.shape[0])])

                # 3) remove empty slices only in DIR-Lab_COPD-----------------------------------------
                if data == 'DIR-Lab_COPD':
                    image, slices_to_remove = remove_empty_slices(image_old)
                    print(im_img_name + ' slices are removed: ' +
                          str(slices_to_remove))
                    shift_indices = len(slices_to_remove)
                    shift_world = shift_indices * dirlab_header[
                        'case' + str(cn)]['Spacing'][2]
                    origin[2] = shift_world

                    # 4c) change indices of landmarks based on the removed slices
                    index_tr_new = [[
                        index_tr_old[i, 0], index_tr_old[i, 1],
                        index_tr_old[i, 2] - shift_indices
                    ] for i in range(index_tr_old.shape[0])]
                else:
                    index_tr_new = index_tr_old.copy()

                np.savetxt(index_tr_new_address, index_tr_new, fmt='%d')
                point_tr_new = ip.index_to_world(
                    index_tr_new,
                    spacing=dirlab_header['case' + str(cn)]['Spacing'],
                    origin=origin)
                np.savetxt(point_tr_new_address, point_tr_new, fmt='%-9.3f')
                open_text = open(index_tr_new_address, "r")
                number_of_landmarks = index_tr_new.shape[0]
                with open(index_elx_new_address, "w") as open_elx:
                    open_elx.write('index \n')
                    open_elx.write(str(number_of_landmarks) + ' \n')
                    open_elx.write(open_text.read())
                open_text.close()

                open_text = open(point_tr_new_address, "r")
                with open(point_elx_new_address, "w") as open_elx:
                    open_elx.write('point \n')
                    open_elx.write(str(number_of_landmarks) + ' \n')
                    open_elx.write(open_text.read())
                open_text.close()

        # 5) normalize the intensity
        image = image - 1024  # we are not sure about the slope and intercept.

        # 6) set the outside value to -2048
        image[image == -3024] = -2048
        image_sitk = ip.array_to_sitk(
            image,
            spacing=dirlab_header['case' + str(cn)]['Spacing'],
            origin=origin)
        sitk.WriteImage(image_sitk, im_mha_address)
        print('case' + str(cn) + ' type' + str(type_im) + ' is done..')
Example #9
0
def perturbation(setting, cn=None, out=None, outfinal=None):
    affine_experiment = setting['affine_experiment']
    if out is None and outfinal is not None:
        mode = 'final_perturbation'
        out = 0
        folder_address = su.address_generator(setting,
                                              'nonRigidFolder_final',
                                              cn=cn,
                                              outfinal=outfinal)
        ref_dvf_address = su.address_generator(setting,
                                               'DVF_nonRigid_composed',
                                               cn=cn,
                                               out=0)
        DVF_perturb_address = su.address_generator(setting,
                                                   'DVF_perturb_final',
                                                   cn=cn,
                                                   outfinal=outfinal)
        DVF_perturb_pure_address = su.address_generator(
            setting, 'DVF_perturb_pure_final', cn=cn, outfinal=outfinal)
    elif outfinal is None and out is not None:
        mode = 'initial_perturbation'
        outfinal = 0
        folder_address = su.address_generator(setting,
                                              'nonRigidFolder',
                                              cn=cn,
                                              out=out)
        ref_dvf_address = su.address_generator(
            setting, 'affineDVF', cn=cn, current_experiment=affine_experiment)
        # if affine_experiment is given, it loads the DVF from that experiment.
        DVF_perturb_address = su.address_generator(setting,
                                                   'DVF_perturb',
                                                   cn=cn,
                                                   out=out)
        DVF_perturb_pure_address = su.address_generator(
            setting, 'DVF_perturb_without_affine', cn=cn, out=out)
    else:
        raise ValueError('out and outfinal cannot be None at the same time')

    seedNumber = 10000 + 1000 * cn + out * 101 + outfinal * 4
    np.random.seed(seedNumber)
    if not os.path.exists(folder_address):
        os.makedirs(folder_address)
    ref_dvf_sitk = sitk.ReadImage(ref_dvf_address)
    if mode == 'initial_perturbation' and out == 0:
        # when out=0, there is no perturbation, so the initial DVF is equal to the affine dvf.
        sitk.WriteImage(
            sitk.Cast(ref_dvf_sitk, sitk.sitkVectorFloat32),
            su.address_generator(setting, 'DVF_perturb', cn=cn, out=out))
    else:
        GridSpacing = setting['GridSpacing']
        gridBorderToZero = setting['GridBorderToZero']
        maxDeform = setting['perturbationOffset']
        numberOfGrids = list(
            np.round(
                np.array(ref_dvf_sitk.GetSize()) *
                np.array(ref_dvf_sitk.GetSpacing()) / GridSpacing))
        numberOfGrids = [
            int(i) for i in numberOfGrids
        ]  # This is a bit funny, it has to be int (and not even np.int)
        BCoeff = sitk.BSplineTransformInitializer(ref_dvf_sitk,
                                                  numberOfGrids,
                                                  order=3)
        grid_side = BCoeff.GetTransformDomainMeshSize()
        BCoeff_parameters = np.random.uniform(-maxDeform, maxDeform,
                                              len(BCoeff.GetParameters()))
        BCoeff_processed_dim = [None] * 3
        for dim in range(3):
            BCoeff_dim = np.reshape(
                np.split(BCoeff_parameters, 3)[dim],
                [grid_side[2] + 3, grid_side[1] + 3, grid_side[0] + 3])
            # number of coefficients in grid is increased by 3 in simpleITK.
            if np.any(gridBorderToZero):
                nonZeroMask = np.zeros(np.shape(BCoeff_dim))
                nonZeroMask[gridBorderToZero[0]:-gridBorderToZero[0],
                            gridBorderToZero[1]:-gridBorderToZero[1],
                            gridBorderToZero[2]:-gridBorderToZero[2]] = 1
                BCoeff_dim = BCoeff_dim * nonZeroMask
            BCoeff_processed_dim[dim] = np.copy(BCoeff_dim)

        sitk.WriteImage(
            sitk.GetImageFromArray(np.stack(
                (BCoeff_processed_dim[0], BCoeff_processed_dim[1],
                 BCoeff_processed_dim[2]),
                axis=3),
                                   isVector=True),
            su.address_generator(setting, 'BSplineGrid', cn=cn, out=out))

        BCoeff_processed = np.hstack((BCoeff_processed_dim[0].flatten(),
                                      BCoeff_processed_dim[1].flatten(),
                                      BCoeff_processed_dim[2].flatten()))
        BCoeff.SetParameters(BCoeff_processed)
        DVF_filter = sitk.TransformToDisplacementFieldFilter()
        DVF_filter.SetReferenceImage(ref_dvf_sitk)
        DVF_perturb_pure_SITK = DVF_filter.Execute(BCoeff)
        if setting['verboseImage']:
            sitk.WriteImage(
                sitk.Cast(DVF_perturb_pure_SITK, sitk.sitkVectorFloat32),
                DVF_perturb_pure_address)
        DVF_perturb_pure = sitk.GetArrayFromImage(DVF_perturb_pure_SITK)
        origDVF = sitk.GetArrayFromImage(ref_dvf_sitk)
        DVF_perturb = origDVF + DVF_perturb_pure
        DVF_perturb_SITK = IP.array_to_sitk(DVF_perturb,
                                            im_ref=ref_dvf_sitk,
                                            is_vector=True)
        sitk.WriteImage(sitk.Cast(DVF_perturb_SITK, sitk.sitkVectorFloat32),
                        DVF_perturb_address)