hazenlib MagNet tasks

hazenlib.tasks.ghosting task

class hazenlib.tasks.ghosting.Ghosting(**kwargs)[source]

Bases: HazenTask

Ghosting measurement class for DICOM images of the MagNet phantom

Inherits from HazenTask class

run() dict[source]

Main function for performing ghosting measurement

Returns

results are returned in a standardised dictionary structure specifying the task name, input DICOM SeriesDescription + EchoTime + NumberOfAverages, task measurement key-value pairs, optionally path to the generated images for visualisation

Return type

dict

calculate_ghost_intensity(ghost: ndarray, phantom: ndarray, noise: ndarray) float[source]

Calculates the ghost intensity

References: IPEM Report 112 - Small Bottle Method

MagNET, Ghosting = (Sg-Sn)/(Sp-Sn) x 100%

Parameters
  • ghost (np.ndarray) –

  • phantom (np.ndarray) –

  • noise (np.ndarray) –

Returns

float

get_signal_bounding_box(array: ndarray)[source]

_summary_

Parameters

array (np.ndarray) – _description_

Returns

positions of left_column, right_column, upper_row, lower_row

Return type

tuple

get_signal_slice(bounding_box, slice_radius=5)[source]

_summary_

Parameters
  • bounding_box (tuple) – left_column, right_column, upper_row, lower_row

  • slice_radius (int, optional) – _description_. Defaults to 5.

Returns

_description_

Return type

tuple of np.array

get_pe_direction(dcm)[source]
get_background_rois(dcm, signal_centre)[source]

Create pixel arrays of the selected regions of interest from the background

Parameters
  • dcm (pydicom.Dataset) – DICOM image object

  • signal_centre (list) – x, y coordinates of the centre

Returns

pixel arrays of the background regions of interest

Return type

list

get_background_slices(background_rois, slice_radius=5)[source]

_summary_

Parameters
  • background_rois (list) – list of pixel arrays (np.array)

  • slice_radius (int, optional) – _description_. Defaults to 5.

Returns

_description_

Return type

list

get_eligible_area(signal_bounding_box, dcm, slice_radius=5)[source]

Get pixel array within ROI from image

Parameters
  • signal_bounding_box (_type_) – _description_

  • dcm (pydicom.Dataset) – DICOM image object

  • slice_radius (int, optional) – _description_. Defaults to 5.

Returns

corresponding to eligible_columns, eligible_rows

Return type

tuple of lists

get_ghost_slice(signal_bounding_box, dcm, slice_radius=5)[source]

Get array of pixel values wihtin bounding box of the ghost slice

Parameters
  • signal_bounding_box (tuple or list) – _description_

  • dcm (pydicom.Dataset) – DICOM image object

  • slice_radius (int, optional) – _description_. Defaults to 5.

Returns

_description_

Return type

tuple of np.array

get_ghosting(dcm) float[source]

Calculate ghosting percentage

Parameters

dcm (pydicom.Dataset) – DICOM image object

Returns

percentage ghosting across eligible area

Return type

float

hazenlib.tasks.slice_position task

Local Otsu thresholding http://scikit-image.org/docs/0.11.x/auto_examples/plot_local_otsu.html

class hazenlib.tasks.slice_position.SlicePosition(**kwargs)[source]

Bases: HazenTask

Slice position measurement class for DICOM images of the MagNet phantom

Inherits from HazenTask class

run() dict[source]

Main function for performing slice position measurement

Notes

expects an input of 60 images (as a list), of which first and last 10 are discarded

Returns

results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation

Return type

dict

get_rod_rotation(x_pos: list, y_pos: list) float[source]

Determine the in-plane rotation i.e. the x-position of the rods should not vary with y-position. If they do it’s because the phantom is rotated in-plane.

We can determine the angle of in-plane rotation by plotting the x-position against the y-position. We then fit a straight line through the points. arctan (gradient) is the angle of rotation.

If y=c+mx, we can formulate the straight line fit matrix problem, y=X*beta where y is the x-position (because if I set y to be the y-position the fit isn’t very good because the x-position hardly varies ), X is the two column design matrix, the first column is a constant and the second column are the y-positions.

Parameters
  • x_pos (int) – x co-ordinate of a rod

  • y_pos (int) – y co-ordinate of a rod

Returns

angle of rotation in degrees

Return type

float

get_rods_coords(dcm: Dataset)[source]

Determine the coordinates of the rods

Parameters

dcm (pydicom.Dataset) – DICOM image object

Raises

Exception – hazenlib.exceptions.ShapeError

Returns

corresponding to rod coordinates of the left and right rods

Return type

tuple of int

get_rods(data: list)[source]

For the whole dataset of 40 DICOMS, record the list of coordinates and nominal positions for the left and right rods

Parameters

data (list) – list of pydicom.Dataset image objects

Returns

left_rod and right_rod are a dictionary of lists for y and x coords nominal positions is a list calculated from SpacingBetweenSlices

Return type

tuple

correct_rods_for_rotation(left_rod: dict, right_rod: dict) -> (<class 'dict'>, <class 'dict'>)[source]

Update rod coordinates corrected for rotational angle

Parameters
  • left_rod (dict) – dict of lists for x and y coordinates across 40 slices

  • right_rod (dict) – dict of lists for x and y coordinates across 40 slices

Returns

updated lists for x and y coordinates across 40 slices

Return type

tuple of dict

slice_position_error(data: list)[source]

Calculate slice position error

Parameters

data (list) – list of pydicom.Dataset image objects

Returns

absolute value of difference between nominal and actual positions

Return type

list

hazenlib.tasks.slice_width task

Assumptions: Square voxels, no multi-frame support

class hazenlib.tasks.slice_width.SliceWidth(**kwargs)[source]

Bases: HazenTask

Slice width measurement class for DICOM images of the MagNet phantom

Inherits from HazenTask class

run()[source]

Main function for performing slice width measurement

Returns

results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation

Return type

dict

sort_rods(rods)[source]

Separate matrix of rods into sorted per row

Parameters

rods (_type_) – _description_

Returns

_description_

Return type

_type_

get_rods(arr)[source]

Locate rods in the pixel array

Parameters

arr (np.array) – DICOM pixel array

Returns

array_like – centroid coordinates of rods rods_initial : array_like – initial guess at rods (center-of mass)

Return type

rods

Notes

The rod indices are ordered as:

789 456 123

plot_rods(ax, arr, rods, rods_initial)[source]

Plot rods and curve fit graphs

Parameters
  • ax (matplotlib.pyplot.axis) – image axis

  • arr (dcm.pixelarray) – pixel array (image of phantom)

  • rods (_type_) – _description_

  • rods_initial (_type_) – _description_

Returns

_description_

Return type

matplotlib.pyplot.axis

get_rod_distances(rods)[source]

Calculates horizontal and vertical distances between adjacent rods in pixels

Parameters

rods (array_like) – rod positions in pixels

Returns

horz_dist, vert_dist – horizontal and vertical distances between rods in pixels

Return type

array_like

get_rod_distortion_correction_coefficients(horizontal_distances) dict[source]

Removes the effect of geometric distortion from the slice width measurement. Assumes that rod separation is 120 mm.

Parameters

horizontal_distances (list) – horizontal distances between rods, in pixels

Returns

dictionary containing top and bottom distortion coefficients, in mm

Return type

dict

get_rod_distortions(horz_dist, vert_dist)[source]
Parameters
  • horz_dist (list) – horizontal distances

  • vert_dist (list) – vertical distances

Returns

horizontal and vertical distortion values, in mm

Return type

tuple of float

baseline_correction(profile, sample_spacing)[source]

Calculates quadratic fit of the baseline and subtracts from profile

Parameters
  • profile (list) –

  • sample_spacing (int) –

Returns

of polynomial_coefficients, x_interpolated,

baseline/polynomial_fit, baseline, baseline_interpolated, profile_interpolated, profile_corrected_interpolated

Return type

dict

gauss_2d(xy_tuple, A, x_0, y_0, sigma_x, sigma_y, theta, C)[source]

Create 2D Gaussian Based on code by Siân Culley, UCL/KCL See also: https://en.wikipedia.org/wiki/Gaussian_function#Two-dimensional_Gaussian_function

Parameters
  • xy_tuple (grid of x-y coordinates) –

  • A (amplitude of 2D Gaussian) –

  • y_0 (x_0 /) –

  • sigma_y (sigma_x /) –

  • theta (rotation of Gaussian) –

  • C (background/intercept of 2D Gaussian) –

Returns

gauss

Return type

1-D list of Gaussian intensities

fit_gauss_2d_to_rods(cropped_data, gauss_amp, gauss_radius, box_radius, x_start, y_start)[source]

Fit 2D Gaussian to Rods - Important: — This uses a cropped region around a rod. If the cropped region is too large, such that it includes signal with intensity similar to the rods, the fitting may fail. — This is a maximisation function, hence the rods should have higher signal than the surrounding region Based on code by Siân Culley, UCL/KCL

Parameters
  • cropped_data (np.array) – 2D array of magnitude voxels (nb: should be inverted if rods hypointense)

  • gauss_amp (float/int) – initial estimate of amplitude of 2D Gaussian

  • gauss_radius (int) – initial estimate of centre of 2D Gaussian

  • box_radius (int) – ‘radius’ of box around rod

  • y_start (x_start /) – coordinates of bounding box in original non-cropped data

Returns

x0_im / y0_im : rod centroid coordinates in dimensions of original image x0 / y0 : rod centroid coordinates in dimensions of cropped image

Return type

tuple of 4 values corresponding to

trapezoid(n_ramp, n_plateau, n_left_baseline, n_right_baseline, plateau_amplitude)[source]
Parameters
  • n_ramp

  • n_plateau

  • n_left_baseline

  • n_right_baseline

  • plateau_amplitude

Returns

trapezoid and fwmh

Return type

tuple

get_ramp_profiles(image_array, rods) dict[source]

Find the central y-axis point for the top and bottom profiles done by finding the distance between the mid-distances of the central rods

Parameters
  • image_array (dcm.pixelarray) – pixel array from a DICOM image

  • rods (list of Rods) – list of rods with x,y coordinates

Returns

top and bottom ramp profiles

Return type

dict

get_initial_trapezoid_fit_and_coefficients(profile, slice_thickness)[source]
Parameters
  • profile

  • slice_thickness (int) –

Returns

of trapezoid_fit_initial and trapezoid_fit_coefficients

Return type

tuple

fit_trapezoid(profiles, slice_thickness)[source]
Parameters
  • profile

  • slice_thickness (int) –

Returns

of trapezoid_fit_initial and trapezoid_fit_coefficients

Return type

tuple

get_slice_width(dcm)[source]

Calculates slice width using double wedge image

Parameters

dcm (pydicom.FileDataset) – DICOM image object

Returns

including
  • slice_width_mm (float):

    calculated slice width (top, bottom, combined; various methods) in mm

  • horizontal_linearity_mm, vertical_linearity_mm (float):

    calculated average rod distance in mm

  • horz_distortion_mm, vert_distortion_mm (float)

    calculated rod distance distortion in mm

Return type

dict

hazenlib.tasks.snr task

SNR(Im)

Calculates the SNR for a single-slice image of a uniform MRI phantom

This script utilises the smoothed subtraction method described in McCann 2013: A quick and robust method for measurement of signal-to-noise ratio in MRI, Phys. Med. Biol. 58 (2013) 3775:3790

Created by Neil Heraghty

04/05/2018

class hazenlib.tasks.snr.SNR(**kwargs)[source]

Bases: HazenTask

Signal-to-noise ratio measurement class for DICOM images of the MagNet phantom

Inherits from HazenTask class

run() dict[source]

Main function for performing signal-to-noise ratio measurement

Notes

Five square ROIs are created, one at the image centre, and four peripheral ROIs with their centres displaced at 45, 135, 225 and 315 degrees from the centre.

Returns

results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation

Return type

dict

two_inputs_match(dcm1: Dataset, dcm2: Dataset) bool[source]
Check if two DICOMs are sufficiently similar, based on the following fields

“StudyInstanceUID”, “RepetitionTime”, “EchoTime”, “FlipAngle”

Parameters
  • dcm1 (pydicom.Dataset) – DICOM object to compare

  • dcm2 (pydicom.Dataset) – _description_

Returns

_description_

Return type

bool

get_normalised_snr_factor(dcm: Dataset, measured_slice_width=None) float[source]

Calculates SNR normalisation factor.

Notes

Method matches MATLAB script. Utilises user provided slice_width if provided. Else finds from dcm. Finds dx, dy and bandwidth from dcm. Seeks to find TR, image columns and rows from dcm. Else uses default values.

Parameters
  • dcm (pydicom.Dataset) – DICOM image object

  • measured_slice_width (float or None) – slice width from user input

Returns

normalised snr factor

Return type

float

filtered_image(dcm: Dataset) array[source]

Performs a 2D convolution (for filtering images) using uniform_filter SciPy function and a kernel size based on user input coil

Parameters

dcm (pydicom.Dataset) – DICOM image to be filtered

Returns

filtered image pixel values

Return type

np.array

get_noise_image(dcm: Dataset) array[source]

Separates the image noise by smoothing the image and subtracting the smoothed image from the original.

Parameters

dcm (pydicom.Dataset) – DICOM image to get noise from

Returns

pixel array representing the image noise

Return type

np.array

threshold_image(dcm: Dataset)[source]

Determine threshold and mask based on image

Parameters

dcm (pydicom.Dataset) – DICOM image to get noise from

Returns

(imthresholded, mask)

pixel array representing the image above threshold and a corresponding mask

Return type

tuple of np.array

get_binary_mask_centre(binary_mask) -> (<class 'int'>, <class 'int'>)[source]

Determine coordinates of binary polygonal shape’s centre

Parameters

binary_mask – mask of a shape

Returns

(col:int, row:int)

Return type

tuple of int corresponding to centroid_coords

get_roi_samples(ax, dcm: Dataset, centre_col: int, centre_row: int) list[source]

Determine region of interest from a pixel array

Parameters
  • ax (matplotlib axes) – diagram axis for visualisation with matplotlib

  • dcm (pydicom.Dataset or np.ndarray) – image pixel array

  • centre_col (int) – center coordinate column

  • centre_row (int) – center coordinate row

Returns

corresponding to pixel array subsets at predefined ROI

Return type

list of np.ndarray

get_object_centre(dcm) -> (<class 'int'>, <class 'int'>)[source]

Find the phantom object within the image and return its centre col and row value. Note first element in output = col, second = row.

Parameters

dcm (pydicom.Dataset) – DICOM image to get noise from

Returns

(col:int, row:int)

Return type

tuple of int corresponding to centroid_coords

snr_by_smoothing(dcm: Dataset, measured_slice_width=None)[source]

Calculate signal to noise ratio by smoothing

Parameters
  • dcm (pydicom.Dataset) – DICOM image object

  • measured_slice_width (float or None) – slice width from user input

Returns

SNR and normalised SNR values

Return type

tuple of float

get_largest_circle(circles)[source]

Determine circle with largest radius from list of detected circles

Parameters

circles (_type_) – _description_

Returns

of centre coordinates (col, row) and radius (float)

Return type

tuple

snr_by_subtraction(dcm1: Dataset, dcm2: Dataset, measured_slice_width=None)[source]

Calculate signal to noise ratio by smoothing

Parameters
  • dcm1 (pydicom.Dataset) – DICOM image object for signal

  • dcm2 (pydicom.Dataset) – DICOM image object for noise calculation

  • measured_slice_width (float or None) – slice width from user input

Returns

SNR and normalised SNR values

Return type

tuple of float

hazenlib.tasks.snr_map task

Map of local SNR across a flood phantom slice.

Introduction

The SNR for each voxel in an image (of a flood phantom) is estimated as the SNR of a ROI centred on that voxel following the single image SNR method of McCann et al. [1]_. The SNR map can show variation in SNR caused by smoothing filters. It also highlights small regions of low signal which could be caused by micro- bubbles or foreign bodies in the phantom. These inhomogeneities can erroneously reduce SNR measurements made by other methods.

Algorithm overview

  1. Apply boxcar smoothing to original image to create smooth image.

  2. Create noise image by subtracting smooth image from original image.

  3. Create image mask to remove background using e.g.

    skimage.filters.threshold_minimum

  4. Calculate SNR using McCann’s method and overlay ROIs on image.

  5. Estimate local noise as standard deviation of pixel values in ROI centred on

    a pixel. Repeat for each pixel in the noise image.

  6. Plot the local noise as a heat map.

References

McCann, A. J., Workman, A., & McGrath, C. (2013). A quick and robust method for measurement of signal-to-noise ratio in MRI. Physics in Medicine & Biology, 58(11), 3775.

class hazenlib.tasks.snr_map.SNRMap(**kwargs)[source]

Bases: HazenTask

Signal-to-noise ratio mapping class for DICOM images of the MagNet phantom

Inherits from HazenTask class

run()[source]

Main function for performing signal-to-noise ratio mapping Returns SNR parametric map on flood phantom DICOM file.

Notes

Five square ROIs are created, one at the image centre, and four peripheral ROIs with their centres displaced at 45, 135, 225 and 315 degrees from the centre. Displays and saves a parametric map.

Returns

results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation

Return type

dict

smooth(dcm, kernel: int = 9)[source]

Create noise and smoothed images from original_image.

Parameters
  • dcm (pydicom.Dataset) – DICOM image object

  • kernel (int) – Kernel used for smoothing. Default is 9x9 boxcar.

Returns

original, smoothed and noise images (pixel array)

Return type

tuple of np.ndarray

get_rois(smooth_image)[source]

Identify phantom and generate ROI locations.

Parameters

smooth_image (np.ndarray) – pixel array of the smoothed image

Returns

tuple of image_centre (tuple), roi_corners (list of int)

calc_snr(original_image, noise_image, roi_corners)[source]

Calculate SNR from original_image and noise_image.

Parameters
  • original_image (np.ndarray) – original pixel array

  • noise_image (np.ndarray) – pixel array of the image noise

  • roi_corners (list) – list of tuples corresponding to coordinates of the ROI corners

Returns

signal to noise ratio value

Return type

float

calc_snr_map(original_image, noise_image)[source]

Calculate SNR map from original_image and noise_image.

Parameters
  • original_image (np.ndarray) – original pixel array

  • noise_image (np.ndarray) – pixel array of the image noise

Returns

snr_map

draw_roi_rectangles(roi_corners, ax)[source]

Add ROI rectangle overlays to plot.

Parameters
  • roi_corners (list) – list of coordinates (col, row) of ROI corners

  • ax (matplotlib.axes) – diagram axes to visualise rectangles on

Returns

None

adds rectangle overlay to matplotlib axes

plot_snr_map(snr_map, fig, ax)[source]

Add SNR map to a figure axis.

Parameters
  • snr_map (__type__) – SNR map diagram to visualise

  • fig (matplotlib.pyplot.fig) – figure handle

  • ax (matplotlib.axes) – diagram axes to visualise rectangles on

Returns
None

adds SNR map overlay to matplotlib axes on figure

plot_detailed(original_image, smooth_image, noise_image, snr, snr_map, image_centre, roi_corners)[source]

Create 4-image detailed SNR map plots

Parameters
  • original_image (np.ndarray) – original image pixel array

  • smooth_image (np.ndarray) – smoothed pixel array

  • noise_image (np.ndarray) – noise image pixel array

  • snr (float) – SNR value to add to the plot title

  • snr_map (np.ndarray) – _description_

  • image_centre (tuple or list) – coordinates of the image centre

  • roi_corners (list of list) – coordinates (col, row) of ROI corners

Returns

figure handle with plots

Return type

matplotlib.figure.Figure

plot_summary(snr_map, original_image, roi_corners)[source]

Create 2-image summary SNR map plot.

Parameters
  • original_image (np.ndarray) – original image pixel array

  • snr_map (np.ndarray) – _description_

  • roi_corners (list of list) – coordinates (col, row) of ROI corners

Returns

figure handle with plots

Return type

matplotlib.figure.Figure

hazenlib.tasks.spatial_resolution task

Spatial Resolution

Contributors: Haris Shuaib, haris.shuaib@gstt.nhs.uk Neil Heraghty, neil.heraghty@nhs.net, 16/05/2018

class hazenlib.tasks.spatial_resolution.SpatialResolution(**kwargs)[source]

Bases: HazenTask

Spatial resolution measurement class for DICOM images of the MagNet phantom

Inherits from HazenTask class

run() dict[source]

Main function for performing spatial resolution measurement

Returns

results are returned in a standardised dictionary structurespecifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation

Return type

dict

get_circles(image)[source]

Locate Hough Circles in a DICOM pixel array

Parameters

image (array) – DICOM pixel array rescaled to byte

Returns

pixel array of the located circle

Return type

np.array

thresh_image(img, bound=150)[source]

Create a threshold image

Parameters
  • img (np.array) – pixel array

  • bound (int, optional) – _description_. Defaults to 150.

Returns

thresholded pixel array

Return type

np.array

find_square(img)[source]
get_roi(pixels, centre, size=20)[source]

Get coordinates of the region of interest

Parameters
  • pixels (np.array) – _description_

  • centre (tuple) – x,y (int) coordinates

  • size (int, optional) – diameter of the region of interest. Defaults to 20.

Returns

subset of the pixel array

Return type

np.array

get_void_roi(pixels, circle, size=20)[source]

Create an ‘empty’ region of interest - same size filles with 0

Parameters
  • pixels (np.array) – _description_

  • centre (tuple) – x,y (int) coordinates

  • size (int, optional) – diameter of the region of interest. Defaults to 20.

Returns

subset of the pixel array

Return type

np.array

get_edge_roi(pixels, edge_centre, size=20)[source]
edge_is_vertical(edge_roi, mean) bool[source]
Determine whether edge is vertical

control_parameter_01=0 ;a control parameter that will be equal to 1 if the edge is vertical and 0 if it is horizontal

for column=0, event.MTF_roi_size-2 do begin if MTF_Data(column, 0 ) EQ mean_value then control_parameter_01=1 if (MTF_Data(column, 0) LT mean_value) AND (MTF_Data(column+1, 0) GT mean_value) then control_parameter_01=1 if (MTF_Data(column, 0) GT mean_value) AND (MTF_Data(column+1, 0) LT mean_value) then control_parameter_01=1 end :param edge_roi: pixel array in ROI :type edge_roi: np.array :param mean: array of mean pixel values :type mean: np.array

Returns

True or false whether edge is vertical

Return type

bool

get_bisecting_normal(vector, centre, length_factor=0.25)[source]
get_top_edge_vector_and_centre(square)[source]
get_right_edge_vector_and_centre(square)[source]
get_signal_roi(pixels, edge, edge_centre, circle_r, size=20)[source]

Get pixel array from the image within ROI

Parameters
  • pixels (np.array) – _description_

  • edge (_type_) – _description_

  • edge_centre (_type_) – _description_

  • circle_r (float/int) – circle radius

  • size (int, optional) – diameter of the region of interest. Defaults to 20.

Returns

subset of the pixel array

Return type

np.array

get_edge(edge_arr, mean_value, spacing)[source]
get_edge_angle_and_intercept(x_edge, y_edge)[source]

Get edge (slope) angle and intercept value

Parameters
  • x_edge (np.ndarray) – _description_

  • y_edge (np.ndarray) – _description_

Returns

angle and intercept values

Return type

tuple

get_edge_profile_coords(angle, intercept, spacing)[source]

translate and rotate the data’s coordinates according to the slope and intercept

Parameters
  • angle (ndarray or scalar) – angle of slope

  • intercept (ndarray or scalar) – intercept of slope

  • spacing (tuple/list) – spacing value in x and y directions

Returns

of np.ndarrays of the rotated MTF positions in x and y directions

Return type

tuple

get_esf(edge_arr, y)[source]

Extract the edge response function

Parameters
  • edge_arr (np.ndarray) – _description_

  • y (np.ndarray) – _description_

Returns

u and esf - ‘normal’ and interpolated edge response function (ESF)

Return type

tuple

calculate_mtf_for_edge(dicom, edge)[source]
calculate_mtf(dicom) tuple[source]

hazenlib.tasks.uniformity task

Uniformity + Ghosting & Distortion

Calculates uniformity for a single-slice image of a uniform MRI phantom

This script implements the IPEM/MAGNET method of measuring fractional uniformity. It also calculates integral uniformity using a 75% area FOV ROI and CoV for the same ROI.

This script also measures Ghosting within a single image of a uniform phantom. This follows the guidance from ACR for testing their large phantom.

A simple measurement of distortion is also made by comparing the height and width of the circular phantom.

Created by Neil Heraghty neil.heraghty@nhs.net

14/05/2018

class hazenlib.tasks.uniformity.Uniformity(**kwargs)[source]

Bases: HazenTask

Uniformity measurement class for DICOM images of the MagNet phantom

Inherits from HazenTask class

run() dict[source]

Main function for performing uniformity measurement

Returns

results are returned in a standardised dictionary structure specifying the task name, input DICOM Series Description + SeriesNumber + InstanceNumber, task measurement key-value pairs, optionally path to the generated images for visualisation

Return type

dict

mode(a, axis=0)[source]

Finds the modal value of an array. From scipy.stats.mode

Parameters
  • a (np.array) – _description_

  • axis (int, optional) – Axis to calculate mode along. Defaults to 0.

Returns

the modal value old_counts: the number of times this value was counted (check this)

Return type

most_frequent

get_object_centre(dcm)[source]

Locate centre coordinates

Parameters

dcm (pydicom.FileDataset) – DICOM image object

Raises

Exception – _description_

Returns

x and y coordinates

Return type

tuple

get_fractional_uniformity(dcm)[source]

Get fractional uniformity

Parameters

dcm (pydicom.FileDataset) – DICOM image object

Returns

values of horizontal and vertical fractional uniformity

Return type

tuple