Exemple #1
0
def assert_compare_nifti(nifti_file_1, nifti_file_2):
    logging.info("%s %s" % (nifti_file_1, nifti_file_2))
    work_dir = tempfile.mkdtemp()
    try:
        tmp_nifti_file_1 = os.path.join(work_dir,
                                        os.path.basename(nifti_file_1))
        tmp_nifti_file_2 = os.path.join(work_dir,
                                        os.path.basename(nifti_file_2))
        image_reorientation.reorient_image(nifti_file_1, tmp_nifti_file_1)
        image_reorientation.reorient_image(nifti_file_2, tmp_nifti_file_2)
        nifti_1 = nibabel.load(tmp_nifti_file_1)
        nifti_2 = nibabel.load(tmp_nifti_file_2)

        # check the affine
        if not numpy.allclose(nifti_1.affine, nifti_2.affine):
            raise Exception('affine mismatch')

        # check the data
        if nifti_1.get_data_dtype() != nifti_2.get_data_dtype():
            raise Exception('dtype mismatch')
        if not numpy.allclose(get_nifti_data(nifti_1),
                              get_nifti_data(nifti_2),
                              rtol=0.01,
                              atol=1):
            difference = get_nifti_data(nifti_1) - get_nifti_data(nifti_2)
            raise Exception('data mismatch %s ' %
                            numpy.max(numpy.abs(difference)))

    except:
        shutil.rmtree(work_dir)
        raise
Exemple #2
0
 def __init__(self, nifti_image):
     self.nifti = nifti_image
     # assert that it is a 3D image
     self.nifti_data = get_nifti_data(self.nifti)
     assert self.nifti_data.squeeze().ndim >= 3
     # do some basic processing like setting dimensions and min/max values
     self.dimensions = self.nifti_data.shape
     self.axial_orientation = None
     self.coronal_orientation = None
     self.sagittal_orientation = None
     self.__calculate_slice_orientation__()
def _fix_diffusion_images(bvals, bvecs, nifti, nifti_file):
    """
    This function will remove the last timepoint from the nifti, bvals and bvecs if the last vector is 0,0,0
    This is sometimes added at the end by philips
    """
    # if all zero continue of if the last bvec is not all zero continue
    if numpy.count_nonzero(bvecs) == 0 or not numpy.count_nonzero(
            bvals[-1]) == 0:
        # nothing needs to be done here
        return nifti, bvals, bvecs
    # remove last elements from bvals and bvecs
    bvals = bvals[:-1]
    bvecs = bvecs[:-1]

    # remove last elements from the nifti
    new_nifti = nibabel.Nifti1Image(
        common.get_nifti_data(nifti)[:, :, :, :-1].squeeze(), nifti.affine)
    new_nifti.to_filename(nifti_file)

    return new_nifti, bvals, bvecs
Exemple #4
0
def resample_nifti_images(nifti_images, voxel_size=None):
    """
    In this function we will create an orthogonal image and resample the original images to this space

    In this calculation we work in 3 spaces / coordinate systems

    - original image coordinates
    - world coordinates
    - "projected" coordinates

    This last one is a new rotated "orthogonal" coordinates system in mm where
    x and y are perpendicular with the x and y or the image

    We do the following steps
    - calculate a new "projection" coordinate system
    - calculate the world coordinates of all corners of the image in world coordinates
    - project the world coordinates of the corners on the projection coordinate system
    - calculate the min and max corners to get the orthogonal bounding box of the image in projected space
    - translate the origin back to world coordinages

    We now have the new xyz axis, origin and size and can create the new affine used for resampling
    """

    # get the smallest voxelsize and use that
    if voxel_size is None:
        voxel_size = nifti_images[0].header.get_zooms()
        for nifti_image in nifti_images[1:]:
            voxel_size = numpy.minimum(voxel_size,
                                       nifti_image.header.get_zooms())

    x_axis_world = numpy.transpose(
        numpy.dot(nifti_images[0].affine, [[1], [0], [0], [0]]))[0, :3]
    y_axis_world = numpy.transpose(
        numpy.dot(nifti_images[0].affine, [[0], [1], [0], [0]]))[0, :3]
    x_axis_world /= numpy.linalg.norm(x_axis_world)  # normalization
    y_axis_world /= numpy.linalg.norm(y_axis_world)  # normalization
    z_axis_world = numpy.cross(y_axis_world, x_axis_world)
    z_axis_world /= numpy.linalg.norm(z_axis_world)  # calculate new z
    y_axis_world = numpy.cross(
        x_axis_world,
        z_axis_world)  # recalculate y in case x and y where not perpendicular
    y_axis_world /= numpy.linalg.norm(y_axis_world)

    points_world = []

    for nifti_image in nifti_images:
        original_size = nifti_image.shape

        points_image = [[0, 0, 0], [original_size[0] - 1, 0, 0],
                        [0, original_size[1] - 1, 0],
                        [original_size[0] - 1, original_size[1] - 1, 0],
                        [0, 0, original_size[2] - 1],
                        [original_size[0] - 1, 0, original_size[2] - 1],
                        [0, original_size[1] - 1, original_size[2] - 1],
                        [
                            original_size[0] - 1, original_size[1] - 1,
                            original_size[2] - 1
                        ]]

        for point in points_image:
            points_world.append(
                numpy.transpose(
                    numpy.dot(
                        nifti_image.affine,
                        [[point[0]], [point[1]], [point[2]], [1]]))[0, :3])

    projections = []
    for point in points_world:
        projection = [
            numpy.dot(point, x_axis_world),
            numpy.dot(point, y_axis_world),
            numpy.dot(point, z_axis_world)
        ]
        projections.append(projection)

    projections = numpy.array(projections)

    min_projected = numpy.amin(projections, axis=0)
    max_projected = numpy.amax(projections, axis=0)
    new_size_mm = max_projected - min_projected

    origin = min_projected[0] * x_axis_world + \
             min_projected[1] * y_axis_world + \
             min_projected[2] * z_axis_world

    new_voxelsize = voxel_size
    new_shape = numpy.ceil(new_size_mm / new_voxelsize).astype(numpy.int16) + 1

    new_affine = _create_affine(x_axis_world, y_axis_world, z_axis_world,
                                origin, voxel_size)

    # Resample each image
    combined_image_data = numpy.full(new_shape,
                                     settings.resample_padding,
                                     dtype=get_nifti_data(
                                         nifti_images[0]).dtype)
    for nifti_image in nifti_images:
        image_affine = nifti_image.affine
        combined_affine = numpy.linalg.inv(new_affine).dot(image_affine)
        matrix, offset = nibabel.affines.to_matvec(
            numpy.linalg.inv(combined_affine))
        resampled_image = scipy.ndimage.affine_transform(
            get_nifti_data(nifti_image),
            matrix=matrix,
            offset=offset,
            output_shape=new_shape,
            output=get_nifti_data(nifti_image).dtype,
            order=settings.resample_spline_interpolation_order,
            mode='constant',
            cval=settings.resample_padding,
            prefilter=False)
        combined_image_data[combined_image_data == settings.resample_padding] = \
            resampled_image[combined_image_data == settings.resample_padding]

    return nibabel.Nifti1Image(combined_image_data.squeeze(), new_affine)