@cornerstonejs/adapters 5.4.11 → 5.4.13
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.
- package/dist/esm/adapters/Cornerstone/Segmentation_4X.d.ts +2 -2
- package/dist/esm/adapters/Cornerstone/Segmentation_4X.js +215 -69
- package/dist/esm/adapters/Cornerstone3D/Segmentation/generateSegmentation.d.ts +10 -1
- package/dist/esm/adapters/Cornerstone3D/Segmentation/generateSegmentation.js +286 -5
- package/dist/esm/adapters/Cornerstone3D/Segmentation/generateToolState.d.ts +20 -1
- package/dist/esm/adapters/Cornerstone3D/Segmentation/generateToolState.js +37 -7
- package/dist/esm/adapters/Cornerstone3D/Segmentation/index.d.ts +2 -2
- package/dist/esm/adapters/Cornerstone3D/Segmentation/index.js +2 -1
- package/dist/esm/adapters/Cornerstone3D/Segmentation/labelmapImagesFromBuffer.d.ts +45 -3
- package/dist/esm/adapters/Cornerstone3D/Segmentation/labelmapImagesFromBuffer.js +577 -145
- package/dist/esm/adapters/Cornerstone3D/Segmentation/perFrameFunctionalGroups.d.ts +17 -0
- package/dist/esm/adapters/Cornerstone3D/Segmentation/perFrameFunctionalGroups.js +116 -0
- package/dist/esm/adapters/Cornerstone3D/encodePixelData.d.ts +46 -0
- package/dist/esm/adapters/Cornerstone3D/encodePixelData.js +440 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +7 -7
|
@@ -1,17 +1,294 @@
|
|
|
1
|
+
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
1
2
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
2
3
|
import { normalizers, derivations } from 'dcmjs';
|
|
3
4
|
import { Enums } from '@cornerstonejs/core';
|
|
4
5
|
import { fillSegmentation } from '../../Cornerstone/Segmentation_4X.js';
|
|
6
|
+
import { getBitmapFramesFromDataset, encodeFramesToTransferSyntax, EXPLICIT_VR_LITTLE_ENDIAN_TRANSFER_SYNTAX_UID } from '../encodePixelData.js';
|
|
7
|
+
import { normalizeSharedFunctionalGroupsSequence, getReferencedSourceImageSequenceItem, applyPerFrameFunctionalGroups } from './perFrameFunctionalGroups.js';
|
|
5
8
|
|
|
6
9
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
7
10
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
8
11
|
const MetadataModules = Enums.MetadataModules;
|
|
9
12
|
const SEGImageNormalizer = normalizers.SEGImageNormalizer;
|
|
10
13
|
const SegmentationDerivation = derivations.Segmentation;
|
|
14
|
+
const LABELMAP_SEG_SOP_CLASS_UID = '1.2.840.10008.5.1.4.1.1.66.7';
|
|
15
|
+
const BITMAP_SEG_SOP_CLASS_UID = '1.2.840.10008.5.1.4.1.1.66.4';
|
|
16
|
+
function resolveTransferSyntaxUid() {
|
|
17
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
18
|
+
const transferSyntaxUid = options.transferSyntaxUid || options.transferSyntaxUID;
|
|
19
|
+
if (!transferSyntaxUid) {
|
|
20
|
+
return EXPLICIT_VR_LITTLE_ENDIAN_TRANSFER_SYNTAX_UID;
|
|
21
|
+
}
|
|
22
|
+
return transferSyntaxUid;
|
|
23
|
+
}
|
|
24
|
+
function applySegDatasetTransferSyntax(dataset, transferSyntaxUid, pixelData, pixelDataVR) {
|
|
25
|
+
dataset.PixelData = pixelData;
|
|
26
|
+
dataset._vrMap = dataset._vrMap || {};
|
|
27
|
+
dataset._vrMap.PixelData = pixelDataVR;
|
|
28
|
+
dataset._meta = dataset._meta || {};
|
|
29
|
+
dataset._meta.TransferSyntaxUID = {
|
|
30
|
+
Value: [transferSyntaxUid],
|
|
31
|
+
vr: 'UI'
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function hasAnySegment(pixelData) {
|
|
35
|
+
for (let i = 0; i < pixelData.length; i++) {
|
|
36
|
+
if (pixelData[i] !== 0) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
function toLabelmap3DArray(inputLabelmaps3D) {
|
|
43
|
+
if (Array.isArray(inputLabelmaps3D)) {
|
|
44
|
+
return inputLabelmaps3D.filter(Boolean);
|
|
45
|
+
}
|
|
46
|
+
return inputLabelmaps3D ? [inputLabelmaps3D] : [];
|
|
47
|
+
}
|
|
48
|
+
function collectNonEmptyFrameIndices(labelmap3DArray) {
|
|
49
|
+
const indices = new Set();
|
|
50
|
+
labelmap3DArray.forEach(labelmap3D => {
|
|
51
|
+
var _labelmap3D$labelmaps;
|
|
52
|
+
const labelmaps2D = (_labelmap3D$labelmaps = labelmap3D === null || labelmap3D === void 0 ? void 0 : labelmap3D.labelmaps2D) !== null && _labelmap3D$labelmaps !== void 0 ? _labelmap3D$labelmaps : [];
|
|
53
|
+
for (let i = 0; i < labelmaps2D.length; i++) {
|
|
54
|
+
const frame = labelmaps2D[i];
|
|
55
|
+
if (frame !== null && frame !== void 0 && frame.pixelData && hasAnySegment(frame.pixelData)) {
|
|
56
|
+
indices.add(i);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return Array.from(indices).sort((a, b) => a - b);
|
|
61
|
+
}
|
|
62
|
+
function resolveReferencedImagesForExport(images, frameIndices) {
|
|
63
|
+
if (!frameIndices.length) {
|
|
64
|
+
throw new Error('No non-empty labelmap frames found for SEG export');
|
|
65
|
+
}
|
|
66
|
+
return frameIndices.map(frameIndex => {
|
|
67
|
+
const image = images[frameIndex];
|
|
68
|
+
if (!(image !== null && image !== void 0 && image.imageId)) {
|
|
69
|
+
throw new Error("Cannot resolve referenced source image for labelmap stack frame ".concat(frameIndex, " ") + "(image not loaded in cache). Load the referenced series before storing the segmentation.");
|
|
70
|
+
}
|
|
71
|
+
return image;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function maxSegmentValue(labelmap3DArray, frameIndices) {
|
|
75
|
+
let max = 0;
|
|
76
|
+
labelmap3DArray.forEach(labelmap3D => {
|
|
77
|
+
var _labelmap3D$labelmaps2;
|
|
78
|
+
const labelmaps2D = (_labelmap3D$labelmaps2 = labelmap3D === null || labelmap3D === void 0 ? void 0 : labelmap3D.labelmaps2D) !== null && _labelmap3D$labelmaps2 !== void 0 ? _labelmap3D$labelmaps2 : [];
|
|
79
|
+
frameIndices.forEach(frameIndex => {
|
|
80
|
+
var _labelmaps2D$frameInd;
|
|
81
|
+
const pixelData = (_labelmaps2D$frameInd = labelmaps2D[frameIndex]) === null || _labelmaps2D$frameInd === void 0 ? void 0 : _labelmaps2D$frameInd.pixelData;
|
|
82
|
+
if (!pixelData) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
for (let i = 0; i < pixelData.length; i++) {
|
|
86
|
+
if (pixelData[i] > max) {
|
|
87
|
+
max = pixelData[i];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
return max;
|
|
93
|
+
}
|
|
94
|
+
function collectSegmentSequence(labelmap3DArray) {
|
|
95
|
+
const bySegmentNumber = new Map();
|
|
96
|
+
labelmap3DArray.forEach(labelmap3D => {
|
|
97
|
+
var _labelmap3D$metadata;
|
|
98
|
+
((_labelmap3D$metadata = labelmap3D === null || labelmap3D === void 0 ? void 0 : labelmap3D.metadata) !== null && _labelmap3D$metadata !== void 0 ? _labelmap3D$metadata : []).forEach((segment, index) => {
|
|
99
|
+
var _segment$SegmentNumbe;
|
|
100
|
+
if (!segment) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const key = Number((_segment$SegmentNumbe = segment.SegmentNumber) !== null && _segment$SegmentNumbe !== void 0 ? _segment$SegmentNumbe : index);
|
|
104
|
+
if (!bySegmentNumber.has(key)) {
|
|
105
|
+
bySegmentNumber.set(key, _objectSpread({}, segment));
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
return Array.from(bySegmentNumber.entries()).sort((a, b) => a[0] - b[0]).map(_ref => {
|
|
110
|
+
let _ref2 = _slicedToArray(_ref, 2),
|
|
111
|
+
segment = _ref2[1];
|
|
112
|
+
return segment;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function getPlaneSequencesForImage(image, metadata) {
|
|
116
|
+
var _metadata$get;
|
|
117
|
+
const imagePlane = metadata === null || metadata === void 0 || (_metadata$get = metadata.get) === null || _metadata$get === void 0 ? void 0 : _metadata$get.call(metadata, MetadataModules.IMAGE_PLANE, image === null || image === void 0 ? void 0 : image.imageId);
|
|
118
|
+
if (!imagePlane) {
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
121
|
+
const result = {};
|
|
122
|
+
const imagePositionPatient = imagePlane.imagePositionPatient,
|
|
123
|
+
imageOrientationPatient = imagePlane.imageOrientationPatient,
|
|
124
|
+
rowCosines = imagePlane.rowCosines,
|
|
125
|
+
columnCosines = imagePlane.columnCosines;
|
|
126
|
+
if (Array.isArray(imagePositionPatient) && imagePositionPatient.length === 3) {
|
|
127
|
+
result.planePositionSequence = {
|
|
128
|
+
ImagePositionPatient: [...imagePositionPatient]
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
let orientation = imageOrientationPatient;
|
|
132
|
+
if ((!Array.isArray(orientation) || orientation.length !== 6) && Array.isArray(rowCosines) && Array.isArray(columnCosines)) {
|
|
133
|
+
orientation = [...rowCosines, ...columnCosines];
|
|
134
|
+
}
|
|
135
|
+
if (Array.isArray(orientation) && orientation.length === 6) {
|
|
136
|
+
result.planeOrientationSequence = {
|
|
137
|
+
ImageOrientationPatient: [...orientation]
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
function fillLabelmapSegmentation(segmentation, inputLabelmaps3D, metadata, images) {
|
|
143
|
+
let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
|
|
144
|
+
const labelmap3DArray = toLabelmap3DArray(inputLabelmaps3D);
|
|
145
|
+
const segmentSequence = collectSegmentSequence(labelmap3DArray);
|
|
146
|
+
const validFrameIndices = collectNonEmptyFrameIndices(labelmap3DArray);
|
|
147
|
+
if (!validFrameIndices.length) {
|
|
148
|
+
throw new Error('No non-empty labelmap frames found for SEG export');
|
|
149
|
+
}
|
|
150
|
+
const firstFrame = labelmap3DArray.map(labelmap3D => {
|
|
151
|
+
var _labelmap3D$labelmaps3;
|
|
152
|
+
return labelmap3D === null || labelmap3D === void 0 || (_labelmap3D$labelmaps3 = labelmap3D.labelmaps2D) === null || _labelmap3D$labelmaps3 === void 0 ? void 0 : _labelmap3D$labelmaps3[validFrameIndices[0]];
|
|
153
|
+
}).find(Boolean);
|
|
154
|
+
const rows = firstFrame.rows;
|
|
155
|
+
const columns = firstFrame.columns;
|
|
156
|
+
const frameLength = rows * columns;
|
|
157
|
+
const numberOfFrames = validFrameIndices.length;
|
|
158
|
+
const maxValue = maxSegmentValue(labelmap3DArray, validFrameIndices);
|
|
159
|
+
const useUint16 = maxValue > 255;
|
|
160
|
+
const FrameArray = useUint16 ? Uint16Array : Uint8Array;
|
|
161
|
+
const bitsAllocated = useUint16 ? 16 : 8;
|
|
162
|
+
let overlapWarned = false;
|
|
163
|
+
const buildExportFrame = frameIndex => {
|
|
164
|
+
const frame = new FrameArray(frameLength);
|
|
165
|
+
labelmap3DArray.forEach(labelmap3D => {
|
|
166
|
+
var _labelmap3D$labelmaps4;
|
|
167
|
+
const source = labelmap3D === null || labelmap3D === void 0 || (_labelmap3D$labelmaps4 = labelmap3D.labelmaps2D) === null || _labelmap3D$labelmaps4 === void 0 || (_labelmap3D$labelmaps4 = _labelmap3D$labelmaps4[frameIndex]) === null || _labelmap3D$labelmaps4 === void 0 ? void 0 : _labelmap3D$labelmaps4.pixelData;
|
|
168
|
+
if (!source) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const len = Math.min(source.length, frameLength);
|
|
172
|
+
for (let i = 0; i < len; i++) {
|
|
173
|
+
const value = source[i];
|
|
174
|
+
if (value === 0) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (frame[i] !== 0 && frame[i] !== value && !overlapWarned) {
|
|
178
|
+
console.warn('generateSegmentation: overlapping labelmap segments detected on the ' + 'same voxel while exporting a LABELMAP SEG; the later labelmap wins.');
|
|
179
|
+
overlapWarned = true;
|
|
180
|
+
}
|
|
181
|
+
frame[i] = value;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return frame;
|
|
185
|
+
};
|
|
186
|
+
const dataset = segmentation.dataset;
|
|
187
|
+
dataset.NumberOfFrames = numberOfFrames;
|
|
188
|
+
dataset.Rows = rows;
|
|
189
|
+
dataset.Columns = columns;
|
|
190
|
+
dataset.SOPClassUID = LABELMAP_SEG_SOP_CLASS_UID;
|
|
191
|
+
dataset.SegmentationType = 'LABELMAP';
|
|
192
|
+
if (segmentSequence.length) {
|
|
193
|
+
dataset.SegmentSequence = segmentSequence;
|
|
194
|
+
}
|
|
195
|
+
dataset.BitsAllocated = useUint16 ? '16' : '8';
|
|
196
|
+
dataset.BitsStored = useUint16 ? '16' : '8';
|
|
197
|
+
dataset.HighBit = useUint16 ? '15' : '7';
|
|
198
|
+
dataset.PixelRepresentation = '0';
|
|
199
|
+
delete dataset.MaximumFractionalValue;
|
|
200
|
+
delete dataset.SegmentationFractionalType;
|
|
201
|
+
dataset.SpecificCharacterSet = 'ISO_IR 192';
|
|
202
|
+
dataset._vrMap || (dataset._vrMap = {});
|
|
203
|
+
const transferSyntaxUid = resolveTransferSyntaxUid(options);
|
|
204
|
+
const _encodeFramesToTransf = encodeFramesToTransferSyntax({
|
|
205
|
+
transferSyntaxUID: transferSyntaxUid,
|
|
206
|
+
buildFrame: outputIndex => buildExportFrame(validFrameIndices[outputIndex]),
|
|
207
|
+
frameCount: validFrameIndices.length,
|
|
208
|
+
bitsAllocated,
|
|
209
|
+
columns
|
|
210
|
+
}),
|
|
211
|
+
pixelData = _encodeFramesToTransf.pixelData,
|
|
212
|
+
pixelDataVR = _encodeFramesToTransf.pixelDataVR;
|
|
213
|
+
applySegDatasetTransferSyntax(dataset, transferSyntaxUid, pixelData, pixelDataVR);
|
|
214
|
+
dataset._meta || (dataset._meta = {});
|
|
215
|
+
dataset._meta.MediaStorageSOPClassUID = {
|
|
216
|
+
Value: [LABELMAP_SEG_SOP_CLASS_UID],
|
|
217
|
+
vr: 'UI'
|
|
218
|
+
};
|
|
219
|
+
const sourceImageSequence = images.map(image => getReferencedSourceImageSequenceItem(image, metadata)).filter(item => item.ReferencedSOPInstanceUID);
|
|
220
|
+
if (sourceImageSequence.length) {
|
|
221
|
+
dataset.SourceImageSequence = sourceImageSequence;
|
|
222
|
+
}
|
|
223
|
+
const perFrameInputs = validFrameIndices.map((_, outputIndex) => {
|
|
224
|
+
var _dataset$PerFrameFunc, _dataset$PerFrameFunc2, _planeSequences$plane, _planeSequences$plane2;
|
|
225
|
+
const image = images[outputIndex];
|
|
226
|
+
const sourceImageSequenceItem = getReferencedSourceImageSequenceItem(image, metadata);
|
|
227
|
+
if (!(sourceImageSequenceItem !== null && sourceImageSequenceItem !== void 0 && sourceImageSequenceItem.ReferencedSOPInstanceUID)) {
|
|
228
|
+
throw new Error("Cannot resolve a source ReferencedSOPInstanceUID for labelmap SEG " + "frame ".concat(outputIndex, ". Refusing to write a SEG with unreliable ") + "source image references.");
|
|
229
|
+
}
|
|
230
|
+
const priorGroup = (_dataset$PerFrameFunc = (_dataset$PerFrameFunc2 = dataset.PerFrameFunctionalGroupsSequence) === null || _dataset$PerFrameFunc2 === void 0 ? void 0 : _dataset$PerFrameFunc2[outputIndex]) !== null && _dataset$PerFrameFunc !== void 0 ? _dataset$PerFrameFunc : {};
|
|
231
|
+
const planeSequences = getPlaneSequencesForImage(image, metadata);
|
|
232
|
+
return {
|
|
233
|
+
sourceImageSequenceItem,
|
|
234
|
+
planeOrientationSequence: (_planeSequences$plane = planeSequences.planeOrientationSequence) !== null && _planeSequences$plane !== void 0 ? _planeSequences$plane : priorGroup === null || priorGroup === void 0 ? void 0 : priorGroup.PlaneOrientationSequence,
|
|
235
|
+
planePositionSequence: (_planeSequences$plane2 = planeSequences.planePositionSequence) !== null && _planeSequences$plane2 !== void 0 ? _planeSequences$plane2 : priorGroup === null || priorGroup === void 0 ? void 0 : priorGroup.PlanePositionSequence
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
applyPerFrameFunctionalGroups(dataset, perFrameInputs);
|
|
239
|
+
const sopInstanceUIDs = new Set(images.map(image => {
|
|
240
|
+
var _metadata$get2;
|
|
241
|
+
return (_metadata$get2 = metadata.get(MetadataModules.IMAGE_DATA, image === null || image === void 0 ? void 0 : image.imageId)) === null || _metadata$get2 === void 0 ? void 0 : _metadata$get2.SOPInstanceUID;
|
|
242
|
+
}).filter(Boolean));
|
|
243
|
+
const referencedSeriesSequence = dataset.ReferencedSeriesSequence;
|
|
244
|
+
const referencedSeries = Array.isArray(referencedSeriesSequence) ? referencedSeriesSequence[0] : referencedSeriesSequence;
|
|
245
|
+
if (referencedSeries !== null && referencedSeries !== void 0 && referencedSeries.ReferencedInstanceSequence && sopInstanceUIDs.size) {
|
|
246
|
+
const referencedInstances = Array.isArray(referencedSeries.ReferencedInstanceSequence) ? referencedSeries.ReferencedInstanceSequence : [referencedSeries.ReferencedInstanceSequence];
|
|
247
|
+
referencedSeries.ReferencedInstanceSequence = referencedInstances.filter(instance => (instance === null || instance === void 0 ? void 0 : instance.ReferencedSOPInstanceUID) && sopInstanceUIDs.has(instance.ReferencedSOPInstanceUID));
|
|
248
|
+
}
|
|
249
|
+
return segmentation;
|
|
250
|
+
}
|
|
11
251
|
function generateSegmentation(images, labelmaps, metadata) {
|
|
12
252
|
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
13
|
-
const
|
|
14
|
-
const
|
|
253
|
+
const requestedSOPClassUID = (options === null || options === void 0 ? void 0 : options.sopClassUID) || BITMAP_SEG_SOP_CLASS_UID;
|
|
254
|
+
const shouldExportBitmap = requestedSOPClassUID === BITMAP_SEG_SOP_CLASS_UID;
|
|
255
|
+
if (shouldExportBitmap) {
|
|
256
|
+
var _segmentationResult$d;
|
|
257
|
+
const transferSyntaxUid = resolveTransferSyntaxUid(options);
|
|
258
|
+
const segmentation = _createMultiframeSegmentationFromReferencedImages(images, metadata, options);
|
|
259
|
+
const segmentationResult = fillSegmentation(segmentation, labelmaps, _objectSpread(_objectSpread({}, options), {}, {
|
|
260
|
+
transferSyntaxUid: EXPLICIT_VR_LITTLE_ENDIAN_TRANSFER_SYNTAX_UID,
|
|
261
|
+
skipTransferSyntaxMeta: true
|
|
262
|
+
}), images, metadata);
|
|
263
|
+
const _getBitmapFramesFromD = getBitmapFramesFromDataset(segmentationResult.dataset),
|
|
264
|
+
frames = _getBitmapFramesFromD.frames,
|
|
265
|
+
bitsAllocated = _getBitmapFramesFromD.bitsAllocated;
|
|
266
|
+
const _encodeFramesToTransf2 = encodeFramesToTransferSyntax({
|
|
267
|
+
transferSyntaxUID: transferSyntaxUid,
|
|
268
|
+
frames,
|
|
269
|
+
bitsAllocated,
|
|
270
|
+
columns: Number(segmentationResult.dataset.Columns) || undefined
|
|
271
|
+
}),
|
|
272
|
+
pixelData = _encodeFramesToTransf2.pixelData,
|
|
273
|
+
pixelDataVR = _encodeFramesToTransf2.pixelDataVR;
|
|
274
|
+
applySegDatasetTransferSyntax(segmentationResult.dataset, transferSyntaxUid, pixelData, pixelDataVR);
|
|
275
|
+
segmentationResult.dataset.SOPClassUID = BITMAP_SEG_SOP_CLASS_UID;
|
|
276
|
+
(_segmentationResult$d = segmentationResult.dataset)._meta || (_segmentationResult$d._meta = {});
|
|
277
|
+
segmentationResult.dataset._meta.MediaStorageSOPClassUID = {
|
|
278
|
+
Value: [BITMAP_SEG_SOP_CLASS_UID],
|
|
279
|
+
vr: 'UI'
|
|
280
|
+
};
|
|
281
|
+
const predecessorImageId = options === null || options === void 0 ? void 0 : options.predecessorImageId;
|
|
282
|
+
if (predecessorImageId) {
|
|
283
|
+
const predecessor = metadata.get(MetadataModules.PREDECESSOR_SEQUENCE, predecessorImageId);
|
|
284
|
+
Object.assign(segmentationResult, predecessor);
|
|
285
|
+
}
|
|
286
|
+
return segmentationResult;
|
|
287
|
+
}
|
|
288
|
+
const nonEmptyFrameIndices = collectNonEmptyFrameIndices(toLabelmap3DArray(labelmaps));
|
|
289
|
+
const filteredImages = resolveReferencedImagesForExport(images, nonEmptyFrameIndices);
|
|
290
|
+
const segmentation = _createMultiframeSegmentationFromReferencedImages(filteredImages, metadata, options);
|
|
291
|
+
const segmentationResult = fillLabelmapSegmentation(segmentation, labelmaps, metadata, filteredImages, options);
|
|
15
292
|
const predecessorImageId = options === null || options === void 0 ? void 0 : options.predecessorImageId;
|
|
16
293
|
if (predecessorImageId) {
|
|
17
294
|
const predecessor = metadata.get(MetadataModules.PREDECESSOR_SEQUENCE, predecessorImageId);
|
|
@@ -20,6 +297,10 @@ function generateSegmentation(images, labelmaps, metadata) {
|
|
|
20
297
|
return segmentationResult;
|
|
21
298
|
}
|
|
22
299
|
function _createMultiframeSegmentationFromReferencedImages(images, metadata, options) {
|
|
300
|
+
var _images$, _multiframe$SharedFun;
|
|
301
|
+
if (!(images !== null && images !== void 0 && images.length) || !((_images$ = images[0]) !== null && _images$ !== void 0 && _images$.imageId)) {
|
|
302
|
+
throw new Error('Cannot create SEG derivation: no referenced source images were resolved.');
|
|
303
|
+
}
|
|
23
304
|
const studyImageId = (options === null || options === void 0 ? void 0 : options.predecessorImageId) || images[0].imageId;
|
|
24
305
|
const studyData = metadata.get(MetadataModules.STUDY_DATA, studyImageId);
|
|
25
306
|
const datasets = images.map(image => {
|
|
@@ -45,8 +326,8 @@ function _createMultiframeSegmentationFromReferencedImages(images, metadata, opt
|
|
|
45
326
|
if (!multiframe) {
|
|
46
327
|
throw new Error('Failed to normalize the multiframe dataset, the data is not multi-frame.');
|
|
47
328
|
}
|
|
48
|
-
|
|
49
|
-
multiframe.SharedFunctionalGroupsSequence.PixelMeasuresSequence = {};
|
|
329
|
+
normalizeSharedFunctionalGroupsSequence(multiframe);
|
|
330
|
+
(_multiframe$SharedFun = multiframe.SharedFunctionalGroupsSequence).PixelMeasuresSequence || (_multiframe$SharedFun.PixelMeasuresSequence = {});
|
|
50
331
|
multiframe.PerFrameFunctionalGroupsSequence || (multiframe.PerFrameFunctionalGroupsSequence = []);
|
|
51
332
|
for (let index = 0; index < images.length; index++) {
|
|
52
333
|
var _multiframe$PerFrameF, _index;
|
|
@@ -62,4 +343,4 @@ function _createMultiframeSegmentationFromReferencedImages(images, metadata, opt
|
|
|
62
343
|
return new SegmentationDerivation([multiframe], options);
|
|
63
344
|
}
|
|
64
345
|
|
|
65
|
-
export { generateSegmentation };
|
|
346
|
+
export { collectNonEmptyFrameIndices, collectSegmentSequence, generateSegmentation, maxSegmentValue, resolveReferencedImagesForExport, toLabelmap3DArray };
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
+
import { createLabelmapsFromDICOMBuffer, createLabelmapsFromSegImageIds } from './labelmapImagesFromBuffer.js';
|
|
1
2
|
declare function generateToolState(imageIds: any, arrayBuffer: any, metadataProvider: any, skipOverlapping?: boolean, tolerance?: number, cs3dVersion?: number): any;
|
|
3
|
+
declare function createFromDicomSegImageId(referencedImageIds: any, segImageId: any, { metadataProvider, tolerance, parserType, frameImageIds, getFrameImageId, decodeImageData, concurrency, }: {
|
|
4
|
+
metadataProvider: any;
|
|
5
|
+
tolerance?: number;
|
|
6
|
+
parserType?: string;
|
|
7
|
+
frameImageIds?: any;
|
|
8
|
+
getFrameImageId?: any;
|
|
9
|
+
decodeImageData?: any;
|
|
10
|
+
concurrency?: any;
|
|
11
|
+
}): Promise<{
|
|
12
|
+
labelMapImages: any;
|
|
13
|
+
segMetadata: {
|
|
14
|
+
seriesInstanceUid: any;
|
|
15
|
+
data: any[];
|
|
16
|
+
};
|
|
17
|
+
segmentsOnFrame: any[];
|
|
18
|
+
centroids: Map<any, any>;
|
|
19
|
+
overlappingSegments: any;
|
|
20
|
+
}>;
|
|
2
21
|
declare function createFromDICOMSegBuffer(referencedImageIds: any, arrayBuffer: any, { metadataProvider, tolerance }: {
|
|
3
22
|
metadataProvider: any;
|
|
4
23
|
tolerance?: number;
|
|
@@ -12,4 +31,4 @@ declare function createFromDICOMSegBuffer(referencedImageIds: any, arrayBuffer:
|
|
|
12
31
|
centroids: Map<any, any>;
|
|
13
32
|
overlappingSegments: any;
|
|
14
33
|
}>;
|
|
15
|
-
export { generateToolState, createFromDICOMSegBuffer };
|
|
34
|
+
export { generateToolState, createFromDicomSegImageId, createFromDICOMSegBuffer, createLabelmapsFromSegImageIds, createLabelmapsFromDICOMBuffer, };
|
|
@@ -1,19 +1,49 @@
|
|
|
1
1
|
import { generateToolState as generateToolState$1 } from '../../Cornerstone/Segmentation.js';
|
|
2
|
-
import {
|
|
2
|
+
import { createLabelmapsFromDICOMBuffer, createLabelmapsFromSegImageIds } from './labelmapImagesFromBuffer.js';
|
|
3
3
|
|
|
4
4
|
function generateToolState(imageIds, arrayBuffer, metadataProvider) {
|
|
5
5
|
let skipOverlapping = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
6
6
|
let tolerance = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1e-3;
|
|
7
7
|
let cs3dVersion = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 4;
|
|
8
|
-
|
|
8
|
+
if (cs3dVersion !== 4) {
|
|
9
|
+
return generateToolState$1(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance, cs3dVersion);
|
|
10
|
+
}
|
|
11
|
+
return createLabelmapsFromDICOMBuffer(imageIds, arrayBuffer, metadataProvider, {
|
|
12
|
+
tolerance,
|
|
13
|
+
parserType: 'bitmap'
|
|
14
|
+
});
|
|
9
15
|
}
|
|
10
|
-
function
|
|
16
|
+
function createFromDicomSegImageId(referencedImageIds, segImageId, _ref) {
|
|
11
17
|
let metadataProvider = _ref.metadataProvider,
|
|
12
18
|
_ref$tolerance = _ref.tolerance,
|
|
13
|
-
tolerance = _ref$tolerance === void 0 ? 1e-3 : _ref$tolerance
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
tolerance = _ref$tolerance === void 0 ? 1e-3 : _ref$tolerance,
|
|
20
|
+
_ref$parserType = _ref.parserType,
|
|
21
|
+
parserType = _ref$parserType === void 0 ? 'bitmap' : _ref$parserType,
|
|
22
|
+
_ref$frameImageIds = _ref.frameImageIds,
|
|
23
|
+
frameImageIds = _ref$frameImageIds === void 0 ? undefined : _ref$frameImageIds,
|
|
24
|
+
_ref$getFrameImageId = _ref.getFrameImageId,
|
|
25
|
+
getFrameImageId = _ref$getFrameImageId === void 0 ? undefined : _ref$getFrameImageId,
|
|
26
|
+
_ref$decodeImageData = _ref.decodeImageData,
|
|
27
|
+
decodeImageData = _ref$decodeImageData === void 0 ? undefined : _ref$decodeImageData,
|
|
28
|
+
_ref$concurrency = _ref.concurrency,
|
|
29
|
+
concurrency = _ref$concurrency === void 0 ? undefined : _ref$concurrency;
|
|
30
|
+
return createLabelmapsFromSegImageIds(referencedImageIds, segImageId, metadataProvider, {
|
|
31
|
+
tolerance,
|
|
32
|
+
parserType,
|
|
33
|
+
frameImageIds,
|
|
34
|
+
getFrameImageId,
|
|
35
|
+
decodeImageData,
|
|
36
|
+
concurrency
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function createFromDICOMSegBuffer(referencedImageIds, arrayBuffer, _ref2) {
|
|
40
|
+
let metadataProvider = _ref2.metadataProvider,
|
|
41
|
+
_ref2$tolerance = _ref2.tolerance,
|
|
42
|
+
tolerance = _ref2$tolerance === void 0 ? 1e-3 : _ref2$tolerance;
|
|
43
|
+
return createLabelmapsFromDICOMBuffer(referencedImageIds, arrayBuffer, metadataProvider, {
|
|
44
|
+
tolerance,
|
|
45
|
+
parserType: 'bitmap'
|
|
16
46
|
});
|
|
17
47
|
}
|
|
18
48
|
|
|
19
|
-
export { createFromDICOMSegBuffer, generateToolState };
|
|
49
|
+
export { createFromDICOMSegBuffer, createFromDicomSegImageId, createLabelmapsFromDICOMBuffer, createLabelmapsFromSegImageIds, generateToolState };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { generateSegmentation } from './generateSegmentation.js';
|
|
2
2
|
import { generateLabelMaps2DFrom3D } from './generateLabelMaps2DFrom3D.js';
|
|
3
|
-
import { generateToolState, createFromDICOMSegBuffer } from './generateToolState.js';
|
|
4
|
-
export { generateLabelMaps2DFrom3D, generateSegmentation, generateToolState, createFromDICOMSegBuffer, };
|
|
3
|
+
import { generateToolState, createFromDicomSegImageId, createFromDICOMSegBuffer, createLabelmapsFromSegImageIds, createLabelmapsFromDICOMBuffer } from './generateToolState.js';
|
|
4
|
+
export { generateLabelMaps2DFrom3D, generateSegmentation, generateToolState, createFromDicomSegImageId, createFromDICOMSegBuffer, createLabelmapsFromSegImageIds, createLabelmapsFromDICOMBuffer, };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { generateSegmentation } from './generateSegmentation.js';
|
|
2
2
|
export { generateLabelMaps2DFrom3D } from './generateLabelMaps2DFrom3D.js';
|
|
3
|
-
export { createFromDICOMSegBuffer, generateToolState } from './generateToolState.js';
|
|
3
|
+
export { createFromDICOMSegBuffer, createFromDicomSegImageId, generateToolState } from './generateToolState.js';
|
|
4
|
+
export { createLabelmapsFromDICOMBuffer, createLabelmapsFromSegImageIds } from './labelmapImagesFromBuffer.js';
|
|
@@ -1,4 +1,24 @@
|
|
|
1
|
-
declare function
|
|
1
|
+
declare function isPseudoBinaryFractional(pixelData: ArrayLike<number>, maximumFractionalValue: unknown): boolean;
|
|
2
|
+
declare function buildSopUIDImageIdIndexMap(referencedImageIds: any, metadataProvider: any): any;
|
|
3
|
+
type DecodeFrameImageData = (frameImageId: string, frameNumber: number) => Promise<ArrayLike<number> | ArrayLike<number>[] | Uint8Array | Uint16Array | (Uint8Array | Uint16Array)[]>;
|
|
4
|
+
declare function resolveFrameImageIds({ segImageId, numberOfFrames, frameImageIds, getFrameImageId, }: {
|
|
5
|
+
segImageId: string;
|
|
6
|
+
numberOfFrames: number;
|
|
7
|
+
frameImageIds?: string[];
|
|
8
|
+
getFrameImageId?: (baseSegImageId: string, frameNumber: number) => string;
|
|
9
|
+
}): string[];
|
|
10
|
+
declare function decodeSegPixelDataFromFrameIds({ segImageId, multiframe, frameImageIds, getFrameImageId, decodeImageData, concurrency, }: {
|
|
11
|
+
segImageId: string;
|
|
12
|
+
multiframe: Record<string, unknown>;
|
|
13
|
+
frameImageIds?: string[];
|
|
14
|
+
getFrameImageId?: (baseSegImageId: string, frameNumber: number) => string;
|
|
15
|
+
decodeImageData: DecodeFrameImageData;
|
|
16
|
+
concurrency?: number;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
pixelDataChunks: (Uint8Array | Uint16Array)[];
|
|
19
|
+
expectedVoxelCount: number;
|
|
20
|
+
}>;
|
|
21
|
+
declare function createLabelmapsFromSegImageIds(referencedImageIds: any, segImageId: any, metadataProvider: any, options: any): Promise<{
|
|
2
22
|
labelMapImages: any;
|
|
3
23
|
segMetadata: {
|
|
4
24
|
seriesInstanceUid: any;
|
|
@@ -8,7 +28,7 @@ declare function createLabelmapsFromBufferInternal(referencedImageIds: any, arra
|
|
|
8
28
|
centroids: Map<any, any>;
|
|
9
29
|
overlappingSegments: any;
|
|
10
30
|
}>;
|
|
11
|
-
export declare function insertPixelDataPlanar({ segmentsOnFrame, labelMapImages, pixelDataChunks, multiframe, referencedImageIds, validOrientations, metadataProvider, tolerance, segmentsPixelIndices, sopUIDImageIdIndexMap, imageIdMaps, }: {
|
|
31
|
+
export declare function insertPixelDataPlanar({ segmentsOnFrame, labelMapImages, pixelDataChunks, multiframe, referencedImageIds, validOrientations, metadataProvider, tolerance, segmentsPixelIndices, sopUIDImageIdIndexMap, imageIdMaps, parserType, decodedFrameCount, }: {
|
|
12
32
|
segmentsOnFrame: any;
|
|
13
33
|
labelMapImages: any;
|
|
14
34
|
pixelDataChunks: any;
|
|
@@ -20,6 +40,8 @@ export declare function insertPixelDataPlanar({ segmentsOnFrame, labelMapImages,
|
|
|
20
40
|
segmentsPixelIndices: any;
|
|
21
41
|
sopUIDImageIdIndexMap: any;
|
|
22
42
|
imageIdMaps: any;
|
|
43
|
+
parserType: any;
|
|
44
|
+
decodedFrameCount: any;
|
|
23
45
|
}): Promise<unknown>;
|
|
24
46
|
export declare function insertOverlappingPixelDataPlanar({ segmentsOnFrame, labelMapImages, pixelDataChunks, multiframe, referencedImageIds, validOrientations, metadataProvider, tolerance, segmentsPixelIndices, sopUIDImageIdIndexMap, imageIdMaps, }: {
|
|
25
47
|
segmentsOnFrame: any;
|
|
@@ -37,4 +59,24 @@ export declare function insertOverlappingPixelDataPlanar({ segmentsOnFrame, labe
|
|
|
37
59
|
arrayOfLabelMapImages: any;
|
|
38
60
|
hasOverlappingSegments: boolean;
|
|
39
61
|
};
|
|
40
|
-
|
|
62
|
+
declare function createLabelmapsFromDICOMBuffer(referencedImageIds: any, arrayBuffer: any, metadataProvider: any, options?: Record<string, unknown>): Promise<{
|
|
63
|
+
labelMapImages: any;
|
|
64
|
+
segMetadata: {
|
|
65
|
+
seriesInstanceUid: any;
|
|
66
|
+
data: any[];
|
|
67
|
+
};
|
|
68
|
+
segmentsOnFrame: any[];
|
|
69
|
+
centroids: Map<any, any>;
|
|
70
|
+
overlappingSegments: any;
|
|
71
|
+
}>;
|
|
72
|
+
declare function createLabelmapsFromBufferInternal(referencedImageIds: any, segImageId: any, metadataProvider: any, options: any): Promise<{
|
|
73
|
+
labelMapImages: any;
|
|
74
|
+
segMetadata: {
|
|
75
|
+
seriesInstanceUid: any;
|
|
76
|
+
data: any[];
|
|
77
|
+
};
|
|
78
|
+
segmentsOnFrame: any[];
|
|
79
|
+
centroids: Map<any, any>;
|
|
80
|
+
overlappingSegments: any;
|
|
81
|
+
}>;
|
|
82
|
+
export { createLabelmapsFromSegImageIds, createLabelmapsFromDICOMBuffer, createLabelmapsFromBufferInternal, decodeSegPixelDataFromFrameIds, resolveFrameImageIds, buildSopUIDImageIdIndexMap, isPseudoBinaryFractional, };
|