All files / tools/src/stateManagement/segmentation/utilities smoothContours.ts

0% Statements 0/25
0% Branches 0/15
0% Functions 0/2
0% Lines 0/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                                                                                                                                                                                   
import type { Types } from '@cornerstonejs/core';
import type {
  ContourSegmentationAnnotation,
  ContourSegmentationData,
} from '../../../types';
import { getAnnotation } from '../../annotation/annotationState';
import { getSegmentation } from '../getSegmentation';
import interpolateSegmentPoints from '../../../utilities/planarFreehandROITool/interpolation/interpolateSegmentPoints';
 
/**
 * Smooths contour polylines for a given segmentation and segment using B-spline interpolation.
 * This function applies smoothing to reduce jagged edges and create more natural-looking contours
 * while preserving the overall shape and important features.
 *
 * @param segmentationId - The unique identifier of the segmentation
 * @param segmentIndex - The index of the segment within the segmentation
 * @param options - Configuration options for smoothing
 * @param options.knotsRatioPercentage - The percentage of points to use as knots for interpolation (default: 30)
 *   This parameter controls the balance between smoothing quality and shape preservation:
 *   - Higher values (50-70%): Use more original points as control knots, which tends to degrade
 *     the smoothing effect as the spline follows the original contour more closely. Results in
 *     less smooth curves but better preservation of original shape details.
 *   - Lower values (10-20%): Use fewer original points as control knots, creating smoother curves
 *     but may cause contour deformation, especially when the original contour has few points.
 *     With insufficient control points, the spline may not accurately represent the intended shape.
 *   - Optimal range (20-40%): Generally provides good balance between smoothing and shape fidelity.
 */
export default function smoothContours(
  segmentationId: string,
  segmentIndex: number,
  options: { knotsRatioPercentage: number } = { knotsRatioPercentage: 30 }
) {
  const segmentation = getSegmentation(segmentationId);
  if (!segmentation) {
    console.warn(`Invalid segmentation given ${segmentationId}`);
    return;
  }
  if (!segmentation.representationData.Contour) {
    console.warn(
      `No contour representation found for segmentation ${segmentationId}`
    );
    return;
  }
 
  const contourRepresentationData = segmentation.representationData
    .Contour as ContourSegmentationData;
 
  const { annotationUIDsMap } = contourRepresentationData;
  if (!annotationUIDsMap) {
    console.warn(`No contours found for segmentation ${segmentationId}`);
    return;
  }
 
  if (!annotationUIDsMap.has(segmentIndex)) {
    console.warn(
      `Error extracting contour data from segment ${segmentIndex} in segmentation ${segmentationId}`
    );
    return;
  }
 
  const annotationList = annotationUIDsMap.get(segmentIndex);
 
  annotationList.forEach((annotationUID) => {
    const annotation = getAnnotation(
      annotationUID
    ) as ContourSegmentationAnnotation;
    if (!annotation) {
      return;
    }
 
    const polyline = annotation.data.contour.polyline;
 
    // Check if we have enough points to smooth
    if (!polyline || polyline.length < 3) {
      return;
    }
 
    // Smooth the polyline using interpolateSegmentPoints
    const smoothedPolyline = interpolateSegmentPoints(
      polyline,
      0,
      polyline.length - 1,
      options.knotsRatioPercentage
    ) as Types.Point3[];
 
    // Update the polyline in the annotation
    annotation.data.contour.polyline = smoothedPolyline;
  });
}