Module pymskt.image.main
Expand source code
from typing import Optional
import os
import vtk
import SimpleITK as sitk
import numpy as np
from vtk.util.numpy_support import numpy_to_vtk
def set_vtk_image_origin(vtk_image, new_origin=(0, 0, 0)):
"""
Reset the origin of a `vtk_image`
Parameters
----------
vtk_image : vtk.image
VTK image that we want to change the origin of.
new_origin : tuple, optional
New origin to asign to `vtk_image`, by default (0, 0, 0)
Returns
-------
vtk.Filter
End of VTK filter pipeline after applying origin change.
"""
change_origin = vtk.vtkImageChangeInformation()
change_origin.SetInputConnection(vtk_image.GetOutputPort())
change_origin.SetOutputOrigin(new_origin)
change_origin.Update()
return change_origin
def read_nrrd(path, set_origin_zero=False):
"""
Read NRRD image file into vtk. Enables usage of marching cubes
and other functions that work on image data.
Parameters
----------
path : str
Path to `.nrrd` medical image to read in.
set_origin_zero : bool, optional
Bool to determine if origin should be set to zeros, by default False
Returns
-------
vtk.Filter
End of VTK filter pipeline.
"""
image_reader = vtk.vtkNrrdReader()
image_reader.SetFileName(path)
image_reader.Update()
if set_origin_zero is True:
change_origin = set_vtk_image_origin(image_reader, new_origin=(0, 0, 0))
return change_origin
elif set_origin_zero is False:
return image_reader
def set_seg_border_to_zeros(seg_image,
border_size=1):
"""
Utility function to ensure that all segmentations are "closed" after marching cubes.
If the segmentation extends to the edges of the image then the surface wont be closed
at the places it touches the edges.
Parameters
----------
seg_image : SimpleITK.Image
Image of a segmentation.
border_size : int, optional
The size of the border to set around the edges of the 3D image, by default 1
Returns
-------
SimpleITK.Image
The image with border set to 0 (background).
"""
seg_array = sitk.GetArrayFromImage(seg_image)
new_seg_array = np.zeros_like(seg_array)
new_seg_array[border_size:-border_size, border_size:-border_size, border_size:-border_size] = seg_array[border_size:-border_size, border_size:-border_size, border_size:-border_size]
new_seg_image = sitk.GetImageFromArray(new_seg_array)
new_seg_image.CopyInformation(seg_image)
return new_seg_image
def smooth_image(image, label_idx, variance=1.0):
"""
Smooth a single label in a SimpleITK image. Used as pre-processing for
bones/cartilage before applying marching cubes. Helps obtain smooth surfaces.
Parameters
----------
image : SimpleITK.Image
Image to be smoothed.
label_idx : int
Integer of the tissue of interest to be smoothed in the image.
variance : float, optional
The size of the smoothing, by default 1.0
Returns
-------
SimpleITK.Image
Image of only the label (tissue) of interest after being smoothed.
"""
new_image = binarize_segmentation_image(image, label_idx)
new_image = sitk.Cast(new_image, sitk.sitkFloat32)
gauss_filter = sitk.DiscreteGaussianImageFilter()
gauss_filter.SetVariance(variance)
# gauss_filter.SetUseImageSpacingOn
gauss_filter.SetUseImageSpacing(True)
filtered_new_image = gauss_filter.Execute(new_image)
return filtered_new_image
def binarize_segmentation_image(seg_image, label_idx):
"""
Return segmentation that is only 0s/1s, with 1s where label_idx is
located in the image.
Parameters
----------
seg_image : SimpleITK.Image
Segmentation image that contains data we want to binarize
label_idx : int
Integer/label that we want to extract (binarize) from the
`seg_image`.
Returns
-------
SimpleITK.Image
New segmentation image that is binarized.
"""
array = sitk.GetArrayFromImage(seg_image)
array_ = np.zeros_like(array)
array_[array == label_idx] = 1
new_seg_image = sitk.GetImageFromArray(array_)
new_seg_image.CopyInformation(seg_image)
return new_seg_image
def crop_bone_based_on_width(seg_image,
bone_idx,
np_med_lat_axis=0,
np_inf_sup_axis=1,
bone_crop_distal=True,
value_to_reassign=0,
percent_width_to_crop_height=1.0):
"""
Crop the bone labelmap of a SimpleITK.Image so that it is proportional to the
bones medial/lateral width.
Parameters
----------
seg_image : SimpleITK.Image
Image to be cropped.
bone_idx : int
Label_index of the bone to be cropped.
np_med_lat_axis : int, optional
Medial/lateral axis, by default 0
np_inf_sup_axis : int, optional
Inferior/superir axis, by default 1
bone_crop_distal : bool, optional
Boolean of cropping should occur distal or proximally, by default True
value_to_reassign : int, optional
Value to replace bone label with, by default 0
percent_width_to_crop_height : float, optional
Bone length as a proportion of width, by default 1.0
Returns
-------
SimpleITK.Image
Image after bone is cropped as a proportion of the bone's width.
"""
seg_array = sitk.GetArrayFromImage(seg_image)
loc_bone = np.where(seg_array == bone_idx)
med_lat_width_bone_mm = (np.max(loc_bone[np_med_lat_axis]) - np.min(loc_bone[np_med_lat_axis])) * \
seg_image.GetSpacing()[::-1][np_med_lat_axis]
inf_sup_crop_in_pixels = (med_lat_width_bone_mm / seg_image.GetSpacing()[::-1][
np_inf_sup_axis]) * percent_width_to_crop_height
if bone_crop_distal is True:
bone_distal_idx = np.max(loc_bone[np_inf_sup_axis])
bone_proximal_idx = bone_distal_idx - inf_sup_crop_in_pixels
if bone_proximal_idx < 1:
bone_proximal_idx = 1
elif bone_crop_distal is False:
bone_proximal_idx = np.min(loc_bone[np_inf_sup_axis])
bone_distal_idx = bone_proximal_idx + inf_sup_crop_in_pixels
if bone_distal_idx > seg_array.shape[np_inf_sup_axis]:
bone_distal_idx = seg_array.shape[np_inf_sup_axis] - 1
max_inf_sup_idx = max(bone_distal_idx, bone_proximal_idx)
min_inf_sup_idx = min(bone_distal_idx, bone_proximal_idx)
idx_bone_to_keep = np.where(
(loc_bone[np_inf_sup_axis] > min_inf_sup_idx) & (loc_bone[np_inf_sup_axis] < max_inf_sup_idx))
loc_bone_to_remove = tuple([np.delete(x, idx_bone_to_keep) for x in loc_bone])
seg_array[loc_bone_to_remove] = value_to_reassign
new_seg_image = sitk.GetImageFromArray(seg_array)
new_seg_image.CopyInformation(seg_image)
return new_seg_image
def apply_transform_retain_array(image, transform, interpolator=sitk.sitkNearestNeighbor):
"""
This function will move the actual image in space but keep the underlying array the same.
So, in x/y/z land the pixels are in a new location, but the actual underlying data array
is the same.
Parameters
----------
image : SimpleITK.Image
Image to be transformed.
transform : SimpleITK.Transform
Transform to apply
interpolator : SimpleITK.Interpolator, optional
Interpolator type to use, by default sitk.sitkNearestNeighbor
Returns
-------
SimpleITK.Image
New image after applying the appropriate transform.
Notes
-----
I have a feeling that this is overkill.
"""
inverse_transform = transform.GetInverse()
new_origin = inverse_transform.TransformPoint(image.GetOrigin())
new_x = inverse_transform.TransformPoint(image.TransformIndexToPhysicalPoint((image.GetSize()[0], 0, 0)))
new_y = inverse_transform.TransformPoint(image.TransformIndexToPhysicalPoint((0, image.GetSize()[1], 0)))
new_z = inverse_transform.TransformPoint(image.TransformIndexToPhysicalPoint((0, 0, image.GetSize()[2])))
# Create x-axis vector
new_x_vector = np.asarray(new_x) - np.asarray(new_origin)
new_x_vector /= np.sqrt(np.sum(np.square(new_x_vector)))
# Create y-axis vector
new_y_vector = np.asarray(new_y) - np.asarray(new_origin)
new_y_vector /= np.sqrt(np.sum(np.square(new_y_vector)))
# Create z-axis vector
new_z_vector = np.asarray(new_z) - np.asarray(new_origin)
new_z_vector /= np.sqrt(np.sum(np.square(new_z_vector)))
# New image size (shape)
new_size = image.GetSize()
# New image spacing
new_spacing = image.GetSpacing()
# Create 3x3 transformation matrix from the x/y/z unit vectors.
new_three_by_three = np.zeros((3,3))
new_three_by_three[:,0] = new_x_vector
new_three_by_three[:,1] = new_y_vector
new_three_by_three[:,2] = new_z_vector
new_image = sitk.Resample(image,
new_size,
transform,
interpolator,
new_origin,
new_spacing,
new_three_by_three.flatten().tolist())
return new_image
def create_vtk_image(
origin: Optional[int] = [0, 0, 0],
dimensions: Optional[list] = [20, 20, 20],
spacing: Optional[float] = [1., 1., 1.],
scalar: Optional[float] = 20.,
data: Optional[np.ndarray] = None
):
"""
Function to create a 3D vtkimage from a numpy array
OR to create a uniform image (all same value)
Parameters
----------
origin : Optional[int], optional
X/Y/Z origin of the image, by default [0, 0, 0]
dimensions : Optional[list], optional
Size of the image along each dimension, by default [20, 20, 20]
spacing : Optional[float], optional
Image spacing along each dimension, by default [1., 1., 1.]
scalar : Optional[float], optional
Scalar value to use for a uniform image, by default 20.
data : Optional[np.ndarray], optional
Data for a non-uniform image, by default None
"""
if data is None:
data = np.ones(dimensions) * scalar
else:
if len(data.shape) == 3:
dimensions = data.shape
else:
dimensions = [1, 1, 1]
for idx, dim_size in enumerate(data.shape):
dimensions[idx] = dim_size
vtk_array = numpy_to_vtk(data.flatten(order='F'))
vtk_array.SetName('test')
# points = vtk.vtkDoubleArray()
# points.SetName('test')
# points.SetNumberOfComponents(1)
# points.SetNumberOfTuples(np.product(dimensions))
# for x in range(dimensions[0]):
# for y in range(dimensions[1]):
# for z in range(dimensions[2]):
# points.SetValue(
# (z * dimensions[0] * dimensions[1]) + (x * dimensions[1]) + y,
# array[x, y, z]
# )
vtk_image = vtk.vtkImageData()
vtk_image.SetOrigin(*origin)
vtk_image.SetDimensions(*dimensions)
vtk_image.SetSpacing(*spacing)
vtk_image.GetPointData().SetScalars(vtk_array)
#
return vtk_image
Functions
def apply_transform_retain_array(image, transform, interpolator=1)
-
This function will move the actual image in space but keep the underlying array the same. So, in x/y/z land the pixels are in a new location, but the actual underlying data array is the same.
Parameters
image
:SimpleITK.Image
- Image to be transformed.
transform
:SimpleITK.Transform
- Transform to apply
interpolator
:SimpleITK.Interpolator
, optional- Interpolator type to use, by default sitk.sitkNearestNeighbor
Returns
SimpleITK.Image
- New image after applying the appropriate transform.
Notes
I have a feeling that this is overkill.
Expand source code
def apply_transform_retain_array(image, transform, interpolator=sitk.sitkNearestNeighbor): """ This function will move the actual image in space but keep the underlying array the same. So, in x/y/z land the pixels are in a new location, but the actual underlying data array is the same. Parameters ---------- image : SimpleITK.Image Image to be transformed. transform : SimpleITK.Transform Transform to apply interpolator : SimpleITK.Interpolator, optional Interpolator type to use, by default sitk.sitkNearestNeighbor Returns ------- SimpleITK.Image New image after applying the appropriate transform. Notes ----- I have a feeling that this is overkill. """ inverse_transform = transform.GetInverse() new_origin = inverse_transform.TransformPoint(image.GetOrigin()) new_x = inverse_transform.TransformPoint(image.TransformIndexToPhysicalPoint((image.GetSize()[0], 0, 0))) new_y = inverse_transform.TransformPoint(image.TransformIndexToPhysicalPoint((0, image.GetSize()[1], 0))) new_z = inverse_transform.TransformPoint(image.TransformIndexToPhysicalPoint((0, 0, image.GetSize()[2]))) # Create x-axis vector new_x_vector = np.asarray(new_x) - np.asarray(new_origin) new_x_vector /= np.sqrt(np.sum(np.square(new_x_vector))) # Create y-axis vector new_y_vector = np.asarray(new_y) - np.asarray(new_origin) new_y_vector /= np.sqrt(np.sum(np.square(new_y_vector))) # Create z-axis vector new_z_vector = np.asarray(new_z) - np.asarray(new_origin) new_z_vector /= np.sqrt(np.sum(np.square(new_z_vector))) # New image size (shape) new_size = image.GetSize() # New image spacing new_spacing = image.GetSpacing() # Create 3x3 transformation matrix from the x/y/z unit vectors. new_three_by_three = np.zeros((3,3)) new_three_by_three[:,0] = new_x_vector new_three_by_three[:,1] = new_y_vector new_three_by_three[:,2] = new_z_vector new_image = sitk.Resample(image, new_size, transform, interpolator, new_origin, new_spacing, new_three_by_three.flatten().tolist()) return new_image
def binarize_segmentation_image(seg_image, label_idx)
-
Return segmentation that is only 0s/1s, with 1s where label_idx is located in the image.
Parameters
seg_image
:SimpleITK.Image
- Segmentation image that contains data we want to binarize
label_idx
:int
- Integer/label that we want to extract (binarize) from the
seg_image
.
Returns
SimpleITK.Image
- New segmentation image that is binarized.
Expand source code
def binarize_segmentation_image(seg_image, label_idx): """ Return segmentation that is only 0s/1s, with 1s where label_idx is located in the image. Parameters ---------- seg_image : SimpleITK.Image Segmentation image that contains data we want to binarize label_idx : int Integer/label that we want to extract (binarize) from the `seg_image`. Returns ------- SimpleITK.Image New segmentation image that is binarized. """ array = sitk.GetArrayFromImage(seg_image) array_ = np.zeros_like(array) array_[array == label_idx] = 1 new_seg_image = sitk.GetImageFromArray(array_) new_seg_image.CopyInformation(seg_image) return new_seg_image
def create_vtk_image(origin: Optional[int] = [0, 0, 0], dimensions: Optional[list] = [20, 20, 20], spacing: Optional[float] = [1.0, 1.0, 1.0], scalar: Optional[float] = 20.0, data: Optional[numpy.ndarray] = None)
-
Function to create a 3D vtkimage from a numpy array OR to create a uniform image (all same value)
Parameters
origin
:Optional[int]
, optional- X/Y/Z origin of the image, by default [0, 0, 0]
dimensions
:Optional[list]
, optional- Size of the image along each dimension, by default [20, 20, 20]
spacing
:Optional[float]
, optional- Image spacing along each dimension, by default [1., 1., 1.]
scalar
:Optional[float]
, optional- Scalar value to use for a uniform image, by default 20.
data
:Optional[np.ndarray]
, optional- Data for a non-uniform image, by default None
Expand source code
def create_vtk_image( origin: Optional[int] = [0, 0, 0], dimensions: Optional[list] = [20, 20, 20], spacing: Optional[float] = [1., 1., 1.], scalar: Optional[float] = 20., data: Optional[np.ndarray] = None ): """ Function to create a 3D vtkimage from a numpy array OR to create a uniform image (all same value) Parameters ---------- origin : Optional[int], optional X/Y/Z origin of the image, by default [0, 0, 0] dimensions : Optional[list], optional Size of the image along each dimension, by default [20, 20, 20] spacing : Optional[float], optional Image spacing along each dimension, by default [1., 1., 1.] scalar : Optional[float], optional Scalar value to use for a uniform image, by default 20. data : Optional[np.ndarray], optional Data for a non-uniform image, by default None """ if data is None: data = np.ones(dimensions) * scalar else: if len(data.shape) == 3: dimensions = data.shape else: dimensions = [1, 1, 1] for idx, dim_size in enumerate(data.shape): dimensions[idx] = dim_size vtk_array = numpy_to_vtk(data.flatten(order='F')) vtk_array.SetName('test') # points = vtk.vtkDoubleArray() # points.SetName('test') # points.SetNumberOfComponents(1) # points.SetNumberOfTuples(np.product(dimensions)) # for x in range(dimensions[0]): # for y in range(dimensions[1]): # for z in range(dimensions[2]): # points.SetValue( # (z * dimensions[0] * dimensions[1]) + (x * dimensions[1]) + y, # array[x, y, z] # ) vtk_image = vtk.vtkImageData() vtk_image.SetOrigin(*origin) vtk_image.SetDimensions(*dimensions) vtk_image.SetSpacing(*spacing) vtk_image.GetPointData().SetScalars(vtk_array) # return vtk_image
def crop_bone_based_on_width(seg_image, bone_idx, np_med_lat_axis=0, np_inf_sup_axis=1, bone_crop_distal=True, value_to_reassign=0, percent_width_to_crop_height=1.0)
-
Crop the bone labelmap of a SimpleITK.Image so that it is proportional to the bones medial/lateral width.
Parameters
seg_image
:SimpleITK.Image
- Image to be cropped.
bone_idx
:int
- Label_index of the bone to be cropped.
np_med_lat_axis
:int
, optional- Medial/lateral axis, by default 0
np_inf_sup_axis
:int
, optional- Inferior/superir axis, by default 1
bone_crop_distal
:bool
, optional- Boolean of cropping should occur distal or proximally, by default True
value_to_reassign
:int
, optional- Value to replace bone label with, by default 0
percent_width_to_crop_height
:float
, optional- Bone length as a proportion of width, by default 1.0
Returns
SimpleITK.Image
- Image after bone is cropped as a proportion of the bone's width.
Expand source code
def crop_bone_based_on_width(seg_image, bone_idx, np_med_lat_axis=0, np_inf_sup_axis=1, bone_crop_distal=True, value_to_reassign=0, percent_width_to_crop_height=1.0): """ Crop the bone labelmap of a SimpleITK.Image so that it is proportional to the bones medial/lateral width. Parameters ---------- seg_image : SimpleITK.Image Image to be cropped. bone_idx : int Label_index of the bone to be cropped. np_med_lat_axis : int, optional Medial/lateral axis, by default 0 np_inf_sup_axis : int, optional Inferior/superir axis, by default 1 bone_crop_distal : bool, optional Boolean of cropping should occur distal or proximally, by default True value_to_reassign : int, optional Value to replace bone label with, by default 0 percent_width_to_crop_height : float, optional Bone length as a proportion of width, by default 1.0 Returns ------- SimpleITK.Image Image after bone is cropped as a proportion of the bone's width. """ seg_array = sitk.GetArrayFromImage(seg_image) loc_bone = np.where(seg_array == bone_idx) med_lat_width_bone_mm = (np.max(loc_bone[np_med_lat_axis]) - np.min(loc_bone[np_med_lat_axis])) * \ seg_image.GetSpacing()[::-1][np_med_lat_axis] inf_sup_crop_in_pixels = (med_lat_width_bone_mm / seg_image.GetSpacing()[::-1][ np_inf_sup_axis]) * percent_width_to_crop_height if bone_crop_distal is True: bone_distal_idx = np.max(loc_bone[np_inf_sup_axis]) bone_proximal_idx = bone_distal_idx - inf_sup_crop_in_pixels if bone_proximal_idx < 1: bone_proximal_idx = 1 elif bone_crop_distal is False: bone_proximal_idx = np.min(loc_bone[np_inf_sup_axis]) bone_distal_idx = bone_proximal_idx + inf_sup_crop_in_pixels if bone_distal_idx > seg_array.shape[np_inf_sup_axis]: bone_distal_idx = seg_array.shape[np_inf_sup_axis] - 1 max_inf_sup_idx = max(bone_distal_idx, bone_proximal_idx) min_inf_sup_idx = min(bone_distal_idx, bone_proximal_idx) idx_bone_to_keep = np.where( (loc_bone[np_inf_sup_axis] > min_inf_sup_idx) & (loc_bone[np_inf_sup_axis] < max_inf_sup_idx)) loc_bone_to_remove = tuple([np.delete(x, idx_bone_to_keep) for x in loc_bone]) seg_array[loc_bone_to_remove] = value_to_reassign new_seg_image = sitk.GetImageFromArray(seg_array) new_seg_image.CopyInformation(seg_image) return new_seg_image
def read_nrrd(path, set_origin_zero=False)
-
Read NRRD image file into vtk. Enables usage of marching cubes and other functions that work on image data.
Parameters
path
:str
- Path to
.nrrd
medical image to read in. set_origin_zero
:bool
, optional- Bool to determine if origin should be set to zeros, by default False
Returns
vtk.Filter
- End of VTK filter pipeline.
Expand source code
def read_nrrd(path, set_origin_zero=False): """ Read NRRD image file into vtk. Enables usage of marching cubes and other functions that work on image data. Parameters ---------- path : str Path to `.nrrd` medical image to read in. set_origin_zero : bool, optional Bool to determine if origin should be set to zeros, by default False Returns ------- vtk.Filter End of VTK filter pipeline. """ image_reader = vtk.vtkNrrdReader() image_reader.SetFileName(path) image_reader.Update() if set_origin_zero is True: change_origin = set_vtk_image_origin(image_reader, new_origin=(0, 0, 0)) return change_origin elif set_origin_zero is False: return image_reader
def set_seg_border_to_zeros(seg_image, border_size=1)
-
Utility function to ensure that all segmentations are "closed" after marching cubes. If the segmentation extends to the edges of the image then the surface wont be closed at the places it touches the edges.
Parameters
seg_image
:SimpleITK.Image
- Image of a segmentation.
border_size
:int
, optional- The size of the border to set around the edges of the 3D image, by default 1
Returns
SimpleITK.Image
- The image with border set to 0 (background).
Expand source code
def set_seg_border_to_zeros(seg_image, border_size=1): """ Utility function to ensure that all segmentations are "closed" after marching cubes. If the segmentation extends to the edges of the image then the surface wont be closed at the places it touches the edges. Parameters ---------- seg_image : SimpleITK.Image Image of a segmentation. border_size : int, optional The size of the border to set around the edges of the 3D image, by default 1 Returns ------- SimpleITK.Image The image with border set to 0 (background). """ seg_array = sitk.GetArrayFromImage(seg_image) new_seg_array = np.zeros_like(seg_array) new_seg_array[border_size:-border_size, border_size:-border_size, border_size:-border_size] = seg_array[border_size:-border_size, border_size:-border_size, border_size:-border_size] new_seg_image = sitk.GetImageFromArray(new_seg_array) new_seg_image.CopyInformation(seg_image) return new_seg_image
def set_vtk_image_origin(vtk_image, new_origin=(0, 0, 0))
-
Reset the origin of a
vtk_image
Parameters
vtk_image
:vtk.image
- VTK image that we want to change the origin of.
new_origin
:tuple
, optional- New origin to asign to
vtk_image
, by default (0, 0, 0)
Returns
vtk.Filter
- End of VTK filter pipeline after applying origin change.
Expand source code
def set_vtk_image_origin(vtk_image, new_origin=(0, 0, 0)): """ Reset the origin of a `vtk_image` Parameters ---------- vtk_image : vtk.image VTK image that we want to change the origin of. new_origin : tuple, optional New origin to asign to `vtk_image`, by default (0, 0, 0) Returns ------- vtk.Filter End of VTK filter pipeline after applying origin change. """ change_origin = vtk.vtkImageChangeInformation() change_origin.SetInputConnection(vtk_image.GetOutputPort()) change_origin.SetOutputOrigin(new_origin) change_origin.Update() return change_origin
def smooth_image(image, label_idx, variance=1.0)
-
Smooth a single label in a SimpleITK image. Used as pre-processing for bones/cartilage before applying marching cubes. Helps obtain smooth surfaces.
Parameters
image
:SimpleITK.Image
- Image to be smoothed.
label_idx
:int
- Integer of the tissue of interest to be smoothed in the image.
variance
:float
, optional- The size of the smoothing, by default 1.0
Returns
SimpleITK.Image
- Image of only the label (tissue) of interest after being smoothed.
Expand source code
def smooth_image(image, label_idx, variance=1.0): """ Smooth a single label in a SimpleITK image. Used as pre-processing for bones/cartilage before applying marching cubes. Helps obtain smooth surfaces. Parameters ---------- image : SimpleITK.Image Image to be smoothed. label_idx : int Integer of the tissue of interest to be smoothed in the image. variance : float, optional The size of the smoothing, by default 1.0 Returns ------- SimpleITK.Image Image of only the label (tissue) of interest after being smoothed. """ new_image = binarize_segmentation_image(image, label_idx) new_image = sitk.Cast(new_image, sitk.sitkFloat32) gauss_filter = sitk.DiscreteGaussianImageFilter() gauss_filter.SetVariance(variance) # gauss_filter.SetUseImageSpacingOn gauss_filter.SetUseImageSpacing(True) filtered_new_image = gauss_filter.Execute(new_image) return filtered_new_image