cerr.contour package
Submodules
cerr.contour.contour_processing module
- cerr.contour.contour_processing.smoothStructure(planC, struct_idx, replace_original=True, name_suffix='', tol=4, taubin_mu=0.8, taubin_factor=0.8, catmull_alpha=1)[source]
Apply 2-D contour smoothing to every segment of a structure in planC.
Deep-copies the structure at
struct_idx, applies piecewise smoothing to each 2-D contour segment viasmooth2DContour(), regenerates raster segments, and either replaces the original structure inplanCor appends a new one depending onreplace_original.- Parameters:
planC (cerr.plan_container.PlanC) – pyCERR plan container object.
struct_idx (int) – Index of the structure to smooth in
planC.structure.replace_original (bool, optional) – When
True(default) the smoothed structure overwrites the original entry. WhenFalsethe smoothed structure is appended as a new entry.name_suffix (str, optional) – String appended to the structure name of the smoothed copy. Defaults to
"".tol (int, optional) – Minimum gap (in vertices) between jagged regions for them to be treated as separate segments. Defaults to
4.taubin_mu (float, optional) – Mu parameter for Taubin smoothing of jagged regions. Defaults to
0.8.taubin_factor (float, optional) – Factor (lambda) for Taubin smoothing. Defaults to
0.8.catmull_alpha (float, optional) – Alpha parameter for Catmull-Rom interpolation of smooth regions. Defaults to
1.
- Returns:
The updated plan container with the smoothed structure in place (or appended).
- Return type:
- cerr.contour.contour_processing.smooth2DContour(C, tol=4, taubin_mu=0.8, taubin_factor=0.8, catmull_alpha=1)[source]
Piecewise-smooth a closed 2-D contour in place.
Identifies “jagged” vertices — those where the cosine of the interior angle (
dot(v1, v2) / (|v1| |v2|)) is either very small (near-perpendicular turns) or very close to 1 (near-collinear, i.e. micro-steps) — groups them into contiguous jagged regions, and applies Taubin smoothing to each jagged region while using Catmull-Rom interpolation on the smooth regions in between. If no jagged vertices are detected the original 2-D coordinates are returned unchanged.- Parameters:
C (np.ndarray) – Contour vertex array of shape
(N, 3)or(N, 2). When 3 columns are present the third (z) column is stripped before processing and not included in the output.tol (int, optional) – Maximum vertex-index gap allowed within a single jagged region. Adjacent jagged vertices separated by more than
tolindices are split into separate regions. Defaults to4.taubin_mu (float, optional) – Mu parameter for Taubin smoothing. Defaults to
0.8.taubin_factor (float, optional) – Factor (lambda) parameter for Taubin smoothing. Defaults to
0.8.catmull_alpha (float, optional) – Alpha parameter for Catmull-Rom interpolation. Defaults to
1.
- Returns:
piecewise_segs (np.ndarray): Smoothed contour vertices as an array of shape
(M, 2)containing only the x/y coordinates. Returns the original(N, 2)array unchanged when no jagged segments are found.taubin_range (list[list[int]] | list): List of
[start, end]vertex-index pairs identifying each jagged region that was Taubin-smoothed. Empty list when no jagged segments were found.
- Return type:
tuple
cerr.contour.rasterseg module
rasterseg module.
Ths rasterseg module defines methods for creation of raster segments from polygonal coordinates and to assemble binary mask from rastersegments.
- cerr.contour.rasterseg.polyFill(rowV, colV, xSize, ySize)[source]
Rasterize a closed polygon into a binary 2-D mask using scanline filling.
Converts a polygon defined by row/column vertex coordinates into a filled binary mask of the requested dimensions. Flat (horizontal) edges and vertex intersections are handled explicitly so that adjacent polygons produce a consistent, non-overlapping fill.
- Parameters:
rowV (array-like) – Row (x) coordinates of the polygon vertices, in order. The polygon is automatically closed (last point connects back to the first).
colV (array-like) – Column (y) coordinates matching
rowV.xSize (int) – Number of rows in the output mask.
ySize (int) – Number of columns in the output mask.
- Returns:
Boolean mask of shape
(xSize, ySize)where filled pixels are 1 and background pixels are 0.- Return type:
np.ndarray
- cerr.contour.rasterseg.xytom(xV, yV, sliceNum, planC, scanNum)[source]
Convert physical (AAPM/DICOM) x/y coordinates to image row/column indices.
Scales the supplied physical coordinates by the per-slice grid spacing and then delegates to
aapmtom()to apply the CT offset and image-centre shift, returning zero-based row and column indices suitable for indexing into the scan array.- Parameters:
xV (np.ndarray) – Physical x-coordinates (cm) of the contour points.
yV (np.ndarray) – Physical y-coordinates (cm) of the contour points.
sliceNum (int) – Zero-based slice index used to look up slice-specific grid spacing from
planC.planC (cerr.plan_container.PlanC) – pyCERR plan container object.
scanNum (int) – Index of the scan set in
planC.scan.
- Returns:
rowV (np.ndarray): Zero-based row indices corresponding to the input coordinates.
colV (np.ndarray): Zero-based column indices corresponding to the input coordinates.
- Return type:
tuple
- cerr.contour.rasterseg.mask2scan(maskM, optS, sliceNum)[source]
Convert a 2-D binary mask into raster-segment run-length rows.
Detects the start and stop column positions of every contiguous run of
Truepixels in each row ofmaskMand encodes each run as a segment row containing the physical y/x start/stop coordinates, voxel width, slice number, and pixel indices.- Parameters:
maskM (np.ndarray) – 2-D boolean mask of shape
(rows, cols)for a single slice, whereTrueindicates structure voxels.optS (dict) –
Option dictionary with the following required keys:
"ROIxVoxelWidth"(float): Voxel width in the x-direction (cm)."ROIyVoxelWidth"(float): Voxel width in the y-direction (cm)."xCTOffset"(float): CT x-offset (cm)."yCTOffset"(float): CT y-offset (cm).
sliceNum (int or float) – Slice index to record in the segment array.
- Returns:
Array of shape
(N, 8)where each row encodes one run-length segment:[y_start, x_start, x_stop, delta_x, slice_num, row_idx, col_start_idx, col_stop_idx].- Return type:
np.ndarray
- Raises:
ValueError – If the derived y-start and y-stop values for any segment are inconsistent, indicating a conversion error.
- cerr.contour.rasterseg.aapmtom(xAAPMShifted, yAAPMShifted, xOffset, yOffset, ImageWidth, voxelSizeV=[1, 1])[source]
Convert AAPM/DICOM-shifted physical coordinates to zero-based image row/column indices.
Applies CT-offset correction, optional voxel-size scaling, and the image-centre shift to map physical (AAPM convention) x/y coordinates into zero-based row and column indices. Values are snapped to the nearest integer when they fall within a tight tolerance, avoiding floating-point artefacts at pixel boundaries.
- Parameters:
xAAPMShifted (np.ndarray) – Physical x-coordinates already shifted by the CT x-offset (cm).
yAAPMShifted (np.ndarray) – Physical y-coordinates already shifted by the CT y-offset (cm).
xOffset (float) – CT x-offset (cm) to subtract from the shifted coordinates.
yOffset (float) – CT y-offset (cm) to subtract from the shifted coordinates.
ImageWidth (list[int]) – Two-element list
[nRows, nCols]giving the image dimensions in pixels.voxelSizeV (list[float], optional) – Two-element list
[yVoxelSize, xVoxelSize]in cm. Defaults to[1, 1](i.e. coordinates are already in pixel units).
- Returns:
Row (np.ndarray): Zero-based row indices.
Col (np.ndarray): Zero-based column indices.
- Return type:
tuple
- cerr.contour.rasterseg.mtoaapm(Row, Col, Dims, gridUnits=[1, 1], offset=[0, 0])[source]
Convert zero-based image row/column indices to physical AAPM x/y coordinates.
Inverts the AAPM-to-matrix mapping: given pixel row and column indices, computes the physical (AAPM convention) x and y coordinates by applying the image-centre shift, optional voxel-size scaling, and an additional coordinate offset.
- Parameters:
Row (np.ndarray) – Zero-based row indices into the image array.
Col (np.ndarray) – Zero-based column indices into the image array.
Dims (list[int]) – Two-element list
[nRows, nCols]giving the image dimensions in pixels.gridUnits (list[float], optional) – Two-element list
[yGridUnit, xGridUnit]specifying voxel size in cm. When both elements are 1 (default) coordinates are returned in pixel units.offset (list[float], optional) – Two-element list
[yOffset, xOffset]added to the scaled coordinates (cm). Defaults to[0, 0].
- Returns:
xAAPM (np.ndarray): Physical x-coordinates (cm) in the AAPM frame.
yAAPM (np.ndarray): Physical y-coordinates (cm) in the AAPM frame.
- Return type:
tuple
- cerr.contour.rasterseg.getStrMask(str_num, planC)[source]
Return a full 3-D binary mask for a structure across all scan slices.
Looks up the raster segments for the specified structure, determines the associated scan dimensions, and assembles a boolean volumetric mask by calling
raster_to_mask()and placing the per-slice masks into the correct slice positions.- Parameters:
str_num (int | float | np.integer | cerr.dataclasses.structure.Structure) – Either the integer index of the structure in
planC.structure, or a structure object itself.planC (cerr.plan_container.PlanC) – pyCERR plan container object.
- Returns:
Boolean array of shape
(nRows, nCols, nSlices)whereTrueindicates voxels belonging to the structure.- Return type:
np.ndarray
- cerr.contour.rasterseg.raster_to_mask(rasterSegments, scanNum, planC)[source]
Convert raster segments to a stack of per-slice 2-D binary masks.
Iterates over the run-length encoded raster segment rows and fills the corresponding pixel spans in a 3-D boolean array indexed by unique slice number. Only the slices actually referenced in
rasterSegmentsare included in the output stack.- Parameters:
rasterSegments (np.ndarray) –
Array of shape
(N, >=9)where each row is a raster segment produced bygenerateRastersegs(). Column indices used:[:, 5]– CT slice number (zero-based).[:, 6]– Row index within the slice.[:, 7]– Start column index of the filled run.[:, 8]– Stop column index of the filled run (inclusive).
scanNum (int) – Index of the scan set in
planC.scan, used to determine the slice dimensions.planC (cerr.plan_container.PlanC) – pyCERR plan container object.
- Returns:
dataSet (np.ndarray): Boolean array of shape
(nRows, nCols, nUniqueSlices)containing the filled masks. Returns a single empty(nRows, nCols)slice whenrasterSegmentsis empty.uniqueSlices (np.ndarray | list): Sorted array of the unique CT slice indices represented in
rasterSegments, or an empty list when there are no segments.
- Return type:
tuple
- cerr.contour.rasterseg.generateRastersegs(strObj, planC)[source]
Generate raster-segment run-length encoding from a structure’s contour polygons.
For each slice that contains contour data, the polygon vertices are converted from physical coordinates to image row/column indices via
xytom(), rasterized into a binary mask withpolyFill(), and then encoded as run-length segments bymask2scan(). The z-coordinate and voxel thickness are appended to each segment row, and all slices are stacked into a single array.Special-case handling ensures that single-point or duplicate-point contours produce at least one filled pixel.
- Parameters:
strObj (cerr.dataclasses.structure.Structure) – Structure object whose
contourlist provides the per-slice polygon data, and whoseassocScanUIDattribute identifies the parent scan.planC (cerr.plan_container.PlanC) – pyCERR plan container object used to retrieve scan geometry.
- Returns:
Array of shape
(N, 10)where each row encodes one raster segment:[z_value, y_start, x_start, x_stop, delta_x, slice_num, row_idx, col_start_idx, col_stop_idx, voxel_thickness]. Returns an emptynp.ndarraywhen the structure has no contour data.- Return type:
np.ndarray