@cornerstonejs/tools 0.34.2 → 0.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,13 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
- export declare type ThresholdRangeOptions = {
2
+ export declare type ThresholdInformation = {
3
+ volume: Types.IImageVolume;
3
4
  lower: number;
4
5
  upper: number;
6
+ };
7
+ export declare type ThresholdOptions = {
5
8
  numSlicesToProject?: number;
6
9
  overwrite: boolean;
10
+ overlapType?: number;
7
11
  };
8
12
  export declare type AnnotationForThresholding = {
9
13
  data: {
@@ -15,5 +19,5 @@ export declare type AnnotationForThresholding = {
15
19
  };
16
20
  };
17
21
  };
18
- declare function rectangleROIThresholdVolumeByRange(annotationUIDs: string[], segmentationVolume: Types.IImageVolume, referenceVolumes: Types.IImageVolume[], options: ThresholdRangeOptions): Types.IImageVolume;
22
+ declare function rectangleROIThresholdVolumeByRange(annotationUIDs: string[], segmentationVolume: Types.IImageVolume, thresholdVolumeInformation: ThresholdInformation[], options: ThresholdOptions): Types.IImageVolume;
19
23
  export default rectangleROIThresholdVolumeByRange;
@@ -7,23 +7,19 @@ const annotation_1 = require("../../stateManagement/annotation");
7
7
  const tools_1 = require("../../tools");
8
8
  const thresholdVolumeByRange_1 = __importDefault(require("./thresholdVolumeByRange"));
9
9
  const getBoundsIJKFromRectangleAnnotations_1 = __importDefault(require("../rectangleROITool/getBoundsIJKFromRectangleAnnotations"));
10
- function rectangleROIThresholdVolumeByRange(annotationUIDs, segmentationVolume, referenceVolumes, options) {
11
- if (referenceVolumes.length > 1) {
12
- throw new Error('thresholding based on more than one reference volumes data is not supported yet');
13
- }
14
- const referenceVolume = referenceVolumes[0];
10
+ function rectangleROIThresholdVolumeByRange(annotationUIDs, segmentationVolume, thresholdVolumeInformation, options) {
15
11
  const annotations = annotationUIDs.map((annotationUID) => {
16
12
  return annotation_1.state.getAnnotation(annotationUID);
17
13
  });
18
14
  _validateAnnotations(annotations);
19
- const boundsIJK = (0, getBoundsIJKFromRectangleAnnotations_1.default)(annotations, referenceVolume, options);
20
- const optionsToUse = {
21
- lower: options.lower,
22
- upper: options.upper,
23
- overwrite: options.overwrite,
24
- boundsIJK,
25
- };
26
- const outputSegmentationVolume = (0, thresholdVolumeByRange_1.default)(segmentationVolume, referenceVolume, optionsToUse);
15
+ let boundsIJK;
16
+ for (let i = 0; i < thresholdVolumeInformation.length; i++) {
17
+ const volumeSize = thresholdVolumeInformation[i].volume.scalarData.length;
18
+ if (volumeSize === segmentationVolume.scalarData.length || i === 0) {
19
+ boundsIJK = (0, getBoundsIJKFromRectangleAnnotations_1.default)(annotations, thresholdVolumeInformation[i].volume, options);
20
+ }
21
+ }
22
+ const outputSegmentationVolume = (0, thresholdVolumeByRange_1.default)(segmentationVolume, thresholdVolumeInformation, Object.assign(Object.assign({}, options), { boundsIJK }));
27
23
  return outputSegmentationVolume;
28
24
  }
29
25
  function _validateAnnotations(annotations) {
@@ -1 +1 @@
1
- {"version":3,"file":"rectangleROIThresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts"],"names":[],"mappings":";;;;;AACA,iEAAyD;AACzD,uCAGqB;AAErB,sFAA8D;AAC9D,oIAA4G;AA+B5G,SAAS,kCAAkC,CACzC,cAAwB,EACxB,kBAAsC,EACtC,gBAAsC,EACtC,OAA8B;IAE9B,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;QAC/B,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;KACH;IAED,MAAM,eAAe,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAE5C,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE;QACvD,OAAO,kBAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAElC,MAAM,SAAS,GAAG,IAAA,8CAAoC,EACpD,WAAW,EACX,eAAe,EACf,OAAO,CACR,CAAC;IAEF,MAAM,YAAY,GAAG;QACnB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS;KACV,CAAC;IAEF,MAAM,wBAAwB,GAAG,IAAA,gCAAsB,EACrD,kBAAkB,EAClB,eAAe,EACf,YAAY,CACb,CAAC;IAEF,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAED,SAAS,oBAAoB,CAAC,WAAW;IACvC,MAAM,cAAc,GAAG;QACrB,iCAAyB,CAAC,QAAQ;QAClC,yCAAiC,CAAC,QAAQ;KAC3C,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAClC,MAAM,IAAI,KAAK,CACb,sHAAsH,CACvH,CAAC;SACH;KACF;AACH,CAAC;AAED,kBAAe,kCAAkC,CAAC"}
1
+ {"version":3,"file":"rectangleROIThresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts"],"names":[],"mappings":";;;;;AACA,iEAAyD;AACzD,uCAGqB;AAErB,sFAA8D;AAC9D,oIAA4G;AAoC5G,SAAS,kCAAkC,CACzC,cAAwB,EACxB,kBAAsC,EACtC,0BAAkD,EAClD,OAAyB;IAEzB,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE;QACvD,OAAO,kBAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAElC,IAAI,SAAS,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,0BAA0B,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAE1D,MAAM,UAAU,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAC1E,IAAI,UAAU,KAAK,kBAAkB,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE;YAClE,SAAS,GAAG,IAAA,8CAAoC,EAC9C,WAAW,EACX,0BAA0B,CAAC,CAAC,CAAC,CAAC,MAAM,EACpC,OAAO,CACR,CAAC;SACH;KACF;IAED,MAAM,wBAAwB,GAAG,IAAA,gCAAsB,EACrD,kBAAkB,EAClB,0BAA0B,kCACrB,OAAO,KAAE,SAAS,IACxB,CAAC;IAEF,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAED,SAAS,oBAAoB,CAAC,WAAW;IACvC,MAAM,cAAc,GAAG;QACrB,iCAAyB,CAAC,QAAQ;QAClC,yCAAiC,CAAC,QAAQ;KAC3C,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAClC,MAAM,IAAI,KAAK,CACb,sHAAsH,CACvH,CAAC;SACH;KACF;AACH,CAAC;AAED,kBAAe,kCAAkC,CAAC"}
@@ -1,10 +1,14 @@
1
- import type { Types } from '@cornerstonejs/core';
1
+ import { Types } from '@cornerstonejs/core';
2
2
  import { BoundsIJK } from '../../types';
3
3
  export declare type ThresholdRangeOptions = {
4
- upper: number;
5
- lower: number;
6
- boundsIJK: BoundsIJK;
7
4
  overwrite: boolean;
5
+ boundsIJK: BoundsIJK;
6
+ overlapType?: number;
7
+ };
8
+ export declare type ThresholdInformation = {
9
+ volume: Types.IImageVolume;
10
+ lower: number;
11
+ upper: number;
8
12
  };
9
- declare function thresholdVolumeByRange(segmentationVolume: Types.IImageVolume, referenceVolume: Types.IImageVolume, options: ThresholdRangeOptions): Types.IImageVolume;
13
+ declare function thresholdVolumeByRange(segmentationVolume: Types.IImageVolume, thresholdVolumeInformation: ThresholdInformation[], options: ThresholdRangeOptions): Types.IImageVolume;
10
14
  export default thresholdVolumeByRange;
@@ -1,24 +1,112 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const core_1 = require("@cornerstonejs/core");
3
7
  const utilities_1 = require("../../utilities");
4
8
  const triggerSegmentationEvents_1 = require("../../stateManagement/segmentation/triggerSegmentationEvents");
5
- function thresholdVolumeByRange(segmentationVolume, referenceVolume, options) {
6
- const { scalarData, imageData: segmentationImageData } = segmentationVolume;
7
- const { overwrite, boundsIJK, upper, lower } = options;
8
- const { imageData } = referenceVolume;
9
- const referenceValues = imageData.getPointData().getScalars().getData();
9
+ const getBoundingBoxAroundShape_1 = __importDefault(require("../boundingBox/getBoundingBoxAroundShape"));
10
+ const equalsCheck = (a, b) => {
11
+ return JSON.stringify(a) === JSON.stringify(b);
12
+ };
13
+ function thresholdVolumeByRange(segmentationVolume, thresholdVolumeInformation, options) {
14
+ const { scalarData, spacing: segmentationSpacing, imageData: segmentationImageData, } = segmentationVolume;
15
+ const { overwrite, boundsIJK } = options;
16
+ const overlapType = (options === null || options === void 0 ? void 0 : options.overlapType) || 0;
10
17
  if (overwrite) {
11
18
  for (let i = 0; i < scalarData.length; i++) {
12
19
  scalarData[i] = 0;
13
20
  }
14
21
  }
15
- const callback = ({ index, pointIJK }) => {
22
+ const volumeInfoList = [];
23
+ let baseVolumeIdx = 0;
24
+ for (let i = 0; i < thresholdVolumeInformation.length; i++) {
25
+ const { imageData, spacing, dimensions } = thresholdVolumeInformation[i].volume;
26
+ const volumeSize = thresholdVolumeInformation[i].volume.scalarData.length;
27
+ if (volumeSize === scalarData.length &&
28
+ equalsCheck(spacing, segmentationSpacing)) {
29
+ baseVolumeIdx = i;
30
+ }
31
+ const referenceValues = imageData.getPointData().getScalars().getData();
32
+ const lower = thresholdVolumeInformation[i].lower;
33
+ const upper = thresholdVolumeInformation[i].upper;
34
+ volumeInfoList.push({
35
+ imageData,
36
+ referenceValues,
37
+ lower,
38
+ upper,
39
+ spacing,
40
+ dimensions,
41
+ volumeSize,
42
+ });
43
+ }
44
+ let overlaps, total, range;
45
+ const testOverlapRange = (volumeInfo, voxelSpacing, voxelCenter) => {
46
+ const callbackOverlap = ({ value }) => {
47
+ total = total + 1;
48
+ if (value >= range.lower && value <= range.upper) {
49
+ overlaps = overlaps + 1;
50
+ }
51
+ };
52
+ const { imageData, dimensions, lower, upper } = volumeInfo;
53
+ const overlapBounds = getVoxelOverlap(imageData, dimensions, voxelSpacing, voxelCenter);
54
+ total = 0;
55
+ overlaps = 0;
56
+ range = { lower, upper };
57
+ let overlapTest = false;
58
+ (0, utilities_1.pointInShapeCallback)(imageData, () => true, callbackOverlap, overlapBounds);
59
+ if (overlapType === 0) {
60
+ overlapTest = overlaps > 0;
61
+ }
62
+ else if (overlapType == 1) {
63
+ overlapTest = overlaps === total;
64
+ }
65
+ return overlapTest;
66
+ };
67
+ const testRange = (volumeInfo, pointIJK) => {
68
+ const { imageData, referenceValues, lower, upper } = volumeInfo;
16
69
  const offset = imageData.computeOffsetIndex(pointIJK);
17
70
  const value = referenceValues[offset];
18
71
  if (value <= lower || value >= upper) {
19
- return;
72
+ return false;
73
+ }
74
+ else {
75
+ return true;
76
+ }
77
+ };
78
+ const getVoxelOverlap = (imageData, dimensions, voxelSpacing, voxelCenter) => {
79
+ const voxelCornersWorld = [];
80
+ for (let i = 0; i < 2; i++) {
81
+ for (let j = 0; j < 2; j++) {
82
+ for (let k = 0; k < 2; k++) {
83
+ const point = voxelCenter;
84
+ point[0] = point[0] + ((i * 2 - 1) * voxelSpacing[0]) / 2;
85
+ point[1] = point[1] + ((j * 2 - 1) * voxelSpacing[1]) / 2;
86
+ point[2] = point[2] + ((k * 2 - 1) * voxelSpacing[2]) / 2;
87
+ voxelCornersWorld.push(point);
88
+ }
89
+ }
90
+ }
91
+ const voxelCornersIJK = voxelCornersWorld.map((world) => core_1.utilities.transformWorldToIndex(imageData, world));
92
+ const overlapBounds = (0, getBoundingBoxAroundShape_1.default)(voxelCornersIJK, dimensions);
93
+ return overlapBounds;
94
+ };
95
+ const callback = ({ index, pointIJK, pointLPS }) => {
96
+ let insert = volumeInfoList.length > 0;
97
+ for (let i = 0; i < volumeInfoList.length; i++) {
98
+ if (volumeInfoList[i].volumeSize === scalarData.length) {
99
+ insert = testRange(volumeInfoList[i], pointIJK);
100
+ }
101
+ else {
102
+ insert = testOverlapRange(volumeInfoList[i], volumeInfoList[baseVolumeIdx].spacing, pointLPS);
103
+ }
104
+ if (!insert) {
105
+ break;
106
+ }
20
107
  }
21
- scalarData[index] = 1;
108
+ if (insert)
109
+ scalarData[index] = 1;
22
110
  };
23
111
  (0, utilities_1.pointInShapeCallback)(segmentationImageData, () => true, callback, boundsIJK);
24
112
  (0, triggerSegmentationEvents_1.triggerSegmentationDataModified)(segmentationVolume.volumeId);
@@ -1 +1 @@
1
- {"version":3,"file":"thresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/thresholdVolumeByRange.ts"],"names":[],"mappings":";;AAEA,+CAAuD;AACvD,4GAA+G;AAkB/G,SAAS,sBAAsB,CAC7B,kBAAsC,EACtC,eAAmC,EACnC,OAA8B;IAE9B,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,qBAAqB,EAAE,GAAG,kBAAkB,CAAC;IAC5E,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEvD,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC;IACtC,MAAM,eAAe,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC;IAGxE,IAAI,SAAS,EAAE;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC1C,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACnB;KACF;IAED,MAAM,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE;YACpC,OAAO;SACR;QAGD,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,IAAA,gCAAoB,EAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE7E,IAAA,2DAA+B,EAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAE7D,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,kBAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"thresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/thresholdVolumeByRange.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,13 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
- export declare type ThresholdRangeOptions = {
2
+ export declare type ThresholdInformation = {
3
+ volume: Types.IImageVolume;
3
4
  lower: number;
4
5
  upper: number;
6
+ };
7
+ export declare type ThresholdOptions = {
5
8
  numSlicesToProject?: number;
6
9
  overwrite: boolean;
10
+ overlapType?: number;
7
11
  };
8
12
  export declare type AnnotationForThresholding = {
9
13
  data: {
@@ -15,5 +19,5 @@ export declare type AnnotationForThresholding = {
15
19
  };
16
20
  };
17
21
  };
18
- declare function rectangleROIThresholdVolumeByRange(annotationUIDs: string[], segmentationVolume: Types.IImageVolume, referenceVolumes: Types.IImageVolume[], options: ThresholdRangeOptions): Types.IImageVolume;
22
+ declare function rectangleROIThresholdVolumeByRange(annotationUIDs: string[], segmentationVolume: Types.IImageVolume, thresholdVolumeInformation: ThresholdInformation[], options: ThresholdOptions): Types.IImageVolume;
19
23
  export default rectangleROIThresholdVolumeByRange;
@@ -2,23 +2,19 @@ import { state } from '../../stateManagement/annotation';
2
2
  import { RectangleROIStartEndThresholdTool, RectangleROIThresholdTool, } from '../../tools';
3
3
  import thresholdVolumeByRange from './thresholdVolumeByRange';
4
4
  import getBoundsIJKFromRectangleAnnotations from '../rectangleROITool/getBoundsIJKFromRectangleAnnotations';
5
- function rectangleROIThresholdVolumeByRange(annotationUIDs, segmentationVolume, referenceVolumes, options) {
6
- if (referenceVolumes.length > 1) {
7
- throw new Error('thresholding based on more than one reference volumes data is not supported yet');
8
- }
9
- const referenceVolume = referenceVolumes[0];
5
+ function rectangleROIThresholdVolumeByRange(annotationUIDs, segmentationVolume, thresholdVolumeInformation, options) {
10
6
  const annotations = annotationUIDs.map((annotationUID) => {
11
7
  return state.getAnnotation(annotationUID);
12
8
  });
13
9
  _validateAnnotations(annotations);
14
- const boundsIJK = getBoundsIJKFromRectangleAnnotations(annotations, referenceVolume, options);
15
- const optionsToUse = {
16
- lower: options.lower,
17
- upper: options.upper,
18
- overwrite: options.overwrite,
19
- boundsIJK,
20
- };
21
- const outputSegmentationVolume = thresholdVolumeByRange(segmentationVolume, referenceVolume, optionsToUse);
10
+ let boundsIJK;
11
+ for (let i = 0; i < thresholdVolumeInformation.length; i++) {
12
+ const volumeSize = thresholdVolumeInformation[i].volume.scalarData.length;
13
+ if (volumeSize === segmentationVolume.scalarData.length || i === 0) {
14
+ boundsIJK = getBoundsIJKFromRectangleAnnotations(annotations, thresholdVolumeInformation[i].volume, options);
15
+ }
16
+ }
17
+ const outputSegmentationVolume = thresholdVolumeByRange(segmentationVolume, thresholdVolumeInformation, { ...options, boundsIJK });
22
18
  return outputSegmentationVolume;
23
19
  }
24
20
  function _validateAnnotations(annotations) {
@@ -1 +1 @@
1
- {"version":3,"file":"rectangleROIThresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AACzD,OAAO,EACL,iCAAiC,EACjC,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,OAAO,sBAAsB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,oCAAoC,MAAM,0DAA0D,CAAC;AA+B5G,SAAS,kCAAkC,CACzC,cAAwB,EACxB,kBAAsC,EACtC,gBAAsC,EACtC,OAA8B;IAE9B,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;QAC/B,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;KACH;IAED,MAAM,eAAe,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAE5C,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE;QACvD,OAAO,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAElC,MAAM,SAAS,GAAG,oCAAoC,CACpD,WAAW,EACX,eAAe,EACf,OAAO,CACR,CAAC;IAEF,MAAM,YAAY,GAAG;QACnB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS;KACV,CAAC;IAEF,MAAM,wBAAwB,GAAG,sBAAsB,CACrD,kBAAkB,EAClB,eAAe,EACf,YAAY,CACb,CAAC;IAEF,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAED,SAAS,oBAAoB,CAAC,WAAW;IACvC,MAAM,cAAc,GAAG;QACrB,yBAAyB,CAAC,QAAQ;QAClC,iCAAiC,CAAC,QAAQ;KAC3C,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAClC,MAAM,IAAI,KAAK,CACb,sHAAsH,CACvH,CAAC;SACH;KACF;AACH,CAAC;AAED,eAAe,kCAAkC,CAAC"}
1
+ {"version":3,"file":"rectangleROIThresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AACzD,OAAO,EACL,iCAAiC,EACjC,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,OAAO,sBAAsB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,oCAAoC,MAAM,0DAA0D,CAAC;AAoC5G,SAAS,kCAAkC,CACzC,cAAwB,EACxB,kBAAsC,EACtC,0BAAkD,EAClD,OAAyB;IAEzB,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE;QACvD,OAAO,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAElC,IAAI,SAAS,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,0BAA0B,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAE1D,MAAM,UAAU,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAC1E,IAAI,UAAU,KAAK,kBAAkB,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE;YAClE,SAAS,GAAG,oCAAoC,CAC9C,WAAW,EACX,0BAA0B,CAAC,CAAC,CAAC,CAAC,MAAM,EACpC,OAAO,CACR,CAAC;SACH;KACF;IAED,MAAM,wBAAwB,GAAG,sBAAsB,CACrD,kBAAkB,EAClB,0BAA0B,EAC1B,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAC1B,CAAC;IAEF,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAED,SAAS,oBAAoB,CAAC,WAAW;IACvC,MAAM,cAAc,GAAG;QACrB,yBAAyB,CAAC,QAAQ;QAClC,iCAAiC,CAAC,QAAQ;KAC3C,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAClC,MAAM,IAAI,KAAK,CACb,sHAAsH,CACvH,CAAC;SACH;KACF;AACH,CAAC;AAED,eAAe,kCAAkC,CAAC"}
@@ -1,10 +1,14 @@
1
- import type { Types } from '@cornerstonejs/core';
1
+ import { Types } from '@cornerstonejs/core';
2
2
  import { BoundsIJK } from '../../types';
3
3
  export declare type ThresholdRangeOptions = {
4
- upper: number;
5
- lower: number;
6
- boundsIJK: BoundsIJK;
7
4
  overwrite: boolean;
5
+ boundsIJK: BoundsIJK;
6
+ overlapType?: number;
7
+ };
8
+ export declare type ThresholdInformation = {
9
+ volume: Types.IImageVolume;
10
+ lower: number;
11
+ upper: number;
8
12
  };
9
- declare function thresholdVolumeByRange(segmentationVolume: Types.IImageVolume, referenceVolume: Types.IImageVolume, options: ThresholdRangeOptions): Types.IImageVolume;
13
+ declare function thresholdVolumeByRange(segmentationVolume: Types.IImageVolume, thresholdVolumeInformation: ThresholdInformation[], options: ThresholdRangeOptions): Types.IImageVolume;
10
14
  export default thresholdVolumeByRange;
@@ -1,22 +1,107 @@
1
+ import { utilities as csUtils } from '@cornerstonejs/core';
1
2
  import { pointInShapeCallback } from '../../utilities';
2
3
  import { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents';
3
- function thresholdVolumeByRange(segmentationVolume, referenceVolume, options) {
4
- const { scalarData, imageData: segmentationImageData } = segmentationVolume;
5
- const { overwrite, boundsIJK, upper, lower } = options;
6
- const { imageData } = referenceVolume;
7
- const referenceValues = imageData.getPointData().getScalars().getData();
4
+ import getBoundingBoxAroundShape from '../boundingBox/getBoundingBoxAroundShape';
5
+ const equalsCheck = (a, b) => {
6
+ return JSON.stringify(a) === JSON.stringify(b);
7
+ };
8
+ function thresholdVolumeByRange(segmentationVolume, thresholdVolumeInformation, options) {
9
+ const { scalarData, spacing: segmentationSpacing, imageData: segmentationImageData, } = segmentationVolume;
10
+ const { overwrite, boundsIJK } = options;
11
+ const overlapType = options?.overlapType || 0;
8
12
  if (overwrite) {
9
13
  for (let i = 0; i < scalarData.length; i++) {
10
14
  scalarData[i] = 0;
11
15
  }
12
16
  }
13
- const callback = ({ index, pointIJK }) => {
17
+ const volumeInfoList = [];
18
+ let baseVolumeIdx = 0;
19
+ for (let i = 0; i < thresholdVolumeInformation.length; i++) {
20
+ const { imageData, spacing, dimensions } = thresholdVolumeInformation[i].volume;
21
+ const volumeSize = thresholdVolumeInformation[i].volume.scalarData.length;
22
+ if (volumeSize === scalarData.length &&
23
+ equalsCheck(spacing, segmentationSpacing)) {
24
+ baseVolumeIdx = i;
25
+ }
26
+ const referenceValues = imageData.getPointData().getScalars().getData();
27
+ const lower = thresholdVolumeInformation[i].lower;
28
+ const upper = thresholdVolumeInformation[i].upper;
29
+ volumeInfoList.push({
30
+ imageData,
31
+ referenceValues,
32
+ lower,
33
+ upper,
34
+ spacing,
35
+ dimensions,
36
+ volumeSize,
37
+ });
38
+ }
39
+ let overlaps, total, range;
40
+ const testOverlapRange = (volumeInfo, voxelSpacing, voxelCenter) => {
41
+ const callbackOverlap = ({ value }) => {
42
+ total = total + 1;
43
+ if (value >= range.lower && value <= range.upper) {
44
+ overlaps = overlaps + 1;
45
+ }
46
+ };
47
+ const { imageData, dimensions, lower, upper } = volumeInfo;
48
+ const overlapBounds = getVoxelOverlap(imageData, dimensions, voxelSpacing, voxelCenter);
49
+ total = 0;
50
+ overlaps = 0;
51
+ range = { lower, upper };
52
+ let overlapTest = false;
53
+ pointInShapeCallback(imageData, () => true, callbackOverlap, overlapBounds);
54
+ if (overlapType === 0) {
55
+ overlapTest = overlaps > 0;
56
+ }
57
+ else if (overlapType == 1) {
58
+ overlapTest = overlaps === total;
59
+ }
60
+ return overlapTest;
61
+ };
62
+ const testRange = (volumeInfo, pointIJK) => {
63
+ const { imageData, referenceValues, lower, upper } = volumeInfo;
14
64
  const offset = imageData.computeOffsetIndex(pointIJK);
15
65
  const value = referenceValues[offset];
16
66
  if (value <= lower || value >= upper) {
17
- return;
67
+ return false;
68
+ }
69
+ else {
70
+ return true;
71
+ }
72
+ };
73
+ const getVoxelOverlap = (imageData, dimensions, voxelSpacing, voxelCenter) => {
74
+ const voxelCornersWorld = [];
75
+ for (let i = 0; i < 2; i++) {
76
+ for (let j = 0; j < 2; j++) {
77
+ for (let k = 0; k < 2; k++) {
78
+ const point = voxelCenter;
79
+ point[0] = point[0] + ((i * 2 - 1) * voxelSpacing[0]) / 2;
80
+ point[1] = point[1] + ((j * 2 - 1) * voxelSpacing[1]) / 2;
81
+ point[2] = point[2] + ((k * 2 - 1) * voxelSpacing[2]) / 2;
82
+ voxelCornersWorld.push(point);
83
+ }
84
+ }
85
+ }
86
+ const voxelCornersIJK = voxelCornersWorld.map((world) => csUtils.transformWorldToIndex(imageData, world));
87
+ const overlapBounds = getBoundingBoxAroundShape(voxelCornersIJK, dimensions);
88
+ return overlapBounds;
89
+ };
90
+ const callback = ({ index, pointIJK, pointLPS }) => {
91
+ let insert = volumeInfoList.length > 0;
92
+ for (let i = 0; i < volumeInfoList.length; i++) {
93
+ if (volumeInfoList[i].volumeSize === scalarData.length) {
94
+ insert = testRange(volumeInfoList[i], pointIJK);
95
+ }
96
+ else {
97
+ insert = testOverlapRange(volumeInfoList[i], volumeInfoList[baseVolumeIdx].spacing, pointLPS);
98
+ }
99
+ if (!insert) {
100
+ break;
101
+ }
18
102
  }
19
- scalarData[index] = 1;
103
+ if (insert)
104
+ scalarData[index] = 1;
20
105
  };
21
106
  pointInShapeCallback(segmentationImageData, () => true, callback, boundsIJK);
22
107
  triggerSegmentationDataModified(segmentationVolume.volumeId);
@@ -1 +1 @@
1
- {"version":3,"file":"thresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/thresholdVolumeByRange.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,+BAA+B,EAAE,MAAM,8DAA8D,CAAC;AAkB/G,SAAS,sBAAsB,CAC7B,kBAAsC,EACtC,eAAmC,EACnC,OAA8B;IAE9B,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,qBAAqB,EAAE,GAAG,kBAAkB,CAAC;IAC5E,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEvD,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC;IACtC,MAAM,eAAe,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC;IAGxE,IAAI,SAAS,EAAE;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC1C,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACnB;KACF;IAED,MAAM,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE;YACpC,OAAO;SACR;QAGD,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,oBAAoB,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE7E,+BAA+B,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAE7D,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"thresholdVolumeByRange.js","sourceRoot":"","sources":["../../../../src/utilities/segmentation/thresholdVolumeByRange.ts"],"names":[],"mappings":"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"}