Example #1
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 #2
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 #3
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 #4
0
def add_noise(setting,
              im_info,
              stage,
              deformed_im_previous_sitk=None,
              deformed_torso_sitk=None,
              gonna_generate_next_im=False):
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth'],
        'stage': stage,
        'padto': im_info['padto']
    }
    seed_number = ag_utils.seed_number_by_im_info(
        im_info,
        'add_noise',
        stage=stage,
        gonna_generate_next_im=gonna_generate_next_im)
    random_state = np.random.RandomState(seed_number)

    if gonna_generate_next_im:
        sigma_noise = setting['deform_exp'][
            im_info['deform_exp']]['NextIm_SigmaN']
        torso_address = su.address_generator(setting, 'NextTorso',
                                             **im_info_su)
    else:
        sigma_noise = setting['deform_exp'][
            im_info['deform_exp']]['Im_NoiseSigma']
        torso_address = su.address_generator(setting, 'DeformedTorso',
                                             **im_info_su)

    if deformed_im_previous_sitk is None:
        deformed_im_previous_sitk = sitk.ReadImage(
            su.address_generator(setting,
                                 'DeformedIm',
                                 deformed_im_ext='Clean',
                                 **im_info_su))

    max_mean_noise = setting['deform_exp'][
        im_info['deform_exp']]['Im_NoiseAverage']
    random_mean = random_state.uniform(-max_mean_noise, max_mean_noise)
    if setting['data'][im_info['data']]['ImageByte'] in [
            sitk.sitkUInt8, sitk.sitkUInt16, sitk.sitkUInt32, sitk.sitkUInt64,
            sitk.sitkInt8, sitk.sitkInt16, sitk.sitkInt32, sitk.sitkInt64
    ]:
        random_mean = int(random_mean)

    deformed_im_noise_sitk = sitk.AdditiveGaussianNoise(
        deformed_im_previous_sitk, sigma_noise, random_mean, 0)
    if setting['UseTorsoMask']:
        # no noise outside of Torso region.
        if deformed_torso_sitk is None:
            deformed_torso_sitk = sitk.ReadImage(torso_address)
        deformed_torso = sitk.GetArrayFromImage(deformed_torso_sitk)
        deformed_im_noise = sitk.GetArrayFromImage(deformed_im_noise_sitk)
        deformed_im_previous = sitk.GetArrayFromImage(
            deformed_im_previous_sitk)
        deformed_im_noise[deformed_torso == 0] = deformed_im_previous[
            deformed_torso == 0]
        deformed_im_noise_sitk = ip.array_to_sitk(
            deformed_im_noise, im_ref=deformed_im_previous_sitk)
    return deformed_im_noise_sitk
Example #5
0
def add_occlusion(setting,
                  im_info,
                  stage,
                  deformed_im_previous_sitk=None,
                  dvf_sitk=None):
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth'],
        'stage': 1,
        'padto': im_info['padto']
    }
    seed_number = ag_utils.seed_number_by_im_info(im_info,
                                                  'add_occlusion',
                                                  stage=stage)
    random_state = np.random.RandomState(seed_number)

    if deformed_im_previous_sitk is None:
        deformed_im_previous_sitk = sitk.ReadImage(
            su.address_generator(setting,
                                 'DeformedIm',
                                 deformed_im_ext='Noise',
                                 **im_info_su))

    if dvf_sitk is None:
        dvf_address = su.address_generator(setting, 'DeformedDVF',
                                           **im_info_su)
        dvf_sitk = sitk.ReadImage(dvf_address)

    deformed_lung_address = su.address_generator(setting, 'DeformedLung',
                                                 **im_info_su)
    if not os.path.isfile(deformed_lung_address):
        im_lung_sitk = sitk.ReadImage(
            su.address_generator(setting, 'Lung', **im_info_su))
        dvf_t = sitk.DisplacementFieldTransform(
            sitk.Cast(dvf_sitk, sitk.sitkVectorFloat64))
        deformed_lung_sitk = ip.resampler_by_transform(
            im_lung_sitk,
            dvf_t,
            im_ref=deformed_im_previous_sitk,
            default_pixel_value=0,
            interpolator=sitk.sitkNearestNeighbor)
        sitk.WriteImage(sitk.Cast(deformed_lung_sitk, sitk.sitkInt8),
                        deformed_lung_address)
        time.sleep(5)

    deformed_im_noise = sitk.GetArrayFromImage(deformed_im_previous_sitk)
    deformed_lung = sitk.GetArrayFromImage(
        sitk.ReadImage(deformed_lung_address))
    struct = np.ones((9, 9, 9), dtype=bool)
    deformed_lung_erode = ndimage.binary_erosion(deformed_lung,
                                                 structure=struct).astype(
                                                     np.bool)
    ellipse_lung = np.zeros(deformed_im_noise.shape, dtype=np.bool)
    ellipse_center_lung = deformed_lung_erode.copy()

    for ellipse_number in range(setting['deform_exp'][im_info['deform_exp']]
                                ['Occlusion_NumberOfEllipse']):
        center_list = np.where(ellipse_center_lung > 0)
        selected_center_i = int(
            random_state.randint(0, len(center_list[0]) - 1, 1,
                                 dtype=np.int64))
        a = random_state.random_sample() * setting['deform_exp'][
            im_info['deform_exp']]['Occlusion_Max_a']
        b = random_state.random_sample() * setting['deform_exp'][
            im_info['deform_exp']]['Occlusion_Max_b']
        c = random_state.random_sample() * setting['deform_exp'][
            im_info['deform_exp']]['Occlusion_Max_c']
        if a < 3:
            a = 3
        if b < 3:
            b = 3
        if c < 3:
            c = 3
        ellipse_crop = np.zeros(
            [2 * round(a) + 1, 2 * round(b) + 1, 2 * round(c) + 1])
        for i1 in range(np.shape(ellipse_crop)[0]):
            for i2 in range(np.shape(ellipse_crop)[1]):
                for i3 in range(np.shape(ellipse_crop)[2]):
                    if (((i1 - a) / a)**2 + ((i2 - b) / b)**2 +
                        ((i3 - c) / c)**2) < 1:
                        ellipse_crop[i1, i2, i3] = 1
        ellipse_lung[center_list[0][selected_center_i]-round(a/2): center_list[0][selected_center_i]-round(a/2)+np.shape(ellipse_crop)[0],
                     center_list[1][selected_center_i]-round(b/2): center_list[1][selected_center_i]-round(b/2)+np.shape(ellipse_crop)[1],
                     center_list[2][selected_center_i]-round(c/2): center_list[2][selected_center_i]-round(c/2)+np.shape(ellipse_crop)[2]] = \
            ellipse_crop

        margin = 5
        ellipse_center_lung[center_list[0][selected_center_i] - round(a / 2) -
                            margin:center_list[0][selected_center_i] -
                            round(a / 2) + np.shape(ellipse_crop)[0] + margin,
                            center_list[1][selected_center_i] - round(b / 2) -
                            margin:center_list[1][selected_center_i] -
                            round(b / 2) + np.shape(ellipse_crop)[1] + margin,
                            center_list[2][selected_center_i] - round(c / 2) -
                            margin:center_list[2][selected_center_i] -
                            round(c / 2) + np.shape(ellipse_crop)[2] +
                            margin] = 0

    sitk.WriteImage(
        sitk.Cast(
            ip.array_to_sitk(ellipse_lung.astype(np.int8),
                             im_ref=deformed_im_previous_sitk), sitk.sitkInt8),
        su.address_generator(setting, 'DeformedLungOccluded', **im_info_su))

    ellipse_lung_erode = (ellipse_lung.copy()).astype(np.bool)
    struct = np.array([[[0, 0, 0], [0, 1, 0], [0, 0, 0]],
                       [[0, 1, 0], [1, 1, 1], [0, 1, 0]],
                       [[0, 0, 0], [0, 1, 0], [0, 0, 0]]])
    weight_occluded_list = np.array([0.2, 0.6, 0.9])
    weight_image_list = 1 - weight_occluded_list
    print(
        '--------------------------------------will be corrected: occlusion intensity is not always an integer'
    )
    print(
        '--------------------------------------will be corrected: occlusion intensity is not always an integer'
    )
    print(
        '--------------------------------------will be corrected: occlusion intensity is not always an integer'
    )
    occlusion_intensity = int(
        random_state.randint(setting['deform_exp'][
            im_info['deform_exp']]['Occlusion_IntensityRange'][0],
                             setting['deform_exp'][im_info['deform_exp']]
                             ['Occlusion_IntensityRange'][1],
                             1,
                             dtype=np.int64))

    for i in range(3):
        ellipse_lung_erode_new = ndimage.binary_erosion(
            ellipse_lung_erode, structure=struct).astype(np.bool)
        edge_lung = ellipse_lung_erode ^ ellipse_lung_erode_new
        i_edge = np.where(edge_lung)
        deformed_im_noise[
            i_edge] = deformed_im_noise[i_edge] * weight_image_list[
                i] + occlusion_intensity * weight_occluded_list[i]
        ellipse_lung_erode = ellipse_lung_erode_new.copy()

    i_inside = np.where(ellipse_lung_erode_new > 0)
    deformed_im_noise[i_inside] = occlusion_intensity + random_state.normal(
        scale=setting['deform_exp'][im_info['deform_exp']]['Im_NoiseSigma'],
        size=len(i_inside[0]))
    deformed_im_occluded_sitk = ip.array_to_sitk(
        deformed_im_noise, im_ref=deformed_im_previous_sitk)

    return deformed_im_occluded_sitk
Example #6
0
def add_sponge_model(setting,
                     im_info,
                     stage,
                     deformed_im_previous_sitk=None,
                     dvf=None,
                     deformed_torso_sitk=None,
                     spacing=None,
                     gonna_generate_next_im=False):
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth'],
        'stage': stage,
        'padto': im_info['padto']
    }
    seed_number = ag_utils.seed_number_by_im_info(
        im_info,
        'add_sponge_model',
        stage=stage,
        gonna_generate_next_im=gonna_generate_next_im)
    random_state = np.random.RandomState(seed_number)

    if gonna_generate_next_im:
        jac_address = su.address_generator(setting, 'NextJac', **im_info_su)
        torso_address = su.address_generator(setting, 'NextTorso',
                                             **im_info_su)
    else:
        jac_address = su.address_generator(setting, 'Jac', **im_info_su)
        torso_address = su.address_generator(setting, 'DeformedTorso',
                                             **im_info_su)

    if deformed_im_previous_sitk is None:
        deformed_im_previous_sitk = sitk.ReadImage(
            su.address_generator(setting,
                                 'DeformedIm',
                                 deformed_im_ext='Clean',
                                 **im_info_su))
    deformed_im_clean = sitk.GetArrayFromImage(deformed_im_previous_sitk)

    if not os.path.isfile(jac_address):
        if dvf is None:
            dvf = sitk.GetArrayFromImage(
                sitk.ReadImage(
                    su.address_generator(setting, 'DeformedDVF',
                                         **im_info_su)))
        if spacing is None:
            spacing = deformed_im_previous_sitk.GetSpacing()[::-1]
        jac = ip.calculate_jac(dvf, spacing)
        if not gonna_generate_next_im:
            sitk.WriteImage(sitk.GetImageFromArray(jac.astype(np.float32)),
                            jac_address)
    else:
        jac = sitk.GetArrayFromImage(sitk.ReadImage(jac_address))

    random_scale = random_state.uniform(0.9, 1.1)
    jac[jac < 0.7] = 0.7
    jac[jac > 1.3] = 1.3
    deformed_im_sponge = deformed_im_clean / jac * random_scale
    if setting['UseTorsoMask']:
        # no scaling outside of Torso region.
        if deformed_torso_sitk is None:
            deformed_torso_sitk = sitk.ReadImage(torso_address)
        deformed_torso = sitk.GetArrayFromImage(deformed_torso_sitk)
        deformed_im_previous = sitk.GetArrayFromImage(
            deformed_im_previous_sitk)
        deformed_im_sponge[deformed_torso == 0] = deformed_im_previous[
            deformed_torso == 0]
    deformed_im_sponge_sitk = ip.array_to_sitk(
        deformed_im_sponge, im_ref=deformed_im_previous_sitk)

    return deformed_im_sponge_sitk
Example #7
0
def multi_stage(setting, pair_info, overwrite=False):
    """
    :param setting:
    :param pair_info: information of the pair to be registered.
    :param overwrite:
    :return: The output moved images and dvf will be written to the disk.
             1: registration is performed correctly
             2: skip overwriting
             3: the dvf is available from the previous experiment [4, 2, 1]. Then just upsample it.
    """
    stage_list = setting['ImagePyramidSchedule']
    if setting['read_pair_mode'] == 'synthetic':
        deformed_im_ext = pair_info[0].get('deformed_im_ext', None)
        im_info_su = {
            'data': pair_info[0]['data'],
            'deform_exp': pair_info[0]['deform_exp'],
            'type_im': pair_info[0]['type_im'],
            'cn': pair_info[0]['cn'],
            'dsmooth': pair_info[0]['dsmooth'],
            'padto': pair_info[0]['padto'],
            'deformed_im_ext': deformed_im_ext
        }
        moved_im_s0_address = su.address_generator(setting,
                                                   'MovedIm_AG',
                                                   stage=1,
                                                   **im_info_su)
        moved_torso_s1_address = su.address_generator(setting,
                                                      'MovedTorso_AG',
                                                      stage=1,
                                                      **im_info_su)
        moved_lung_s1_address = su.address_generator(setting,
                                                     'MovedLung_AG',
                                                     stage=1,
                                                     **im_info_su)
    else:
        moved_im_s0_address = su.address_generator(setting,
                                                   'MovedIm',
                                                   pair_info=pair_info,
                                                   stage=0,
                                                   stage_list=stage_list)
        moved_torso_s1_address = None
        moved_lung_s1_address = None

    if setting['read_pair_mode'] == 'synthetic':
        if os.path.isfile(moved_im_s0_address) and os.path.isfile(
                moved_torso_s1_address):
            if not overwrite:
                logging.debug('overwrite=False, file ' + moved_im_s0_address +
                              ' already exists, skipping .....')
                return 2
            else:
                logging.debug('overwrite=True, file ' + moved_im_s0_address +
                              ' already exists, but overwriting .....')
    else:
        if os.path.isfile(moved_im_s0_address):
            if not overwrite:
                logging.debug('overwrite=False, file ' + moved_im_s0_address +
                              ' already exists, skipping .....')
                return 2
            else:
                logging.debug('overwrite=True, file ' + moved_im_s0_address +
                              ' already exists, but overwriting .....')

    pair_stage1 = real_pair.Images(
        setting, pair_info, stage=1, padto=setting['PadTo']
        ['stage1'])  # just read the original images without any padding
    pyr = dict()  # pyr: a dictionary of pyramid images
    pyr['fixed_im_s1_sitk'] = pair_stage1.get_fixed_im_sitk()
    pyr['moving_im_s1_sitk'] = pair_stage1.get_moved_im_affine_sitk()
    pyr['fixed_im_s1'] = pair_stage1.get_fixed_im()
    pyr['moving_im_s1'] = pair_stage1.get_moved_im_affine()
    if setting['UseMask']:
        pyr['fixed_mask_s1_sitk'] = pair_stage1.get_fixed_mask_sitk()
        pyr['moving_mask_s1_sitk'] = pair_stage1.get_moved_mask_affine_sitk()
    if setting['read_pair_mode'] == 'real':
        if not (os.path.isdir(
                su.address_generator(setting,
                                     'full_reg_folder',
                                     pair_info=pair_info,
                                     stage_list=stage_list))):
            os.makedirs(
                su.address_generator(setting,
                                     'full_reg_folder',
                                     pair_info=pair_info,
                                     stage_list=stage_list))
    setting['GPUMemory'], setting['NumberOfGPU'] = tfu.client.read_gpu_memory()
    time_before_dvf = time.time()

    # check if DVF is available from the previous experiment [4, 2, 1]. Then just upsample it.
    if stage_list in [[4, 2], [4]]:
        dvf0_address = su.address_generator(setting,
                                            'dvf_s0',
                                            pair_info=pair_info,
                                            stage_list=stage_list)
        chosen_stage = None
        if stage_list == [4, 2]:
            chosen_stage = 2
        elif stage_list == [4]:
            chosen_stage = 4
        if chosen_stage is not None:
            dvf_s_up_address = su.address_generator(setting,
                                                    'dvf_s_up',
                                                    pair_info=pair_info,
                                                    stage=chosen_stage,
                                                    stage_list=[4, 2, 1])
            if os.path.isfile(dvf_s_up_address):
                logging.debug('DVF found from prev exp:' + dvf_s_up_address +
                              ', only performing upsampling')
                dvf_s_up = sitk.ReadImage(dvf_s_up_address)
                dvf0 = ip.resampler_sitk(
                    dvf_s_up,
                    scale=1 / (chosen_stage / 2),
                    im_ref_size=pyr['fixed_im_s1_sitk'].GetSize(),
                    interpolator=sitk.sitkLinear)
                sitk.WriteImage(sitk.Cast(dvf0, sitk.sitkVectorFloat32),
                                dvf0_address)
                return 3

    for i_stage, stage in enumerate(setting['ImagePyramidSchedule']):
        mask_to_zero_stage = setting['network_dict']['stage' +
                                                     str(stage)]['MaskToZero']
        if stage != 1:
            pyr['fixed_im_s' + str(stage) + '_sitk'] = ip.downsampler_gpu(
                pyr['fixed_im_s1_sitk'],
                stage,
                default_pixel_value=setting['data'][
                    pair_info[0]['data']]['DefaultPixelValue'])
            pyr['moving_im_s' + str(stage) + '_sitk'] = ip.downsampler_gpu(
                pyr['moving_im_s1_sitk'],
                stage,
                default_pixel_value=setting['data'][
                    pair_info[1]['data']]['DefaultPixelValue'])
        if setting['UseMask']:
            pyr['fixed_mask_s' + str(stage) + '_sitk'] = ip.resampler_sitk(
                pyr['fixed_mask_s1_sitk'],
                scale=stage,
                im_ref=pyr['fixed_im_s' + str(stage) + '_sitk'],
                default_pixel_value=0,
                interpolator=sitk.sitkNearestNeighbor)
            pyr['moving_mask_s' + str(stage) + '_sitk'] = ip.resampler_sitk(
                pyr['moving_mask_s1_sitk'],
                scale=stage,
                im_ref=pyr['moving_im_s' + str(stage) + '_sitk'],
                default_pixel_value=0,
                interpolator=sitk.sitkNearestNeighbor)

            if setting['WriteMasksForLSTM']:
                # only to be used in sequential training (LSTM)
                if setting['read_pair_mode'] == 'synthetic':
                    fixed_mask_stage_address = su.address_generator(
                        setting,
                        'Deformed' + mask_to_zero_stage,
                        stage=stage,
                        **im_info_su)
                    moving_mask_stage_address = su.address_generator(
                        setting, mask_to_zero_stage, stage=stage, **im_info_su)
                    fixed_im_stage_address = su.address_generator(setting,
                                                                  'DeformedIm',
                                                                  stage=stage,
                                                                  **im_info_su)
                    sitk.WriteImage(
                        sitk.Cast(
                            pyr['fixed_im_s' + str(stage) + '_sitk'],
                            setting['data'][pair_info[1]['data']]
                            ['ImageByte']), fixed_im_stage_address)
                    sitk.WriteImage(pyr['fixed_mask_s' + str(stage) + '_sitk'],
                                    fixed_mask_stage_address)
                    if im_info_su['dsmooth'] != 0 and stage == 4:
                        # not overwirte original images
                        moving_im_stage_address = su.address_generator(
                            setting, 'Im', stage=stage, **im_info_su)
                        sitk.WriteImage(
                            sitk.Cast(
                                pyr['moving_im_s' + str(stage) + '_sitk'],
                                setting['data'][pair_info[1]['data']]
                                ['ImageByte']), moving_im_stage_address)
                        sitk.WriteImage(
                            pyr['moving_mask_s' + str(stage) + '_sitk'],
                            moving_mask_stage_address)
                else:
                    fixed_im_stage_address = su.address_generator(
                        setting, 'Im', stage=stage, **pair_info[0])
                    fixed_mask_stage_address = su.address_generator(
                        setting,
                        mask_to_zero_stage,
                        stage=stage,
                        **pair_info[0])
                    if not os.path.isfile(fixed_im_stage_address):
                        sitk.WriteImage(
                            sitk.Cast(
                                pyr['fixed_im_s' + str(stage) + '_sitk'],
                                setting['data'][pair_info[1]['data']]
                                ['ImageByte']), fixed_im_stage_address)
                    if not os.path.isfile(fixed_mask_stage_address):
                        sitk.WriteImage(
                            pyr['fixed_mask_s' + str(stage) + '_sitk'],
                            fixed_mask_stage_address)
                    if i_stage == 0:
                        moved_im_affine_stage_address = su.address_generator(
                            setting,
                            'MovedImBaseReg',
                            pair_info=pair_info,
                            stage=stage,
                            **pair_info[1])
                        moved_mask_affine_stage_address = su.address_generator(
                            setting,
                            'Moved' + mask_to_zero_stage + 'BaseReg',
                            pair_info=pair_info,
                            stage=stage,
                            **pair_info[1])
                        if not os.path.isfile(moved_im_affine_stage_address):
                            sitk.WriteImage(
                                sitk.Cast(
                                    pyr['moving_im_s' + str(stage) + '_sitk'],
                                    setting['data'][pair_info[1]
                                                    ['data']]['ImageByte']),
                                moved_im_affine_stage_address)
                        if not os.path.isfile(moved_mask_affine_stage_address):
                            sitk.WriteImage(
                                pyr['moving_mask_s' + str(stage) + '_sitk'],
                                moved_mask_affine_stage_address)

        else:
            pyr['fixed_mask_s' + str(stage) + '_sitk'] = None
            pyr['moving_mask_s' + str(stage) + '_sitk'] = None
        input_regnet_moving_mask = None
        if i_stage == 0:
            input_regnet_moving = 'moving_im_s' + str(stage) + '_sitk'
            if setting['UseMask']:
                input_regnet_moving_mask = 'moving_mask_s' + str(
                    stage) + '_sitk'
        else:
            previous_pyramid = setting['ImagePyramidSchedule'][i_stage - 1]
            dvf_composed_previous_up_sitk = 'DVF_s' + str(
                previous_pyramid) + '_composed_up_sitk'
            dvf_composed_previous_sitk = 'DVF_s' + str(
                previous_pyramid) + '_composed_sitk'
            if i_stage == 1:
                pyr[dvf_composed_previous_sitk] = pyr[
                    'DVF_s' +
                    str(setting['ImagePyramidSchedule'][i_stage - 1]) +
                    '_sitk']
            elif i_stage > 1:
                pyr[dvf_composed_previous_sitk] = sitk.Add(
                    pyr['DVF_s' +
                        str(setting['ImagePyramidSchedule'][i_stage - 2]) +
                        '_composed_up_sitk'],
                    pyr['DVF_s' +
                        str(setting['ImagePyramidSchedule'][i_stage - 1]) +
                        '_sitk'])
            pyr[dvf_composed_previous_up_sitk] = ip.upsampler_gpu(
                pyr[dvf_composed_previous_sitk],
                round(previous_pyramid / stage),
                output_shape_3d=pyr['fixed_im_s' + str(stage) +
                                    '_sitk'].GetSize()[::-1],
            )
            if setting['WriteAfterEachStage'] and not setting['WriteNoDVF']:
                sitk.WriteImage(
                    sitk.Cast(pyr[dvf_composed_previous_up_sitk],
                              sitk.sitkVectorFloat32),
                    su.address_generator(setting,
                                         'dvf_s_up',
                                         pair_info=pair_info,
                                         stage=previous_pyramid,
                                         stage_list=stage_list))

            dvf_t = sitk.DisplacementFieldTransform(
                pyr[dvf_composed_previous_up_sitk])
            # after this line DVF_composed_previous_up_sitk is converted to a transform. so we need to load it again.
            pyr['moved_im_s' + str(stage) +
                '_sitk'] = ip.resampler_by_transform(
                    pyr['moving_im_s' + str(stage) + '_sitk'],
                    dvf_t,
                    default_pixel_value=setting['data'][
                        pair_info[1]['data']]['DefaultPixelValue'])
            if setting['UseMask']:
                pyr['moved_mask_s' + str(stage) +
                    '_sitk'] = ip.resampler_by_transform(
                        pyr['moving_mask_s' + str(stage) + '_sitk'],
                        dvf_t,
                        default_pixel_value=0,
                        interpolator=sitk.sitkNearestNeighbor)

            pyr[dvf_composed_previous_up_sitk] = dvf_t.GetDisplacementField()
            if setting['WriteAfterEachStage']:
                if setting['read_pair_mode'] == 'synthetic':
                    moved_im_s_address = su.address_generator(setting,
                                                              'MovedIm_AG',
                                                              stage=stage,
                                                              **im_info_su)
                    moved_mask_s_address = su.address_generator(
                        setting,
                        'Moved' + mask_to_zero_stage + '_AG',
                        stage=stage,
                        **im_info_su)
                else:
                    moved_im_s_address = su.address_generator(
                        setting,
                        'MovedIm',
                        pair_info=pair_info,
                        stage=stage,
                        stage_list=stage_list)
                    moved_mask_s_address = su.address_generator(
                        setting,
                        'Moved' + mask_to_zero_stage,
                        pair_info=pair_info,
                        stage=stage,
                        stage_list=stage_list)

                sitk.WriteImage(
                    sitk.Cast(
                        pyr['moved_im_s' + str(stage) + '_sitk'],
                        setting['data'][pair_info[1]['data']]['ImageByte']),
                    moved_im_s_address)

                if setting['WriteMasksForLSTM']:
                    sitk.WriteImage(pyr['moved_mask_s' + str(stage) + '_sitk'],
                                    moved_mask_s_address)

            input_regnet_moving = 'moved_im_s' + str(stage) + '_sitk'
            if setting['UseMask']:
                input_regnet_moving_mask = 'moved_mask_s' + str(
                    stage) + '_sitk'

        pyr['DVF_s' + str(stage)] = np.zeros(
            np.r_[pyr['fixed_im_s' + str(stage) + '_sitk'].GetSize()[::-1], 3],
            dtype=np.float64)
        if setting['network_dict']['stage'+str(stage)]['R'] == 'Auto' and \
                setting['network_dict']['stage'+str(stage)]['Ry'] == 'Auto':
            current_network_name = setting['network_dict'][
                'stage' + str(stage)]['NetworkDesign']
            r_out_erode_default = setting['network_dict'][
                'stage' + str(stage)]['Ry_erode']
            r_in, r_out, r_out_erode = network.utils.find_optimal_radius(
                pyr['fixed_im_s' + str(stage) + '_sitk'],
                current_network_name,
                r_out_erode_default,
                gpu_memory=setting['GPUMemory'],
                number_of_gpu=setting['NumberOfGPU'])

        else:
            r_in = setting['network_dict']['stage' + str(stage)][
                'R']  # Radius of normal resolution patch size. Total size is (2*R +1)
            r_out = setting['network_dict']['stage' + str(stage)][
                'Ry']  # Radius of output. Total size is (2*Ry +1)
            r_out_erode = setting['network_dict']['stage' + str(stage)][
                'Ry_erode']  # at the test time, sometimes there are some problems at the border

        logging.debug(
            'stage' + str(stage) + ' ,' + pair_info[0]['data'] +
            ', CN{}, ImType{}, Size={}'.format(
                pair_info[0]['cn'], pair_info[0]['type_im'], pyr[
                    'fixed_im_s' + str(stage) + '_sitk'].GetSize()[::-1]) +
            ', ' +
            setting['network_dict']['stage' + str(stage)]['NetworkDesign'] +
            ': r_in:{}, r_out:{}, r_out_erode:{}'.format(
                r_in, r_out, r_out_erode))
        pair_pyramid = real_pair.Images(
            setting,
            pair_info,
            stage=stage,
            fixed_im_sitk=pyr['fixed_im_s' + str(stage) + '_sitk'],
            moved_im_affine_sitk=pyr[input_regnet_moving],
            fixed_mask_sitk=pyr['fixed_mask_s' + str(stage) + '_sitk'],
            moved_mask_affine_sitk=pyr[input_regnet_moving_mask],
            padto=setting['PadTo']['stage' + str(stage)],
            r_in=r_in,
            r_out=r_out,
            r_out_erode=r_out_erode)

        # building and loading network
        tf.reset_default_graph()
        images_tf = tf.placeholder(
            tf.float32,
            shape=[None, 2 * r_in + 1, 2 * r_in + 1, 2 * r_in + 1, 2],
            name="Images")
        bn_training = tf.placeholder(tf.bool, name='bn_training')
        dvf_tf = getattr(
            getattr(
                network, setting['network_dict']['stage' +
                                                 str(stage)]['NetworkDesign']),
            'network')(images_tf, bn_training)
        logging.debug(' Total number of variables %s' % (np.sum([
            np.prod(v.get_shape().as_list()) for v in tf.trainable_variables()
        ])))
        saver = tf.train.Saver(tf.global_variables(), max_to_keep=1)
        sess = tf.Session()
        saver.restore(
            sess,
            su.address_generator(
                setting,
                'saved_model_with_step',
                current_experiment=setting['network_dict'][
                    'stage' + str(stage)]['NetworkLoad'],
                step=setting['network_dict']['stage' +
                                             str(stage)]['GlobalStepLoad']))
        while not pair_pyramid.get_sweep_completed():
            # The pyr[DVF_S] is the numpy DVF which will be filled. the dvf_np is an output
            # patch from the network. We control the spatial location of both dvf in this function
            batch_im, win_center, win_r_before, win_r_after, predicted_begin, predicted_end = pair_pyramid.next_sweep_patch(
            )
            time_before_gpu = time.time()
            [dvf_np] = sess.run([dvf_tf],
                                feed_dict={
                                    images_tf: batch_im,
                                    bn_training: 0
                                })
            time_after_gpu = time.time()
            logging.debug('GPU: ' + pair_info[0]['data'] +
                          ', CN{} center={} is done in {:.2f}s '.format(
                              pair_info[0]['cn'], win_center, time_after_gpu -
                              time_before_gpu))

            pyr['DVF_s'+str(stage)][win_center[0] - win_r_before[0]: win_center[0] + win_r_after[0],
                                    win_center[1] - win_r_before[1]: win_center[1] + win_r_after[1],
                                    win_center[2] - win_r_before[2]: win_center[2] + win_r_after[2], :] = \
                dvf_np[0, predicted_begin[0]:predicted_end[0], predicted_begin[1]:predicted_end[1], predicted_begin[2]:predicted_end[2], :]
            # rescaling dvf based on the voxel spacing:
            spacing_ref = [1.0 * stage for _ in range(3)]
            spacing_current = pyr['fixed_im_s' + str(stage) +
                                  '_sitk'].GetSpacing()
            for dim in range(3):
                pyr['DVF_s' + str(stage)][:, :, :, dim] = pyr['DVF_s' + str(
                    stage)][:, :, :,
                            dim] * spacing_current[dim] / spacing_ref[dim]

        pyr['DVF_s' + str(stage) + '_sitk'] = ip.array_to_sitk(
            pyr['DVF_s' + str(stage)],
            im_ref=pyr['fixed_im_s' + str(stage) + '_sitk'],
            is_vector=True)

        if i_stage == (len(setting['ImagePyramidSchedule']) - 1):
            # when all stages are finished, final dvf and moved image are written
            dvf_composed_final_sitk = 'DVF_s' + str(stage) + '_composed_sitk'
            if len(setting['ImagePyramidSchedule']) == 1:
                # need to upsample in the case that last stage is not 1
                if stage == 1:
                    pyr[dvf_composed_final_sitk] = pyr['DVF_s' + str(stage) +
                                                       '_sitk']
                else:
                    pyr[dvf_composed_final_sitk] = ip.resampler_sitk(
                        pyr['DVF_s' + str(stage) + '_sitk'],
                        scale=1 / stage,
                        im_ref_size=pyr['fixed_im_s1_sitk'].GetSize(),
                        interpolator=sitk.sitkLinear)
            else:
                pyr[dvf_composed_final_sitk] = sitk.Add(
                    pyr['DVF_s' + str(setting['ImagePyramidSchedule'][-2]) +
                        '_composed_up_sitk'],
                    pyr['DVF_s' + str(stage) + '_sitk'])
                if stage != 1:
                    pyr[dvf_composed_final_sitk] = ip.resampler_sitk(
                        pyr[dvf_composed_final_sitk],
                        scale=1 / stage,
                        im_ref_size=pyr['fixed_im_s1_sitk'].GetSize(),
                        interpolator=sitk.sitkLinear)
            if not setting['WriteNoDVF']:
                sitk.WriteImage(
                    sitk.Cast(pyr[dvf_composed_final_sitk],
                              sitk.sitkVectorFloat32),
                    su.address_generator(setting,
                                         'dvf_s0',
                                         pair_info=pair_info,
                                         stage_list=stage_list))
            dvf_t = sitk.DisplacementFieldTransform(
                pyr[dvf_composed_final_sitk])
            pyr['moved_im_s0_sitk'] = ip.resampler_by_transform(
                pyr['moving_im_s1_sitk'],
                dvf_t,
                default_pixel_value=setting['data'][
                    pair_info[1]['data']]['DefaultPixelValue'])
            sitk.WriteImage(
                sitk.Cast(pyr['moved_im_s0_sitk'],
                          setting['data'][pair_info[1]['data']]['ImageByte']),
                moved_im_s0_address)

            if setting['WriteMasksForLSTM']:
                mask_to_zero_stage = setting['network_dict'][
                    'stage' + str(stage)]['MaskToZero']
                if setting['read_pair_mode'] == 'synthetic':
                    moving_mask_sitk = sitk.ReadImage(
                        su.address_generator(setting,
                                             mask_to_zero_stage,
                                             stage=1,
                                             **im_info_su))
                    moved_mask_stage1 = ip.resampler_by_transform(
                        moving_mask_sitk,
                        dvf_t,
                        default_pixel_value=0,
                        interpolator=sitk.sitkNearestNeighbor)
                    sitk.WriteImage(
                        moved_mask_stage1,
                        su.address_generator(setting,
                                             'Moved' + mask_to_zero_stage +
                                             '_AG',
                                             stage=1,
                                             **im_info_su))
                    logging.debug('writing ' +
                                  su.address_generator(setting,
                                                       'Moved' +
                                                       mask_to_zero_stage +
                                                       '_AG',
                                                       stage=1,
                                                       **im_info_su))

    time_after_dvf = time.time()
    logging.debug(
        pair_info[0]['data'] + ', CN{}, ImType{} is done in {:.2f}s '.format(
            pair_info[0]['cn'], pair_info[0]['type_im'], time_after_dvf -
            time_before_dvf))

    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 are flipped. The reason is that to make it more similar to SPREAD study.
        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: converted mha image and converted landmark files:
        example: 
            copd1_eBHCT.mha
            copd1_300_eBH_world_r1_tr.txt:  landmarks in world coordinate (truncated)
            copd1_300_eBH_world_r1_elx.txt: landmarks in world coordinate with two additional lines for elastix
            copd1_300_eBH_xyz_r1_tr.txt:    landmark in indices
            copd1_300_eBH_xyz_r1_elx.txt:   landmark in indices with two additional lines for elastix
    """

    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) + '/'
        if cn < 6:
            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'
            ]
        else:
            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) +
                '_dirLab300_' + 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 check_downsampled_base_reg(setting,
                               stage,
                               base_reg=None,
                               pair_info=None,
                               mask_to_zero_stage=None):
    if 'DownSamplingByGPU' not in setting.keys():
        setting['DownSamplingByGPU'] = False
    im_info_moving = pair_info[1]
    im_list_downsample = [
        {
            'Image':
            'MovedImBaseReg',
            'interpolator':
            'BSpline',
            'DefaultPixelValue':
            setting['data'][im_info_moving['data']]['DefaultPixelValue'],
            'ImageByte':
            setting['data'][im_info_moving['data']]['ImageByte']
        },
        {
            'Image': 'Moved' + mask_to_zero_stage + 'BaseReg',
            'interpolator': 'NearestNeighbor',
            'DefaultPixelValue': 0,
            'ImageByte': sitk.sitkInt8
        },
    ]
    #
    # im_stage_address = su.address_generator(setting, 'MovedImBaseReg', pair_info=pair_info,
    #                          stage=stage, base_reg=base_reg, **im_info_moving)
    # mask_stage_address = su.address_generator(setting, 'Moved' + mask_to_zero_stage + 'BaseReg', pair_info=pair_info,
    #                          stage=stage, base_reg=base_reg, **im_info_moving)

    for im_dict in im_list_downsample:
        im_stage_address = su.address_generator(setting,
                                                im_dict['Image'],
                                                stage=stage,
                                                pair_info=pair_info,
                                                base_reg=base_reg,
                                                **im_info_moving)

        if not os.path.isfile(im_stage_address):
            im_s1_sitk = sitk.ReadImage(
                su.address_generator(setting,
                                     im_dict['Image'],
                                     stage=1,
                                     pair_info=pair_info,
                                     base_reg=base_reg,
                                     **im_info_moving))
            if setting['DownSamplingByGPU'] and im_dict[
                    'Image'] == 'MovedImBaseReg':
                im_s1 = sitk.GetArrayFromImage(im_s1_sitk)
                im_stage = ip.downsampler_gpu(
                    im_s1,
                    stage,
                    normalize_kernel=True,
                    default_pixel_value=im_dict['DefaultPixelValue'])

                im_stage_sitk = ip.array_to_sitk(
                    im_stage,
                    origin=im_s1_sitk.GetOrigin(),
                    spacing=tuple(i * stage for i in im_s1_sitk.GetSpacing()),
                    direction=im_s1_sitk.GetDirection())
            else:
                if im_dict['interpolator'] == 'NearestNeighbor':
                    interpolator = sitk.sitkNearestNeighbor
                elif im_dict['interpolator'] == 'BSpline':
                    interpolator = sitk.sitkBSpline
                else:
                    raise ValueError(
                        "interpolator should be in ['NearestNeighbor', 'BSpline']"
                    )

                if im_dict['Image'] in [
                        'MovedTorsoBaseReg', 'MovedLungBaseReg'
                ]:
                    im_ref_sitk = sitk.ReadImage(
                        su.address_generator(setting,
                                             'MovedImBaseReg',
                                             pair_info=pair_info,
                                             stage=stage,
                                             base_reg=base_reg,
                                             **im_info_moving))
                else:
                    im_ref_sitk = None
                im_stage_sitk = ip.resampler_sitk(
                    im_s1_sitk,
                    scale=stage,
                    im_ref=im_ref_sitk,
                    default_pixel_value=im_dict['DefaultPixelValue'],
                    interpolator=interpolator)

            sitk.WriteImage(sitk.Cast(im_stage_sitk, im_dict['ImageByte']),
                            im_stage_address)
    return 0
Example #10
0
def single_freq(setting,
                im_info,
                stage,
                im_input_sitk,
                gonna_generate_next_im=False):
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth'],
        'stage': stage,
        'padto': im_info['padto']
    }
    seed_number = ag_utils.seed_number_by_im_info(
        im_info,
        'single_freq',
        stage=stage,
        gonna_generate_next_im=gonna_generate_next_im)
    deform_number = im_info['deform_number']

    if gonna_generate_next_im:
        max_deform = setting['deform_exp'][
            im_info['deform_exp']]['NextIm_MaxDeform']
        dim_im = 3  # The deformation of the NextIm is always 3D
        seed_number = seed_number + 1
        grid_border_to_zero = setting['deform_exp'][
            im_info['deform_exp']]['SingleFrequency_SetGridBorderToZero'][0]
        grid_spacing = setting['deform_exp'][
            im_info['deform_exp']]['SingleFrequency_BSplineGridSpacing'][0]
        grid_smoothing_sigma = [
            i / stage for i in setting['deform_exp'][im_info['deform_exp']]
            ['SingleFrequency_GridSmoothingSigma'][0]
        ]
        bspline_transform_address = su.address_generator(
            setting, 'NextBSplineTransform', **im_info_su)
        bspline_im_address = su.address_generator(setting,
                                                  'NextBSplineTransformIm',
                                                  **im_info_su)
    else:
        max_deform = setting['deform_exp'][im_info['deform_exp']]['MaxDeform'] * \
            setting['deform_exp'][im_info['deform_exp']]['SingleFrequency_MaxDeformRatio'][deform_number]
        dim_im = 3
        grid_border_to_zero = setting['deform_exp'][im_info['deform_exp']][
            'SingleFrequency_SetGridBorderToZero'][deform_number]
        grid_spacing = setting['deform_exp'][im_info['deform_exp']][
            'SingleFrequency_BSplineGridSpacing'][deform_number]
        grid_smoothing_sigma = [
            i / stage for i in setting['deform_exp'][im_info['deform_exp']]
            ['SingleFrequency_GridSmoothingSigma'][deform_number]
        ]
        bspline_transform_address = su.address_generator(
            setting, 'BSplineTransform', **im_info_su)
        bspline_im_address = su.address_generator(setting,
                                                  'BSplineTransformIm',
                                                  **im_info_su)
    random_state = np.random.RandomState(seed_number)

    if setting['DVFPad_S' + str(stage)] > 0:
        # im_input is already zeropadded in this case
        padded_mm = setting['DVFPad_S' +
                            str(stage)] * im_input_sitk.GetSpacing()[0]
        grid_border_to_zero = (grid_border_to_zero + np.ceil(
            np.repeat(padded_mm, int(dim_im)) / grid_spacing)).astype(np.int)
        if len(np.unique(im_input_sitk.GetSpacing())) > 1:
            raise ValueError(
                'dvf_generation: padding is only implemented for isotropic voxel size. current voxel size = [{}, {}, {}]'
                .format(im_input_sitk.GetSpacing()[0],
                        im_input_sitk.GetSpacing()[1],
                        im_input_sitk.GetSpacing()[2]))

    bcoeff = bspline_coeff(im_input_sitk,
                           max_deform,
                           grid_border_to_zero,
                           grid_smoothing_sigma,
                           grid_spacing,
                           random_state,
                           dim_im,
                           artificial_generation='single_frequency')

    if setting['WriteBSplineTransform']:
        sitk.WriteTransform(bcoeff, bspline_transform_address)
        bspline_im_sitk_tuple = bcoeff.GetCoefficientImages()
        bspline_im = np.concatenate(
            (np.expand_dims(sitk.GetArrayFromImage(bspline_im_sitk_tuple[0]),
                            axis=-1),
             np.expand_dims(sitk.GetArrayFromImage(bspline_im_sitk_tuple[1]),
                            axis=-1),
             np.expand_dims(sitk.GetArrayFromImage(bspline_im_sitk_tuple[1]),
                            axis=-1)),
            axis=-1)
        bspline_spacing = bspline_im_sitk_tuple[0].GetSpacing()
        bspling_origin = [
            list(bspline_im_sitk_tuple[0].GetOrigin())[i] +
            list(im_input_sitk.GetOrigin())[i] for i in range(3)
        ]
        bspline_direction = im_input_sitk.GetDirection()
        bspline_im_sitk = ip.array_to_sitk(bspline_im,
                                           origin=bspling_origin,
                                           spacing=bspline_spacing,
                                           direction=bspline_direction,
                                           is_vector=True)
        sitk.WriteImage(bspline_im_sitk, bspline_im_address)

    dvf_filter = sitk.TransformToDisplacementFieldFilter()
    dvf_filter.SetSize(im_input_sitk.GetSize())
    dvf_sitk = dvf_filter.Execute(bcoeff)
    dvf = sitk.GetArrayFromImage(dvf_sitk)

    mask_to_zero = setting['deform_exp'][im_info['deform_exp']]['MaskToZero']
    if mask_to_zero is not None and not gonna_generate_next_im:
        sigma = setting['deform_exp'][im_info['deform_exp']][
            'SingleFrequency_BackgroundSmoothingSigma'][deform_number]
        dvf = do_mask_to_zero_gaussian(setting, im_info_su, dvf, mask_to_zero,
                                       stage, max_deform, sigma)

    if setting['deform_exp'][im_info['deform_exp']]['DVFNormalization']:
        dvf = normalize_dvf(dvf, max_deform)
    return dvf
Example #11
0
def get_dvf_and_deformed_images_seq(setting,
                                    im_info=None,
                                    stage_sequence=None,
                                    mode_synthetic_dvf='generation'):
    """
    This function generates the synthetic displacement vector fields and writes them to disk and returns them.
    If synthetic DVFs are already generated and can be found on the disk, this function just reads and returns them.
    Please note that in 2D setting, we still have a 3D DVF with zero values for the third direction.

    :param setting:
    :param im_info:
                    'data':
                    'deform_exp':
                    'type_im':
                    'CN":            Case Number: (Image Number )Please note that it starts from 1 not 0
                    'dsmooth':       This variable is used to generate another deformed version of the moving image.
                                     Then, use that image to make synthetic DVFs. More information available on [sokooti2017nonrigid]
                    'deform_method'
                    'deform_number'
    :param stage_sequence
    :param mode_synthetic_dvf:      'generation': generating images
                                    'reading':  : only reading images without generating them. In this mode, the function will just wait

    :return im             image with mentioned ImageType and CN
    :return deformed_im    Deformed image by applying the synthetic DeformedDVF_ on the Im_
    :return dvf            Syntethic DVF
    """
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth'],
        'padto': im_info['padto']
    }
    # A dictionary of arguments, which only be used in setting_utils.address_generator. This dictionary helps to have shorter code line.
    logging.debug('artifical_generation[' + mode_synthetic_dvf + ']: Data=' +
                  im_info['data'] + ', TypeIm=' + str(im_info['type_im']) +
                  ', CN=' + str(im_info['cn']) + ' Dsmooth=' +
                  str(im_info['dsmooth']) + ' D=' +
                  str(im_info['deform_number']) + '  starting')
    time_before = time.time()
    if stage_sequence != [4, 2, 1]:
        raise ValueError(' not implemented ')

    # later
    # for stage in stage_sequence:
    #     if stage != 1:
    #         check_downsampled_images(setting, im_info, stage)
    mask_to_zero = setting['deform_exp'][im_info['deform_exp']]['MaskToZero']

    # this is the last image to write by registration:
    if setting['UseRegisteredImages']:
        moved_mask_s1 = su.address_generator(setting,
                                             'Moved' + mask_to_zero + '_AG',
                                             stage=1,
                                             **im_info_su)

        while not os.path.isfile(moved_mask_s1):
            logging.debug('artifical_generation[' + mode_synthetic_dvf +
                          ']: Data=' + im_info['data'] + ', TypeIm=' +
                          str(im_info['type_im']) + ', CN=' +
                          str(im_info['cn']) + ' Dsmooth=' +
                          str(im_info['dsmooth']) + ' D=' +
                          str(im_info['deform_number']) +
                          ' waiting for moved images by registration')
            time.sleep(5)
        if (time.time() - os.path.getmtime(moved_mask_s1)) < 5:
            time.sleep(5)
    else:
        check_downsampled_images(setting, im_info, stage=2)
        check_downsampled_images(setting, im_info, stage=4)

    fixed_im_seq = dict()
    fixed_mask_seq = dict()
    moved_im_seq = dict()
    moved_mask_seq = dict()

    for stage in stage_sequence:
        fixed_im_seq['stage' + str(stage)] = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(
                    setting,
                    'DeformedIm',
                    deformed_im_ext=im_info['deformed_im_ext'],
                    stage=stage,
                    **im_info_su)))
        fixed_mask_seq['stage' + str(stage)] = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(
                    setting,
                    'Deformed' + mask_to_zero,
                    deformed_im_ext=im_info['deformed_im_ext'],
                    stage=stage,
                    **im_info_su)))

    moved_im_seq['stage4'] = sitk.GetArrayFromImage(
        sitk.ReadImage(
            su.address_generator(setting, 'Im', stage=4, **im_info_su)))
    moved_mask_seq['stage4'] = sitk.GetArrayFromImage(
        sitk.ReadImage(
            su.address_generator(setting, mask_to_zero, stage=4,
                                 **im_info_su)))
    for stage in [2, 1]:
        if setting['UseRegisteredImages']:
            moved_im_seq['stage' + str(stage)] = sitk.GetArrayFromImage(
                sitk.ReadImage(
                    su.address_generator(setting,
                                         'MovedIm_AG',
                                         stage=stage,
                                         **im_info_su)))
            moved_mask_seq['stage' + str(stage)] = sitk.GetArrayFromImage(
                sitk.ReadImage(
                    su.address_generator(setting,
                                         'Moved' + mask_to_zero + '_AG',
                                         stage=stage,
                                         **im_info_su)))
        else:
            moved_im_seq['stage' + str(stage)] = sitk.GetArrayFromImage(
                sitk.ReadImage(
                    su.address_generator(setting,
                                         'Im',
                                         stage=stage,
                                         **im_info_su)))
            moved_mask_seq['stage' + str(stage)] = sitk.GetArrayFromImage(
                sitk.ReadImage(
                    su.address_generator(setting,
                                         mask_to_zero,
                                         stage=stage,
                                         **im_info_su)))

    if mask_to_zero is not None:
        for stage in stage_sequence:
            size_fixed_im = np.array(
                np.shape(fixed_im_seq['stage' + str(stage)]))
            size_fixed_mask = np.array(
                np.shape(fixed_mask_seq['stage' + str(stage)]))
            size_diff = size_fixed_im - size_fixed_mask
            if abs(sum(size_diff)):
                if sum(size_diff) > 0:
                    # mask is smaller so we need to pad it
                    fixed_mask_seq['stage' + str(stage)] = np.pad(
                        fixed_mask_seq['stage' + str(stage)],
                        ((0, size_diff[0]), (0, size_diff[1]),
                         (0, size_diff[2])),
                        'constant',
                        constant_values=(0, ))
                else:
                    # mask is bigger
                    size_mask_crop = size_fixed_mask + size_diff
                    fixed_mask_seq['stage' + str(stage)] = fixed_mask_seq[
                        'stage' + str(stage)][0:size_mask_crop[0],
                                              0:size_mask_crop[1],
                                              0:size_mask_crop[2]]

            size_moved_im = np.array(
                np.shape(moved_im_seq['stage' + str(stage)]))
            size_moved_mask = np.array(
                np.shape(moved_mask_seq['stage' + str(stage)]))
            size_diff = size_moved_im - size_moved_mask
            if abs(sum(size_diff)):
                logging.debug(
                    'warning size are not same.............. size_dife={}'.
                    format(size_diff))
                if sum(size_diff) > 0:
                    # mask is smaller so we need to pad it
                    moved_mask_seq['stage' + str(stage)] = np.pad(
                        moved_mask_seq['stage' + str(stage)],
                        ((0, size_diff[0]), (0, size_diff[1]),
                         (0, size_diff[2])),
                        'constant',
                        constant_values=(0, ))
                else:
                    # mask is bigger
                    moved_mask_seq['stage' + str(stage)] = moved_mask_seq[
                        'stage' + str(stage)][0:size_diff[0], 0:size_diff[1],
                                              0:size_diff[2]]

            fixed_im_seq['stage' + str(stage)][fixed_mask_seq[
                'stage' + str(stage)] == 0] = setting['data'][
                    im_info['data']]['DefaultPixelValue']
            moved_im_seq['stage' + str(stage)][moved_mask_seq[
                'stage' + str(stage)] == 0] = setting['data'][
                    im_info['data']]['DefaultPixelValue']

    for stage in stage_sequence:
        # stage 4 and 2 has more padding in order to be possible that all patches have the same center
        if setting['ImPad_S' + str(stage)] > 0:
            fixed_im_seq['stage' + str(stage)] = np.pad(
                fixed_im_seq['stage' + str(stage)],
                setting['ImPad_S' + str(stage)],
                'constant',
                constant_values=(
                    setting['data'][im_info['data']]['DefaultPixelValue'], ))
            moved_im_seq['stage' + str(stage)] = np.pad(
                moved_im_seq['stage' + str(stage)],
                setting['ImPad_S' + str(stage)],
                'constant',
                constant_values=(
                    setting['data'][im_info['data']]['DefaultPixelValue'], ))

    dvf_threshold_list = setting['DVFThresholdList']
    dvf_label_address = su.address_generator(
        setting,
        'DeformedDVFLabel',
        stage=1,
        dvf_threshold_list=dvf_threshold_list,
        **im_info_su)
    if not os.path.isfile(dvf_label_address):
        dvf_address = su.address_generator(setting,
                                           'DeformedDVF',
                                           stage=1,
                                           **im_info_su)
        dvf = sitk.GetArrayFromImage(sitk.ReadImage(dvf_address))
        dvf_magnitude = np.sqrt(
            np.square(dvf[:, :, :, 0]) + np.square(dvf[:, :, :, 1]) +
            np.square(dvf[:, :, :, 2]))
        dvf_label = np.zeros(dvf_magnitude.shape, dtype=np.int8)
        for i_label in range(len(dvf_threshold_list) - 1):
            dvf_label[(dvf_threshold_list[i_label] <= dvf_magnitude) & (
                dvf_magnitude < dvf_threshold_list[i_label + 1])] = i_label

        dvf_label_sitk = ip.array_to_sitk(
            dvf_label,
            im_ref=sitk.ReadImage(
                su.address_generator(
                    setting,
                    'DeformedIm',
                    deformed_im_ext=im_info['deformed_im_ext'],
                    stage=stage,
                    **im_info_su)))
        sitk.WriteImage(sitk.Cast(dvf_label_sitk, sitk.sitkInt8),
                        dvf_label_address)
    else:
        dvf_label = sitk.GetArrayFromImage(sitk.ReadImage(dvf_label_address))

    # no mask for now
    # dvf_mask = sitk.GetArrayFromImage(sitk.ReadImage(su.address_generator(
    #     setting, 'Deformed' + setting['Label_Mask'], deformed_im_ext=im_info['deformed_im_ext'], stage=stage, **im_info_su)))
    # dvf_label[dvf_mask == 0] = 0

    time_after = time.time()
    logging.debug('artifical_generation[' + mode_synthetic_dvf + ']: Data=' +
                  im_info['data'] + ', TypeIm=' + str(im_info['type_im']) +
                  ', CN=' + str(im_info['cn']) + ' Dsmooth=' +
                  str(im_info['dsmooth']) + ' D=' +
                  str(im_info['deform_number']) +
                  ' is Done in {:.3f}s'.format(time_after - time_before))
    return fixed_im_seq, moved_im_seq, dvf_label, fixed_mask_seq
Example #12
0
def check_downsampled_images(setting, im_info, stage):
    padto = im_info['padto']
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth']
    }

    im_list_downsample = [{
        'Image':
        'Im',
        'interpolator':
        'BSpline',
        'DefaultPixelValue':
        setting['data'][im_info['data']]['DefaultPixelValue'],
        'ImageByte':
        setting['data'][im_info['data']]['ImageByte']
    }, {
        'Image': 'Lung',
        'interpolator': 'NearestNeighbor',
        'DefaultPixelValue': 0,
        'ImageByte': sitk.sitkInt8
    }, {
        'Image': 'Torso',
        'interpolator': 'NearestNeighbor',
        'DefaultPixelValue': 0,
        'ImageByte': sitk.sitkInt8
    }, {
        'Image':
        'DeformedIm',
        'interpolator':
        'BSpline',
        'DefaultPixelValue':
        setting['data'][im_info['data']]['DefaultPixelValue'],
        'ImageByte':
        setting['data'][im_info['data']]['ImageByte']
    }, {
        'Image': 'DeformedLung',
        'interpolator': 'NearestNeighbor',
        'DefaultPixelValue': 0,
        'ImageByte': sitk.sitkInt8
    }, {
        'Image': 'DeformedTorso',
        'interpolator': 'NearestNeighbor',
        'DefaultPixelValue': 0,
        'ImageByte': sitk.sitkInt8
    }]

    for im_dict in im_list_downsample:
        im_stage_address = su.address_generator(
            setting,
            im_dict['Image'],
            stage=stage,
            padto=padto,
            deformed_im_ext=im_info['deformed_im_ext'],
            **im_info_su)
        # remove the second condition later, that was for fixing some images ['Im', 'Lung'] --> I removed

        if not os.path.isfile(im_stage_address):
            im_s1_sitk = sitk.ReadImage(
                su.address_generator(
                    setting,
                    im_dict['Image'],
                    stage=1,
                    padto=padto,
                    deformed_im_ext=im_info['deformed_im_ext'],
                    **im_info_su))
            if setting['DownSamplingByGPU'] and im_dict[
                    'Image'] == 'OriginalIm':
                im_s1 = sitk.GetArrayFromImage(im_s1_sitk)
                im_stage = ip.downsampler_gpu(
                    im_s1,
                    stage,
                    normalize_kernel=True,
                    default_pixel_value=im_dict['DefaultPixelValue'])

                im_stage_sitk = ip.array_to_sitk(
                    im_stage,
                    origin=im_s1_sitk.GetOrigin(),
                    spacing=tuple(i * stage for i in im_s1_sitk.GetSpacing()),
                    direction=im_s1_sitk.GetDirection())
            else:
                if im_dict['interpolator'] == 'NearestNeighbor':
                    interpolator = sitk.sitkNearestNeighbor
                elif im_dict['interpolator'] == 'BSpline':
                    interpolator = sitk.sitkBSpline
                else:
                    raise ValueError(
                        "interpolator should be in ['NearestNeighbor', 'BSpline']"
                    )

                if im_dict['Image'] in ['Torso', 'Lung']:
                    im_ref_sitk = sitk.ReadImage(
                        su.address_generator(setting,
                                             'Im',
                                             stage=stage,
                                             padto=padto,
                                             **im_info_su))
                else:
                    im_ref_sitk = None
                im_stage_sitk = ip.resampler_sitk(
                    im_s1_sitk,
                    scale=stage,
                    im_ref=im_ref_sitk,
                    default_pixel_value=im_dict['DefaultPixelValue'],
                    interpolator=interpolator)

                # for debugging
                # sitk.WriteImage(sitk.Cast(im_stage_sitk, im_dict['ImageByte']),
                #                 su.address_generator(setting, im_dict['Image'], stage=stage, padto=None, **im_info_su))
                if padto is not None:
                    dim_im = setting['Dim']
                    pad_before = np.zeros(dim_im, dtype=np.int)
                    pad_after = np.zeros(dim_im, dtype=np.int)
                    im_size = np.array(im_stage_sitk.GetSize())
                    extra_to_pad = padto - im_size
                    for d in range(dim_im):
                        if extra_to_pad[d] < 0:
                            raise ValueError(
                                'size of the padto=' + str(padto) +
                                ' should be smaller than the size of the image {}'
                                .format(im_size))
                        elif extra_to_pad[d] == 0:
                            pad_before[d] = 0
                            pad_after[d] = 0
                        else:
                            if extra_to_pad[d] % 2 == 0:
                                pad_before[d] = np.int(extra_to_pad[d] / 2)
                                pad_after[d] = np.int(extra_to_pad[d] / 2)
                            else:
                                pad_before[d] = np.floor(extra_to_pad[d] / 2)
                                pad_after[d] = np.floor(
                                    extra_to_pad[d] / 2) + 1

                    pad_before = [int(p) for p in pad_before]
                    pad_after = [int(p) for p in pad_after]
                    im_stage_sitk = sitk.ConstantPad(
                        im_stage_sitk,
                        [pad_before[0], pad_before[1], pad_before[2]],
                        [pad_after[0], pad_after[1], pad_after[2]],
                        constant=im_dict['DefaultPixelValue'],
                    )

            sitk.WriteImage(sitk.Cast(im_stage_sitk, im_dict['ImageByte']),
                            im_stage_address)
    return 0
Example #13
0
def generate_next_im(setting, im_info, stage):
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth'],
        'stage': stage,
        'padto': im_info['padto']
    }
    next_folder = su.address_generator(setting, 'NextFolder', **im_info_su)
    if not os.path.exists(next_folder):
        os.makedirs(next_folder)
    original_im_sitk = sitk.ReadImage(
        su.address_generator(setting, 'OriginalIm', **im_info_su))
    next_dvf = dvf_generation.single_freq(setting,
                                          im_input_sitk=original_im_sitk,
                                          im_info=im_info,
                                          stage=stage,
                                          gonna_generate_next_im=True)
    next_dvf_sitk = ip.array_to_sitk(next_dvf,
                                     is_vector=True,
                                     im_ref=original_im_sitk)
    if setting['verbose_image']:
        sitk.WriteImage(sitk.Cast(next_dvf_sitk, sitk.sitkVectorFloat32),
                        su.address_generator(setting, 'NextDVF', **im_info_su))
    dvf_t = sitk.DisplacementFieldTransform(
        next_dvf_sitk
    )  # After this line you cannot save NextDVF any more !!!!!!!!!
    next_im_clean_sitk = ip.resampler_by_transform(
        original_im_sitk,
        dvf_t,
        im_ref=original_im_sitk,
        default_pixel_value=setting['data'][
            im_info['data']]['DefaultPixelValue'])

    if setting['UseLungMask']:
        original_mask_sitk = sitk.ReadImage(
            su.address_generator(setting, 'OriginalLung', **im_info_su))
        next_mask_sitk = ip.resampler_by_transform(
            original_mask_sitk,
            dvf_t,
            default_pixel_value=0,
            interpolator=sitk.sitkNearestNeighbor)
        sitk.WriteImage(
            sitk.Cast(next_mask_sitk, sitk.sitkInt8),
            su.address_generator(setting, 'NextLung', **im_info_su))
    if setting['UseTorsoMask']:
        original_torso_sitk = sitk.ReadImage(
            su.address_generator(setting, 'OriginalTorso', **im_info_su))
        next_torso_sitk = ip.resampler_by_transform(
            original_torso_sitk,
            dvf_t,
            default_pixel_value=0,
            interpolator=sitk.sitkNearestNeighbor)
        sitk.WriteImage(
            sitk.Cast(next_torso_sitk, sitk.sitkInt8),
            su.address_generator(setting, 'NextTorso', **im_info_su))

    next_im_sponge_sitk = intensity_augmentation.add_sponge_model(
        setting,
        im_info,
        stage=stage,
        deformed_im_previous_sitk=next_im_clean_sitk,
        dvf=next_dvf,
        gonna_generate_next_im=True)
    next_im_sitk = intensity_augmentation.add_noise(
        setting,
        im_info,
        stage=stage,
        deformed_im_previous_sitk=next_im_sponge_sitk,
        gonna_generate_next_im=True)

    sitk.WriteImage(
        sitk.Cast(next_im_sitk, setting['data'][im_info['data']]['ImageByte']),
        su.address_generator(setting, 'NextIm', **im_info_su))
Example #14
0
def get_dvf_and_deformed_images(setting,
                                im_info=None,
                                stage=None,
                                mode_synthetic_dvf='generation'):
    """
    This function generates the synthetic displacement vector fields and writes them to disk and returns them.
    If synthetic DVFs are already generated and can be found on the disk, this function just reads and returns them.
    Please note that in 2D setting, we still have a 3D DVF with zero values for the third direction.

    :param setting:
    :param im_info:
                    'data':
                    'deform_exp':
                    'type_im':
                    'CN":            Case Number: (Image Number )Please note that it starts from 1 not 0
                    'dsmooth':       This variable is used to generate another deformed version of the moving image.
                                     Then, use that image to make synthetic DVFs. More information available on [sokooti2017nonrigid]
                    'deform_method'
                    'deform_number'
    :param stage
    :param mode_synthetic_dvf:      'generation': generating images
                                    'reading':  : only reading images without generating them. In this mode, the function will just wait

    :return im             image with mentioned ImageType and CN
    :return deformed_im    Deformed image by applying the synthetic DeformedDVF_ on the Im_
    :return dvf            Syntethic DVF
    """
    im_info_su = {
        'data': im_info['data'],
        'deform_exp': im_info['deform_exp'],
        'type_im': im_info['type_im'],
        'cn': im_info['cn'],
        'dsmooth': im_info['dsmooth'],
        'stage': stage,
        'padto': im_info['padto']
    }
    # A dictionary of arguments, which only be used in setting_utils.address_generator. This dictionary helps to have shorter code line.

    if stage > 1:
        check_downsampled_original_images(setting, im_info, stage)

    if im_info['dsmooth'] == 0:
        im_sitk = ip.ReadImage(
            su.address_generator(setting, 'OriginalIm', **im_info_su))
        if setting['UseTorsoMask']:
            im_torso_sitk = sitk.ReadImage(
                su.address_generator(setting, 'OriginalTorso', **im_info_su))
        if setting['UseLungMask']:
            im_lung_sitk = sitk.ReadImage(
                su.address_generator(setting, 'OriginalLung', **im_info_su))
    else:
        next_im_address = (su.address_generator(setting, 'NextIm',
                                                **im_info_su))
        if not os.path.isfile(next_im_address):
            if mode_synthetic_dvf == 'reading':
                wait_for_image(next_im_address)
            if mode_synthetic_dvf == 'generation':
                logging.debug(
                    'artifical_generation[generation]: start ' +
                    su.address_generator(
                        setting, 'NextIm', print_mode=True, **im_info_su))
                generate_next_im(setting, im_info=im_info, stage=stage)
        im_sitk = ip.ReadImage(next_im_address, waiting_time=3)
        if setting['UseTorsoMask']:
            # please note that torso might be created a few minutes after NextIm. So we have to wait for the torso.
            im_torso_address = su.address_generator(setting, 'NextTorso',
                                                    **im_info_su)
            im_lung_address = su.address_generator(setting, 'NextLung',
                                                   **im_info_su)
            if mode_synthetic_dvf == 'reading':
                wait_for_image(im_torso_address)
                wait_for_image(im_lung_address)
            im_torso_sitk = ip.ReadImage(im_torso_address, waiting_time=1)
            im_lung_sitk = ip.ReadImage(im_lung_address, waiting_time=1)

    im = sitk.GetArrayFromImage(im_sitk)
    start_time = time.time()
    dvf_address = su.address_generator(setting, 'DeformedDVF', **im_info_su)
    deformed_im_address = su.address_generator(
        setting,
        'DeformedIm',
        deformed_im_ext=im_info['deformed_im_ext'],
        **im_info_su)

    if not os.path.isfile(deformed_im_address):
        if mode_synthetic_dvf == 'reading':
            wait_for_image(dvf_address)
            wait_for_image(deformed_im_address)

        if mode_synthetic_dvf == 'generation':
            if os.path.isfile(dvf_address):
                dvf_sitk = sitk.ReadImage(dvf_address)
            else:
                logging.debug(
                    'artifical_generation[generation]: start ' +
                    su.address_generator(
                        setting, 'DeformedDVF', print_mode=True, **im_info_su))
                if not os.path.exists(
                        su.address_generator(setting, 'DFolder', **
                                             im_info_su)):
                    os.makedirs(
                        su.address_generator(setting, 'DFolder', **im_info_su))

                if setting['DVFPad_S' + str(stage)] > 0:
                    pad = setting['DVFPad_S' + str(stage)]
                    dvf_ref_sitk = sitk.ConstantPad(
                        im_sitk, [pad, pad, pad], [pad, pad, pad],
                        constant=setting['data'][
                            im_info['data']]['DefaultPixelValue'])
                else:
                    dvf_ref_sitk = im_sitk
                if im_info['deform_method'] == 'single_frequency':
                    dvf = dvf_generation.single_freq(
                        setting,
                        im_info,
                        stage=stage,
                        im_input_sitk=dvf_ref_sitk)
                elif im_info['deform_method'] == 'mixed_frequency':
                    dvf = dvf_generation.mixed_freq(setting,
                                                    im_info,
                                                    stage=stage)
                elif im_info['deform_method'] == 'translation':
                    dvf = dvf_generation.translation(
                        setting,
                        im_info,
                        stage=stage,
                        im_input_sitk=dvf_ref_sitk)
                elif im_info['deform_method'] == 'zero':
                    dvf = dvf_generation.zero(im_input_sitk=dvf_ref_sitk)
                elif im_info['deform_method'] == 'respiratory_motion':
                    dvf = dvf_generation.respiratory_motion(
                        setting,
                        im_info,
                        stage=stage,
                        moving_image_mode='Exhale')
                else:
                    raise ValueError('DeformMethod= ' +
                                     im_info['deform_method'] +
                                     ' is not defined. ')

                dvf_sitk = ip.array_to_sitk(dvf,
                                            im_ref=dvf_ref_sitk,
                                            is_vector=True)
                sitk.WriteImage(sitk.Cast(dvf_sitk, sitk.sitkVectorFloat32),
                                dvf_address)
                if setting['WriteDVFStatistics']:
                    dvf_statistics(setting,
                                   dvf,
                                   spacing=im_sitk.GetSpacing()[::-1],
                                   im_info=im_info,
                                   stage=stage)

            deformed_im_clean_address = su.address_generator(
                setting, 'DeformedIm', deformed_im_ext='Clean', **im_info_su)
            deformed_torso_address = su.address_generator(
                setting, 'DeformedTorso', **im_info_su)
            deformed_lung_address = su.address_generator(
                setting, 'DeformedLung', **im_info_su)
            write_intermediate_images = setting['deform_exp'][im_info[
                'deform_exp']]['WriteIntermediateIntensityAugmentation']
            if not os.path.isfile(deformed_im_clean_address) or \
                    (setting['UseTorsoMask'] and not os.path.isfile(deformed_torso_address)) or \
                    (setting['UseLungMask'] and not os.path.isfile(deformed_lung_address)):
                dvf_t = sitk.DisplacementFieldTransform(
                    sitk.Cast(dvf_sitk, sitk.sitkVectorFloat64)
                )  # After this line you cannot save dvf_sitk any more !!!!!!!!!
            if not os.path.isfile(deformed_im_clean_address):
                deformed_im_clean_sitk = ip.resampler_by_transform(
                    im_sitk,
                    dvf_t,
                    im_ref=im_sitk,
                    default_pixel_value=setting['data'][
                        im_info['data']]['DefaultPixelValue'])
                if write_intermediate_images:
                    sitk.WriteImage(
                        sitk.Cast(
                            deformed_im_clean_sitk,
                            setting['data'][im_info['data']]['ImageByte']),
                        deformed_im_clean_address)
            else:
                deformed_im_clean_sitk = sitk.ReadImage(
                    deformed_im_clean_address)
            if setting['UseTorsoMask']:
                deformed_torso_sitk = ip.resampler_by_transform(
                    im_torso_sitk,
                    dvf_t,
                    im_ref=im_sitk,
                    default_pixel_value=0,
                    interpolator=sitk.sitkNearestNeighbor)
                sitk.WriteImage(sitk.Cast(deformed_torso_sitk, sitk.sitkInt8),
                                deformed_torso_address)
            if setting['UseLungMask']:
                deformed_lung_sitk = ip.resampler_by_transform(
                    im_lung_sitk,
                    dvf_t,
                    im_ref=im_sitk,
                    default_pixel_value=0,
                    interpolator=sitk.sitkNearestNeighbor)
                sitk.WriteImage(sitk.Cast(deformed_lung_sitk, sitk.sitkInt8),
                                deformed_lung_address)

            if deformed_im_clean_address != deformed_im_address:
                deformed_im_ext_combined = ['Clean']
                deformed_im_previous_sitk = sitk.Image(deformed_im_clean_sitk)
                for i_ext, deformed_im_ext_current in enumerate(
                        im_info['deformed_im_ext']):
                    if deformed_im_ext_current != 'Clean':
                        # deformed_im_previous_address = su.address_generator(setting, 'DeformedIm', deformed_im_ext=deformed_im_ext_combined, **im_info_su)
                        # deformed_im_previous_sitk = ip.ReadImage(deformed_im_previous_address, waiting_time=2)
                        deformed_im_ext_combined.append(
                            deformed_im_ext_current)
                        deformed_im_ext_combined_address = su.address_generator(
                            setting,
                            'DeformedIm',
                            deformed_im_ext=deformed_im_ext_combined,
                            **im_info_su)
                        if not os.path.isfile(
                                deformed_im_ext_combined_address):
                            if deformed_im_ext_current == 'Noise':
                                deformed_im_current_sitk = intensity_augmentation.add_noise(
                                    setting,
                                    im_info,
                                    stage,
                                    deformed_im_previous_sitk=
                                    deformed_im_previous_sitk)
                            elif deformed_im_ext_current == 'Occluded':
                                deformed_im_current_sitk = intensity_augmentation.add_occlusion(
                                    setting,
                                    im_info,
                                    stage,
                                    deformed_im_previous_sitk=
                                    deformed_im_previous_sitk)
                            elif deformed_im_ext_current == 'Sponge':
                                deformed_im_current_sitk = intensity_augmentation.add_sponge_model(
                                    setting,
                                    im_info,
                                    stage,
                                    deformed_im_previous_sitk=
                                    deformed_im_previous_sitk)
                            else:
                                raise ValueError(
                                    "deformed_im_ext should be in ['Noise', 'Sponge', 'Occluded']"
                                )
                            if write_intermediate_images or i_ext == (
                                    len(im_info['deformed_im_ext']) - 1):
                                sitk.WriteImage(
                                    sitk.Cast(
                                        deformed_im_current_sitk,
                                        setting['data'][
                                            im_info['data']]['ImageByte']),
                                    deformed_im_ext_combined_address)
                            deformed_im_previous_sitk = sitk.Image(
                                deformed_im_current_sitk)
                        else:
                            deformed_im_previous_sitk = sitk.ReadImage(
                                deformed_im_ext_combined_address)

    dvf_sitk = ip.ReadImage(dvf_address, waiting_time=4)
    dvf = sitk.GetArrayFromImage(dvf_sitk)
    deformed_im_sitk = ip.ReadImage(deformed_im_address, waiting_time=2)
    deformed_im = sitk.GetArrayFromImage(deformed_im_sitk)
    dvf = dvf.astype(np.float32)

    mask_to_zero = setting['deform_exp'][im_info['deform_exp']]['MaskToZero']
    if mask_to_zero is not None:
        im_mask = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(setting, mask_to_zero, **im_info_su)))
        im[im_mask == 0] = setting['data'][
            im_info['data']]['DefaultPixelValue']
        deformed_mask = sitk.GetArrayFromImage(
            sitk.ReadImage(
                su.address_generator(setting, 'Deformed' + mask_to_zero,
                                     **im_info_su)))
        deformed_im[deformed_mask == 0] = setting['data'][
            im_info['data']]['DefaultPixelValue']

        # UseTorsoMask has the same size as DVF not the ImPad. We've already used im_torso to
        # mask the image. Later we use it only to find the indices. So it should have the
        # the same size as the dvf.
        dvf_pad = setting['DVFPad_S' + str(stage)]
        if dvf_pad > 0:
            im_mask = np.pad(im_mask,
                             dvf_pad,
                             'constant',
                             constant_values=(0, ))
    else:
        im_mask = None

    im_pad = setting['ImPad_S' + str(stage)]
    if im_pad > 0:
        im = np.pad(
            im,
            im_pad,
            'constant',
            constant_values=(
                setting['data'][im_info['data']]['DefaultPixelValue'], ))
        deformed_im = np.pad(
            deformed_im,
            im_pad,
            'constant',
            constant_values=(
                setting['data'][im_info['data']]['DefaultPixelValue'], ))

    end_time = time.time()
    if setting['verbose']:
        logging.debug('artifical_generation[' + mode_synthetic_dvf +
                      ']: Data=' + im_info['data'] + ', TypeIm=' +
                      str(im_info['type_im']) + ', CN=' + str(im_info['cn']) +
                      ' Dsmooth=' + str(im_info['dsmooth']) + ' D=' +
                      str(im_info['deform_number']) +
                      ' is Done in {:.3f}s'.format(end_time - start_time))
    return im, deformed_im, dvf, im_mask