Image Analysis

A collection of useful functions for image analysis, implemented in the fredtools.ImgAnalyse subpackage. The image must be an instance of a SimpleITK image.

Image analysis

fredtools.getExtent(img: Image, displayInfo: bool = False) tuple[tuple[float, float], ...]

Get the extent of an image.

The function calculates the extent of an image, which is defined as the coordinates of the most side voxels’ borders in each direction. The extent is assumed to be in millimeters.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – If True, a summary of the function results will be displayed. (def. False)

Returns:

A tuple of extent values in the form ((xmin, xmax), (ymin, ymax), …)

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getExtMpl

Get the extent of a SimpleITK image object describing a slice in matplotlib format.

fredtools.getSize(img: Image, displayInfo: bool = False) tuple[float, ...]

Get the size of an image.

This function calculates the size of an image in each direction. The size is defined as the absolute difference of the image extent. It is assumed that the coordinate system is in millimeters.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – If True, displays a summary of the function results. (def. False)

Returns:

A tuple of sizes in each direction in the form (xSize, ySize, …)

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getExtent

Get the extent of an image.

fredtools.getImageCenter(img: Image, displayInfo: bool = False) tuple[float, ...]

Get the centre of an image.

The function calculates the centre of an image defined as a SimpleITK image object in each direction. It is assumed that the coordinate system is in [mm].

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A Tuple of image centre coordinates in form (xCenter,yCenter,…)

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getMassCenter

get the centre of mass of an image.

getMaxPosition

get the position of an image maximum.

getMinPosition

get the position of an image minimum.

fredtools.getMassCenter(img: Image, displayInfo: bool = False) tuple[float, ...]

Get the centre of mass of an image.

The function calculates the centre of mass of an image defined as a SimpleITK image object in each direction. It is assumed that the coordinate system is in [mm]. Any NaN values are replaced with zeros.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A tuple of image centre of mass coordinates in form (xMassCenter,yMassCenter,…)

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getImageCenter

get the centre of an image.

getMaxPosition

get the position of an image maximum.

getMinPosition

get the position of an image minimum.

fredtools.getMaxPosition(img: Image, displayInfo: bool = False) tuple[float, ...]

Get the maximum position of an image.

The function calculates the position of the maximum voxel of an image defined as a SimpleITK image object. It is assumed that the coordinate system is in [mm].

Parameters:
  • img (SimpleITK Image) – The object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A Tuple of image maximum voxel coordinates in form (xPosition,yPosition,…).

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getImageCenter

get the centre of an image.

getMassCenter

get the centre of mass of an image.

getMinPosition

get the position of an image minimum.

fredtools.getMinPosition(img: Image, displayInfo: bool = False) tuple[float, ...]

Get the minimum position of an image.

The function calculates the position of the minimum voxel of an image defined as a SimpleITK image object. It is assumed that the coordinate system is in [mm].

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A Tuple of image minimum voxel coordinates in form (xPosition,yPosition,…).

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getImageCenter

get the centre of an image.

getMassCenter

get the centre of mass of an image.

getMaxPosition

get the position of an image maximum.

fredtools.getVoxelCentres(img: Image, displayInfo: bool = False) tuple[tuple[float, ...], ...]

Get voxel centres.

The function gets voxels’ centres in each direction of an image defined as a SimpleITK image object. It is assumed that the coordinate system is in [mm].

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A tuple of tuples with voxels’ centres in each direction in form ([x0,x1,…],[y0,y1,…],…)

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getVoxelEdges

get voxel edges.

fredtools.getVoxelEdges(img: Image, displayInfo: bool = False) tuple[tuple[float, ...], ...]

Get voxel edges.

The function gets voxels’ edges in each direction of an image defined as a SimpleITK image object. It is assumed that the coordinate system is in [mm].

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A tuple of tuples with voxels’ edges in each direction in form ([x0,x1,…],[y0,y1,…],…)

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getVoxelCentres

get voxel centres.

fredtools.getVoxelPhysicalPoints(img: Image, insideMask: bool = False, displayInfo: bool = False) Iterable[Iterable[int | float | number]]

Get physical positions of voxels.

The function gets voxels’ physical positions of an image defined as a SimpleITK image object. If the image is a binary mask, then the voxel positions only inside the mask can be requested with insideMask parameter, otherwise all voxels’ positions will be returned.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • insideMask (bool, optional) – Determine if only the voxels’ positions inside the mask should be returned. The img must describe a binary mask. (def. False)

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A numpy array of size NxD where N is the number of voxel and D is the axis.

Return type:

NxD numpy.array

Raises:

TypeError – If img is not an instance of a SimpleITK image, or if insideMask is True and img does not describe a binary mask.

See also

getVoxelCentres

get voxel centres.

fredtools.getExtMpl(img: Image) tuple[float, float, float, float]

Get the extent of a slice in a format consistent with imshow of matplotlib module.

The function gets the extent of an image defined as a SimpleITK image object describing a slice. Extent means the coordinates of the most side pixels’ borders in each direction and are returned in format (left, right, bottom, top), which is consistent with the extent optional parameter of imshow of matplotlib.pyplot module.

Parameters:

img (SimpleITK Image) – An object of a SimpleITK image describing a slice.

Returns:

A tuple of extent values in the form (left, right, bottom, top).

Return type:

tuple

Raises:

TypeError – If img is not an instance of a SimpleITK image describing a slice.

See also

matplotlib.pyplot.imshow

displaying 2D images.

getExtent

get the extent of the image in each direction.

getSize

get the size of the image in each direction.

arr

get squeezed array from image.

Examples

Assuming that the img is describing a slice (e.g. the shape is [100,1,300,1]), the line:

>>> matplotlib.pyplot.imshow(fredtools.arr(img), extent=fredtools.getExtMpl(img))

will display a 2D image of the shape 100x300 px in real coordinates.

fredtools.isPointInside(img: Image, point: Iterable[int | float | number] | Iterable[Iterable[int | float | number]], displayInfo: bool = False) bool | tuple[bool, ...]

Check if a point or a list of points is inside the extent of an image.

This function checks if a point or a list of points are inside the extent of an image defined as a SimpleITK image object. The points at the border of the image (equal to the image extent) are considered to be inside the image.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • point (Iterable[float] | Iterable[Iterable[float]]) – An iterable (numpy array, list of lists, etc) of N points. Every point must be of the image dimension size.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A single boolean value if a single point is provided, or a tuple of boolean values if a list of points is provided.

Return type:

bool | tuple[bool, …]

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getExtent

Get the extent of the image in each direction.

Examples

Let’s assume that the img is a 3D image with extent:

>>> fredtools.getExtent(img)
((-175.0, 174.3),
 (-354.6, -70.9),
 (-786.2, -524.6))

It means that the img expands from -175.0 to 174.3, from -354.6 to -70.9, and from -786.2 to -524.6 in the X, Y, and Z directions, respectively. Let’s check if the point [0,0,0] and a list of points [[0,0,0],[0,-100,-600],[-175,-354.6,-786.2]] are inside the image extent:

>>> fredtools.isPointInside(img, [0,0,0])
False
>>> fredtools.isPointInside(img, [[0,0,0],[0,-100,-600],[-175,-354.6,-786.2]])
(False, True, True)
fredtools.getStatistics(img: Image, displayInfo: bool = False) StatisticsImageFilter

Get statistics of image

The function gets basic statistics of an image defined as a SimpleITK image object. It is a wrapper for SimpleITK.StatisticsImageFilter routine executed on the image. If the image is a vector image, it is silently converted to a scalar image being the sum of the vector components (with fredtools.sumVectorImg) and a warning is logged; the statistics are then calculated for the sum of vectors.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

SimpleITK image filter with image statistics.

Return type:

SimpleITK filter

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

SimpleITK.StatisticsImageFilter

more about possible statistics.

Examples

It is assumed that the image is a 3D dose distribution. Some statistics of the image, like the mean, standard deviation or sum can be calculated.

>>> stat=fredtools.getStatistics(img)
>>> stat.GetMean()
-732.6387321958799
>>> stat.GetSigma()
468.4351857326367
>>> stat.GetSum()
-33870013138.0
fredtools.getIntegral(img: Image, displayInfo: bool = False) int | float | number

Get integral of image

The function calculates the integral of an image defined as a SimpleITK image object. The integral is calculated as the sum of all voxel values multiplied by the voxel volume, where the voxel volume is the product of the image spacing (assumed to be in mm), hence the integral is expressed in the voxel value units times mm³. If the image is a vector image, it is converted to a scalar image being the sum of the vector components (with fredtools.sumVectorImg) and a warning is logged; the integral is then calculated for the sum of vectors.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A float value with the integral of the image.

Return type:

float

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getStatistics

get basic statistics of the image.

fredtools.compareImg(img1: Image, img2: Image, decimal: int = 3, displayInfo: bool = False) bool

Compare two images pixel by pixel.

The function gets two images defined as instances of a SimpleITK image object and compares them pixel by pixel. The comparison is done with a given decimal tolerance.

Parameters:
  • img1 (SimpleITK Image) – An object of a SimpleITK image.

  • img2 (SimpleITK Image) – An object of a SimpleITK image.

  • decimal (int, optional) – The number of decimal places to compare the images. (def. 3)

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A true/false value describing if the images are the same in the sense of the pixel values.

Return type:

bool

Raises:

TypeError – If img1 or img2 is not an instance of a SimpleITK image.

fredtools.compareImgFoR(img1: Image, img2: Image, decimal: int = 3, displayInfo: bool = False) bool

Compare two images frame of reference

The function gets two images defined as instances of a SimpleITK image object and compares the frame of reference, i.e. dimension, size, origin, spacing and direction.

Parameters:
  • img1 (SimpleITK Image) – An object of a SimpleITK image.

  • img2 (SimpleITK Image) – An object of a SimpleITK image.

  • decimal (int, optional) – Use rounding to a given number of decimals when comparing origin and spacing. (def. 3)

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

A true/false value describing if the images are the same in the sense of the frame of reference.

Return type:

bool

Raises:

TypeError – If img1 or img2 is not an instance of a SimpleITK image.

See also

compareImg

compare two images voxel by voxel.

fredtools.pos(img: Image) tuple[float, ...] | tuple[tuple[float, ...], ...]

Get voxels’ centres for axes of the size different than one.

The function calculates the voxels’ centres of an image defined as a SimpleITK image object in each direction, only for those axes for which the size is more than one. The function is useful for plotting profiles.

Parameters:

img (SimpleITK Image) – An object of a SimpleITK image.

Returns:

A tuple with voxels’ centres for the image describing a profile (the size in only one direction is greater than one) or list of tuples for all directions for which the size is greater than one.

Return type:

tuple or list of tuples

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

getVoxelCentres

get voxels’ centres of the image in each direction.

vec

get a vector with values for the image describing a profile.

Examples

Let’s assume that the img is a 3D image describing a profile, so is of size [1,200,1]. It is possible to get the voxels’ centres only in the Y direction:

>>> fredtools.pos(img)
(-174.658203125,
 -173.974609375,
 ...
)

This can be used for plotting profiles. The line:

>>> matplotlib.pyplot.plot(fredtools.pos(img), fredtools.vec(img))

will plot the profile in the Y direction of the image.

fredtools.arr(img: Image) ndarray[tuple[Any, ...], dtype[_ScalarT]]

Get squeezed array from image.

The function gets a squeezed array (with no unitary dimensions) from an image defined as a SimpleITK image object. This can be used for plotting

Parameters:

img (SimpleITK Image) – An object of a SimpleITK image.

Returns:

A numpy array with no unitary dimensions.

Return type:

numpy array

Raises:

TypeError – If img is not an instance of a SimpleITK image.

See also

pos

get voxels’ centres for axes of size different than one.

getExtMpl

Get the extent of a slice in a format consistent with imshow of matplotlib module.

vec

get a vector with values for the image describing a profile.

Examples

Assuming that the img is describing a slice (e.g. the shape is [100,1,300,1]), the line:

>>> matplotlib.pyplot.imshow(fredtools.arr(img), extent=fredtools.getExtMpl(img))

will display a 2D image of the shape 100x300 px in real coordinates.

fredtools.vec(img: Image) ndarray[tuple[Any, ...], dtype[_ScalarT]]

Get 1D array from image describing a profile.

The function gets a squeezed (with no unitary dimensions), 1D array from an image defined as a SimpleITK image object describing a profile. This can be used for plotting

Parameters:

img (SimpleITK Image) – An object of a SimpleITK image describing a profile.

Returns:

A 1D numpy array.

Return type:

numpy array

Raises:

TypeError – If img is not an instance of a SimpleITK image describing a profile.

See also

pos

get voxels’ centres for axes of the size different than one.

arr

Get squeezed array from image.

Examples

Assuming that the img is describing a profile (e.g. the shape is [1,1,300,1]), the line:

>>> matplotlib.pyplot.plot(fredtools.pos(img), fredtools.vec(img))

will plot the profile in the Z direction of the image.

Image information

fredtools.displayImageInfo(img: Image, metadata: bool = True) None

Display some image information.

The function displays information about an image given as a SimpleITK image object. The information is logged with the module logger at the INFO level.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • metadata (bool, optional) – Display additional metadata. (def. True)

Raises:

TypeError – If img is not an instance of a SimpleITK image.

Notes

The function sets the level of the module logger to INFO as a side effect, so that the image information is always displayed, regardless of the logging level configured before the call.

Examples

Reading image from file and displaying the image information.

>>> imgCT=fredtools.readMHD('CT.mhd')
>>> fredtools.displayImageInfo(imgCT)
displayImageInfo: Image info:
    3D image describing a volume (3D)
    dims (xyz)      = [511 415 218]
    voxel size [mm] = [0.68359375 0.68359375 1.2       ]
    origin [mm]     = [-174.65820312 -354.28710938 -785.6       ]
    x-spatial voxel centre [mm] = [  -174.658203,  -173.974609, ...,   173.291016,   173.974609 ]
    ...
    data type: 16-bit signed integer
    range: from -1024 to 3071
    ...

The same can be displayed when reading the image with displayInfo=True, for instance:

>>> imgCT=fredtools.readMHD('CT.mhd', displayInfo=True)

Coordinate transformations

fredtools.transformIndexToPhysicalPoint(img: Image, indices: Iterable[Iterable[int | float | number]]) Tuple[Tuple[float, ...], ...]

Transform indices to physical points.

The function transforms an iterable of indices into a tuple of physical points based on the frame of reference (FoR) of an image defined as an instance of a SimpleITK image object. The function is a wrapper for TransformIndexToPhysicalPoint SimpleITK function, but it works for multiple points. The shape of indices must be NxD, where N is the number of points to be converted, and D is the dimension of the image.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • indices (NxD array_like) – An iterable (numpy array, list of lists, etc) of N points. Every index must be of the image dimension size and of any integer type (int64, uint16, etc.).

Returns:

A NxD tuple of tuples with physical points.

Return type:

tuple

Raises:
  • TypeError – If img is not an instance of a SimpleITK image.

  • AttributeError – If indices is not of an integer type or is not of the NxD shape, where D is the image dimension.

See also

transformContinuousIndexToPhysicalPoint

transform continuous indices to physical points.

transformPhysicalPointToIndex

transform physical points to indices.

transformPhysicalPointToContinuousIndex

transform physical points to continuous indices.

fredtools.transformContinuousIndexToPhysicalPoint(img: Image, indices: Iterable[Iterable[int | float | number]]) Tuple[Tuple[float, ...], ...]

Transform continuous indices to physical points.

The function transforms an iterable of indices into a tuple of physical points based on the frame of reference (FoR) of an image defined as an instance of a SimpleITK image object. The function is a wrapper for TransformContinuousIndexToPhysicalPoint SimpleITK function, but it works for multiple points. The shape of indices must be NxD, where N is the number of points to be converted, and D is the dimension of the image.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • indices (NxD array_like) – An iterable (numpy array, list of lists, etc) of N points. Every index must be of the image dimension size and can be of float or integer type.

Returns:

A NxD tuple of tuples with physical points.

Return type:

tuple

Raises:
  • TypeError – If img is not an instance of a SimpleITK image.

  • AttributeError – If indices is not of the NxD shape, where D is the image dimension.

See also

transformIndexToPhysicalPoint

transform indices to physical points.

transformPhysicalPointToIndex

transform physical points to indices.

transformPhysicalPointToContinuousIndex

transform physical points to continuous indices.

fredtools.transformPhysicalPointToIndex(img: Image, points: Iterable[Iterable[int | float | number]]) Tuple[Tuple[int, ...], ...]

Transform physical points to indices.

The function transforms an iterable of points into a tuple of indices based on the frame of reference (FoR) of an image defined as an instance of a SimpleITK image object. The function is a wrapper for TransformPhysicalPointToIndex SimpleITK function, but it works for multiple points. The shape of points must be NxD, where N is the number of points to be converted, and D is the dimension of the image.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • points (NxD array_like) – An iterable (numpy array, list of lists, etc) of N points. Every point must be of the image dimension size.

Returns:

A NxD tuple of tuples with indices.

Return type:

tuple

Raises:
  • TypeError – If img is not an instance of a SimpleITK image.

  • AttributeError – If points is not of the NxD shape, where D is the image dimension.

See also

transformIndexToPhysicalPoint

transform indices to physical points.

transformContinuousIndexToPhysicalPoint

transform continuous indices to physical points.

transformPhysicalPointToContinuousIndex

transform physical points to continuous indices.

fredtools.transformPhysicalPointToContinuousIndex(img: Image, points: Iterable[Iterable[int | float | number]]) Tuple[Tuple[float, ...], ...]

Transform physical points to continuous indices.

The function transforms an iterable of points into a tuple of continuous indices based on the frame of reference (FoR) of an image defined as an instance of a SimpleITK image object. The function is a wrapper for TransformPhysicalPointToContinuousIndex SimpleITK function, but it works for multiple points. The shape of points must be NxD, where N is the number of points to be converted, and D is the dimension of the image.

Parameters:
  • img (SimpleITK Image) – An object of a SimpleITK image.

  • points (NxD array_like) – An iterable (numpy array, list of lists, etc) of N points. Every point must be of the image dimension size.

Returns:

A NxD tuple of tuples with continuous indices.

Return type:

tuple

Raises:
  • TypeError – If img is not an instance of a SimpleITK image.

  • AttributeError – If points is not of the NxD shape, where D is the image dimension.

See also

transformIndexToPhysicalPoint

transform indices to physical points.

transformContinuousIndexToPhysicalPoint

transform continuous indices to physical points.

transformPhysicalPointToIndex

transform physical points to indices.

Image display

Functions and classes for image displaying. The functionalities have been designed to quickly display and analyse 3D images of CT and/or dose (or any other 3D quantity distribution) in jupyter, including the interactive mode.

fredtools.showSlice(ax: Axes, imgBack: Image | None = None, imgFront: Image | None = None, plane: str = 'XY', point: Iterable[int | float | number] | None = None, cmapBack: str | Colormap = 'bone', cmapFront: str | Colormap = 'jet', alphaFront: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Strict(strict=True), Ge(ge=0), Le(le=1)])] = 0.7, imgROIs: Iterable[Image] | None = None, vmaxBack: float | None = None, vmaxFront: float | None = None, showLegend: bool = True, fontsize: Annotated[int, Ge(ge=0)] = 8) AxesImage

Display image slice in front of another image slice including contours.

The function displays on ax a plane going through point of a 3D image describing the front image overlapped on a slice of another image describing the background. It forms a simple wrapper to matplotlib.pyplot.imshow allowing for a quick display of a slice from a 3D image of signal (e.g. dose) and/or another image (e.g. CT).

Usually imgBack describes the CT and imgFront describes the dose or other signal. At least one variable, imgBack or imgFront must be given.

Parameters:
  • ax (AxesSubplot) – Axis to plot the image on.

  • imgBack (SimpleITK Image, optional) – Object of a SimpleITK 3D image describing the background image. (def. None)

  • imgFront (SimpleITK Image, optional) – Object of a SimpleITK 3D image describing the foreground image. (def. None)

  • plane (str, optional) – Plane to generate the 2D slice given as a string. See fredtools.getSlice for more details. (def. ‘XY’)

  • point (array_like, optional) – 3D point to generate the 2D slice through. If None then the centre of mass of the 3D foreground image (or background image if the foreground image is not given) will be used. (def. None)

  • cmapBack (string or matplotlib.colors.Colormap, optional) – Colormap to display the background image slice. (def. ‘bone’)

  • cmapFront (string or matplotlib.colors.Colormap, optional) – Colormap to display the foreground image slice. (def. ‘jet’)

  • imgROIs (SimpleITK Image or list of SimpleITK Images, optional) – An Instance of a SimpleITK image or list of instances of SimpleITK image objects describing a 3D mask. (def. None)

  • vmaxBack (scalar, optional) – Maximum value of the background image. If None then the maximum value of the 3D background image will be used. (def. None)

  • vmaxFront (scalar, optional) – Maximum value of the foreground dose map. If None then the maximum value of the 3D foreground image will be used. (def. None)

  • alphaFront (float, optional) – Alpha value of the transparency of the foreground image. (def. 0.7)

  • showLegend (bool, optional) – Show legend of the ROI contour names if they exist. (def. True)

  • fontsize (scalar, optional) – Basic font size to be used for ticks, labels, legend, etc. (def. 8)

Returns:

Foreground image (or background image if the foreground image is not given) attached to the axis ax.

Return type:

matplotlib.image.AxesImage

Raises:
  • AttributeError – If neither imgBack nor imgFront is given, or if the image slice cannot be displayed.

  • ValueError – If cmapBack or cmapFront colormap cannot be recognised.

  • TypeError – If any of the imgROIs is not an instance of a SimpleITK image describing a binary or floating mask.

See also

showSlices

show three projections of a 3D image, also interactively.

getSlice

get a 2D image slice from SimpleITK Image.

class fredtools.showSlices(imgBack: Image | None = None, imgFront: Image | None = None, imgROIs: Iterable[Image] | None = None, point: Iterable[int | float | number] | None = None, DCOFront: Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Strict(strict=True), Ge(ge=0), Le(le=1)])] = 0.1, cmapBack: str | Colormap = 'bone', cmapFront: str | Colormap = 'jet', figsize: Iterable[int | float | number] = (15, 5))

Class to display three projections of 3D image slices on an another 3D image slices including contours.

The class creates a figure with three axes and displays three projections (planes), ‘XY’, ‘ZY’ and ‘X-Z’ (reversed Z), going through point, of a 3D image describing foreground overlapped on a background image. The class can display in an interactive mode exploiting ipywidgets functionality, allowing to move slices with a mouse wheel or move slices to the point when the mouse button is pressed. All those interactive features work with Shift pressed.

Usually imgBack describes the CT and imgFront describes the dose or other signal. At least one variable, imgBack or imgFront must be given.

Parameters:
  • imgBack (SimpleITK Image, optional) – Object of a 3D SimpleITK image describing the background image. (e.g. CT). (def. None)

  • imgFront (SimpleITK Image, optional) – Object of a 3D SimpleITK image describing the foreground image. (e.g. dose or gamma index map). (def. None)

  • imgROIs (SimpleITK Image or list of SimpleITK Images, optional) – An Instance of a SimpleITK image or list of instances of SimpleITK image objects describing a 3D mask. (def. None)

  • point (array_like, optional) – 3D point to generate the 2D slice through. If None then the centre of mass of the 3D foreground image (or the background image if the foreground is not given) will be used. (def. None)

  • DCOFront (float, optional) – Dose cut-off. The fraction of the maximum value of the foreground image below which the data will not be displayed. (def. 0.1)

  • cmapBack (string or matplotlib.colors.Colormap, optional) – Colormap to display the background image slice. (def. ‘bone’)

  • cmapFront (string or matplotlib.colors.Colormap, optional) – Colormap to display the foreground image slice. (def. ‘jet’)

  • figsize (2-element list, optional) – Width and height of the figure in inches. (def. [15, 5])

Raises:
  • AttributeError – If neither imgBack nor imgFront is given.

  • ValueError – If point is not a 3-element vector, or if cmapBack or cmapFront colormap cannot be recognised.

Notes

1. The foreground image is thresholded destructively on the instance: the imgFront attribute stores a copy of the foreground image in which all values below DCOFront times the image maximum are replaced with NaN (the image object passed by the caller is not modified).

2. The interactive slicing (sliders, mouse wheel and mouse button with Shift pressed) is only activated when the matplotlib backend is ‘widget’ or ‘ipympl’ (i.e. in Jupyter with the ipympl backend). For any other backend, the three static slices going through point are displayed.

mouseButtonPressEvent(event)

Move the slices to the clicked point (with Shift pressed) by updating the sliders of the other two axes.

removeArtist(ax)

Remove all line and collection artists (contours and point lines) as well as the legend from an axis.

replotPointLines()

Redraw the crosshair lines marking the current point position on all three axes.

scrollEvent(event)

Move the slice of the axis under the cursor by one voxel per mouse-wheel step (with Shift pressed).

scrollEventShiftPress(event)

Enable the interactive scroll/click mode when the Shift key is pressed.

scrollEventShiftRelease(event)

Disable the interactive scroll/click mode when the Shift key is released.

showSliceAX0(Z)

Replot the first (left) axis with the ‘XY’ plane slice, driven by the Z coordinate.

showSliceAX1(X)

Replot the second (middle) axis with the ‘ZY’ plane slice, driven by the X coordinate.

showSliceAX2(Y)

Replot the third (right) axis with the ‘X-Z’ (reversed Z) plane slice, driven by the Y coordinate.

Spot analysis

fredtools.fitSpotProfile(pos: ArrayLike, vec: ArrayLike, cutLevel: Annotated[float, Ge(ge=0)] = 0, fixAmplitude: bool = False, fixCentreToZero: bool = False, method: Literal['singleGauss'] = 'singleGauss') ModelResult

Fit a gaussian-like function to profile.

The function fits a gaussian-like function defined by method to a profile defined as pos and vec parameters, where they are vectors of positions and values, respectively.

Parameters:
  • pos (array_like 1xN) – An iterable with the positions of the values.

  • vec (array_like 1xN) – An iterable with the values corresponding to pos.

  • cutLevel (scalar, optional) – Fraction of the maximum value of vec for which the fit will be performed. Only the points with values greater than or equal to max(vec)*`cutLevel` are kept for the fit. (def. 0)

  • fixAmplitude (bool, optional) – Fix the amplitude to the maximum value of vec and do not use it in the fitting. (def. False)

  • fixCentreToZero (bool, optional) – Fix the centre to zero and do not use it in the fitting. (def. False)

  • method ({"singleGauss"}, optional) – Method of the fitting. Only single gaussian fitting is implemented now. (def. “singleGauss”)

Returns:

An instance of lmfit.model.ModelResult class.

Return type:

lmfit.model.ModelResult

Raises:
  • TypeError – If pos or vec is not iterable, is not a one-dimensional vector, or if pos and vec are not of the same length.

  • ValueError – If the method is not recognised.

fredtools.fitSpotImg(img: Image, cutLevel: Annotated[float, Ge(ge=0)] = 0, fixAmplitude: bool = False, fixCentreToZero: bool = False, method: Literal['singleGauss'] = 'singleGauss') ModelResult

Fit a 2D gaussian-like function to spot image.

The function fits a 2D gaussian-like function defined by method to a spot image defined as img parameter, which is a 2D SimpleITK image.

Parameters:
  • img (SITKImage) – 2D SimpleITK image of the spot.

  • cutLevel (scalar, optional) – Fraction of the maximum value of img for which the fit will be performed. Only the voxels with values greater than or equal to max(img)*`cutLevel` are kept for the fit (the others are set to zero). (def. 0)

  • fixAmplitude (bool, optional) – Fix the amplitude to the maximum value of img and do not use it in the fitting. (def. False)

  • fixCentreToZero (bool, optional) – Fix the centre to zero and do not use it in the fitting. (def. False)

  • method ({"singleGauss"}, optional) – Method of the fitting. Only single gaussian fitting is implemented now. (def. “singleGauss”)

Returns:

An instance of lmfit.model.ModelResult class.

Return type:

lmfit.model.ModelResult

Raises:
  • TypeError – If img is not a 2D SimpleITK image.

  • ValueError – If the method is not recognised.

fredtools.findSpots(img: Image, DCO: Annotated[int | float | number, FieldInfo(annotation=NoneType, required=True, metadata=[Strict(strict=True), Ge(ge=0), Le(le=1)])] = 0.1, margin: Annotated[float, Gt(gt=0)] | Iterable[Annotated[float, Gt(gt=0)]] = 3, displayInfo: bool = False) Image

Find spots in 2D SITK image.

The function identifies spots in a 2D SimpleITK image by applying a dose cut-off (DCO) to define the spot region, followed by morphological operations to refine the regions. The identified spots are then labelled and returned as a labelled image. In detail, the image is first smoothed with a median filter of a fixed 5x5 voxel kernel and binarised at DCO times the image maximum. The binary regions are dilated by margin (converted from mm to voxels), labelled as fully connected components with holes filled, and components smaller than 20 voxels are dropped. The remaining labels are sorted by size (the largest component gets label 1), and finally each label region is replaced by its axis-aligned bounding box, so each spot is described by a rectangular label region.

Parameters:
  • img (SITKImage) – 2D SITK image.

  • DCO (Numeric, optional) – Dose cut-off to define spot region. (def. 0.1)

  • margin (Numeric | Iterable[Numeric], optional) – Margin around spot region in mm. (def. 3)

  • displayInfo (bool, optional) – Display information about found spots. (def. False)

Returns:

Labelled image of found spots.

Return type:

SITKImage

Raises:
  • TypeError – If img is not a 2D SimpleITK image. If margin is not a scalar or an iterable.

  • ValueError – If DCO is not a positive scalar between 0 and 1.

fredtools.fitSigmaSquaredModel(pos: Iterable[int | float | number], beamSize: Iterable[int | float | number]) ModelResult

Fit sigma squared model to beam size data.

The function fits the sigma squared model to the beam size data provided. The model is defined as: σ²(z) = a + b*z + c*z², where σ is the beam size at position z, and a, b, c are the parameters to be fitted. Note that the fit is performed on the squared beam size, i.e. beamSize**2.

Parameters:
  • pos (Iterable[Numeric]) – Positions where the beam sizes were measured.

  • beamSize (Iterable[Numeric]) – Measured beam sizes at the corresponding positions.

Returns:

An instance of lmfit.model.ModelResult class.

Return type:

lmfit.model.ModelResult

DVH analysis

Functions for Dose-Volume Histogram (DVH) analysis. The DVH data is returned as an instance of the DVH class described below.

fredtools.getDVHMask(img: Image, imgMask: Image, dosePrescribed: Annotated[float, Ge(ge=0)], displayInfo: bool = False) DVH

Calculate DVH for the mask.

The function calculates a dose-volume histogram (DVH) for voxels inside a mask with the same field of reference (FoR). The mask must be defined as a SimpleITK image object describing a binary or floating mask. The routine exploits and returns DVH class to hold the DVH. The class has been adapted from dicompyler-core DVH module (https://dicompyler-core.readthedocs.io/en/latest/index.html)

Parameters:
  • img (SimpleITK Image) – Object of a SimpleITK 3D image.

  • imgMask (SimpleITK Image) – Object of a SimpleITK 3D image describing the binary or floating mask.

  • dosePrescribed (scalar) – Target prescription dose.

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

An instance of a DVH class holding the DVH.

Return type:

DVH

Raises:
  • TypeError – If img or imgMask is not an instance of a 3D SimpleITK image, if imgMask does not describe a binary or floating mask, or if img and imgMask do not have the same FoR.

  • ValueError – If the image contains NaN values inside the mask.

See also

resampleImg

resample image.

mapStructToImg

map structure to image (refer for more information about mapping algorithms).

getDVHStruct

calculate DVH for structure.

fredtools.getDVHStruct(img: Image, RSfileName: str, structName: str, dosePrescribed: float, resampleImg: float | Iterable[float] | None = None, displayInfo: bool = False) DVH

Calculate DVH for the structure.

The function calculates a dose-volume histogram (DVH) for voxels inside a structure named structName and is defined in the structure dicom file. The image can be resampled before mapping to increase the resolution. The routine exploits and returns DVH class to hold the DVH. The class has been adapted from dicompyler-core DVH module (https://dicompyler-core.readthedocs.io/en/latest/index.html)

Parameters:
  • img (SimpleITK Image) – Object of a SimpleITK 3D image.

  • RSfileName (path) – String path to RS dicom file.

  • structName (string) – Name of the structure to calculate the DVH in.

  • dosePrescribed (scalar) – Target prescription dose.

  • resampleImg (scalar, array_like or None, optional) – Define if and how to resample the image while mapping the structure. Can be a scalar, then the same number will be used for each axis, 3-element iterable defining the voxel size for each axis, or None meaning no interpolation. (def. None)

  • displayInfo (bool, optional) – Displays a summary of the function results. (def. False)

Returns:

An instance of a DVH class holding the DVH.

Return type:

DVH

Raises:
  • TypeError – If img is not an instance of a 3D SimpleITK image, or if RSfileName is not a proper dicom file describing structures.

  • AttributeError – If the structure structName cannot be found in the RSfileName dicom file.

  • ValueError – If the shape of resampleImg does not match the image dimension and is not a scalar.

See also

resampleImg

resample image.

mapStructToImg

map structure to image (refer for more information about mapping algorithms).

getDVHMask

calculate DVH for a mask.

Notes

The structure mapping is performed in ‘floating’ mode meaning that the fractional structure occupancy is assigned to each voxel of the image. Use getDVHMask to use a specially prepared mask for the DVH calculation.

class fredtools.ImgAnalyse.dvhAnalyse.DVH(volume: Iterable[int | float | number], dose: Iterable[int | float | number], type: Literal['cumulative', 'differential'] = 'cumulative', dosePrescribed: int | float | number | None = None, name: str | None = None, color: str | Sequence[int | float | number] | None = None)

Class that stores dose volume histogram (DVH) data.

compare(other: Self) None

Compare two DVHs.

The method compares two DVHs in terms of basic DVH parameters and plots the DVHs.

Parameters:

other (DVH) – DVH instance to compare against.

Raises:

TypeError – If the comparison object is not a DVH instance.

displayInfo() None

Describe a summary of DVH statistics in a text based format.

doseConstraint(volume: int | float | number, absolute: bool = False) float

Calculate dose constraint for a specific volume.

The method calculates the maximum dose that a specific absolute or relative volume receives. e.g.: D90, D100, D2cc , etc. The results is always given in the absolute dose units.

Parameters:
  • volume (Numeric) – Volume used to determine the maximum dose that the volume receives. Can either be in relative or absolute volume units.

  • absolute (bool, optional) – If True, the volume is considered in absolute units. (def. False)

Returns:

Absolute dose that a specific volume receives.

Return type:

number

Raises:

AttributeError – If the volume value is negative.

property doseDiffCenters: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Return a numpy array containing the dose bin centres for differential type.

property doseDiffEdges: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Return a numpy array containing the bin edges for differential type.

property doseLevels: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Return a numpy array containing the dose levels for cumulative type.

property dosePrescribed: float

Return the prescribed dose.

property max: float

Return the maximum dose.

property mean: float

Return the mean dose.

property median: float

Return the median dose.

property min: float

Return the minimum dose.

plot() None

Plot the DVH using Matplotlib if present.

statistic(name: str) float

DVH dose or volume statistics

The method returns DVH dose or volume statistics. The statistics can be in the form of D90, D100, D2cc, V100, V20Gy, etc.

Parameters:

name (str) – DVH statistic in the form of D90, D100, D2cc, V100, V20Gy, etc.

Returns:

Value from the dose or volume statistic calculation.

Return type:

Numeric

Raises:

AttributeError – If the attribute name cannot be resolved.

property stdDev: float

Return the standard deviation of the dose.

property volume: float

Return the volume of the structure.

volumeConstraint(dose: int | float | number, absolute: bool = False) float

Calculate volume constraint for a specific dose.

The method calculates the volume that receives at least a specific relative or absolute dose. e.g.: V100, V50, V20Gy, etc.

Parameters:
  • dose (Numeric) – Dose value used to determine minimum volume that receives this dose. Can either be in relative or absolute dose units.

  • absolute (bool, optional) – If True, the dose is considered in absolute units. (def. False)

Returns:

Volume that receives at least a specific dose.

Return type:

Numeric

Raises:

AttributeError – If the dose value is negative.

property volumeCumAbs: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Return a numpy array containing the absolute cumulative volume for each dose level.

property volumeCumRel: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Return a numpy array containing the relative cumulative volume for each dose level.

property volumeDiffAbs: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Return a numpy array containing the absolute differential volume for each bin.

property volumeDiffRel: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Return a numpy array containing the relative differential volume for each bin.