@cornerstonejs/adapters 2.0.0-beta.24 → 2.0.0-beta.25
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/ParametricMap.d.ts +7 -0
- package/dist/esm/adapters/Cornerstone/ParametricMap.js +216 -0
- package/dist/esm/adapters/Cornerstone/Segmentation_3X.js +2 -19
- package/dist/esm/adapters/Cornerstone/Segmentation_4X.js +6 -79
- package/dist/esm/adapters/Cornerstone/index.d.ts +8 -1
- package/dist/esm/adapters/Cornerstone/index.js +5 -1
- package/dist/esm/adapters/Cornerstone3D/ParametricMap/generateToolState.d.ts +3 -0
- package/dist/esm/adapters/Cornerstone3D/ParametricMap/generateToolState.js +11 -0
- package/dist/esm/adapters/Cornerstone3D/ParametricMap/index.d.ts +1 -0
- package/dist/esm/adapters/Cornerstone3D/ParametricMap/index.js +1 -0
- package/dist/esm/adapters/Cornerstone3D/index.d.ts +5 -1
- package/dist/esm/adapters/Cornerstone3D/index.js +7 -3
- package/dist/esm/adapters/helpers/checkIfPerpendicular.d.ts +9 -0
- package/dist/esm/adapters/helpers/checkIfPerpendicular.js +15 -0
- package/dist/esm/adapters/helpers/checkOrientation.d.ts +1 -0
- package/dist/esm/adapters/helpers/checkOrientation.js +24 -0
- package/dist/esm/adapters/helpers/compareArrays.d.ts +9 -0
- package/dist/esm/adapters/helpers/compareArrays.js +24 -0
- package/dist/esm/adapters/helpers/getDatasetsFromImages.d.ts +9 -0
- package/dist/esm/adapters/helpers/getDatasetsFromImages.js +41 -0
- package/dist/esm/adapters/index.d.ts +13 -1
- package/dist/esm/adapters/index.js +8 -3
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/node_modules/lodash.clonedeep/index.js +1692 -0
- package/dist/umd/adapters.umd.js +378 -145
- package/dist/umd/adapters.umd.js.map +1 -1
- package/package.json +14 -8
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare function generateToolState(imageIds: any, arrayBuffer: any, metadataProvider: any, tolerance?: number): Promise<{
|
|
2
|
+
pixelData: any;
|
|
3
|
+
}>;
|
|
4
|
+
declare const ParametricMapObj: {
|
|
5
|
+
generateToolState: typeof generateToolState;
|
|
6
|
+
};
|
|
7
|
+
export { ParametricMapObj as default, ParametricMapObj as ParametricMap };
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { asyncToGenerator as _asyncToGenerator, regeneratorRuntime as _regeneratorRuntime, toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import { data, normalizers, log } from 'dcmjs';
|
|
3
|
+
import checkOrientation from '../helpers/checkOrientation.js';
|
|
4
|
+
import compareArrays from '../helpers/compareArrays.js';
|
|
5
|
+
|
|
6
|
+
var DicomMessage = data.DicomMessage,
|
|
7
|
+
DicomMetaDictionary = data.DicomMetaDictionary;
|
|
8
|
+
var Normalizer = normalizers.Normalizer;
|
|
9
|
+
function generateToolState(_x, _x2, _x3) {
|
|
10
|
+
return _generateToolState.apply(this, arguments);
|
|
11
|
+
}
|
|
12
|
+
function _generateToolState() {
|
|
13
|
+
_generateToolState = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(imageIds, arrayBuffer, metadataProvider) {
|
|
14
|
+
var tolerance,
|
|
15
|
+
dicomData,
|
|
16
|
+
dataset,
|
|
17
|
+
multiframe,
|
|
18
|
+
imagePlaneModule,
|
|
19
|
+
ImageOrientationPatient,
|
|
20
|
+
validOrientations,
|
|
21
|
+
pixelData,
|
|
22
|
+
orientation,
|
|
23
|
+
sopUIDImageIdIndexMap,
|
|
24
|
+
orientationText,
|
|
25
|
+
imageIdMaps,
|
|
26
|
+
_args = arguments;
|
|
27
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
28
|
+
while (1) switch (_context.prev = _context.next) {
|
|
29
|
+
case 0:
|
|
30
|
+
tolerance = _args.length > 3 && _args[3] !== undefined ? _args[3] : 1e-3;
|
|
31
|
+
dicomData = DicomMessage.readFile(arrayBuffer);
|
|
32
|
+
dataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
|
33
|
+
dataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
|
|
34
|
+
multiframe = Normalizer.normalizeToDataset([dataset]);
|
|
35
|
+
imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
36
|
+
if (!imagePlaneModule) {
|
|
37
|
+
console.warn("Insufficient metadata, imagePlaneModule missing.");
|
|
38
|
+
}
|
|
39
|
+
ImageOrientationPatient = Array.isArray(imagePlaneModule.rowCosines) ? [].concat(_toConsumableArray(imagePlaneModule.rowCosines), _toConsumableArray(imagePlaneModule.columnCosines)) : [imagePlaneModule.rowCosines.x, imagePlaneModule.rowCosines.y, imagePlaneModule.rowCosines.z, imagePlaneModule.columnCosines.x, imagePlaneModule.columnCosines.y, imagePlaneModule.columnCosines.z]; // It currently supports parametric maps with same orientation
|
|
40
|
+
validOrientations = [ImageOrientationPatient];
|
|
41
|
+
pixelData = getPixelData(multiframe);
|
|
42
|
+
orientation = checkOrientation(multiframe, validOrientations, [imagePlaneModule.rows, imagePlaneModule.columns, imageIds.length], tolerance); // Pre-compute the sop UID to imageId index map so that in the for loop
|
|
43
|
+
// we don't have to call metadataProvider.get() for each imageId over
|
|
44
|
+
// and over again.
|
|
45
|
+
sopUIDImageIdIndexMap = imageIds.reduce(function (acc, imageId) {
|
|
46
|
+
var _metadataProvider$get = metadataProvider.get("generalImageModule", imageId),
|
|
47
|
+
sopInstanceUID = _metadataProvider$get.sopInstanceUID;
|
|
48
|
+
acc[sopInstanceUID] = imageId;
|
|
49
|
+
return acc;
|
|
50
|
+
}, {});
|
|
51
|
+
if (!(orientation !== "Planar")) {
|
|
52
|
+
_context.next = 15;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
orientationText = {
|
|
56
|
+
Perpendicular: "orthogonal",
|
|
57
|
+
Oblique: "oblique"
|
|
58
|
+
};
|
|
59
|
+
throw new Error("Parametric maps ".concat(orientationText[orientation], " to the acquisition plane of the source data are not yet supported."));
|
|
60
|
+
case 15:
|
|
61
|
+
// Pre-compute the indices and metadata so that we don't have to call
|
|
62
|
+
// a function for each imageId in the for loop.
|
|
63
|
+
imageIdMaps = imageIds.reduce(function (acc, curr, index) {
|
|
64
|
+
acc.indices[curr] = index;
|
|
65
|
+
acc.metadata[curr] = metadataProvider.get("instance", curr);
|
|
66
|
+
return acc;
|
|
67
|
+
}, {
|
|
68
|
+
indices: {},
|
|
69
|
+
metadata: {}
|
|
70
|
+
});
|
|
71
|
+
_context.next = 18;
|
|
72
|
+
return insertPixelDataPlanar(pixelData, multiframe, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap, imageIdMaps);
|
|
73
|
+
case 18:
|
|
74
|
+
return _context.abrupt("return", {
|
|
75
|
+
pixelData: pixelData
|
|
76
|
+
});
|
|
77
|
+
case 19:
|
|
78
|
+
case "end":
|
|
79
|
+
return _context.stop();
|
|
80
|
+
}
|
|
81
|
+
}, _callee);
|
|
82
|
+
}));
|
|
83
|
+
return _generateToolState.apply(this, arguments);
|
|
84
|
+
}
|
|
85
|
+
function insertPixelDataPlanar(sourcePixelData, multiframe, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap, imageIdMaps) {
|
|
86
|
+
var targetPixelData = new sourcePixelData.constructor(sourcePixelData.length);
|
|
87
|
+
var PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
88
|
+
Rows = multiframe.Rows,
|
|
89
|
+
Columns = multiframe.Columns;
|
|
90
|
+
var sliceLength = Columns * Rows;
|
|
91
|
+
var numSlices = PerFrameFunctionalGroupsSequence.length;
|
|
92
|
+
for (var i = 0; i < numSlices; i++) {
|
|
93
|
+
var sourceSliceDataView = new sourcePixelData.constructor(sourcePixelData.buffer, i * sliceLength, sliceLength);
|
|
94
|
+
var imageId = findReferenceSourceImageId(multiframe, i, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
|
|
95
|
+
if (!imageId) {
|
|
96
|
+
console.warn("Image not present in stack, can't import frame : " + i + ".");
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
var sourceImageMetadata = imageIdMaps.metadata[imageId];
|
|
100
|
+
if (Rows !== sourceImageMetadata.Rows || Columns !== sourceImageMetadata.Columns) {
|
|
101
|
+
throw new Error("Parametric map have different geometry dimensions (Rows and Columns) " + "respect to the source image reference frame. This is not yet supported.");
|
|
102
|
+
}
|
|
103
|
+
var imageIdIndex = imageIdMaps.indices[imageId];
|
|
104
|
+
var byteOffset = sliceLength * imageIdIndex * targetPixelData.BYTES_PER_ELEMENT;
|
|
105
|
+
var targetSliceDataView = new targetPixelData.constructor(targetPixelData.buffer, byteOffset, sliceLength);
|
|
106
|
+
// Copy from source to target which works for parametric maps with same orientation.
|
|
107
|
+
// TODO: Find a dataset with parametric map in a different orientation and add finish this implementation
|
|
108
|
+
targetSliceDataView.set(sourceSliceDataView);
|
|
109
|
+
}
|
|
110
|
+
return targetPixelData;
|
|
111
|
+
}
|
|
112
|
+
function getPixelData(multiframe) {
|
|
113
|
+
var TypedArrayClass;
|
|
114
|
+
var data;
|
|
115
|
+
if (multiframe.PixelData) {
|
|
116
|
+
var _multiframe$PixelRepr;
|
|
117
|
+
var validTypedArrays = multiframe.BitsAllocated === 16 ? [Uint16Array, Int16Array] : [Uint32Array, Int32Array];
|
|
118
|
+
TypedArrayClass = validTypedArrays[(_multiframe$PixelRepr = multiframe.PixelRepresentation) !== null && _multiframe$PixelRepr !== void 0 ? _multiframe$PixelRepr : 0];
|
|
119
|
+
data = multiframe.PixelData;
|
|
120
|
+
} else if (multiframe.FloatPixelData) {
|
|
121
|
+
TypedArrayClass = Float32Array;
|
|
122
|
+
data = multiframe.FloatPixelData;
|
|
123
|
+
} else if (multiframe.DoubleFloatPixelData) {
|
|
124
|
+
TypedArrayClass = Float64Array;
|
|
125
|
+
data = multiframe.DoubleFloatPixelData;
|
|
126
|
+
}
|
|
127
|
+
if (data === undefined) {
|
|
128
|
+
log.error("This parametric map pixel data is undefined.");
|
|
129
|
+
}
|
|
130
|
+
if (Array.isArray(data)) {
|
|
131
|
+
data = data[0];
|
|
132
|
+
}
|
|
133
|
+
return new TypedArrayClass(data);
|
|
134
|
+
}
|
|
135
|
+
function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap) {
|
|
136
|
+
var imageId = undefined;
|
|
137
|
+
if (!multiframe) {
|
|
138
|
+
return imageId;
|
|
139
|
+
}
|
|
140
|
+
var FrameOfReferenceUID = multiframe.FrameOfReferenceUID,
|
|
141
|
+
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
142
|
+
SourceImageSequence = multiframe.SourceImageSequence,
|
|
143
|
+
ReferencedSeriesSequence = multiframe.ReferencedSeriesSequence;
|
|
144
|
+
if (!PerFrameFunctionalGroupsSequence || PerFrameFunctionalGroupsSequence.length === 0) {
|
|
145
|
+
return imageId;
|
|
146
|
+
}
|
|
147
|
+
var PerFrameFunctionalGroup = PerFrameFunctionalGroupsSequence[frameSegment];
|
|
148
|
+
if (!PerFrameFunctionalGroup) {
|
|
149
|
+
return imageId;
|
|
150
|
+
}
|
|
151
|
+
var frameSourceImageSequence = undefined;
|
|
152
|
+
if (PerFrameFunctionalGroup.DerivationImageSequence) {
|
|
153
|
+
var DerivationImageSequence = PerFrameFunctionalGroup.DerivationImageSequence;
|
|
154
|
+
if (Array.isArray(DerivationImageSequence)) {
|
|
155
|
+
if (DerivationImageSequence.length !== 0) {
|
|
156
|
+
DerivationImageSequence = DerivationImageSequence[0];
|
|
157
|
+
} else {
|
|
158
|
+
DerivationImageSequence = undefined;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (DerivationImageSequence) {
|
|
162
|
+
frameSourceImageSequence = DerivationImageSequence.SourceImageSequence;
|
|
163
|
+
if (Array.isArray(frameSourceImageSequence)) {
|
|
164
|
+
if (frameSourceImageSequence.length !== 0) {
|
|
165
|
+
frameSourceImageSequence = frameSourceImageSequence[0];
|
|
166
|
+
} else {
|
|
167
|
+
frameSourceImageSequence = undefined;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
} else if (SourceImageSequence && SourceImageSequence.length !== 0) {
|
|
172
|
+
console.warn("DerivationImageSequence not present, using SourceImageSequence assuming SEG has the same geometry as the source image.");
|
|
173
|
+
frameSourceImageSequence = SourceImageSequence[frameSegment];
|
|
174
|
+
}
|
|
175
|
+
if (frameSourceImageSequence) {
|
|
176
|
+
imageId = getImageIdOfSourceImageBySourceImageSequence(frameSourceImageSequence, sopUIDImageIdIndexMap);
|
|
177
|
+
}
|
|
178
|
+
if (imageId === undefined && ReferencedSeriesSequence) {
|
|
179
|
+
var referencedSeriesSequence = Array.isArray(ReferencedSeriesSequence) ? ReferencedSeriesSequence[0] : ReferencedSeriesSequence;
|
|
180
|
+
var ReferencedSeriesInstanceUID = referencedSeriesSequence.SeriesInstanceUID;
|
|
181
|
+
imageId = getImageIdOfSourceImagebyGeometry(ReferencedSeriesInstanceUID, FrameOfReferenceUID, PerFrameFunctionalGroup, imageIds, metadataProvider, tolerance);
|
|
182
|
+
}
|
|
183
|
+
return imageId;
|
|
184
|
+
}
|
|
185
|
+
function getImageIdOfSourceImageBySourceImageSequence(SourceImageSequence, sopUIDImageIdIndexMap) {
|
|
186
|
+
var ReferencedSOPInstanceUID = SourceImageSequence.ReferencedSOPInstanceUID,
|
|
187
|
+
ReferencedFrameNumber = SourceImageSequence.ReferencedFrameNumber;
|
|
188
|
+
return ReferencedFrameNumber ? getImageIdOfReferencedFrame(ReferencedSOPInstanceUID, ReferencedFrameNumber, sopUIDImageIdIndexMap) : sopUIDImageIdIndexMap[ReferencedSOPInstanceUID];
|
|
189
|
+
}
|
|
190
|
+
function getImageIdOfSourceImagebyGeometry(ReferencedSeriesInstanceUID, FrameOfReferenceUID, PerFrameFunctionalGroup, imageIds, metadataProvider, tolerance) {
|
|
191
|
+
if (ReferencedSeriesInstanceUID === undefined || PerFrameFunctionalGroup.PlanePositionSequence === undefined || PerFrameFunctionalGroup.PlanePositionSequence[0] === undefined || PerFrameFunctionalGroup.PlanePositionSequence[0].ImagePositionPatient === undefined) {
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
for (var imageIdsIndex = 0; imageIdsIndex < imageIds.length; ++imageIdsIndex) {
|
|
195
|
+
var sourceImageMetadata = metadataProvider.get("instance", imageIds[imageIdsIndex]);
|
|
196
|
+
if (sourceImageMetadata === undefined || sourceImageMetadata.ImagePositionPatient === undefined || sourceImageMetadata.FrameOfReferenceUID !== FrameOfReferenceUID || sourceImageMetadata.SeriesInstanceUID !== ReferencedSeriesInstanceUID) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (compareArrays(PerFrameFunctionalGroup.PlanePositionSequence[0].ImagePositionPatient, sourceImageMetadata.ImagePositionPatient, tolerance)) {
|
|
200
|
+
return imageIds[imageIdsIndex];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function getImageIdOfReferencedFrame(sopInstanceUid, frameNumber, sopUIDImageIdIndexMap) {
|
|
205
|
+
var imageId = sopUIDImageIdIndexMap[sopInstanceUid];
|
|
206
|
+
if (!imageId) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
var imageIdFrameNumber = Number(imageId.split("frame=")[1]);
|
|
210
|
+
return imageIdFrameNumber === frameNumber - 1 ? imageId : undefined;
|
|
211
|
+
}
|
|
212
|
+
var ParametricMapObj = {
|
|
213
|
+
generateToolState: generateToolState
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export { ParametricMapObj as ParametricMap, ParametricMapObj as default };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
import { utilities, normalizers, derivations, log } from 'dcmjs';
|
|
3
3
|
import ndarray from 'ndarray';
|
|
4
|
+
import getDatasetsFromImages from '../helpers/getDatasetsFromImages.js';
|
|
4
5
|
|
|
5
6
|
var _utilities$orientatio = utilities.orientation,
|
|
6
7
|
rotateDirectionCosinesInPlane = _utilities$orientatio.rotateDirectionCosinesInPlane,
|
|
@@ -135,25 +136,7 @@ function _getSegCount(seg, segments) {
|
|
|
135
136
|
* @returns {Object} The Seg derived dataSet.
|
|
136
137
|
*/
|
|
137
138
|
function _createSegFromImages(images, isMultiframe, options) {
|
|
138
|
-
var
|
|
139
|
-
if (isMultiframe) {
|
|
140
|
-
var image = images[0];
|
|
141
|
-
var arrayBuffer = image.data.byteArray.buffer;
|
|
142
|
-
var dicomData = DicomMessage.readFile(arrayBuffer);
|
|
143
|
-
var dataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
|
144
|
-
dataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
|
|
145
|
-
datasets.push(dataset);
|
|
146
|
-
} else {
|
|
147
|
-
for (var i = 0; i < images.length; i++) {
|
|
148
|
-
var _image = images[i];
|
|
149
|
-
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
150
|
-
var _dicomData = DicomMessage.readFile(_arrayBuffer);
|
|
151
|
-
var _dataset = DicomMetaDictionary.naturalizeDataset(_dicomData.dict);
|
|
152
|
-
_dataset._meta = DicomMetaDictionary.namifyDataset(_dicomData.meta);
|
|
153
|
-
datasets.push(_dataset);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
var multiframe = Normalizer.normalizeToDataset(datasets);
|
|
139
|
+
var multiframe = getDatasetsFromImages(images, isMultiframe);
|
|
157
140
|
return new SegmentationDerivation([multiframe], options);
|
|
158
141
|
}
|
|
159
142
|
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { asyncToGenerator as _asyncToGenerator, regeneratorRuntime as _regeneratorRuntime, toConsumableArray as _toConsumableArray, createForOfIteratorHelper as _createForOfIteratorHelper, slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
import { utilities, data, normalizers, derivations, log } from 'dcmjs';
|
|
3
3
|
import ndarray from 'ndarray';
|
|
4
|
+
import '../../node_modules/lodash.clonedeep/index.js';
|
|
5
|
+
import getDatasetsFromImages from '../helpers/getDatasetsFromImages.js';
|
|
6
|
+
import checkOrientation from '../helpers/checkOrientation.js';
|
|
7
|
+
import compareArrays from '../helpers/compareArrays.js';
|
|
4
8
|
import Events from '../enums/Events.js';
|
|
5
9
|
|
|
6
10
|
var _utilities$orientatio = utilities.orientation,
|
|
7
11
|
rotateDirectionCosinesInPlane = _utilities$orientatio.rotateDirectionCosinesInPlane,
|
|
8
12
|
flipIOP = _utilities$orientatio.flipImageOrientationPatient,
|
|
9
13
|
flipMatrix2D = _utilities$orientatio.flipMatrix2D,
|
|
10
|
-
rotateMatrix902D = _utilities$orientatio.rotateMatrix902D
|
|
11
|
-
nearlyEqual = _utilities$orientatio.nearlyEqual;
|
|
14
|
+
rotateMatrix902D = _utilities$orientatio.rotateMatrix902D;
|
|
12
15
|
var BitArray = data.BitArray,
|
|
13
16
|
DicomMessage = data.DicomMessage,
|
|
14
17
|
DicomMetaDictionary = data.DicomMetaDictionary;
|
|
@@ -157,27 +160,7 @@ function _getLabelmapsFromReferencedFrameIndicies(labelmap3D, referencedFrameInd
|
|
|
157
160
|
* @returns {Object} The Seg derived dataSet.
|
|
158
161
|
*/
|
|
159
162
|
function _createSegFromImages(images, isMultiframe, options) {
|
|
160
|
-
var
|
|
161
|
-
if (isMultiframe) {
|
|
162
|
-
var image = images[0];
|
|
163
|
-
var arrayBuffer = image.data.byteArray.buffer;
|
|
164
|
-
var dicomData = DicomMessage.readFile(arrayBuffer);
|
|
165
|
-
var dataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
|
166
|
-
dataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
|
|
167
|
-
dataset.SpecificCharacterSet = "ISO_IR 192";
|
|
168
|
-
datasets.push(dataset);
|
|
169
|
-
} else {
|
|
170
|
-
for (var i = 0; i < images.length; i++) {
|
|
171
|
-
var _image = images[i];
|
|
172
|
-
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
173
|
-
var _dicomData = DicomMessage.readFile(_arrayBuffer);
|
|
174
|
-
var _dataset = DicomMetaDictionary.naturalizeDataset(_dicomData.dict);
|
|
175
|
-
_dataset._meta = DicomMetaDictionary.namifyDataset(_dicomData.meta);
|
|
176
|
-
_dataset.SpecificCharacterSet = "ISO_IR 192";
|
|
177
|
-
datasets.push(_dataset);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
var multiframe = Normalizer.normalizeToDataset(datasets);
|
|
163
|
+
var multiframe = getDatasetsFromImages(images, isMultiframe);
|
|
181
164
|
return new SegmentationDerivation([multiframe], options);
|
|
182
165
|
}
|
|
183
166
|
|
|
@@ -837,41 +820,6 @@ function insertPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBu
|
|
|
837
820
|
processInChunks();
|
|
838
821
|
});
|
|
839
822
|
}
|
|
840
|
-
function checkOrientation(multiframe, validOrientations, sourceDataDimensions, tolerance) {
|
|
841
|
-
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
842
|
-
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence;
|
|
843
|
-
var sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence ? SharedFunctionalGroupsSequence.PlaneOrientationSequence.ImageOrientationPatient : undefined;
|
|
844
|
-
|
|
845
|
-
// Check if in plane.
|
|
846
|
-
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[0];
|
|
847
|
-
var iop = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
848
|
-
var inPlane = validOrientations.some(function (operation) {
|
|
849
|
-
return compareArrays(iop, operation, tolerance);
|
|
850
|
-
});
|
|
851
|
-
if (inPlane) {
|
|
852
|
-
return "Planar";
|
|
853
|
-
}
|
|
854
|
-
if (checkIfPerpendicular(iop, validOrientations[0], tolerance) && sourceDataDimensions.includes(multiframe.Rows) && sourceDataDimensions.includes(multiframe.Columns)) {
|
|
855
|
-
// Perpendicular and fits on same grid.
|
|
856
|
-
return "Perpendicular";
|
|
857
|
-
}
|
|
858
|
-
return "Oblique";
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
/**
|
|
862
|
-
* checkIfPerpendicular - Returns true if iop1 and iop2 are perpendicular
|
|
863
|
-
* within a tolerance.
|
|
864
|
-
*
|
|
865
|
-
* @param {Number[6]} iop1 An ImageOrientationPatient array.
|
|
866
|
-
* @param {Number[6]} iop2 An ImageOrientationPatient array.
|
|
867
|
-
* @param {Number} tolerance.
|
|
868
|
-
* @return {Boolean} True if iop1 and iop2 are equal.
|
|
869
|
-
*/
|
|
870
|
-
function checkIfPerpendicular(iop1, iop2, tolerance) {
|
|
871
|
-
var absDotColumnCosines = Math.abs(iop1[0] * iop2[0] + iop1[1] * iop2[1] + iop1[2] * iop2[2]);
|
|
872
|
-
var absDotRowCosines = Math.abs(iop1[3] * iop2[3] + iop1[4] * iop2[4] + iop1[5] * iop2[5]);
|
|
873
|
-
return (absDotColumnCosines < tolerance || Math.abs(absDotColumnCosines - 1) < tolerance) && (absDotRowCosines < tolerance || Math.abs(absDotRowCosines - 1) < tolerance);
|
|
874
|
-
}
|
|
875
823
|
|
|
876
824
|
/**
|
|
877
825
|
* unpackPixelData - Unpacks bit packed pixelData if the Segmentation is BINARY.
|
|
@@ -1059,27 +1007,6 @@ function alignPixelDataWithSourceData(pixelData2D, iop, orientations, tolerance)
|
|
|
1059
1007
|
return rotateMatrix902D(rotateMatrix902D(rotateMatrix902D(pixelData2D)));
|
|
1060
1008
|
}
|
|
1061
1009
|
}
|
|
1062
|
-
|
|
1063
|
-
/**
|
|
1064
|
-
* compareArrays - Returns true if array1 and array2 are equal
|
|
1065
|
-
* within a tolerance.
|
|
1066
|
-
*
|
|
1067
|
-
* @param {Number[]} array1 - An array.
|
|
1068
|
-
* @param {Number[]} array2 - An array.
|
|
1069
|
-
* @param {Number} tolerance.
|
|
1070
|
-
* @return {Boolean} True if array1 and array2 are equal.
|
|
1071
|
-
*/
|
|
1072
|
-
function compareArrays(array1, array2, tolerance) {
|
|
1073
|
-
if (array1.length != array2.length) {
|
|
1074
|
-
return false;
|
|
1075
|
-
}
|
|
1076
|
-
for (var i = 0; i < array1.length; ++i) {
|
|
1077
|
-
if (!nearlyEqual(array1[i], array2[i], tolerance)) {
|
|
1078
|
-
return false;
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
return true;
|
|
1082
|
-
}
|
|
1083
1010
|
function getSegmentMetadata(multiframe, seriesInstanceUid) {
|
|
1084
1011
|
var segmentSequence = multiframe.SegmentSequence;
|
|
1085
1012
|
var data = [];
|
|
@@ -31,4 +31,11 @@ declare const CornerstoneSEG: {
|
|
|
31
31
|
}, cornerstoneToolsVersion?: number) => Blob;
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
|
-
|
|
34
|
+
declare const CornerstonePMAP: {
|
|
35
|
+
ParametricMap: {
|
|
36
|
+
generateToolState: (imageIds: any, arrayBuffer: any, metadataProvider: any, tolerance?: number) => Promise<{
|
|
37
|
+
pixelData: any;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export { CornerstoneSR, CornerstoneSEG, CornerstonePMAP };
|
|
@@ -9,6 +9,7 @@ import CobbAngle from './CobbAngle.js';
|
|
|
9
9
|
import Angle from './Angle.js';
|
|
10
10
|
import RectangleRoi from './RectangleRoi.js';
|
|
11
11
|
import Segmentation from './Segmentation.js';
|
|
12
|
+
import ParametricMapObj from './ParametricMap.js';
|
|
12
13
|
|
|
13
14
|
var CornerstoneSR = {
|
|
14
15
|
Length: Length,
|
|
@@ -25,5 +26,8 @@ var CornerstoneSR = {
|
|
|
25
26
|
var CornerstoneSEG = {
|
|
26
27
|
Segmentation: Segmentation
|
|
27
28
|
};
|
|
29
|
+
var CornerstonePMAP = {
|
|
30
|
+
ParametricMap: ParametricMapObj
|
|
31
|
+
};
|
|
28
32
|
|
|
29
|
-
export { CornerstoneSEG, CornerstoneSR };
|
|
33
|
+
export { CornerstonePMAP, CornerstoneSEG, CornerstoneSR };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CornerstonePMAP } from '../../Cornerstone/index.js';
|
|
2
|
+
|
|
3
|
+
var ParametricMap = CornerstonePMAP.ParametricMap;
|
|
4
|
+
var generateToolStateCornerstone = ParametricMap.generateToolState;
|
|
5
|
+
function generateToolState(imageIds, arrayBuffer, metadataProvider) {
|
|
6
|
+
var skipOverlapping = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
7
|
+
var tolerance = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1e-3;
|
|
8
|
+
return generateToolStateCornerstone(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { generateToolState };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { generateToolState } from "./generateToolState";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { generateToolState } from './generateToolState.js';
|
|
@@ -11,6 +11,7 @@ import PlanarFreehandROI from "./PlanarFreehandROI";
|
|
|
11
11
|
import Probe from "./Probe";
|
|
12
12
|
import UltrasoundDirectional from "./UltrasoundDirectional";
|
|
13
13
|
import * as Segmentation from "./Segmentation";
|
|
14
|
+
import * as ParametricMap from "./ParametricMap";
|
|
14
15
|
import * as RTSS from "./RTStruct";
|
|
15
16
|
declare const Cornerstone3DSR: {
|
|
16
17
|
Bidirectional: typeof Bidirectional;
|
|
@@ -36,7 +37,10 @@ declare const Cornerstone3DSR: {
|
|
|
36
37
|
declare const Cornerstone3DSEG: {
|
|
37
38
|
Segmentation: typeof Segmentation;
|
|
38
39
|
};
|
|
40
|
+
declare const Cornerstone3DPMAP: {
|
|
41
|
+
ParametricMap: typeof ParametricMap;
|
|
42
|
+
};
|
|
39
43
|
declare const Cornerstone3DRT: {
|
|
40
44
|
RTSS: typeof RTSS;
|
|
41
45
|
};
|
|
42
|
-
export { Cornerstone3DSR, Cornerstone3DSEG, Cornerstone3DRT };
|
|
46
|
+
export { Cornerstone3DSR, Cornerstone3DSEG, Cornerstone3DPMAP, Cornerstone3DRT };
|
|
@@ -13,7 +13,8 @@ import PlanarFreehandROI from './PlanarFreehandROI.js';
|
|
|
13
13
|
import Probe from './Probe.js';
|
|
14
14
|
import UltrasoundDirectional from './UltrasoundDirectional.js';
|
|
15
15
|
import * as index from './Segmentation/index.js';
|
|
16
|
-
import * as index$1 from './
|
|
16
|
+
import * as index$1 from './ParametricMap/index.js';
|
|
17
|
+
import * as index$2 from './RTStruct/index.js';
|
|
17
18
|
|
|
18
19
|
var Cornerstone3DSR = {
|
|
19
20
|
Bidirectional: Bidirectional,
|
|
@@ -34,8 +35,11 @@ var Cornerstone3DSR = {
|
|
|
34
35
|
var Cornerstone3DSEG = {
|
|
35
36
|
Segmentation: index
|
|
36
37
|
};
|
|
38
|
+
var Cornerstone3DPMAP = {
|
|
39
|
+
ParametricMap: index$1
|
|
40
|
+
};
|
|
37
41
|
var Cornerstone3DRT = {
|
|
38
|
-
RTSS: index$
|
|
42
|
+
RTSS: index$2
|
|
39
43
|
};
|
|
40
44
|
|
|
41
|
-
export { Cornerstone3DRT, Cornerstone3DSEG, Cornerstone3DSR };
|
|
45
|
+
export { Cornerstone3DPMAP, Cornerstone3DRT, Cornerstone3DSEG, Cornerstone3DSR };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if iop1 and iop2 are perpendicular within a tolerance.
|
|
3
|
+
*
|
|
4
|
+
* @param iop1 - First ImageOrientationPatient
|
|
5
|
+
* @param iop2 - Second ImageOrientationPatient
|
|
6
|
+
* @param tolerance - Tolerance
|
|
7
|
+
* @returns True if iop1 and iop2 are equal.
|
|
8
|
+
*/
|
|
9
|
+
export default function checkIfPerpendicular(iop1: number[], iop2: number[], tolerance: number): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if iop1 and iop2 are perpendicular within a tolerance.
|
|
3
|
+
*
|
|
4
|
+
* @param iop1 - First ImageOrientationPatient
|
|
5
|
+
* @param iop2 - Second ImageOrientationPatient
|
|
6
|
+
* @param tolerance - Tolerance
|
|
7
|
+
* @returns True if iop1 and iop2 are equal.
|
|
8
|
+
*/
|
|
9
|
+
function checkIfPerpendicular(iop1, iop2, tolerance) {
|
|
10
|
+
var absDotColumnCosines = Math.abs(iop1[0] * iop2[0] + iop1[1] * iop2[1] + iop1[2] * iop2[2]);
|
|
11
|
+
var absDotRowCosines = Math.abs(iop1[3] * iop2[3] + iop1[4] * iop2[4] + iop1[5] * iop2[5]);
|
|
12
|
+
return (absDotColumnCosines < tolerance || Math.abs(absDotColumnCosines - 1) < tolerance) && (absDotRowCosines < tolerance || Math.abs(absDotRowCosines - 1) < tolerance);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { checkIfPerpendicular as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function checkOrientation(multiframe: any, validOrientations: any, sourceDataDimensions: any, tolerance: any): "Planar" | "Perpendicular" | "Oblique";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import checkIfPerpendicular from './checkIfPerpendicular.js';
|
|
2
|
+
import compareArrays from './compareArrays.js';
|
|
3
|
+
|
|
4
|
+
function checkOrientation(multiframe, validOrientations, sourceDataDimensions, tolerance) {
|
|
5
|
+
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
6
|
+
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence;
|
|
7
|
+
var sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence ? SharedFunctionalGroupsSequence.PlaneOrientationSequence.ImageOrientationPatient : undefined;
|
|
8
|
+
// Check if in plane.
|
|
9
|
+
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[0];
|
|
10
|
+
var iop = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
11
|
+
var inPlane = validOrientations.some(function (operation) {
|
|
12
|
+
return compareArrays(iop, operation, tolerance);
|
|
13
|
+
});
|
|
14
|
+
if (inPlane) {
|
|
15
|
+
return "Planar";
|
|
16
|
+
}
|
|
17
|
+
if (checkIfPerpendicular(iop, validOrientations[0], tolerance) && sourceDataDimensions.includes(multiframe.Rows) && sourceDataDimensions.includes(multiframe.Columns)) {
|
|
18
|
+
// Perpendicular and fits on same grid.
|
|
19
|
+
return "Perpendicular";
|
|
20
|
+
}
|
|
21
|
+
return "Oblique";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { checkOrientation as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if array1 and array2 are equal within a tolerance.
|
|
3
|
+
*
|
|
4
|
+
* @param array1 - First array
|
|
5
|
+
* @param array2 - Second array
|
|
6
|
+
* @param tolerance - Tolerance
|
|
7
|
+
* @returns True if array1 and array2 are equal.
|
|
8
|
+
*/
|
|
9
|
+
export default function compareArrays(array1: number[], array2: number[], tolerance: number): boolean;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { utilities } from 'dcmjs';
|
|
2
|
+
|
|
3
|
+
var nearlyEqual = utilities.orientation.nearlyEqual;
|
|
4
|
+
/**
|
|
5
|
+
* Returns true if array1 and array2 are equal within a tolerance.
|
|
6
|
+
*
|
|
7
|
+
* @param array1 - First array
|
|
8
|
+
* @param array2 - Second array
|
|
9
|
+
* @param tolerance - Tolerance
|
|
10
|
+
* @returns True if array1 and array2 are equal.
|
|
11
|
+
*/
|
|
12
|
+
function compareArrays(array1, array2, tolerance) {
|
|
13
|
+
if (array1.length !== array2.length) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
for (var i = 0; i < array1.length; ++i) {
|
|
17
|
+
if (!nearlyEqual(array1[i], array2[i], tolerance)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { compareArrays as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert an array of cornerstone images into datasets
|
|
3
|
+
*
|
|
4
|
+
* @param images - An array of the cornerstone image objects
|
|
5
|
+
* @param isMultiframe - Whether the images are multiframe
|
|
6
|
+
* @param options - Options object that may contain:
|
|
7
|
+
* - SpecificCharacterSet: character set to be set to each dataset
|
|
8
|
+
*/
|
|
9
|
+
export default function getDatasetsFromImages(images: any, isMultiframe: any, options?: any): any;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { data, normalizers } from 'dcmjs';
|
|
2
|
+
|
|
3
|
+
var DicomMessage = data.DicomMessage,
|
|
4
|
+
DicomMetaDictionary = data.DicomMetaDictionary;
|
|
5
|
+
var Normalizer = normalizers.Normalizer;
|
|
6
|
+
/**
|
|
7
|
+
* Convert an array of cornerstone images into datasets
|
|
8
|
+
*
|
|
9
|
+
* @param images - An array of the cornerstone image objects
|
|
10
|
+
* @param isMultiframe - Whether the images are multiframe
|
|
11
|
+
* @param options - Options object that may contain:
|
|
12
|
+
* - SpecificCharacterSet: character set to be set to each dataset
|
|
13
|
+
*/
|
|
14
|
+
function getDatasetsFromImages(images, isMultiframe, options) {
|
|
15
|
+
var datasets = [];
|
|
16
|
+
if (isMultiframe) {
|
|
17
|
+
var image = images[0];
|
|
18
|
+
var arrayBuffer = image.data.byteArray.buffer;
|
|
19
|
+
var dicomData = DicomMessage.readFile(arrayBuffer);
|
|
20
|
+
var dataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
|
21
|
+
dataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
|
|
22
|
+
datasets.push(dataset);
|
|
23
|
+
} else {
|
|
24
|
+
for (var i = 0; i < images.length; i++) {
|
|
25
|
+
var _image = images[i];
|
|
26
|
+
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
27
|
+
var _dicomData = DicomMessage.readFile(_arrayBuffer);
|
|
28
|
+
var _dataset = DicomMetaDictionary.naturalizeDataset(_dicomData.dict);
|
|
29
|
+
_dataset._meta = DicomMetaDictionary.namifyDataset(_dicomData.meta);
|
|
30
|
+
datasets.push(_dataset);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (options !== null && options !== void 0 && options.SpecificCharacterSet) {
|
|
34
|
+
datasets.forEach(function (dataset) {
|
|
35
|
+
return dataset.SpecificCharacterSet = options.SpecificCharacterSet;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return Normalizer.normalizeToDataset(datasets);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { getDatasetsFromImages as default };
|
|
@@ -54,9 +54,21 @@ declare const adaptersSEG: {
|
|
|
54
54
|
Segmentation: typeof import("./VTKjs/Segmentation").default;
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
|
+
declare const adaptersPMAP: {
|
|
58
|
+
Cornerstone: {
|
|
59
|
+
ParametricMap: {
|
|
60
|
+
generateToolState: (imageIds: any, arrayBuffer: any, metadataProvider: any, tolerance?: number) => Promise<{
|
|
61
|
+
pixelData: any;
|
|
62
|
+
}>;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
Cornerstone3D: {
|
|
66
|
+
ParametricMap: typeof import("./Cornerstone3D/ParametricMap");
|
|
67
|
+
};
|
|
68
|
+
};
|
|
57
69
|
declare const adaptersRT: {
|
|
58
70
|
Cornerstone3D: {
|
|
59
71
|
RTSS: typeof import("./Cornerstone3D/RTStruct");
|
|
60
72
|
};
|
|
61
73
|
};
|
|
62
|
-
export { adaptersSR, adaptersSEG, adaptersRT, Enums, helpers };
|
|
74
|
+
export { adaptersSR, adaptersSEG, adaptersPMAP, adaptersRT, Enums, helpers };
|