Exemple #1
0
def test_warp_image_ddf():
    """
    Test warp_image_ddf by checking input/output shapes
    """
    batch_size = 2
    fixed_image_size = (32, 32, 16)
    moving_image_size = (24, 24, 16)
    channel = 6
    image = tf.ones((batch_size, *moving_image_size), dtype="float32")
    image_ch = tf.ones((batch_size, *moving_image_size, channel),
                       dtype="float32")
    ddf = tf.ones((batch_size, *fixed_image_size, 3), dtype="float32")
    grid_ref = tf.ones((1, *fixed_image_size, 3), dtype="float32")

    # without channel, with grid_ref
    got = layer_util.warp_image_ddf(image=image, ddf=ddf, grid_ref=grid_ref)
    assert got.shape == (batch_size, *fixed_image_size)

    # without channel, without grid_ref
    got = layer_util.warp_image_ddf(image=image, ddf=ddf, grid_ref=None)
    assert got.shape == (batch_size, *fixed_image_size)

    # with channel, with grid_ref
    got = layer_util.warp_image_ddf(image=image_ch, ddf=ddf, grid_ref=grid_ref)
    assert got.shape == (batch_size, *fixed_image_size, channel)

    # with channel, without grid_ref
    got = layer_util.warp_image_ddf(image=image_ch, ddf=ddf, grid_ref=None)
    assert got.shape == (batch_size, *fixed_image_size, channel)

    # wrong image shape
    wrong_image = tf.ones(moving_image_size, dtype="float32")
    with pytest.raises(ValueError) as err_info:
        layer_util.warp_image_ddf(image=wrong_image,
                                  ddf=ddf,
                                  grid_ref=grid_ref)
    assert "image shape must be (batch, m_dim1, m_dim2, m_dim3)" in str(
        err_info.value)

    # wrong ddf shape
    wrong_ddf = tf.ones((batch_size, *fixed_image_size, 2), dtype="float32")
    with pytest.raises(ValueError) as err_info:
        layer_util.warp_image_ddf(image=image,
                                  ddf=wrong_ddf,
                                  grid_ref=grid_ref)
    assert "ddf shape must be (batch, f_dim1, f_dim2, f_dim3, 3)" in str(
        err_info.value)

    # wrong grid_ref shape
    wrong_grid_ref = tf.ones((batch_size, *moving_image_size, 3),
                             dtype="float32")
    with pytest.raises(ValueError) as err_info:
        layer_util.warp_image_ddf(image=image,
                                  ddf=ddf,
                                  grid_ref=wrong_grid_ref)
    assert "grid_ref shape must be (1, f_dim1, f_dim2, f_dim3, 3) or None" in str(
        err_info.value)
Exemple #2
0
def gif_warp(
    img_paths, ddf_path, slice_inds=None, num_interval=100, interval=50, save_path=""
):
    """
    Apply ddf to image slice/s to generate gif

    :param img_paths: list or comma separated string of image paths
    :param ddf_path: path to ddf to use for warping
    :param slice_inds: list of slice indices to use for each image
    :param num_interval: number of intervals in which to apply ddf
    :param interval: time in miliseconds between frames of gif
    :param save_path: path to directory where visualisation/s is/are to be saved
    """
    if type(img_paths) is str:
        img_paths = string_to_list(img_paths)

    image = load_nifti_file(img_paths[0])
    img_shape = np.shape(image)

    if slice_inds is None:
        slice_inds = [round(np.random.rand() * (img_shape[-1]) - 1)]

    for img_path in img_paths:
        for slice_ind in slice_inds:

            fig = plt.figure()
            ax = plt.Axes(fig, [0.0, 0.0, 1.0, 1.0])
            ax.set_axis_off()
            fig.add_axes(ax)

            ddf_scalers = np.linspace(0, 1, num=num_interval)

            frames = []
            for ddf_scaler in ddf_scalers:
                image = load_nifti_file(img_path)
                ddf = load_nifti_file(ddf_path)
                image = np.expand_dims(image, axis=0)
                ddf = np.expand_dims(ddf, axis=0) * ddf_scaler

                warped_image = warp_image_ddf(image=image, ddf=ddf, grid_ref=None)
                warped_image = np.squeeze(warped_image.numpy())

                frame = plt.imshow(
                    warped_image[:, :, slice_ind], aspect="auto", animated=True
                )

                frames.append([frame])

            anim = animation.ArtistAnimation(fig, frames, interval=interval)
            path_to_anim_save = os.path.join(
                save_path,
                os.path.split(img_path)[-1].split(".")[0]
                + "_slice_"
                + str(slice_ind)
                + ".gif",
            )

            anim.save(path_to_anim_save)
            print("Animation saved to:", path_to_anim_save)
Exemple #3
0
    def call(self, inputs, **kwargs) -> tf.Tensor:
        """
        :param inputs: (ddf, image)

          - ddf, shape = (batch, f_dim1, f_dim2, f_dim3, 3), dtype = float32
          - image, shape = (batch, m_dim1, m_dim2, m_dim3), dtype = float32
        :param kwargs: additional arguments.
        :return: shape = (batch, f_dim1, f_dim2, f_dim3)
        """
        return layer_util.warp_image_ddf(
            image=inputs[1], ddf=inputs[0], grid_ref=self.grid_ref
        )
Exemple #4
0
 def call(self, inputs, **kwargs):
     """
     wrap an image into a fixed size using ddf
     same functionality as transform of neuron
     https://github.com/adalca/neuron/blob/master/neuron/utils.py
     vol = image
     loc_shift = ddf
     :param inputs: [ddf, image]
                     ddf.shape = (batch, f_dim1, f_dim2, f_dim3, 3)
                     image.shape = (batch, m_dim1, m_dim2, m_dim3)
                     ddf.type = float32
                     image.type = float32
     :param kwargs:
     :return: shape = (batch, f_dim1, f_dim2, f_dim3)
     """
     return layer_util.warp_image_ddf(image=inputs[1],
                                      ddf=inputs[0],
                                      grid_ref=self.grid_ref)
Exemple #5
0
def warp(image_path: str, ddf_path: str, out_path: str):
    """
    :param image_path: file path of the image file
    :param ddf_path: file path of the ddf file
    :param out_path: file path of the output
    """
    if out_path == "":
        out_path = "warped.nii.gz"
        logging.warning(
            f"Output file path is not provided, will save output in {out_path}."
        )
    else:
        if not (out_path.endswith(".nii") or out_path.endswith(".nii.gz")):
            out_path = os.path.join(os.path.dirname(out_path), "warped.nii.gz")
            logging.warning(
                f"Output file path should end with .nii or .nii.gz, "
                f"will save output in {out_path}.")
        os.makedirs(os.path.dirname(out_path), exist_ok=True)

    # load image and ddf
    image = load_nifti_file(image_path)
    ddf = load_nifti_file(ddf_path)
    if len(image.shape) not in [3, 4]:
        raise ValueError(f"image shape must be (m_dim1, m_dim2, m_dim3) "
                         f"or (m_dim1, m_dim2, m_dim3, ch),"
                         f" got {image.shape}")
    if not (len(ddf.shape) == 4 and ddf.shape[-1] == 3):
        raise ValueError(
            f"ddf shape must be (f_dim1, f_dim2, f_dim3, 3), got {ddf.shape}")
    # add batch dimension manually
    image = tf.expand_dims(image, axis=0)
    ddf = tf.expand_dims(ddf, axis=0)

    # warp
    warped_image = warp_image_ddf(image=image, ddf=ddf, grid_ref=None)
    warped_image = warped_image.numpy()
    warped_image = warped_image[0, ...]  # removed added batch dimension

    # save output
    nib.save(img=nib.Nifti2Image(warped_image, affine=np.eye(4)),
             filename=out_path)
Exemple #6
0
def warp(image_path: str, ddf_path: str, out_path: str):
    """
    :param image_path: file path of the image file
    :param ddf_path: file path of the ddf file
    :param out_path: file path of the output
    """
    if out_path == "":
        out_path = "warped.nii.gz"
        logging.warning(
            f"Output file path is not provided, will save output in {out_path}."
        )
    else:
        if not (out_path.endswith(".nii") or out_path.endswith(".nii.gz")):
            out_path = os.path.join(os.path.dirname(out_path), "warped.nii.gz")
            logging.warning(
                f"Output file path should end with .nii or .nii.gz, "
                f"will save output in {out_path}."
            )
        os.makedirs(os.path.dirname(out_path), exist_ok=True)

    # load image and ddf
    image = load_nifti_file(image_path)
    ddf = load_nifti_file(ddf_path)
    shape_sanity_check(image=image, ddf=ddf)

    # add batch dimension manually
    image = tf.expand_dims(image, axis=0)
    ddf = tf.expand_dims(ddf, axis=0)

    # warp
    warped_image = warp_image_ddf(image=image, ddf=ddf, grid_ref=None)
    warped_image = warped_image.numpy()
    warped_image = warped_image[0, ...]  # removed added batch dimension

    # save output
    nib.save(img=nib.Nifti1Image(warped_image, affine=np.eye(4)), filename=out_path)