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
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
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
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
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
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
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)
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
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
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)
# ========================================================================== # # 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)
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
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()
# 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)