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 via smooth2DContour(), regenerates raster segments, and either replaces the original structure in planC or appends a new one depending on replace_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. When False the 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.plan_container.PlanC

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 tol indices are split into separate regions. Defaults to 4.

  • 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 True pixels in each row of maskM and 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, where True indicates 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:
Returns:

Boolean array of shape (nRows, nCols, nSlices) where True indicates 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 rasterSegments are included in the output stack.

Parameters:
  • rasterSegments (np.ndarray) –

    Array of shape (N, >=9) where each row is a raster segment produced by generateRastersegs(). 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 when rasterSegments is 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 with polyFill(), and then encoded as run-length segments by mask2scan(). 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:
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 empty np.ndarray when the structure has no contour data.

Return type:

np.ndarray

Module contents