/
getBoundsIJKFromRectangleAnnotations.ts
79 lines (68 loc) · 2.43 KB
/
getBoundsIJKFromRectangleAnnotations.ts
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
import { utilities as csUtils } from '@cornerstonejs/core';
import type { Types } from '@cornerstonejs/core';
import { getBoundingBoxAroundShapeIJK } from '../boundingBox/getBoundingBoxAroundShape';
import extend2DBoundingBoxInViewAxis from '../boundingBox/extend2DBoundingBoxInViewAxis';
type Options = {
numSlicesToProject?: number;
};
function getBoundsIJKFromRectangleAnnotations(
annotations,
referenceVolume,
options = {} as Options
) {
const AllBoundsIJK = [];
annotations.forEach((annotation) => {
const { data } = annotation;
const { points } = data.handles;
const { imageData, dimensions } = referenceVolume;
let pointsToUse = points;
// If the tool is a 2D tool but has projection points, use them
if (data.cachedStats?.projectionPoints) {
const { projectionPoints } = data.cachedStats;
pointsToUse = [].concat(...projectionPoints); // cannot use flat() because of typescript compiler right now
}
const rectangleCornersIJK = pointsToUse.map(
(world) => csUtils.transformWorldToIndex(imageData, world) as Types.Point3
);
let boundsIJK = getBoundingBoxAroundShapeIJK(
rectangleCornersIJK,
dimensions
);
// If the tool is 2D but it is configured to project to X amount of slices
// Don't project the slices if projectionPoints have been used to define the extents
if (options.numSlicesToProject && !data.cachedStats?.projectionPoints) {
boundsIJK = extend2DBoundingBoxInViewAxis(
boundsIJK,
options.numSlicesToProject
);
}
AllBoundsIJK.push(boundsIJK);
});
if (AllBoundsIJK.length === 1) {
return AllBoundsIJK[0];
}
// Get the intersection of all the bounding boxes
// This is the bounding box that contains all the ROIs
const boundsIJK = AllBoundsIJK.reduce(
(accumulator, currentValue) => {
return {
iMin: Math.min(accumulator.iMin, currentValue.iMin),
jMin: Math.min(accumulator.jMin, currentValue.jMin),
kMin: Math.min(accumulator.kMin, currentValue.kMin),
iMax: Math.max(accumulator.iMax, currentValue.iMax),
jMax: Math.max(accumulator.jMax, currentValue.jMax),
kMax: Math.max(accumulator.kMax, currentValue.kMax),
};
},
{
iMin: Infinity,
jMin: Infinity,
kMin: Infinity,
iMax: -Infinity,
jMax: -Infinity,
kMax: -Infinity,
}
);
return boundsIJK;
}
export default getBoundsIJKFromRectangleAnnotations;