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 91 92 93 94 95 96 97 98 99 | import type { Types } from '@cornerstonejs/core';
import { state } from '../../stateManagement/annotation';
import {
RectangleROIStartEndThresholdTool,
RectangleROIThresholdTool,
} from '../../tools';
import thresholdVolumeByRange from './thresholdVolumeByRange';
import getBoundsIJKFromRectangleAnnotations from '../rectangleROITool/getBoundsIJKFromRectangleAnnotations';
export type ThresholdRangeOptions = {
lower: number;
upper: number;
numSlicesToProject?: number; // number of slices to project before and after current slice
overwrite: boolean;
};
export type AnnotationForThresholding = {
data: {
handles: {
points: Types.Point3[];
};
cachedStats?: {
projectionPoints?: Types.Point3[][];
};
};
};
/**
* It uses the provided rectangleROI annotations (either RectangleROIThreshold, or
* RectangleROIStartEndThreshold) to compute an ROI that is the intersection of
* all the annotations. Then it uses the rectangleROIThreshold utility to threshold
* the volume.
* @param annotations - rectangleROI annotations to use for ROI
* @param segmentationVolume - the segmentation volume
* @param referenceVolumes - the reference volumes to use for the segmentation volume
* @param options - options for thresholding
* @returns
*/
function rectangleROIThresholdVolumeByRange(
annotationUIDs: string[],
segmentationVolume: Types.IImageVolume,
referenceVolumes: Types.IImageVolume[],
options: ThresholdRangeOptions
): Types.IImageVolume {
if (referenceVolumes.length > 1) {
throw new Error(
'thresholding based on more than one reference volumes data is not supported yet'
);
}
const referenceVolume = referenceVolumes[0];
const annotations = annotationUIDs.map((annotationUID) => {
return state.getAnnotation(annotationUID);
});
_validateAnnotations(annotations);
const boundsIJK = getBoundsIJKFromRectangleAnnotations(
annotations,
referenceVolume,
options
);
const optionsToUse = {
lower: options.lower,
upper: options.upper,
overwrite: options.overwrite,
boundsIJK,
};
const outputSegmentationVolume = thresholdVolumeByRange(
segmentationVolume,
referenceVolume,
optionsToUse
);
return outputSegmentationVolume;
}
function _validateAnnotations(annotations) {
const validToolNames = [
RectangleROIThresholdTool.toolName,
RectangleROIStartEndThresholdTool.toolName,
];
for (const annotation of annotations) {
const name = annotation.metadata.toolName;
if (!validToolNames.includes(name)) {
throw new Error(
'rectangleROIThresholdVolumeByRange only supports RectangleROIThreshold and RectangleROIStartEndThreshold annotations'
);
}
}
}
export default rectangleROIThresholdVolumeByRange;
|