Пример #1
0
def test(model_name,
         gpu_id,
         nf_enc=[16, 32, 32, 32],
         nf_dec=[32, 32, 32, 32, 32, 16, 16]):
    """
    test

    nf_enc and nf_dec
    #nf_dec = [32,32,32,32,32,16,16,3]
    # This needs to be changed. Ideally, we could just call load_model, and we wont have to
    # specify the # of channels here, but the load_model is not working with the custom loss...
    """

    # load subject test
    print("load_data start")
    X_train, y_train = load_data(data_dir='../data',
                                 mode='test',
                                 fixed='joyoungje')
    vol_size = y_train.shape[1:-1]

    # gpu handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        net = networks.cvpr2018_net(vol_size, nf_enc, nf_dec)
        print("model load weights")
        net.load_weights(model_name)

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size, indexing='ij')


#    # if CPU, prepare grid
#    if compute_type == 'CPU':
#        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    with tf.device(gpu):
        print("model predict")
        pred = net.predict([X_train, y_train])
        print("nn_tft_model.predict")
        X_warp = nn_trf_model.predict([X_train, pred[1]])[0, ..., 0]

    reshape_y_train = y_train.reshape(y_train.shape[1:-1])
    vals = dice(pred[0].reshape(pred[0].shape[1:-1]), reshape_y_train)
    dice_mean = np.mean(vals)
    dice_std = np.std(vals)
    print('Dice mean over structures: {:.2f} ({:.2f})'.format(
        dice_mean, dice_std))
Пример #2
0
def test(gpu_id, compute_type='GPU', vol_size=(256, 256, 256), flow=None):
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))
    flow = sitk.GetArrayFromImage(sitk.ReadImage(flow))
    flow = np.reshape(flow, (1, ) + np.shape(flow))
    flow_tensor = tf.convert_to_tensor(flow)
    print(flow_tensor.shape)
    # load weights of model
    with tf.device(gpu):
        nn_trf_model = networks.nn_trf(vol_size, indexing='ij')
        warped_seg = nn_trf_model.predict([X_seg, flow])[0, ..., 0]
        print(warped_seg.shape)

    result_seg = sitk.GetImageFromArray(warped_seg)
    result_seg.CopyInformation(mov)
    sitk.WriteImage(result_seg, '../data/results/warped_seg.nii.gz')
Пример #3
0
def test(
        gpu_id,
        model_dir,
        iter_num,
        compute_type='GPU',  # GPU or CPU
        vol_size=(160, 192, 224),
        nf_enc=[16, 32, 32, 32],
        nf_dec=[32, 32, 32, 32, 16, 3],
        save_file=None):
    """
    test via segmetnation propagation
    works by iterating over some iamge files, registering them to atlas,
    propagating the warps, then computing Dice with atlas segmentations
    """

    # GPU handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        # if testing miccai run, should be xy indexing.
        net = networks.miccai2018_net(vol_size,
                                      nf_enc,
                                      nf_dec,
                                      use_miccai_int=False,
                                      indexing='ij')
        net.load_weights(os.path.join(model_dir, str(iter_num) + '.h5'))

        # compose diffeomorphic flow output model
        diff_net = keras.models.Model(net.inputs,
                                      net.get_layer('diffflow').output)

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size, indexing='ij')

    # if CPU, prepare grid
    if compute_type == 'CPU':
        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    # prepare a matrix of dice values
    dice_vals = np.zeros((len(good_labels), n_batches))
    for k in range(n_batches):
        # get data
        vol_name, seg_name = test_brain_strings[k].split(",")
        X_vol, X_seg = datagenerators.load_example_by_name(vol_name, seg_name)

        # predict transform
        with tf.device(gpu):
            pred = diff_net.predict([X_vol, atlas_vol])

        # Warp segments with flow
        if compute_type == 'CPU':
            flow = pred[0, :, :, :, :]
            warp_seg = util.warp_seg(X_seg,
                                     flow,
                                     grid=grid,
                                     xx=xx,
                                     yy=yy,
                                     zz=zz)

        else:  # GPU
            warp_seg = nn_trf_model.predict([X_seg, pred])[0, ..., 0]

        # compute Volume Overlap (Dice)
        dice_vals[:, k] = dice(warp_seg, atlas_seg, labels=good_labels)
        print('%3d %5.3f %5.3f' % (k, np.mean(
            dice_vals[:, k]), np.mean(np.mean(dice_vals[:, :k + 1]))))

        if save_file is not None:
            sio.savemat(save_file, {
                'dice_vals': dice_vals,
                'labels': good_labels
            })
def test(
        gpu_id,
        model_dir,
        iter_num,
        compute_type='GPU',  # GPU or CPU
        vol_size=(160, 192, 224),
        nf_enc=[16, 32, 32, 32],
        nf_dec=[32, 32, 32, 32, 16, 3],
        save_file=None):
    """
    test via segmetnation propagation
    works by iterating over some iamge files, registering them to atlas,
    propagating the warps, then computing Dice with atlas segmentations
    """

    # GPU handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        # if testing miccai run, should be xy indexing.
        net = networks.miccai2018_net(vol_size,
                                      nf_enc,
                                      nf_dec,
                                      use_miccai_int=False,
                                      indexing='ij')
        net.load_weights(os.path.join(model_dir, str(iter_num) + '.h5'))

        # compose diffeomorphic flow output model
        diff_net = keras.models.Model(net.inputs,
                                      net.get_layer('diffflow').output)

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size, indexing='ij')

    # if CPU, prepare grid
    if compute_type == 'CPU':
        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    # get data
    X_vol = nib.load(r'D:\users\zzx\data\2018nor\pre\01.nii').get_data()
    X_vol = X_vol[np.newaxis, ..., np.newaxis]
    atlas_vol = nib.load(r'D:\users\zzx\data\2018nor\pre\01_a.nii').get_data()
    atlas_vol = atlas_vol[np.newaxis, ..., np.newaxis]

    X_mask = nib.load(
        r'D:\users\zzx\data\2018mask\pre\pig01_pre_final_r.nii').get_data()
    X_mask = X_mask[np.newaxis, ..., np.newaxis]
    X_mask[X_mask == np.max(X_mask)] = 1
    X_mask[X_mask != 1] = 0
    atlas_mask = nib.load(
        r'D:\users\zzx\data\2018mask\aft\pig01_02_final_r.nii').get_data()
    atlas_mask[atlas_mask == np.max(atlas_mask)] = 1
    atlas_mask[atlas_mask != 1] = 0
    ## feature point
    # X_feapt = np.zeros((160,192,224))
    # X_feapt[128,51,165] = 1
    # X_feapt = X_feapt[np.newaxis,...,np.newaxis]

    # predict transform
    with tf.device(gpu):
        pred = diff_net.predict([X_vol, atlas_vol])

    # Warp segments with flow
    if compute_type == 'CPU':
        flow = pred[0, :, :, :, :]
        warp_seg = util.warp_seg(X_mask, flow, grid=grid, xx=xx, yy=yy, zz=zz)

    else:  # GPU
        warp_mask = nn_trf_model.predict([X_mask, pred])[0, ..., 0]
        warp_vol = nn_trf_model.predict([X_vol, pred])[0, ..., 0]
        # pred_point1 = nn_trf_model.predict([X_feapt, pred])[0,...,0]
    print(X_vol.shape)
    # warp_vol = nib.Nifti1Image(warp_vol,np.eye(4))
    warp_vol = nib.Nifti1Image(warp_vol, np.eye(4))
    nib.save(warp_vol, r'D:\users\zzx\data\2018warp\1w.nii')
    # compute Volume Overlap (Dice)
    # X_mask = X_mask[0,...,0]
    # print(X_mask.shape, atlas_mask.shape,pred_point1.shape,np.where(pred_point1 != 0))
    dice_vals = dice(warp_mask, atlas_mask)
    # print('%3d %5.3f %5.3f' % (k, np.mean(dice_vals[:, k]), np.mean(np.mean(dice_vals[:, :k+1]))))
    print(dice_vals)
    if save_file is not None:
        sio.savemat(save_file, {'dice_vals': dice_vals})
Пример #5
0
def test(
        model_name,
        gpu_id,
        compute_type='GPU',  # GPU or CPU
        nf_enc=[16, 32, 32, 32],
        nf_dec=[32, 32, 32, 32, 32, 16, 16]):
    """
    test

    nf_enc and nf_dec
    #nf_dec = [32,32,32,32,32,16,16,3]
    # This needs to be changed. Ideally, we could just call load_model, and we wont have to
    # specify the # of channels here, but the load_model is not working with the custom loss...
    """

    # Anatomical labels we want to evaluate
    labels = sio.loadmat('../data/labels.mat')['labels'][0]

    atlas = np.load('../data/atlas_norm.npz')
    atlas_vol = atlas['vol'][np.newaxis, ..., np.newaxis]
    atlas_seg = atlas['seg']
    vol_size = atlas_vol.shape[1:-1]

    # gpu handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        net = networks.cvpr2018_net(vol_size, nf_enc, nf_dec)
        net.load_weights(model_name)

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size, indexing='ij')

    # if CPU, prepare grid
    if compute_type == 'CPU':
        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    # load subject test
    X_vol, X_seg = datagenerators.load_example_by_name('../data/test_vol.npz',
                                                       '../data/test_seg.npz')

    with tf.device(gpu):
        pred = net.predict([X_vol, atlas_vol])

        # Warp segments with flow
        if compute_type == 'CPU':
            flow = pred[1][0, :, :, :, :]
            warp_seg = util.warp_seg(X_seg,
                                     flow,
                                     grid=grid,
                                     xx=xx,
                                     yy=yy,
                                     zz=zz)

        else:  # GPU
            warp_seg = nn_trf_model.predict([X_seg, pred[1]])[0, ..., 0]

    vals, _ = dice(warp_seg, atlas_seg, labels=labels, nargout=2)
    dice_mean = np.mean(vals)
    dice_std = np.std(vals)
    print('Dice mean over structures: {:.2f} ({:.2f})'.format(
        dice_mean, dice_std))
def test(
        gpu_id,
        model_dir,
        iter_num,
        compute_type='GPU',  # GPU or CPU
        vol_size=(160, 192, 224),
        nf_enc=[16, 32, 32, 32],
        nf_dec=[32, 32, 32, 32, 16, 3],
        save_file=None):
    """
    test via segmetnation propagation
    works by iterating over some iamge files, registering them to atlas,
    propagating the warps, then computing Dice with atlas segmentations
    """

    # GPU handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        # if testing miccai run, should be xy indexing.
        net = networks.miccai2018_net(vol_size,
                                      nf_enc,
                                      nf_dec,
                                      use_miccai_int=True,
                                      indexing='xy')
        net.load_weights(os.path.join(model_dir, str(iter_num) + '.h5'))

        # compose diffeomorphic flow output model
        diff_net = keras.models.Model(net.inputs,
                                      net.get_layer('diffflow').output)

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size)

    # if CPU, prepare grid
    if compute_type == 'CPU':
        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    # prepare a matrix of dice values
    dice_vals = np.zeros((len(good_labels), n_batches))
    for k in range(n_batches):
        # get data
        vol_name, seg_name = test_brain_strings[k].split(",")
        X_vol, X_seg = datagenerators.load_example_by_name(vol_name, seg_name)

        # predict transform
        with tf.device(gpu):
            pred = diff_net.predict([X_vol, atlas_vol])

        # Warp segments with flow
        if compute_type == 'CPU':
            flow = pred[0, :, :, :, :]
            warp_seg = util.warp_seg(X_seg,
                                     flow,
                                     grid=grid,
                                     xx=xx,
                                     yy=yy,
                                     zz=zz)

        else:  # GPU
            # Rigid registration only by GPU
            flow = pred[0, :, :, :, :]
            # Compute A(all about coordinate computation)
            x = np.linspace(0, 160 - 16, sample_num)
            x = x.astype(np.int32)
            y = np.linspace(0, 190 - 19, sample_num)
            y = y.astype(np.int32)
            z = np.linspace(0, 220 - 22, sample_num)
            z = z.astype(np.int32)
            index = np.rollaxis(np.array(np.meshgrid(x, y, z)), 0, 4)
            x = index[:, :, :, 0]
            y = index[:, :, :, 1]
            z = index[:, :, :, 2]

            # Y in formula
            x_flow = np.arange(vol_size[0])
            y_flow = np.arange(vol_size[1])
            z_flow = np.arange(vol_size[2])
            grid = np.rollaxis(np.array((np.meshgrid(y_flow, x_flow, z_flow))),
                               0, 4)  # original coordinate
            grid_x = grid_sample(x, y, z, grid[:, :, :, 0], sample_num)
            grid_y = grid_sample(x, y, z, grid[:, :, :, 1], sample_num)
            grid_z = grid_sample(x, y, z, grid[:, :, :, 2],
                                 sample_num)  # X (10,10,10)

            sample = flow + grid
            sample_x = grid_sample(x, y, z, sample[:, :, :, 0], sample_num)
            sample_y = grid_sample(x, y, z, sample[:, :, :, 1], sample_num)
            sample_z = grid_sample(x, y, z, sample[:, :, :, 2],
                                   sample_num)  # Y (10,10,10)

            sum_x = np.sum(flow[:, :, :, 0])
            sum_y = np.sum(flow[:, :, :, 1])
            sum_z = np.sum(flow[:, :, :, 2])

            ave_x = sum_x / (vol_size[0] * vol_size[1] * vol_size[2])
            ave_y = sum_y / (vol_size[0] * vol_size[1] * vol_size[2])
            ave_z = sum_z / (vol_size[0] * vol_size[1] * vol_size[2])

            # formula
            Y = np.zeros((10, 10, 10, grid_dimension))
            X = np.zeros((10, 10, 10, grid_dimension))
            T = np.array([ave_x, ave_y, ave_z, 1])  # (4,1)
            # R = np.zeros((10, 10, 10, grid_dimension, grid_dimension))

            for i in np.arange(10):
                for j in np.arange(10):
                    for z in np.arange(10):
                        Y[i, j, z, :] = np.array([
                            sample_x[i, j, z], sample_y[i, j, z],
                            sample_z[i, j, z], 1
                        ])

            for i in np.arange(10):
                for j in np.arange(10):
                    for z in np.arange(10):
                        X[i, j, z, :] = np.array([
                            grid_x[i, j, z], grid_y[i, j, z], grid_z[i, j, z],
                            1
                        ])

            X = X.reshape((1000, grid_dimension))
            Y = Y.reshape((1000, grid_dimension))
            R = np.dot(
                np.dot(np.linalg.pinv(np.dot(np.transpose(X), X)),
                       np.transpose(X)), Y)  # R

            # build new grid(Use R to do the spatial transform)
            shifted_x = np.arange(vol_size[0])
            shifted_y = np.arange(vol_size[1])
            shifted_z = np.arange(vol_size[2])
            print(shifted_x.shape)
            print(shifted_y.shape)
            print(shifted_z.shape)
            shifted_grid = np.rollaxis(
                np.array((np.meshgrid(shifted_y, shifted_x, shifted_z))), 0, 4)
            print(shifted_grid.shape)
            for i in np.arange(vol_size[0]):
                for j in np.arange(vol_size[1]):
                    for z in np.arange(vol_size[2]):
                        coordinates = np.dot(
                            R,
                            np.array([i, j, z, 1]).reshape(4, 1)) + T.reshape(
                                4, 1)
                        print("voxel." + '(' + str(i) + ',' + str(j) + ',' +
                              str(z) + ')')
                        shifted_grid[i, j, z, 0] = coordinates[0]
                        shifted_grid[i, j, z, 1] = coordinates[1]
                        shifted_grid[i, j, z, 2] = coordinates[2]

            # interpolation
            xx = np.arange(vol_size[1])
            yy = np.arange(vol_size[0])
            zz = np.arange(vol_size[2])
            warp_seg = interpn((yy, xx, zz),
                               X_seg[0, :, :, :, 0],
                               shifted_grid,
                               method='nearest',
                               bounds_error=False,
                               fill_value=0)

            # CVPR
            grid = np.rollaxis(np.array(np.meshgrid(xx, yy, zz)), 0, 4)
            sample = flow + grid
            sample = np.stack(
                (sample[:, :, :, 1], sample[:, :, :, 0], sample[:, :, :, 2]),
                3)
            warp_seg2 = interpn((yy, xx, zz),
                                X_seg[0, :, :, :, 0],
                                sample,
                                method='nearest',
                                bounds_error=False,
                                fill_value=0)

            # compute dice
            vals, _ = dice(warp_seg, atlas_seg, labels=labels, nargout=2)
            vals2, _ = dice(X_seg[0, :, :, :, 0],
                            atlas_seg,
                            labels=labels,
                            nargout=2)
            vals3, _ = dice(warp_seg2, atlas_seg, labels=labels, nargout=2)
            print("dice before:")
            print(np.mean(vals2), np.std(vals2))
            print("dice after deformable registration:")
            print(np.mean(vals3), np.std(vals3))
            print("dice after rigid registration:")
            print(np.mean(vals), np.std(vals))
            warp_seg = nn_trf_model.predict([X_seg, pred])[0, ..., 0]

        # compute Volume Overlap (Dice)
        dice_vals[:, k] = dice(warp_seg, atlas_seg, labels=good_labels)
        print('%3d %5.3f %5.3f' % (k, np.mean(
            dice_vals[:, k]), np.mean(np.mean(dice_vals[:, :k + 1]))))

        if save_file is not None:
            sio.savemat(save_file, {
                'dice_vals': dice_vals,
                'labels': good_labels
            })
Пример #7
0
def test(data_dir, fixed_image, label, device, load_model_file, DLR_model):

    assert DLR_model in [
        'VM', 'FAIM'
    ], 'DLR_model should be one of VM or FAIM, found %s' % LBR_model

    # prepare data files
    # inside the folder are npz files with the 'vol' and 'label'.
    test_vol_names = glob.glob(os.path.join(data_dir, '*.npz'))
    assert len(test_vol_names) > 0, "Could not find any testing data"

    fixed_vol = np.load(fixed_image)['vol'][np.newaxis, ..., np.newaxis]
    fixed_seg = np.load(fixed_image)['label']
    vol_size = fixed_vol.shape[1:-1]
    label = np.load(label)

    # device handling
    if 'gpu' in device:
        if '0' in device:
            device = '/gpu:0'
        if '1' in device:
            device = '/gpu:1'
        config = tf.ConfigProto()
        config.gpu_options.allow_growth = True
        config.allow_soft_placement = True
        set_session(tf.Session(config=config))
    else:
        device = '/cpu:0'

    # load weights of model
    with tf.device(device):
        net = networks.AAN(vol_size, DLR_model)
        net.load_weights(load_model_file)

        # NN transfer model
        nn_trf_model_nearest = networks.nn_trf(vol_size,
                                               interp_method='nearest',
                                               indexing='ij')
        nn_trf_model_linear = networks.nn_trf(vol_size,
                                              interp_method='linear',
                                              indexing='ij')

    dice_result = []
    for test_image in test_vol_names:

        X_vol, X_seg, x_boundary = datagenerators.load_example_by_name(
            test_image, return_boundary=True)

        with tf.device(device):
            pred = net.predict([X_vol, fixing_vol, x_boundary])
            warp_vol = nn_trf_model_linear.predict([X_vol, pred[1]])[0, ..., 0]
            warp_seg = nn_trf_model_nearest.predict([X_seg, pred[1]])[0, ...,
                                                                      0]

        vals, _ = dice(warp_seg, fixing_seg, label, nargout=2)
        dice_result.append(vals)

        print('Dice mean: {:.3f} ({:.3f})'.format(np.mean(vals), np.std(vals)))

    dice_result = np.array(dice_result)
    print('Average dice mean: {:.3f} ({:.3f})'.format(np.mean(dice_result),
                                                      np.std(dice_result)))
def test(expr_name,
         epoch,
         gpu_id,
         sample_num,
         dataset,
         nf_enc=[16, 32, 32, 32],
         nf_dec=[32, 32, 32, 32, 32, 16, 16]):
    """
    test

    nf_enc and nf_dec
    #nf_dec = [32,32,32,32,32,16,16,3]
    # This needs to be changed. Ideally, we could just call load_model, and we wont have to
    # specify the # of channels here, but the load_model is not working with the custom loss...
    """

    # load subject test
    print("load_data start")
    X_train, y_train = load_data(data_dir='../data',
                                 sample_num=sample_num,
                                 mode=dataset,
                                 fixed='joyoungje')
    vol_size = y_train.shape[1:-1]

    # gpu handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        net = networks.cvpr2018_net(vol_size, nf_enc, nf_dec)
        print("model load weights")
        net.load_weights(
            os.path.join("../models", expr_name, "{}.h5".format(epoch)))

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size, indexing='ij')


#    # if CPU, prepare grid
#    if compute_type == 'CPU':
#        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    with tf.device(gpu):
        print("model predict")
        pred = net.predict([X_train, y_train])
        #print("nn_tft_model.predict")
        #X_warp = nn_trf_model.predict([X_train, pred[1]])[0,...,0]

    warp_img = nib.Nifti1Image(pred[0].reshape(pred[0].shape[1:-1]),
                               affine=np.eye(4))
    nib.save(
        warp_img,
        os.path.join(
            '../result', '{}_epoch{}_{}{}_registration.nii.gz'.format(
                expr_name, epoch, dataset, sample_num)))

    moving_img = nib.Nifti1Image(X_train.reshape(X_train.shape[1:-1]),
                                 affine=np.eye(4))
    nib.save(
        moving_img,
        os.path.join(
            '../result',
            '{}_epoch{}_{}{}_original.nii.gz'.format(expr_name, epoch, dataset,
                                                     sample_num)))

    fixed_img = nib.Nifti1Image(y_train.reshape(y_train.shape[1:-1]),
                                affine=np.eye(4))
    nib.save(
        fixed_img,
        os.path.join(
            '../result',
            '{}_epoch{}_{}{}_reference.nii.gz'.format(expr_name, epoch,
                                                      dataset, sample_num)))
Пример #9
0
def test(expr_name, epoch, gpu_id,
         nf_enc=(16, 32, 32, 32), nf_dec=(32, 32, 32, 32, 32, 16, 16)):
    """
    test

    nf_enc and nf_dec
    #nf_dec = [32,32,32,32,32,16,16,3]
    # This needs to be changed. Ideally, we could just call load_model, and we wont have to
    # specify the # of channels here, but the load_model is not working with the custom loss...
    """
    vol_size = (256, 256, 144)

    # gpu handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        net = networks.cvpr2018_net(vol_size, nf_enc, nf_dec)
        print("model load weights")
        net.load_weights(os.path.join("../models", expr_name, "{:04d}.h5".format(epoch)))

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size, indexing='ij')

    # load subject test
    data_dir = '../../../dataset/urinary'

    except_list = [6, 97, 125, 198, 199, 228, 271]
    # vol_names = [filename for filename in os.listdir(data_dir) if (int(filename.split("_")[-1].split('.')[0]) <= 10) and
    #                                                           (int(filename.split("_")[-1].split('.')[0]) not in except_list)]

    vol_names = [filename for filename in os.listdir(data_dir) if int(filename.split("_")[-1].split(".")[0]) in normal]
    vol_names.sort()
    print("data length:", len(vol_names))
    vol_names = vol_names[:10]

    generator = eval_gen(data_dir=data_dir, vol_names=vol_names)

#    # if CPU, prepare grid
#    if compute_type == 'CPU':
#        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    if not os.path.isdir(os.path.join('../result', '{}_epoch{}'.format(expr_name, epoch))):
        os.mkdir(os.path.join('../result', '{}_epoch{}'.format(expr_name, epoch)))

    for pre, delay, vol_name in generator:
        with tf.device(gpu):
            pred = net.predict([pre, delay])
            X_warp = nn_trf_model.predict([pre, pred[1]])[0, ..., 0]

            pre = np.flip(pre, 3)[0, ..., 0]
            delay = np.flip(delay, 3)[0, ..., 0]
            X_warp = np.flip(X_warp, 2)

            pre = np.rot90(pre, 3)
            delay = np.rot90(delay, 3)
            X_warp = np.rot90(X_warp, 3)

            pre = pre * 4096 - 1024
            pre = pre.astype(np.int16)
            delay = delay * 4096 - 1024
            delay = delay.astype(np.int16)
            X_warp = X_warp * 4096 - 1024
            X_warp = X_warp.astype(np.int16)

            warp_img = nib.Nifti1Image(X_warp, affine=np.eye(4))
            nib.save(warp_img, os.path.join('../result', '{}_epoch{}'.format(expr_name, epoch),
                                            "{}_registration.nii.gz".format(vol_name)))

            moving_img = nib.Nifti1Image(pre, affine=np.eye(4))
            nib.save(moving_img, os.path.join('../result', '{}_epoch{}'.format(expr_name, epoch),
                                              "{}_pre.nii.gz".format(vol_name)))

            fixed_img = nib.Nifti1Image(delay, affine=np.eye(4))
            nib.save(fixed_img, os.path.join('../result', '{}_epoch{}'.format(expr_name, epoch),
                                             "{}_delay.nii.gz".format(vol_name)))

    print("successfully done!")
def test(
        gpu_id,
        iter_num,
        compute_type='GPU',  # GPU or CPU
        vol_size=(160, 192, 224),
        nf_enc=[16, 32, 32, 32],
        nf_dec=[32, 32, 32, 32, 16, 3],
        save_file=None):
    """
    test by segmentation, compute dice between atlas_seg and warp_seg
    :param gpu_id: gpu id
    :param iter_num: specify the model to read
    :param compute_type: CPU/GPU
    :param vol_size: volume size
    :param nf_enc: number of encoder
    :param nf_dec: number of decoder
    :param save_file: None
    :return: None
    """

    # GPU handling
    gpu = '/gpu:' + str(gpu_id)
    os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.allow_soft_placement = True
    set_session(tf.Session(config=config))

    # load weights of model
    with tf.device(gpu):
        # if testing miccai run, should be xy indexing.
        net = networks.miccai2018_net(vol_size,
                                      nf_enc,
                                      nf_dec,
                                      use_miccai_int=True,
                                      indexing='xy')
        model_dir = "/home/ys895/rigid_diff_model/"
        net.load_weights(os.path.join(model_dir, str(iter_num) + '.h5'))

        # compose diffeomorphic flow output model
        diff_net = keras.models.Model(net.inputs,
                                      net.get_layer('diffflow').output)

        # NN transfer model
        nn_trf_model = networks.nn_trf(vol_size)

    # if CPU, prepare grid
    if compute_type == 'CPU':
        grid, xx, yy, zz = util.volshape2grid_3d(vol_size, nargout=4)

    # prepare a matrix of dice values
    dice_vals = np.zeros((len(good_labels), n_batches))
    for k in range(n_batches):
        # get data
        vol_name, seg_name = test_brain_strings[k].split(",")
        X_vol, X_seg = datagenerators.load_example_by_name(vol_name, seg_name)
        orig_vol = X_vol
        orig_seg = X_seg

        theta = 0
        beta = 5
        omega = 0
        X_seg = rotate_img(X_seg[0, :, :, :, 0],
                           theta=theta,
                           beta=beta,
                           omega=omega)
        X_vol = rotate_img(X_vol[0, :, :, :, 0],
                           theta=theta,
                           beta=beta,
                           omega=omega)
        X_seg = X_seg.reshape((1, ) + X_seg.shape + (1, ))
        X_vol = X_vol.reshape((1, ) + X_vol.shape + (1, ))

        sample_num = 30
        grid_dimension = 4

        # predict transform
        with tf.device(gpu):
            pred = diff_net.predict([X_vol, atlas_vol])

        # Warp segments with flow
        if compute_type == 'CPU':
            flow = pred[0, :, :, :, :]
            warp_seg = util.warp_seg(X_seg,
                                     flow,
                                     grid=grid,
                                     xx=xx,
                                     yy=yy,
                                     zz=zz)
        else:  # GPU

            flow = pred[0, :, :, :, :]

            # sample coordinate(sample_num * sample_num * sample_num)
            x = np.linspace(0, (vol_size[0] / sample_num) * (sample_num - 1),
                            sample_num)
            x = x.astype(np.int32)
            y = np.linspace(0, (vol_size[1] / sample_num) * (sample_num - 1),
                            sample_num)
            y = y.astype(np.int32)
            z = np.linspace(0, (vol_size[2] / sample_num) * (sample_num - 1),
                            sample_num)
            z = z.astype(np.int32)
            index = np.rollaxis(np.array(np.meshgrid(y, x, z)), 0, 4)
            x = index[:, :, :, 1]
            y = index[:, :, :, 0]
            z = index[:, :, :, 2]

            # Y in formula
            x_flow = np.arange(vol_size[0])
            y_flow = np.arange(vol_size[1])
            z_flow = np.arange(vol_size[2])
            grid = np.rollaxis(np.array((np.meshgrid(y_flow, x_flow, z_flow))),
                               0, 4)  # original coordinate
            grid_x = grid_sample(x, y, z, grid[:, :, :, 1], sample_num)
            grid_y = grid_sample(x, y, z, grid[:, :, :, 0], sample_num)
            grid_z = grid_sample(x, y, z, grid[:, :, :, 2],
                                 sample_num)  # X (10,10,10)

            sample = flow + grid
            sample_x = grid_sample(x, y, z, sample[:, :, :, 1], sample_num)
            sample_y = grid_sample(x, y, z, sample[:, :, :, 0], sample_num)
            sample_z = grid_sample(x, y, z, sample[:, :, :, 2],
                                   sample_num)  # Y (10,10,10)

            sum_x = np.sum(flow[:, :, :, 1])
            sum_y = np.sum(flow[:, :, :, 0])
            sum_z = np.sum(flow[:, :, :, 2])

            ave_x = sum_x / (vol_size[0] * vol_size[1] * vol_size[2])
            ave_y = sum_y / (vol_size[0] * vol_size[1] * vol_size[2])
            ave_z = sum_z / (vol_size[0] * vol_size[1] * vol_size[2])

            # formula
            Y = np.zeros((sample_num, sample_num, sample_num, grid_dimension))
            X = np.zeros((sample_num, sample_num, sample_num, grid_dimension))
            T = np.array([ave_x, ave_y, ave_z, 1])  # (4,1)
            print(T)

            for i in np.arange(sample_num):
                for j in np.arange(sample_num):
                    for z in np.arange(sample_num):
                        Y[i, j, z, :] = np.array([
                            sample_x[i, j, z], sample_y[i, j, z],
                            sample_z[i, j, z], 1
                        ])
                        #Y[i, j, z, :] = Y[i, j, z, :] - np.array([ave_x, ave_y, ave_z, 0])  # amend: Y` = Y - T

            for i in np.arange(sample_num):
                for j in np.arange(sample_num):
                    for z in np.arange(sample_num):
                        X[i, j, z, :] = np.array([
                            grid_x[i, j, z], grid_y[i, j, z], grid_z[i, j, z],
                            1
                        ])

            X = X.reshape(
                (sample_num * sample_num * sample_num, grid_dimension))
            Y = Y.reshape(
                (sample_num * sample_num * sample_num, grid_dimension))
            R = np.dot(
                np.dot(np.linalg.pinv(np.dot(np.transpose(X), X)),
                       np.transpose(X)), Y)  # R(4, 4)
            print(R)
            beta = -(beta / 180) * math.pi
            R = np.array([[math.cos(beta), 0, -math.sin(beta), 0],
                          [0, 1, 0, 0], [math.sin(beta), 0,
                                         math.cos(beta), 0], [0, 0, 0, 1]])
            #R = R.transpose()

            # build new grid(Use R to do the spatial transform)
            shifted_x = np.arange(vol_size[0])
            shifted_y = np.arange(vol_size[1])
            shifted_z = np.arange(vol_size[2])
            shifted_grid = np.rollaxis(
                np.array((np.meshgrid(shifted_y, shifted_x, shifted_z))), 0, 4)

            # some required matrixs
            T1 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                           [
                               -int(vol_size[0] / 2), -int(vol_size[1] / 2),
                               -int(vol_size[2] / 2), 1
                           ]])

            T2 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                           [
                               int(vol_size[0] / 2),
                               int(vol_size[1] / 2),
                               int(vol_size[2] / 2), 1
                           ]])

            for i in np.arange(vol_size[0]):
                for j in np.arange(vol_size[1]):
                    for z in np.arange(vol_size[2]):
                        #coordinates = np.dot(R, np.array([i, j, z, 1]).reshape(4, 1)) + T.reshape(4, 1)
                        coordinates = np.dot(
                            np.dot(
                                np.dot(
                                    np.array([i, j, z, 1]).reshape(1, 4), T1),
                                R), T2)  # new implementation
                        # print("voxel." + '(' + str(i) + ',' + str(j) + ',' + str(z) + ')')
                        shifted_grid[i, j, z, 1] = coordinates[0, 0]
                        shifted_grid[i, j, z, 0] = coordinates[0, 1]
                        shifted_grid[i, j, z, 2] = coordinates[0, 2]

            # interpolation
            xx = np.arange(vol_size[1])
            yy = np.arange(vol_size[0])
            zz = np.arange(vol_size[2])
            shifted_grid = np.stack(
                (shifted_grid[:, :, :, 1], shifted_grid[:, :, :, 0],
                 shifted_grid[:, :, :, 2]), 3
            )  # notice: the shifted_grid is reverse in x and y, so this step is used for making it back.
            warp_seg = interpn((yy, xx, zz),
                               X_seg[0, :, :, :, 0],
                               shifted_grid,
                               method='nearest',
                               bounds_error=False,
                               fill_value=0)  # rigid registration
            warp_vol = interpn((yy, xx, zz),
                               X_vol[0, :, :, :, 0],
                               shifted_grid,
                               method='nearest',
                               bounds_error=False,
                               fill_value=0)  # rigid registration

        # compute Volume Overlap (Dice)
        dice_vals[:, k] = dice(warp_seg,
                               orig_seg[0, :, :, :, 0],
                               labels=good_labels)
        print('%3d %5.3f %5.3f' % (k, np.mean(
            dice_vals[:, k]), np.mean(np.mean(dice_vals[:, :k + 1]))))

        if save_file is not None:
            sio.savemat(save_file, {
                'dice_vals': dice_vals,
                'labels': good_labels
            })

        # specify slice
        num_slice = 90

        plt.figure()
        plt.subplot(1, 3, 1)
        plt.imshow(orig_vol[0, :, num_slice, :, 0])
        plt.subplot(1, 3, 2)
        plt.imshow(X_vol[0, :, num_slice, :, 0])
        plt.subplot(1, 3, 3)
        plt.imshow(warp_vol[:, num_slice, :])
        plt.savefig("slice" + str(num_slice) + '_' + str(k) + ".png")

        plt.figure()
        plt.subplot(1, 3, 1)
        plt.imshow(flow[:, num_slice, :, 1])
        plt.subplot(1, 3, 2)
        plt.imshow(flow[:, num_slice, :, 0])
        plt.subplot(1, 3, 3)
        plt.imshow(flow[:, num_slice, :, 2])
        plt.savefig("flow.png")