hazenlib package
Core functions
Welcome to the hazen Command Line Interface
The following Tasks are available: - ACR phantom: acr_snr | acr_slice_position | acr_slice_thickness | acr_spatial_resolution | acr_uniformity | acr_ghosting | acr_geometric_accuracy - MagNET Test Objects: snr | snr_map | slice_position | slice_width | spatial_resolution | uniformity | ghosting - Caliber phantom: relaxometry
All tasks can be run by executing ‘hazen <task> <folder>’. Optional flags are available for the Tasks; see the General Options section below. The ‘acr_snr’ and ‘snr’ Tasks have additional optional flags, also detailed below.
- Usage:
hazen <task> <folder> [options] hazen snr <folder> [–measured_slice_width=<mm>] [–coil=<head or body>] [options] hazen acr_snr <folder> [–measured_slice_width=<mm>] [–subtract=<folder2>] [options] hazen relaxometry <folder> –calc=<T1> –plate_number=<4> [options]
hazen -h | –help hazen –version
- General Options: available for all Tasks
- --report
Whether to generate visualisation of the measurement steps.
- --output=<path>
Provide a folder where report images are to be saved.
- --verbose
Whether to provide additional metadata about the calculation in the result (slice position and relaxometry tasks)
- --log=<level>
Set the level of logging based on severity. Available levels are “debug”, “warning”, “error”, “critical”, with “info” as default.
- acr_snr & snr Task options:
- --measured_slice_width=<mm>
Provide a slice width to be used for SNR measurement, by default it is parsed from the DICOM (optional for acr_snr and snr)
- --subtract=<folder2>
Provide a second folder path to calculate SNR by subtraction for the ACR phantom (optional for acr_snr)
- relaxometry Task options:
- --calc=<n>
Choose ‘T1’ or ‘T2’ for relaxometry measurement (required)
- --plate_number=<n>
Which plate to use for measurement: 4 or 5 (required)
- hazenlib.init_task(selected_task, files, report, report_dir, **kwargs)[source]
Initialise object of the correct HazenTask class
- Parameters
selected_task (string) – name of task script/module to load
files (list) – list of filepaths to DICOM images
report (bool) – whether to generate report images
report_dir (string) – path to folder to save report images to
kwargs – any other key word arguments
- Returns
an object of the specified HazenTask class
Task-specific functions
Utility functions:
hazenlib.ACRObject
- class hazenlib.ACRObject.ACRObject(dcm_list)[source]
Bases:
objectBase class for performing tasks on image sets of the ACR phantom.
acquired following the ACR Large phantom guidelines
- sort_dcms(dcm_list)[source]
Sort a stack of DICOM images based on slice position.
- Parameters
dcm_list (list) – list of pyDICOM image objects
- Returns
sorted list of pydicom.Dataset objects
- Return type
list
- order_phantom_slices(dcm_list)[source]
Determine slice order based on the detection of the small circle in the first slice # or an LR orientation swap is required.
# This function analyzes the given set of images and their associated DICOM objects to determine if any # adjustments are needed to restore the correct slice order and view orientation.
- Parameters
dcm_list (list) – list of pyDICOM image objects
- Returns
sorted list of pydicom.Dataset objects corresponding to ordered phantom slices
- Return type
list
- static determine_rotation(img)[source]
Determine the rotation angle of the phantom using edge detection and the Hough transform.
- Parameters
img (np.ndarray) – pixel array of a DICOM object
- Returns
The rotation angle in degrees.
- Return type
float
- rotate_images(dcm_list, rot_angle)[source]
Rotate the images by a specified angle. The value range and dimensions of the image are preserved.
- Parameters
dcm_list (list) – list of pyDICOM image objects
rot_angle (float) – angle in degrees that image (pixel array) should be rotated by
- Returns
The rotated images.
- Return type
list of np.ndarray
- static find_phantom_center(img, dx, dy)[source]
Find the center of the ACR phantom in a given slice (pixel array)
using the Hough circle detector on a blurred image.
- Parameters
img (np.ndarray) – pixel array of the DICOM image.
- Returns
(x, y) coordinates of the center of the image
- Return type
tuple of ints
- get_mask_image(image, mag_threshold=0.07, open_threshold=500)[source]
Create a masked pixel array.
Mask an image by magnitude threshold before applying morphological opening to remove small unconnected features. The convex hull is calculated in order to accommodate for potential air bubbles.
- Parameters
image (np.ndarray) – pixel array of the dicom
mag_threshold (float, optional) – magnitude threshold. Defaults to 0.07.
open_threshold (int, optional) – open threshold. Defaults to 500.
- Returns
the masked image
- Return type
np.ndarray
- static circular_mask(centre, radius, dims)[source]
Generates a circular mask using given centre coordinates and a given radius. Generates a linspace grid the size of the given dimensions and checks whether each point on the linspace grid is within the desired radius from the given centre coordinates. Each linspace value within the chosen radius then becomes part of the mask.
- Parameters
centre (tuple) – centre coordinates of the circular mask.
radius (int) – radius of the circular mask.
dims (tuple) – dimensions to create the base linspace grid from.
- Returns
A sorted stack of images, where each image is represented as a 2D numpy array.
- Return type
np.ndarray
- measure_orthogonal_lengths(mask, slice_index)[source]
Compute the horizontal and vertical lengths of a mask, based on the centroid.
- Parameters
mask (np.ndarray) – Boolean array of the image where pixel values meet threshold
- Returns
- a dictionary with the following:
- ’Horizontal Start’ | ‘Vertical Start’tuple of int
Horizontal/vertical starting point of the object.
- ’Horizontal End’ | ‘Vertical End’tuple of int
Horizontal/vertical ending point of the object.
- ’Horizontal Extent’ | ‘Vertical Extent’np.ndarray of int
Indices of the non-zero elements of the horizontal/vertical line profile.
- ’Horizontal Distance’ | ‘Vertical Distance’float
The horizontal/vertical length of the object.
- Return type
dict
- static rotate_point(origin, point, angle)[source]
Compute the horizontal and vertical lengths of a mask, based on the centroid.
- Parameters
origin (tuple) – The coordinates of the point around which the rotation is performed.
point (tuple) – The coordinates of the point to rotate.
angle (int) – Angle in degrees.
- Returns
Floats representing the x and y coordinates of the input point after being rotated around an origin.
- Return type
tuple of float
- static find_n_highest_peaks(data, n, height=1)[source]
Find the indices and amplitudes of the N highest peaks within a 1D array.
- Parameters
data (np.ndarray) – pixel array containing the data to perform peak extraction on
n (int) – The coordinates of the point to rotate
height (int, optional) – The amplitude threshold for peak identification. Defaults to 1.
- Returns
peak_locs: A numpy array containing the indices of the N highest peaks identified.
peak_heights: A numpy array containing the amplitudes of the N highest peaks identified.
- Return type
tuple of np.ndarray
hazenlib.HazenTask
HazenTask.py
- class hazenlib.HazenTask.HazenTask(input_data: list, report: bool = False, report_dir=None, **kwargs)[source]
Bases:
objectBase class for performing tasks on image sets
- init_result_dict() dict[source]
Initialise the dictionary that holds measurement results and input description
- Returns
holds measurement results and task input description
- Return type
dict
- img_desc(dcm, properties=None) str[source]
Obtain values from the DICOM header to identify input series
- Parameters
dcm (pydicom.Dataset) – DICOM image object
properties (list, optional) – list of DICOM header field names supported by pydicom that shuld be used to generate sereis identifier. Defaults to None.
- Returns
contatenation of the specified DICOM header property values
- Return type
str
hazenlib.exceptions
Application-specific errors
- exception hazenlib.exceptions.ShapeError(shape, msg=None)[source]
Bases:
ExceptionBase exception for shapes.
- exception hazenlib.exceptions.ShapeDetectionError(shape, msg=None)[source]
Bases:
ShapeErrorShape not found
- exception hazenlib.exceptions.MultipleShapesError(shape, msg=None)[source]
Bases:
ShapeDetectionErrorShape not found
hazenlib.logger
hazenlib.utils
- hazenlib.utils.get_dicom_files(folder: str, sort=False) list[source]
Collect files in the folder into a list if they are parsable DICOMs
- Parameters
folder (str) – path to folder
sort (bool, optional) – whether to sort file list based on InstanceNumber. Defaults to False.
- Returns
full path to DICOM files found within a folder
- Return type
list
- hazenlib.utils.is_dicom_file(filename)[source]
Check if file is a DICOM file, using the the first 128 bytes are preamble the next 4 bytes should contain DICM otherwise it is not a dicom
- Parameters
filename (str) – path to file to be checked for the DICM header block
- Returns
True or False whether file is a DICOM
- Return type
bool
- hazenlib.utils.is_enhanced_dicom(dcm: Dataset) bool[source]
Check if file is an enhanced DICOM file
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Raises
Exception – Unrecognised_SOPClassUID
- Returns
True or False whether file is an enhanced DICOM
- Return type
bool
- hazenlib.utils.get_manufacturer(dcm: Dataset) str[source]
Get the manufacturer field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Raises
Exception – _description_
- Returns
manufacturer of the scanner used to obtain the DICOM image
- Return type
str
- hazenlib.utils.get_average(dcm: Dataset) float[source]
Get the NumberOfAverages field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
value of the NumberOfAverages field from the DICOM header
- Return type
float
- hazenlib.utils.get_bandwidth(dcm: Dataset) float[source]
Get the PixelBandwidth field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
value of the PixelBandwidth field from the DICOM header
- Return type
float
- hazenlib.utils.get_num_of_frames(dcm: Dataset) int[source]
Get the number of frames from the DICOM pixel_array
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
value of the PixelBandwidth field from the DICOM header
- Return type
float
- hazenlib.utils.get_slice_thickness(dcm: Dataset) float[source]
Get the SliceThickness field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
value of the SliceThickness field from the DICOM header
- Return type
float
- hazenlib.utils.get_pixel_size(dcm: ~pydicom.dataset.Dataset) -> (<class 'float'>, <class 'float'>)[source]
Get the PixelSpacing field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
x and y values of the PixelSpacing field from the DICOM header
- Return type
tuple of float
- hazenlib.utils.get_TR(dcm: Dataset) float[source]
Get the RepetitionTime field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
value of the RepetitionTime field from the DICOM header, or defaults to 1000
- Return type
float
- hazenlib.utils.get_rows(dcm: Dataset) float[source]
Get the Rows field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
value of the Rows field from the DICOM header, or defaults to 256
- Return type
float
- hazenlib.utils.get_columns(dcm: Dataset) float[source]
Get the Columns field from the DICOM header
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Returns
value of the Columns field from the DICOM header, or defaults to 256
- Return type
float
- hazenlib.utils.get_field_of_view(dcm: Dataset)[source]
Get Field of View value from DICOM header depending on manufacturer encoding
- Parameters
dcm (pydicom.Dataset) – DICOM image object
- Raises
NotImplementedError – Manufacturer not GE, Siemens, Toshiba or Philips so FOV cannot be calculated.
- Returns
value of the Field of View (calculated as Columns * PixelSpacing[0])
- Return type
float
- hazenlib.utils.get_image_orientation(iop)[source]
From http://dicomiseasy.blogspot.com/2013/06/getting-oriented-using-image-plane.html
- Parameters
iop (list) – values of dcm.ImageOrientationPatient - list of float
- Returns
Sagittal, Coronal or Transverse
- Return type
str
- hazenlib.utils.determine_orientation(dcm_list)[source]
Determine the phantom orientation based on DICOM metadata from a list of DICOM images.
Note
The ImageOrientationPatient tag is a record of the orientation of the imaging volume which contains the phantom. The orientation of the imaging volume MAY NOT align with the true phantom orientation.
- Parameters
dcm_list (list) – list of pyDICOM image objects.
- Returns
“saggital”, “coronal”, “axial”, or “unexpected” orientation.
list of the changing ImagePositionPatient values.
- Return type
tuple (string, list)
- hazenlib.utils.rescale_to_byte(array)[source]
WARNING: This function normalises/equalises the histogram. This might have unintended consequences.
- Parameters
array (np.array) – dcm.pixel_array
- Returns
normalised pixel values as 8-bit (byte) integer
- Return type
np.array
- class hazenlib.utils.Rod(x, y)[source]
Bases:
objectClass for rods detected in the image
- property centroid
- class hazenlib.utils.ShapeDetector(arr)[source]
Bases:
objectClass for the detection of shapes in pixel arrays This class is largely adapted from https://www.pyimagesearch.com/2016/02/08/opencv-shape-detection/
- detect()[source]
Detect specified shapes in pixel array
- Currently supported shapes:
circle
triangle
rectangle
pentagon
- get_shape(shape)[source]
Identify shapes in pixel array
- Parameters
shape (_type_) – _description_
- Raises
exc.ShapeDetectionError – ensure that only expected shapes are detected
exc.MultipleShapesError – ensure that only 1 shape is detected
- Returns
- varies depending on shape detected
circle: x, y, r - corresponding to x,y coords of centre and radius
rectangle/square: (x, y), size, angle - corresponding to x,y coords of centre, size (tuple) and angle in degrees
- Return type
tuple