Beispiel #1
0
    def _get_meta_dict(self, img) -> Dict:
        """
        Get all the meta data of the image and convert to dict type.

        Args:
            img: a ITK image object loaded from a image file.

        """
        img_meta_dict = img.GetMetaDataDictionary()
        meta_dict = {}
        for key in img_meta_dict.GetKeys():
            # ignore deprecated, legacy members that cause issues
            if key.startswith("ITK_original_"):
                continue
            if (key == "NRRD_measurement frame"
                    and int(itk.Version.GetITKMajorVersion()) == 5
                    and int(itk.Version.GetITKMinorVersion()) < 2):
                warnings.warn(
                    "Ignoring 'measurement frame' field. "
                    "Correct reading of NRRD05 files requires ITK >= 5.2: `pip install --upgrade --pre itk`"
                )
                continue
            meta_dict[key] = img_meta_dict[key]
        meta_dict["origin"] = np.asarray(img.GetOrigin())
        meta_dict["spacing"] = np.asarray(img.GetSpacing())
        meta_dict["direction"] = itk.array_from_matrix(img.GetDirection())
        return meta_dict
Beispiel #2
0
def imageStatistics(input=None, mask=None, resample=False, histogramBins=1000):

    if input is None:
        logger.error("Set an input")
        sys.exit(1)

    inputArray = itk.array_from_image(input)
    outputStats = {}
    outputStats["nbPixel"] = inputArray.size
    if not mask is None:
        if resample:
            mask = gt.applyTransformation(input=mask, like=input, force_resample=True)
        if not np.allclose(mask.GetSpacing(), input.GetSpacing()):
            logger.error("Input and mask do not have the same spacing")
            sys.exit(1)
        if not np.allclose(mask.GetOrigin(), input.GetOrigin()):
            logger.error("Input and mask do not have the same origin")
            sys.exit(1)
        if not np.allclose(itk.array_from_matrix(mask.GetDirection()), itk.array_from_matrix(input.GetDirection())):
            logger.error("Input and mask do not have the same direction")
            sys.exit(1)
        if not np.allclose(mask.GetLargestPossibleRegion().GetSize(),  input.GetLargestPossibleRegion().GetSize()):
            logger.error("Input and mask do not have the same size")
            sys.exit(1)

        maskArray = itk.array_from_image(mask)
        if len(np.where(maskArray > 1)[0]) >0:
            logger.error("The mask seems to be a non-binary image")
        index = np.where(maskArray == 1)
        outputStats["nbPixel"] = len(index[0])
        inputArray = inputArray[index]

    outputStats["minimum"] = np.amin(inputArray)
    outputStats["maximum"] = np.amax(inputArray)
    outputStats["sum"] = np.sum(inputArray)
    outputStats["median"] = np.median(inputArray)
    outputStats["mean"] = np.mean(outputStats["sum"]/outputStats["nbPixel"])
    outputStats["variance"] = np.var(inputArray)
    outputStats["sigma"] = np.sqrt(outputStats["variance"])
    outputStats["hist"] = np.histogram(inputArray, histogramBins)

    return outputStats
Beispiel #3
0
def resampling_transform(image, shape):
    
    imageType = itk.template(image)[0][itk.template(image)[1]]
    
    dummy_image = itk.image_from_array(np.zeros(tuple(reversed(shape)), dtype=itk.array_from_image(image).dtype))
    if len(shape) == 2:
        transformType = itk.MatrixOffsetTransformBase[itk.D, 2, 2]
    else:
        transformType = itk.VersorRigid3DTransform[itk.D]
    initType = itk.CenteredTransformInitializer[transformType, imageType, imageType]
    initializer = initType.New()
    initializer.SetFixedImage(dummy_image)
    initializer.SetMovingImage(image)
    transform = transformType.New()
    
    initializer.SetTransform(transform)
    initializer.InitializeTransform()
    
    if len(shape) == 3:
        transformType = itk.MatrixOffsetTransformBase[itk.D, 3, 3]
        t2 = transformType.New()
        t2.SetCenter(transform.GetCenter())
        t2.SetOffset(transform.GetOffset())
        transform = t2
    m = transform.GetMatrix()
    m_a = itk.array_from_matrix(m)
    
    input_shape = image.GetLargestPossibleRegion().GetSize()
    
    for i in range(len(shape)):
    
        m_a[i, i] = image.GetSpacing()[i] * (input_shape[i] / shape[i])
    
    m_a = itk.array_from_matrix(image.GetDirection()) @ m_a 
    
    transform.SetMatrix(itk.matrix_from_array(m_a))
    
    return transform
     
Beispiel #4
0
    def _get_meta_dict(self, img) -> Dict:
        """
        Get all the meta data of the image and convert to dict type.

        Args:
            img: a ITK image object loaded from a image file.

        """
        img_meta_dict = img.GetMetaDataDictionary()
        meta_dict = {}
        for key in img_meta_dict.GetKeys():
            # ignore deprecated, legacy members that cause issues
            if key.startswith("ITK_original_"):
                continue
            meta_dict[key] = img_meta_dict[key]
        meta_dict["origin"] = np.asarray(img.GetOrigin())
        meta_dict["spacing"] = np.asarray(img.GetSpacing())
        meta_dict["direction"] = itk.array_from_matrix(img.GetDirection())
        return meta_dict
Beispiel #5
0
    def _get_affine(self, img) -> np.ndarray:
        """
        Get or construct the affine matrix of the image, it can be used to correct
        spacing, orientation or execute spatial transforms.
        Construct Affine matrix based on direction, spacing, origin information.
        Refer to: https://github.com/RSIP-Vision/medio

        Args:
            img: a ITK image object loaded from a image file.

        """
        direction = itk.array_from_matrix(img.GetDirection())
        spacing = np.asarray(img.GetSpacing())
        origin = np.asarray(img.GetOrigin())

        direction = np.asarray(direction)
        affine = np.eye(direction.shape[0] + 1)
        affine[(slice(-1), slice(-1))] = direction @ np.diag(spacing)
        affine[(slice(-1), -1)] = origin
        return affine
Beispiel #6
0
def xarray_from_image(l_image):
    """Convert an itk.Image to an xarray.DataArray.

    Origin and spacing metadata is preserved in the xarray's coords. The
    Direction is set in the `direction` attribute.
    Dims are labeled as `x`, `y`, `z`, and `c`.

    This interface is and behavior is experimental and is subject to possible
    future changes."""
    import xarray as xr
    import itk
    import numpy as np

    array_view = itk.array_view_from_image(l_image)
    l_spacing = itk.spacing(l_image)
    l_origin = itk.origin(l_image)
    l_size = itk.size(l_image)
    direction = np.flip(itk.array_from_matrix(l_image.GetDirection()))
    spatial_dimension = l_image.GetImageDimension()

    spatial_dims = ("x", "y", "z")
    coords = {}
    for l_index, dim in enumerate(spatial_dims[:spatial_dimension]):
        coords[dim] = np.linspace(
            l_origin[l_index],
            l_origin[l_index] + (l_size[l_index] - 1) * l_spacing[l_index],
            l_size[l_index],
            dtype=np.float64,
        )

    dims = list(reversed(spatial_dims[:spatial_dimension]))
    components = l_image.GetNumberOfComponentsPerPixel()
    if components > 1:
        dims.append("c")
        coords["c"] = np.arange(components, dtype=np.uint64)

    data_array = xr.DataArray(array_view,
                              dims=dims,
                              coords=coords,
                              attrs={"direction": direction})
    return data_array
Beispiel #7
0
m_vnl.put(0, 0, 3)
assert m_vnl(0, 0) == 3
assert arr[0, 0] == 0
# ITK Matrix
arr = np.zeros([3, 3], float)
m_itk = itk.GetMatrixFromArray(arr)
# Test snake case function
m_itk = itk.matrix_from_array(arr)
m_itk.SetIdentity()
# Test that the numpy array has not changed,...
assert arr[0, 0] == 0
# but that the ITK matrix has the correct value.
assert m_itk(0, 0) == 1
arr2 = itk.GetArrayFromMatrix(m_itk)
# Check that snake case function also works
arr2 = itk.array_from_matrix(m_itk)
# Check that the new array has the new value.
assert arr2[0, 0] == 1
arr2[0, 0] = 2
# Change the array value,...
assert arr2[0, 0] == 2
# and make sure that the matrix hasn't changed.
assert m_itk(0, 0) == 1

# test .astype for itk.Image
numpyImage = np.random.randint(0, 256, (8, 12, 5)).astype(np.uint8)
image = itk.image_from_array(numpyImage, is_vector=False)
cast = image.astype(np.uint8)
assert cast == image
(input_image_template, (input_pixel_type,
                        input_image_dimension)) = itk.template(image)
Beispiel #8
0
    m_vnl = itk.GetVnlMatrixFromArray(arr)
    assert m_vnl(0,0) == 0
    m_vnl.put(0,0,3)
    assert m_vnl(0,0) == 3
    assert arr[0,0] == 0
    # ITK Matrix
    arr = np.zeros([3,3],float)
    m_itk = itk.GetMatrixFromArray(arr)
    # Test snake case function
    m_itk = itk.matrix_from_array(arr)
    m_itk.SetIdentity()
    # Test that the numpy array has not changed,...
    assert arr[0,0] == 0
    # but that the ITK matrix has the correct value.
    assert m_itk(0,0) == 1
    arr2 = itk.GetArrayFromMatrix(m_itk)
    # Check that snake case function also works
    arr2 = itk.array_from_matrix(m_itk)
    # Check that the new array has the new value.
    assert arr2[0,0] == 1
    arr2[0,0]=2
    # Change the array value,...
    assert arr2[0,0] == 2
    # and make sure that the matrix hasn't changed.
    assert m_itk(0,0) == 1

except ImportError:
    print("NumPy not imported. Skipping BridgeNumPy tests")
    # Numpy is not available, do not run the Bridge NumPy tests
    pass
Beispiel #9
0
m_vnl.put(0, 0, 3)
assert m_vnl(0, 0) == 3
assert arr[0, 0] == 0
# ITK Matrix
arr = np.zeros([3, 3], float)
m_itk = itk.GetMatrixFromArray(arr)
# Test snake case function
m_itk = itk.matrix_from_array(arr)
m_itk.SetIdentity()
# Test that the numpy array has not changed,...
assert arr[0, 0] == 0
# but that the ITK matrix has the correct value.
assert m_itk(0, 0) == 1
arr2 = itk.GetArrayFromMatrix(m_itk)
# Check that snake case function also works
arr2 = itk.array_from_matrix(m_itk)
# Check that the new array has the new value.
assert arr2[0, 0] == 1
arr2[0, 0] = 2
# Change the array value,...
assert arr2[0, 0] == 2
# and make sure that the matrix hasn't changed.
assert m_itk(0, 0) == 1
# Test __repr__
assert repr(m_itk) == "itkMatrixD33 ([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])"
# Test __array__
assert np.array_equal(np.asarray(m_itk), np.eye(3))
# Test array like input
arr3 = [[0., 0.], [0., 0.]]
m_itk = itk.matrix_from_array(arr3)
m_itk.SetIdentity()
def faf_register_planar_image(planar, spect):

    if planar.GetImageDimension() != 2:
        print("Planar image dimension (" + str(planar.GetImageDimension()) +
              ") is not 2")
        sys.exit(1)
    if spect.GetImageDimension() != 3:
        print("Planar image dimension (" + str(spect.GetImageDimension()) +
              ") is not 3")
        sys.exit(1)

    if not (itk.array_from_matrix(spect.GetDirection()) == np.eye(
            spect.GetImageDimension())).all():
        spect = gt.applyTransformation(input=spect, force_resample=True, pad=0)

    projectedSpect = image_projection.image_projection(spect, 1)
    flipFilter = itk.FlipImageFilter.New(Input=projectedSpect)
    flipFilter.SetFlipAxes((False, True))
    flipFilter.Update()
    projectedSpect = flipFilter.GetOutput()
    projectedSpect = gt.applyTransformation(input=projectedSpect,
                                            spacinglike=planar,
                                            force_resample=True,
                                            adaptive=True)

    minCorrelation = 10
    minCorrelationIndex = 0

    for i in range(projectedSpect.GetLargestPossibleRegion().GetSize()[1] +
                   planar.GetLargestPossibleRegion().GetSize()[1] - 1):
        newOrigin = itk.Vector[itk.D, 2]()
        newOrigin[0] = projectedSpect.GetOrigin()[0] + (
            projectedSpect.GetLargestPossibleRegion().GetSize()[0] -
            planar.GetLargestPossibleRegion().GetSize()[0]
        ) * projectedSpect.GetSpacing()[0] / 2.0
        newOrigin[1] = projectedSpect.GetOrigin()[1] - (
            planar.GetLargestPossibleRegion().GetSize()[1] - 1 -
            i) * projectedSpect.GetSpacing()[1]
        centeredPlanar = gt.applyTransformation(input=planar,
                                                neworigin=newOrigin)
        centredPlanarOriginInProjectedSpect = projectedSpect.TransformPhysicalPointToIndex(
            newOrigin)

        identityTransform = itk.IdentityTransform[itk.D, 2].New()
        identityTransform.SetIdentity()
        interpolator = itk.LinearInterpolateImageFunction[type(planar),
                                                          itk.D].New()

        smallRegion = itk.ImageRegion[2]()
        smallRegionSize = itk.Size[2]()
        smallRegionSize[0] = min(
            centeredPlanar.GetLargestPossibleRegion().GetSize()[0],
            projectedSpect.GetLargestPossibleRegion().GetSize()[0])
        smallRegionSize[1] = min(
            i + 1,
            projectedSpect.GetLargestPossibleRegion().GetSize()[1] +
            planar.GetLargestPossibleRegion().GetSize()[1] - 1 - i,
            projectedSpect.GetLargestPossibleRegion().GetSize()[1])
        smallRegion.SetSize(smallRegionSize)
        smallRegionIndex = itk.Index[2]()
        smallRegionIndex[0] = max(0, centredPlanarOriginInProjectedSpect[0])
        smallRegionIndex[1] = max(0, centredPlanarOriginInProjectedSpect[1])
        smallRegion.SetIndex(smallRegionIndex)

        miCoeffFilter = itk.MattesMutualInformationImageToImageMetric[
            type(planar), type(planar)].New()
        miCoeffFilter.SetMovingImage(centeredPlanar)
        miCoeffFilter.SetFixedImage(projectedSpect)
        miCoeffFilter.SetTransform(identityTransform)
        miCoeffFilter.SetInterpolator(interpolator)
        miCoeffFilter.SetFixedImageRegion(smallRegion)
        miCoeffFilter.UseAllPixelsOn()
        miCoeffFilter.SetNumberOfHistogramBins(50)
        miCoeffFilter.ReinitializeSeed()
        miCoeffFilter.Initialize()
        if miCoeffFilter.GetValue(
                identityTransform.GetParameters()) < minCorrelation:
            minCorrelation = miCoeffFilter.GetValue(
                identityTransform.GetParameters())
            minCorrelationIndex = i

    newOrigin = itk.Vector[itk.D, 2]()
    newOrigin[0] = projectedSpect.GetOrigin()[0] + (
        projectedSpect.GetLargestPossibleRegion().GetSize()[0] -
        planar.GetLargestPossibleRegion().GetSize()[0]
    ) * projectedSpect.GetSpacing()[0] / 2.0
    newOrigin[1] = projectedSpect.GetOrigin()[1] - (
        planar.GetLargestPossibleRegion().GetSize()[1] - 1 -
        minCorrelationIndex) * projectedSpect.GetSpacing()[1]
    centeredPlanar = gt.applyTransformation(input=planar, neworigin=newOrigin)

    return centeredPlanar
Beispiel #11
0
def faf_calibration(spect,
                    acgm,
                    injected_activity=1.0,
                    half_life=6.0067,
                    delta_time=1.0,
                    acquisition_duration=900,
                    verbose=False):

    if spect.GetImageDimension() != 3:
        print("spect image dimension (" + str(spect.GetImageDimension()) +
              ") is not 3")
        sys.exit(1)

    if acgm.GetImageDimension() != 2:
        print("acgm image dimension (" + str(acgm.GetImageDimension()) +
              ") is not 2")
        sys.exit(1)

    if not (itk.array_from_matrix(spect.GetDirection()) == np.eye(
            spect.GetImageDimension())).all():
        spect = gt.applyTransformation(input=spect, force_resample=True, pad=0)

    projectedSPECT = image_projection.image_projection(spect, 1)
    flipFilter = itk.FlipImageFilter.New(Input=projectedSPECT)
    flipFilter.SetFlipAxes((False, True))
    flipFilter.Update()
    projectedSPECT = flipFilter.GetOutput()
    projectedSPECT = gt.applyTransformation(input=projectedSPECT,
                                            like=acgm,
                                            force_resample=True)
    projectedSPECTArray = itk.array_from_image(projectedSPECT)
    acgmArray = itk.array_from_image(acgm)
    spectArray = itk.array_from_image(spect)

    lambdaDecay = np.log(2.0) / (half_life * 3600)
    A0 = injected_activity * np.exp(-lambdaDecay * delta_time * 3600)
    #integral = (1 - np.exp(-lambdaDecay*acquisition_duration))/lambdaDecay
    #integralActivity = A0*integral
    #volume = np.prod(np.array(spect.GetSpacing()))

    sumSPECT = np.sum(spectArray)
    sumACGM = np.sum(acgmArray)
    partialSumACGM = np.sum(acgmArray[projectedSPECTArray > 1])

    sensitivityFAF = sumSPECT / (A0 * partialSumACGM / sumACGM)

    if verbose:
        print("sum in SPECT (counts): " + str(sumSPECT))
        print("partial sum in ACGM (counts): " + str(partialSumACGM))
        print("sum in ACGM (counts): " + str(sumACGM))
        print("FAF: " + str(partialSumACGM / sumACGM))
        print("A0 at the beginning of the SPECT acquisition (MBq): " + str(A0))
        print("lambda decay (s-1): " + str(lambdaDecay))
        print("sensitivityFAF (counts/MBq): " + str(sensitivityFAF))
        #print("volume of SPECT (mm3): " + str(volume))
        #print("integral Activity (MBq.s): " + str(integralActivity))

    calibrationFactor = 1.0 / sensitivityFAF
    calibratedSpectArray = spectArray * calibrationFactor
    calibratedSpectImage = itk.image_from_array(calibratedSpectArray)
    calibratedSpectImage.CopyInformation(spect)

    return (calibratedSpectImage, calibrationFactor * 1000000)
Beispiel #12
0
# ==========================================================================
#
#   Copyright NumFOCUS
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0.txt
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# ==========================================================================*/

import itk
import numpy as np

Dimension = 2
PixelType = itk.UC
ImageType = itk.Image[PixelType, Dimension]
image = ImageType.New()

new_direction = np.rot90(np.eye(Dimension))
image.SetDirection(new_direction)
direction = itk.array_from_matrix(image.GetDirection())
assert np.array_equal(new_direction, direction)
Beispiel #13
0
def stitch_image(image1, image2, dimension=2, pad=0):

    Dimension = image1.GetImageDimension()
    if image2.GetImageDimension() != Dimension:
        print("Image1 dimension (" + str(Dimension) +
              ") and Image2 dimension (" + str(image2.GetImageDimension()) +
              ") are different")
        sys.exit(1)

    #Check negative spacing or non identity direction
    if not (itk.array_from_matrix(image1.GetDirection())
            == np.eye(Dimension)).all():
        image1 = gt.applyTransformation(input=image1,
                                        force_resample=True,
                                        pad=pad)
    if not (itk.array_from_matrix(image2.GetDirection())
            == np.eye(Dimension)).all():
        image2 = gt.applyTransformation(input=image2,
                                        force_resample=True,
                                        pad=pad)

    #Determine the FOV1image and FOV2image
    if image1.GetOrigin()[dimension] > image2.GetOrigin()[dimension]:
        FOV1image = image2
        FOV2image = image1
    else:
        FOV1image = image1
        FOV2image = image2

    #Determine dimension for resampled FOV2
    lowFOV2index = itk.ContinuousIndex[itk.D, Dimension]()
    for i in range(Dimension):
        lowFOV2index[i] = -0.5
    lowFOV2point = FOV2image.TransformContinuousIndexToPhysicalPoint(
        lowFOV2index)
    lowFOV2index = FOV1image.TransformPhysicalPointToIndex(lowFOV2point)
    lowFOV2point = FOV1image.TransformIndexToPhysicalPoint(lowFOV2index)
    highFOV2index = itk.ContinuousIndex[itk.D, Dimension]()
    for i in range(Dimension):
        highFOV2index[i] = FOV2image.GetLargestPossibleRegion().GetSize(
        )[i] - 0.5
    highFOV2point = FOV2image.TransformContinuousIndexToPhysicalPoint(
        highFOV2index)
    highFOV2index = FOV1image.TransformPhysicalPointToIndex(highFOV2point)
    newFOV2Origin = [0] * Dimension
    for i in range(Dimension):
        newFOV2Origin[i] = FOV1image.GetOrigin()[i]
    newFOV2Origin[dimension] = lowFOV2point[dimension]
    newFOV2Size = [0] * Dimension
    for i in range(Dimension):
        newFOV2Size[i] = FOV1image.GetLargestPossibleRegion().GetSize()[i]
    newFOV2Size[
        dimension] = highFOV2index[dimension] - lowFOV2index[dimension] + 1

    #Resample FOV2image to be aligned with FOV1image
    resampledFOV2image = gt.applyTransformation(input=FOV2image,
                                                spacinglike=FOV1image,
                                                newsize=newFOV2Size,
                                                neworigin=newFOV2Origin,
                                                force_resample=True,
                                                pad=pad)

    #Determine size of the output
    outputLastIndex = itk.Index[Dimension]()
    for i in range(Dimension):
        outputLastIndex[i] = resampledFOV2image.GetLargestPossibleRegion(
        ).GetSize()[i] - 1
    outputLastPoint = resampledFOV2image.TransformIndexToPhysicalPoint(
        outputLastIndex)
    outputLastIndex = FOV1image.TransformPhysicalPointToIndex(outputLastPoint)
    outputSize = itk.Size[Dimension]()
    for i in range(Dimension):
        outputSize[i] = FOV1image.GetLargestPossibleRegion().GetSize()[i]
    outputSize[dimension] = outputLastIndex[dimension] + 1

    #Create output
    ImageType = itk.Image[itk.template(image1)[1][0], Dimension]
    outputImage = ImageType.New()
    outputStart = itk.Index[Dimension]()
    for i in range(Dimension):
        outputStart[i] = 0
    outputRegion = itk.ImageRegion[Dimension]()
    outputRegion.SetSize(outputSize)
    outputRegion.SetIndex(outputStart)
    outputImage.SetRegions(outputRegion)
    outputImage.Allocate()
    outputImage.FillBuffer(pad)
    outputImage.SetSpacing(FOV1image.GetSpacing())
    outputImage.SetDirection(FOV1image.GetDirection())
    outputImage.SetOrigin(FOV1image.GetOrigin())

    #Fill the output with resampledFOV2image to begin
    outputArrayView = itk.array_view_from_image(outputImage)
    resampledFOV2ArrayView = itk.array_view_from_image(resampledFOV2image)
    FOV1ArrayView = itk.array_view_from_image(FOV1image)
    outputBeginFOV2Index = itk.Index[Dimension]()
    for i in range(Dimension):
        outputBeginFOV2Index[i] = 0
    outputBeginFOV2Point = resampledFOV2image.TransformIndexToPhysicalPoint(
        outputBeginFOV2Index)
    outputBeginFOV2Index = outputImage.TransformPhysicalPointToIndex(
        outputBeginFOV2Point)
    outputArrayView[outputBeginFOV2Index[2]:, outputBeginFOV2Index[1]:,
                    outputBeginFOV2Index[0]:] = resampledFOV2ArrayView[:]

    #Fill the output with FOV1image where it's superior to current output (to avoid artifact)
    outputEndFOV1Index = itk.Index[Dimension]()
    for i in range(Dimension):
        outputEndFOV1Index[i] = FOV1image.GetLargestPossibleRegion().GetSize(
        )[i]
    outputArrayView[np.where(
        FOV1ArrayView >
        outputArrayView[:outputEndFOV1Index[2], :outputEndFOV1Index[1], :
                        outputEndFOV1Index[0]]
    )] = FOV1ArrayView[np.where(
        FOV1ArrayView >
        outputArrayView[:outputEndFOV1Index[2], :outputEndFOV1Index[1], :
                        outputEndFOV1Index[0]])]
    return outputImage
Beispiel #14
0
def applyTransformation(input=None,
                        like=None,
                        spacinglike=None,
                        matrix=None,
                        newsize=None,
                        neworigin=None,
                        newspacing=None,
                        newdirection=None,
                        force_resample=None,
                        keep_original_canvas=None,
                        adaptive=None,
                        rotation=None,
                        rotation_center=None,
                        translation=None,
                        pad=None,
                        interpolation_mode=None,
                        bspline_order=2):

    if like is not None and spacinglike is not None:
        logger.error("Choose between like and spacinglike options")
        sys.exit(1)
    if newspacing is not None and spacinglike is not None:
        logger.error("Choose between newspacing and spacinglike options")
        sys.exit(1)

    if force_resample is None:
        force_resample = False
    if keep_original_canvas is None:
        keep_original_canvas = False
    if force_resample and keep_original_canvas:
        logger.error(
            "Choose between force_resample and keep_original_canvas options")
        sys.exit(1)
    if adaptive is None:
        adaptive = False
    if adaptive and not force_resample:
        logger.error(
            "Be sure to activate force_resample flag with adaptive flag")
        sys.exit(1)

    if force_resample and adaptive and (newspacing is not None or spacinglike
                                        is not None) and newsize is not None:
        logger.error(
            "With adaptive flag, choose between spacing and size options")
        sys.exit(1)
    imageDimension = input.GetImageDimension()
    if newsize is None:
        newsize = input.GetLargestPossibleRegion().GetSize()
    if len(newsize) != imageDimension:
        logger.error("Size of newsize is not correct (" + str(imageDimension) +
                     "): " + str(newsize))
        sys.exit(1)
    if newspacing is None:
        newspacing = input.GetSpacing()
    if len(newspacing) != imageDimension:
        logger.error("Size of newspacing is not correct (" +
                     str(imageDimension) + "): " + str(newspacing))
        sys.exit(1)
    if newdirection is None:
        newdirection = input.GetDirection()
    if newdirection.GetVnlMatrix().columns(
    ) != imageDimension or newdirection.GetVnlMatrix().rows(
    ) != imageDimension:
        logger.error("Size of newdirection is not correct (" +
                     str(imageDimension) + "): " + str(newdirection))
        sys.exit(1)

    if like is not None:
        if like.GetImageDimension() != imageDimension:
            logger.error(
                "Like image does not have the same dimension than input")
            sys.exit(1)
        newsize = like.GetLargestPossibleRegion().GetSize()
        neworigin = like.GetOrigin()
        newspacing = like.GetSpacing()
        newdirection = like.GetDirection()
    if spacinglike is not None:
        if spacinglike.GetImageDimension() != imageDimension:
            logger.error(
                "Spacinglike image does not have the same dimension than input"
            )
            sys.exit(1)
        newspacing = spacinglike.GetSpacing()

    if pad is None:
        pad = 0.0
    if interpolation_mode is None:
        interpolation_mode: "linear"

    if not force_resample and not keep_original_canvas:
        if neworigin is None:
            neworigin = input.GetOrigin()
        changeInfoFilter = itk.ChangeInformationImageFilter.New(Input=input)
        changeInfoFilter.SetOutputSpacing(newspacing)
        changeInfoFilter.SetOutputOrigin(neworigin)
        changeInfoFilter.SetOutputDirection(newdirection)
        changeInfoFilter.ChangeSpacingOn()
        changeInfoFilter.ChangeOriginOn()
        changeInfoFilter.ChangeDirectionOn()
        changeInfoFilter.Update()
        return changeInfoFilter.GetOutput()

    centerImageIndex = itk.ContinuousIndex[itk.D, imageDimension]()
    for i in range(imageDimension):
        centerImageIndex[i] = (input.GetLargestPossibleRegion().GetSize()[i] -
                               1) / 2.0
    centerImagePoint = input.TransformContinuousIndexToPhysicalPoint(
        centerImageIndex)
    centerImageArray = [0] * imageDimension
    for i in range(imageDimension):
        centerImageArray[i] = centerImagePoint[i]
    if rotation_center is None:
        rotation_center = np.zeros(imageDimension)
        for i in range(imageDimension):
            rotation_center[i] = centerImagePoint[i]
    if len(rotation_center) != imageDimension:
        logger.error("Size of rotation_center is not correct (" +
                     str(imageDimension) + "): " + str(rotation_center))
        sys.exit(1)

    rotationMatrix = []
    translationMatrix = []
    if not matrix is None:
        if not rotation is None or not translation is None:
            logger.error(
                "Choose between matrix or rotation/translation, not both")
            sys.exit(1)
        if matrix.GetVnlMatrix().columns(
        ) != imageDimension + 1 or matrix.GetVnlMatrix().rows(
        ) != imageDimension + 1:
            logger.error("Size of matrix transformation is not correct (" +
                         str(imageDimension + 1) + "): " + str(matrix))
            sys.exit(1)
        if matrix.GetVnlMatrix().columns() == 3 or matrix.GetVnlMatrix(
        ).columns() == 4:
            rotationMatrix = itk.matrix_from_array(
                itk.array_from_matrix(matrix)
                [:imageDimension, :imageDimension])
        else:
            logger.error("We can transform only 2D and 3D images")
            sys.exit(1)
    else:
        if imageDimension == 2:
            if rotation is None:
                rotation = [0]
            if len(rotation) != 1:
                logger.error("Size of rotation is not correct (1): " +
                             str(rotation))
                sys.exit(1)
        elif imageDimension == 3:
            if rotation is None:
                rotation = [0] * imageDimension
            if len(rotation) != imageDimension:
                logger.error("Size of rotation is not correct (3): " +
                             str(rotation))
                sys.exit(1)
        if translation is None:
            translation = [0] * imageDimension
        if len(translation) != imageDimension:
            logger.error("Size of translation is not correct (" +
                         str(imageDimension) + "): " + str(translation))
            sys.exit(1)
        if imageDimension == 2:
            euler = itk.Euler2DTransform[itk.D].New()
            euler.SetRotation(rotation[0] * math.pi / 180.0)
            rotationMatrix = euler.GetMatrix()
        elif imageDimension == 3:
            euler = itk.Euler3DTransform[itk.D].New()
            euler.SetRotation(rotation[0] * math.pi / 180.0,
                              rotation[1] * math.pi / 180.0,
                              rotation[2] * math.pi / 180.0)
            rotationMatrix = euler.GetMatrix()
        else:
            logger.error("We can transform only 2D and 3D images")
            sys.exit(1)

    transform = itk.AffineTransform[itk.D, imageDimension].New()
    transform.SetCenter([0] * imageDimension)
    transform.SetTranslation([0] * imageDimension)
    transform.SetMatrix(rotationMatrix)
    inverseTransform = itk.AffineTransform[itk.D, imageDimension].New()
    transform.GetInverse(inverseTransform)
    if not matrix is None:
        translation = itk.array_from_matrix(
            matrix
        )[:imageDimension,
          imageDimension] - rotation_center + rotationMatrix * rotation_center
    translationMatrix = inverseTransform.GetMatrix() * (
        centerImageArray - rotation_center) - (
            centerImageArray -
            rotation_center) - inverseTransform.GetMatrix() * translation

    inputOrigin = itk.Point[itk.D, imageDimension]()
    for i in range(imageDimension):
        inputOrigin[i] = input.GetOrigin()[i]
    preTranslateFilter = itk.ChangeInformationImageFilter.New(Input=input)
    preTranslateFilter.CenterImageOn()
    preTranslateFilter.Update()

    cornersIndex = [
        itk.ContinuousIndex[itk.D, imageDimension]()
        for i in range(2**imageDimension)
    ]
    if imageDimension == 2 or imageDimension == 3:
        cornersIndex[0][0] = -0.5
        cornersIndex[0][1] = -0.5
        if imageDimension == 3:
            cornersIndex[0][2] = -0.5
        cornersIndex[1][0] = input.GetLargestPossibleRegion().GetSize(
        )[0] - 0.5
        cornersIndex[1][1] = cornersIndex[0][1]
        if imageDimension == 3:
            cornersIndex[1][2] = cornersIndex[0][2]
        cornersIndex[2][0] = cornersIndex[0][0]
        cornersIndex[2][1] = input.GetLargestPossibleRegion().GetSize(
        )[1] - 0.5
        if imageDimension == 3:
            cornersIndex[2][2] = cornersIndex[0][2]
        cornersIndex[3][0] = cornersIndex[1][0]
        cornersIndex[3][1] = cornersIndex[2][1]
        if imageDimension == 3:
            cornersIndex[3][2] = cornersIndex[0][2]
        if imageDimension == 3:
            cornersIndex[4][0] = cornersIndex[0][0]
            cornersIndex[4][1] = cornersIndex[0][1]
            cornersIndex[4][2] = input.GetLargestPossibleRegion().GetSize(
            )[2] - 0.5
            cornersIndex[5][0] = cornersIndex[1][0]
            cornersIndex[5][1] = cornersIndex[0][1]
            cornersIndex[5][2] = cornersIndex[4][2]
            cornersIndex[6][0] = cornersIndex[0][0]
            cornersIndex[6][1] = cornersIndex[2][1]
            cornersIndex[6][2] = cornersIndex[4][2]
            cornersIndex[7][0] = cornersIndex[1][0]
            cornersIndex[7][1] = cornersIndex[2][1]
            cornersIndex[7][2] = cornersIndex[4][2]
        outputCorners = np.zeros((2**imageDimension, imageDimension))
        for i in range(2**imageDimension):
            outputCorners[i, :] = inverseTransform.GetMatrix(
            ) * preTranslateFilter.GetOutput(
            ).TransformContinuousIndexToPhysicalPoint(cornersIndex[i])
        minOutputCorner = np.zeros(imageDimension)
        maxOutputCorner = np.zeros(imageDimension)

        for i in range(imageDimension):
            minOutputCorner[i] = min(outputCorners[:, i])
            maxOutputCorner[i] = max(outputCorners[:, i])
        temp = minOutputCorner + 0.5 * itk.array_from_vnl_vector(
            newspacing.GetVnlVector())
        originAfterRotation = itk.Point[itk.D, imageDimension]()
        for i in range(imageDimension):
            originAfterRotation[i] = temp[i]
        temp = (maxOutputCorner - minOutputCorner) / itk.array_from_vnl_vector(
            newspacing.GetVnlVector())
        sizeAfterRotation = itk.Size[imageDimension]()
        for i in range(imageDimension):
            sizeAfterRotation[i] = int(math.ceil(temp[i]))
    else:
        logger.error("We can transform only 2D and 3D images")
        sys.exit(1)

    tempImageType = itk.Image[itk.F, imageDimension]
    castImageFilter = itk.CastImageFilter[type(input), tempImageType].New()
    castImageFilter.SetInput(preTranslateFilter.GetOutput())
    castImageFilter.Update()

    resampleFilter = itk.ResampleImageFilter.New(
        Input=castImageFilter.GetOutput())
    resampleFilter.SetOutputSpacing(newspacing)
    resampleFilter.SetOutputOrigin(originAfterRotation)
    resampleDirection = itk.matrix_from_array(np.eye(imageDimension))
    resampleFilter.SetOutputDirection(resampleDirection)
    resampleFilter.SetSize(sizeAfterRotation)
    resampleFilter.SetTransform(transform)
    if interpolation_mode == "NN":
        interpolator = itk.NearestNeighborInterpolateImageFunction[
            tempImageType, itk.D].New()
    elif interpolation_mode == "BSpline":
        interpolator = itk.BSplineInterpolateImageFunction[tempImageType,
                                                           itk.D, itk.F].New()
        interpolator.SetSplineOrder(bspline_order)
    else:
        interpolator = itk.LinearInterpolateImageFunction[tempImageType,
                                                          itk.D].New()
    resampleFilter.SetInterpolator(interpolator)
    resampleFilter.SetDefaultPixelValue(pad)
    resampleFilter.Update()

    postTranslateFilter = itk.ChangeInformationImageFilter.New(
        Input=resampleFilter.GetOutput())
    postTranslateFilter.SetOutputOrigin(originAfterRotation +
                                        centerImagePoint + translationMatrix)
    postTranslateFilter.ChangeOriginOn()
    postTranslateFilter.Update()

    if neworigin is None and not (itk.array_from_matrix(input.GetDirection())
                                  == np.eye(imageDimension)).all():
        neworigin = postTranslateFilter.GetOutput().GetOrigin()
    elif neworigin is None:
        neworigin = inputOrigin
    if len(neworigin) != imageDimension:
        logger.error("Size of neworigin is not correct (" +
                     str(imageDimension) + "): " + str(neworigin))
        sys.exit(1)

    if force_resample and adaptive:
        if (np.array(newspacing) == np.array(input.GetSpacing())).all():
            temp = np.array(sizeAfterRotation) * itk.array_from_vnl_vector(
                newspacing.GetVnlVector()) / np.array(newsize)
            newspacing = itk.Vector[itk.D, imageDimension]()
            for i in range(imageDimension):
                newspacing[i] = temp[i]
        else:
            newsize = itk.Size[imageDimension]()
            for i in range(imageDimension):
                newsize[i] = sizeAfterRotation[i]

    identityTransform = itk.AffineTransform[itk.D, imageDimension].New()
    resampleFilterCanvas = itk.ResampleImageFilter.New(
        Input=postTranslateFilter.GetOutput())
    resampleFilterCanvas.SetOutputSpacing(newspacing)
    resampleFilterCanvas.SetOutputOrigin(neworigin)
    resampleFilterCanvas.SetOutputDirection(resampleDirection)
    resampleFilterCanvas.SetSize(newsize)
    resampleFilterCanvas.SetTransform(identityTransform)
    if interpolation_mode == "NN":
        interpolator = itk.NearestNeighborInterpolateImageFunction[
            tempImageType, itk.D].New()
    else:
        interpolator = itk.LinearInterpolateImageFunction[tempImageType,
                                                          itk.D].New()
    resampleFilterCanvas.SetInterpolator(interpolator)
    resampleFilterCanvas.SetDefaultPixelValue(pad)
    resampleFilterCanvas.Update()

    castImageFilter2 = itk.CastImageFilter[tempImageType, type(input)].New()
    castImageFilter2.SetInput(resampleFilterCanvas.GetOutput())
    castImageFilter2.Update()

    return castImageFilter2.GetOutput()
Beispiel #15
0
# Do NumPy stuff...

# Convert back to ITK, view only, data is not copied
itk_np_view = itk.image_view_from_array(np_copy)

# Convert back to ITK, data is copied
itk_np_copy = itk.image_from_array(np_copy)

# Save result
itk.imwrite(itk_np_view, output_filename)

# VNL matrix from array
arr = np.zeros([3, 3], np.uint8)
matrix = itk.vnl_matrix_from_array(arr)

# Array from VNL matrix
arr = itk.array_from_vnl_matrix(matrix)

# VNL vector from array
vec = np.zeros([3], np.uint8)
vnl_vector = itk.vnl_vector_from_array(vec)

# Array from VNL vector
vec = itk.array_from_vnl_vector(vnl_vector)

# itk.Matrix from array
mat = itk.matrix_from_array(np.eye(3))

# array from itk.Matrix
arr = itk.array_from_matrix(mat)