@cornerstonejs/core 1.5.0 → 1.7.0
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/cjs/RenderingEngine/StackViewport.js +43 -75
- package/dist/cjs/RenderingEngine/StackViewport.js.map +1 -1
- package/dist/cjs/RenderingEngine/Viewport.d.ts +2 -0
- package/dist/cjs/RenderingEngine/Viewport.js.map +1 -1
- package/dist/cjs/enums/CalibrationTypes.d.ts +10 -0
- package/dist/cjs/enums/CalibrationTypes.js +15 -0
- package/dist/cjs/enums/CalibrationTypes.js.map +1 -0
- package/dist/cjs/enums/Events.d.ts +1 -0
- package/dist/cjs/enums/Events.js +1 -0
- package/dist/cjs/enums/Events.js.map +1 -1
- package/dist/cjs/enums/index.d.ts +2 -1
- package/dist/cjs/enums/index.js +3 -1
- package/dist/cjs/enums/index.js.map +1 -1
- package/dist/cjs/types/CPUIImageData.d.ts +2 -0
- package/dist/cjs/types/EventTypes.d.ts +8 -3
- package/dist/cjs/types/IImageCalibration.d.ts +11 -0
- package/dist/cjs/types/IImageCalibration.js +3 -0
- package/dist/cjs/types/IImageCalibration.js.map +1 -0
- package/dist/cjs/types/IImageData.d.ts +2 -0
- package/dist/cjs/types/index.d.ts +2 -1
- package/dist/cjs/utilities/calibratedPixelSpacingMetadataProvider.d.ts +3 -7
- package/dist/cjs/utilities/calibratedPixelSpacingMetadataProvider.js.map +1 -1
- package/dist/cjs/utilities/imageToWorldCoords.js +4 -1
- package/dist/cjs/utilities/imageToWorldCoords.js.map +1 -1
- package/dist/cjs/utilities/worldToImageCoords.js +4 -1
- package/dist/cjs/utilities/worldToImageCoords.js.map +1 -1
- package/dist/esm/RenderingEngine/StackViewport.js +16 -49
- package/dist/esm/RenderingEngine/StackViewport.js.map +1 -1
- package/dist/esm/RenderingEngine/Viewport.d.ts +2 -0
- package/dist/esm/RenderingEngine/Viewport.js.map +1 -1
- package/dist/esm/enums/CalibrationTypes.d.ts +10 -0
- package/dist/esm/enums/CalibrationTypes.js +12 -0
- package/dist/esm/enums/CalibrationTypes.js.map +1 -0
- package/dist/esm/enums/Events.d.ts +1 -0
- package/dist/esm/enums/Events.js +1 -0
- package/dist/esm/enums/Events.js.map +1 -1
- package/dist/esm/enums/index.d.ts +2 -1
- package/dist/esm/enums/index.js +2 -1
- package/dist/esm/enums/index.js.map +1 -1
- package/dist/esm/types/CPUIImageData.d.ts +2 -0
- package/dist/esm/types/EventTypes.d.ts +8 -3
- package/dist/esm/types/IImageCalibration.d.ts +11 -0
- package/dist/esm/types/IImageCalibration.js +2 -0
- package/dist/esm/types/IImageCalibration.js.map +1 -0
- package/dist/esm/types/IImageData.d.ts +2 -0
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.d.ts +3 -7
- package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.js.map +1 -1
- package/dist/esm/utilities/imageToWorldCoords.js +4 -1
- package/dist/esm/utilities/imageToWorldCoords.js.map +1 -1
- package/dist/esm/utilities/worldToImageCoords.js +4 -1
- package/dist/esm/utilities/worldToImageCoords.js.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +2 -2
- package/src/RenderingEngine/StackViewport.ts +28 -97
- package/src/RenderingEngine/Viewport.ts +2 -0
- package/src/enums/CalibrationTypes.ts +55 -0
- package/src/enums/Events.ts +9 -0
- package/src/enums/index.ts +2 -0
- package/src/types/CPUIImageData.ts +3 -0
- package/src/types/EventTypes.ts +23 -2
- package/src/types/IImageCalibration.ts +41 -0
- package/src/types/IImageData.ts +4 -0
- package/src/types/index.ts +2 -0
- package/src/utilities/calibratedPixelSpacingMetadataProvider.ts +4 -10
- package/src/utilities/imageToWorldCoords.ts +5 -2
- package/src/utilities/worldToImageCoords.ts +5 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/umd/index.js",
|
|
6
6
|
"types": "dist/esm/index.d.ts",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"type": "individual",
|
|
45
45
|
"url": "https://ohif.org/donate"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "757fe06aab211f0bd506c40f262264e90290b702"
|
|
48
48
|
}
|
|
@@ -10,7 +10,6 @@ import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransf
|
|
|
10
10
|
import * as metaData from '../metaData';
|
|
11
11
|
import Viewport from './Viewport';
|
|
12
12
|
import eventTarget from '../eventTarget';
|
|
13
|
-
import Events from '../enums/Events';
|
|
14
13
|
import {
|
|
15
14
|
triggerEvent,
|
|
16
15
|
isEqual,
|
|
@@ -41,6 +40,7 @@ import {
|
|
|
41
40
|
VolumeActor,
|
|
42
41
|
Mat3,
|
|
43
42
|
ColormapRegistration,
|
|
43
|
+
IImageCalibration,
|
|
44
44
|
} from '../types';
|
|
45
45
|
import { ViewportInput } from '../types/IViewport';
|
|
46
46
|
import drawImageSync from './helpers/cpuFallback/drawImageSync';
|
|
@@ -48,8 +48,13 @@ import { getColormap } from './helpers/cpuFallback/colors/index';
|
|
|
48
48
|
|
|
49
49
|
import { loadAndCacheImage } from '../loaders/imageLoader';
|
|
50
50
|
import imageLoadPoolManager from '../requestPool/imageLoadPoolManager';
|
|
51
|
-
import
|
|
52
|
-
|
|
51
|
+
import {
|
|
52
|
+
InterpolationType,
|
|
53
|
+
RequestType,
|
|
54
|
+
Events,
|
|
55
|
+
CalibrationTypes,
|
|
56
|
+
VOILUTFunctionType,
|
|
57
|
+
} from '../enums';
|
|
53
58
|
import canvasToPixel from './helpers/cpuFallback/rendering/canvasToPixel';
|
|
54
59
|
import pixelToCanvas from './helpers/cpuFallback/rendering/pixelToCanvas';
|
|
55
60
|
import getDefaultViewport from './helpers/cpuFallback/rendering/getDefaultViewport';
|
|
@@ -59,7 +64,6 @@ import resize from './helpers/cpuFallback/rendering/resize';
|
|
|
59
64
|
import resetCamera from './helpers/cpuFallback/rendering/resetCamera';
|
|
60
65
|
import { Transform } from './helpers/cpuFallback/rendering/transform';
|
|
61
66
|
import { getConfiguration, getShouldUseCPURendering } from '../init';
|
|
62
|
-
import RequestType from '../enums/RequestType';
|
|
63
67
|
import {
|
|
64
68
|
StackViewportNewStackEventDetail,
|
|
65
69
|
StackViewportScrollEventDetail,
|
|
@@ -91,8 +95,10 @@ interface ImageDataMetaData {
|
|
|
91
95
|
}
|
|
92
96
|
// TODO This needs to be exposed as its published to consumers.
|
|
93
97
|
type CalibrationEvent = {
|
|
94
|
-
rowScale
|
|
95
|
-
columnScale
|
|
98
|
+
rowScale?: number;
|
|
99
|
+
columnScale?: number;
|
|
100
|
+
scale: number;
|
|
101
|
+
calibration: IImageCalibration;
|
|
96
102
|
};
|
|
97
103
|
|
|
98
104
|
type SetVOIOptions = {
|
|
@@ -411,6 +417,7 @@ class StackViewport extends Viewport implements IStackViewport {
|
|
|
411
417
|
metadata: { Modality: this.modality },
|
|
412
418
|
scaling: this.scaling,
|
|
413
419
|
hasPixelSpacing: this.hasPixelSpacing,
|
|
420
|
+
calibration: this.calibration,
|
|
414
421
|
preScale: {
|
|
415
422
|
...this.csImage.preScale,
|
|
416
423
|
},
|
|
@@ -452,6 +459,7 @@ class StackViewport extends Viewport implements IStackViewport {
|
|
|
452
459
|
},
|
|
453
460
|
scalarData: this.cpuImagePixelData,
|
|
454
461
|
hasPixelSpacing: this.hasPixelSpacing,
|
|
462
|
+
calibration: this.calibration,
|
|
455
463
|
preScale: {
|
|
456
464
|
...this.csImage.preScale,
|
|
457
465
|
},
|
|
@@ -558,6 +566,7 @@ class StackViewport extends Viewport implements IStackViewport {
|
|
|
558
566
|
const voiLUTFunctionEnum = this._getValidVOILUTFunction(voiLUTFunction);
|
|
559
567
|
this.VOILUTFunction = voiLUTFunctionEnum;
|
|
560
568
|
|
|
569
|
+
this.calibration = null;
|
|
561
570
|
let imagePlaneModule = this._getImagePlaneModule(imageId);
|
|
562
571
|
|
|
563
572
|
if (!this.useCPURendering) {
|
|
@@ -591,89 +600,19 @@ class StackViewport extends Viewport implements IStackViewport {
|
|
|
591
600
|
* @returns modified imagePlaneModule with the calibrated spacings
|
|
592
601
|
*/
|
|
593
602
|
private calibrateIfNecessary(imageId, imagePlaneModule) {
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
if (!calibratedPixelSpacing) {
|
|
600
|
-
return imagePlaneModule;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
const {
|
|
604
|
-
rowPixelSpacing: calibratedRowSpacing,
|
|
605
|
-
columnPixelSpacing: calibratedColumnSpacing,
|
|
606
|
-
} = calibratedPixelSpacing;
|
|
603
|
+
const calibration = metaData.get('calibratedPixelSpacing', imageId);
|
|
604
|
+
const isUpdated = this.calibration !== calibration;
|
|
605
|
+
const { scale } = calibration || {};
|
|
606
|
+
this.hasPixelSpacing = scale > 0 || imagePlaneModule.rowPixelSpacing > 0;
|
|
607
|
+
imagePlaneModule.calibration = calibration;
|
|
607
608
|
|
|
608
|
-
|
|
609
|
-
// is calibrated to some other spacing, and it gets calibrated BACK to the
|
|
610
|
-
// original spacing.
|
|
611
|
-
if (
|
|
612
|
-
imagePlaneModule.rowPixelSpacing === calibratedRowSpacing &&
|
|
613
|
-
imagePlaneModule.columnPixelSpacing === calibratedColumnSpacing
|
|
614
|
-
) {
|
|
615
|
-
return imagePlaneModule;
|
|
616
|
-
}
|
|
609
|
+
if (!isUpdated) return imagePlaneModule;
|
|
617
610
|
|
|
618
|
-
|
|
619
|
-
const imageDataMetadata = this.getImageData();
|
|
620
|
-
|
|
621
|
-
// If no actor (first load) and calibration matches the dicom header
|
|
622
|
-
if (
|
|
623
|
-
!imageDataMetadata &&
|
|
624
|
-
imagePlaneModule.rowPixelSpacing === calibratedRowSpacing &&
|
|
625
|
-
imagePlaneModule.columnPixelSpacing === calibratedColumnSpacing
|
|
626
|
-
) {
|
|
627
|
-
return imagePlaneModule;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// If no actor (first load) and calibration doesn't match headers
|
|
631
|
-
// -> needs calibration
|
|
632
|
-
if (
|
|
633
|
-
!imageDataMetadata &&
|
|
634
|
-
(imagePlaneModule.rowPixelSpacing !== calibratedRowSpacing ||
|
|
635
|
-
imagePlaneModule.columnPixelSpacing !== calibratedColumnSpacing)
|
|
636
|
-
) {
|
|
637
|
-
this._publishCalibratedEvent = true;
|
|
638
|
-
|
|
639
|
-
this._calibrationEvent = <CalibrationEvent>{
|
|
640
|
-
rowScale: calibratedRowSpacing / imagePlaneModule.rowPixelSpacing,
|
|
641
|
-
columnScale:
|
|
642
|
-
calibratedColumnSpacing / imagePlaneModule.columnPixelSpacing,
|
|
643
|
-
};
|
|
644
|
-
|
|
645
|
-
// modify the calibration object to store the actual updated values applied
|
|
646
|
-
calibratedPixelSpacing.appliedSpacing = calibratedPixelSpacing;
|
|
647
|
-
// This updates the render copy
|
|
648
|
-
imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;
|
|
649
|
-
imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;
|
|
650
|
-
return imagePlaneModule;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// If there is already an actor, check if calibration is needed for the current actor
|
|
654
|
-
const { imageData } = imageDataMetadata;
|
|
655
|
-
const [columnPixelSpacing, rowPixelSpacing] = imageData.getSpacing();
|
|
656
|
-
|
|
657
|
-
// modify the calibration object to store the actual updated values applied
|
|
658
|
-
calibratedPixelSpacing.appliedSpacing = calibratedPixelSpacing;
|
|
659
|
-
imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;
|
|
660
|
-
imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;
|
|
661
|
-
|
|
662
|
-
// If current actor spacing matches the calibrated spacing
|
|
663
|
-
if (
|
|
664
|
-
rowPixelSpacing === calibratedRowSpacing &&
|
|
665
|
-
columnPixelSpacing === calibratedPixelSpacing
|
|
666
|
-
) {
|
|
667
|
-
// No calibration is required
|
|
668
|
-
return imagePlaneModule;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
// Calibration is required
|
|
611
|
+
this.calibration = calibration;
|
|
672
612
|
this._publishCalibratedEvent = true;
|
|
673
|
-
|
|
674
613
|
this._calibrationEvent = <CalibrationEvent>{
|
|
675
|
-
|
|
676
|
-
|
|
614
|
+
scale,
|
|
615
|
+
calibration,
|
|
677
616
|
};
|
|
678
617
|
|
|
679
618
|
return imagePlaneModule;
|
|
@@ -2717,28 +2656,20 @@ class StackViewport extends Viewport implements IStackViewport {
|
|
|
2717
2656
|
imageId
|
|
2718
2657
|
);
|
|
2719
2658
|
|
|
2659
|
+
this.calibration ||= imagePlaneModule.calibration;
|
|
2660
|
+
|
|
2720
2661
|
const newImagePlaneModule: ImagePlaneModule = {
|
|
2721
2662
|
...imagePlaneModule,
|
|
2722
2663
|
};
|
|
2723
2664
|
|
|
2724
|
-
if (calibratedPixelSpacing?.appliedSpacing) {
|
|
2725
|
-
// Over-ride the image plane module spacing, as the measurement data
|
|
2726
|
-
// has already been created with the calibrated spacing provided from
|
|
2727
|
-
// down below inside calibrateIfNecessary
|
|
2728
|
-
const { rowPixelSpacing, columnPixelSpacing } =
|
|
2729
|
-
calibratedPixelSpacing.appliedSpacing;
|
|
2730
|
-
newImagePlaneModule.rowPixelSpacing = rowPixelSpacing;
|
|
2731
|
-
newImagePlaneModule.columnPixelSpacing = columnPixelSpacing;
|
|
2732
|
-
}
|
|
2733
|
-
|
|
2734
2665
|
if (!newImagePlaneModule.columnPixelSpacing) {
|
|
2735
2666
|
newImagePlaneModule.columnPixelSpacing = 1;
|
|
2736
|
-
this.hasPixelSpacing =
|
|
2667
|
+
this.hasPixelSpacing = this.calibration?.scale > 0;
|
|
2737
2668
|
}
|
|
2738
2669
|
|
|
2739
2670
|
if (!newImagePlaneModule.rowPixelSpacing) {
|
|
2740
2671
|
newImagePlaneModule.rowPixelSpacing = 1;
|
|
2741
|
-
this.hasPixelSpacing =
|
|
2672
|
+
this.hasPixelSpacing = this.calibration?.scale > 0;
|
|
2742
2673
|
}
|
|
2743
2674
|
|
|
2744
2675
|
if (!newImagePlaneModule.columnCosines) {
|
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
import type { ViewportInput, IViewport } from '../types/IViewport';
|
|
28
28
|
import type { vtkSlabCamera } from './vtkClasses/vtkSlabCamera';
|
|
29
29
|
import { getConfiguration } from '../init';
|
|
30
|
+
import IImageCalibration from '../types/IImageCalibration';
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* An object representing a single viewport, which is a camera
|
|
@@ -74,6 +75,7 @@ class Viewport implements IViewport {
|
|
|
74
75
|
/** A flag representing if viewport methods should fire events or not */
|
|
75
76
|
readonly suppressEvents: boolean;
|
|
76
77
|
protected hasPixelSpacing = true;
|
|
78
|
+
protected calibration: IImageCalibration;
|
|
77
79
|
/** The camera that is initially defined on the reset for
|
|
78
80
|
* the relative pan/zoom
|
|
79
81
|
*/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines the calibration types available. These define how the units
|
|
3
|
+
* for measurements are specified.
|
|
4
|
+
*/
|
|
5
|
+
export enum CalibrationTypes {
|
|
6
|
+
/**
|
|
7
|
+
* Not applicable means the units are directly defind by the underlying
|
|
8
|
+
* hardware, such as CT and MR volumetric displays, so no special handling
|
|
9
|
+
* or notification is required.
|
|
10
|
+
*/
|
|
11
|
+
NOT_APPLICABLE = '',
|
|
12
|
+
/**
|
|
13
|
+
* ERMF is estimated radiographic magnification factor. This defines how
|
|
14
|
+
* much the image is magnified at the detector as opposed to the location in
|
|
15
|
+
* the body of interest. This occurs because the radiation beam is expanding
|
|
16
|
+
* and effectively magnifies the image on the detector compared to where the
|
|
17
|
+
* point of interest in the body is.
|
|
18
|
+
* This suggests that measurements can be partially trusted, but the user
|
|
19
|
+
* still needs to be aware that different depths within the body have differing
|
|
20
|
+
* ERMF values, so precise measurements would still need to be manually calibrated.
|
|
21
|
+
*/
|
|
22
|
+
ERMF = 'ERMF',
|
|
23
|
+
/**
|
|
24
|
+
* User calibration means that the user has provided a custom calibration
|
|
25
|
+
* specifying how large the image data is. This type can occur on
|
|
26
|
+
* volumetric images, eg for scout images that might have invalid spacing
|
|
27
|
+
* tags.
|
|
28
|
+
*/
|
|
29
|
+
USER = 'User',
|
|
30
|
+
/**
|
|
31
|
+
* A projection calibration means the raw detector size, without any
|
|
32
|
+
* ERMF applied, meaning that the size in the body cannot be trusted and
|
|
33
|
+
* that a calibration should be applied.
|
|
34
|
+
* This is different from Error in that there is simply no magnification
|
|
35
|
+
* factor applied as opposed to having multiple, inconsistent magnification
|
|
36
|
+
* factors.
|
|
37
|
+
*/
|
|
38
|
+
PROJECTION = 'Proj',
|
|
39
|
+
/**
|
|
40
|
+
* A region calibration is used for other types of images, typically
|
|
41
|
+
* ultrasouunds where the distance in the image may mean something other than
|
|
42
|
+
* physical distance, such as mV or Hz or some other measurement values.
|
|
43
|
+
*/
|
|
44
|
+
REGION = 'Region',
|
|
45
|
+
/**
|
|
46
|
+
* Error is used to define mismatches between various units, such as when
|
|
47
|
+
* there are two different ERMF values specified. This is an indication to
|
|
48
|
+
* NOT trust the measurement values but to manually calibrate.
|
|
49
|
+
*/
|
|
50
|
+
ERROR = 'Error',
|
|
51
|
+
/** Uncalibrated image */
|
|
52
|
+
UNCALIBRATED = 'Uncalibrated',
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default CalibrationTypes;
|
package/src/enums/Events.ts
CHANGED
|
@@ -75,6 +75,15 @@ enum Events {
|
|
|
75
75
|
* and see what event detail is included in {@link EventTypes.ImageVolumeModifiedEventDetail | ImageVolumeModified Event Detail }
|
|
76
76
|
*/
|
|
77
77
|
IMAGE_VOLUME_MODIFIED = 'CORNERSTONE_IMAGE_VOLUME_MODIFIED',
|
|
78
|
+
/**
|
|
79
|
+
* Triggers on the eventTarget when the image volume loading is completed and all
|
|
80
|
+
* frames are loaded and inserted into a volume.
|
|
81
|
+
*
|
|
82
|
+
* Make use of {@link EventTypes.ImageVolumeLoadingCompletedEvent | ImageVolumeLoadingCompleted Event Type } for typing your
|
|
83
|
+
* event listeners for IMAGE_VOLUME_LOADING_COMPLETED event, and see what event detail is included
|
|
84
|
+
* in {@link EventTypes.ImageVolumeLoadingCompletedEventDetail | ImageVolumeLoadingCompleted Event Detail }
|
|
85
|
+
*/
|
|
86
|
+
IMAGE_VOLUME_LOADING_COMPLETED = 'CORNERSTONE_IMAGE_VOLUME_LOADING_COMPLETED',
|
|
78
87
|
/**
|
|
79
88
|
* Triggers on the eventTarget when the image has successfully loaded by imageLoaders
|
|
80
89
|
*
|
package/src/enums/index.ts
CHANGED
|
@@ -9,11 +9,13 @@ import GeometryType from './GeometryType';
|
|
|
9
9
|
import ContourType from './ContourType';
|
|
10
10
|
import VOILUTFunctionType from './VOILUTFunctionType';
|
|
11
11
|
import DynamicOperatorType from './DynamicOperatorType';
|
|
12
|
+
import CalibrationTypes from './CalibrationTypes';
|
|
12
13
|
import ViewportStatus from './ViewportStatus';
|
|
13
14
|
|
|
14
15
|
export {
|
|
15
16
|
Events,
|
|
16
17
|
BlendModes,
|
|
18
|
+
CalibrationTypes,
|
|
17
19
|
InterpolationType,
|
|
18
20
|
RequestType,
|
|
19
21
|
ViewportType,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Point3, Scaling, Mat3, PixelDataTypedArray } from '../types';
|
|
2
|
+
import IImageCalibration from './IImageCalibration';
|
|
2
3
|
|
|
3
4
|
type CPUImageData = {
|
|
4
5
|
worldToIndex?: (point: Point3) => Point3;
|
|
@@ -24,6 +25,8 @@ type CPUIImageData = {
|
|
|
24
25
|
scaling: Scaling;
|
|
25
26
|
/** whether the image has pixel spacing and it is not undefined */
|
|
26
27
|
hasPixelSpacing?: boolean;
|
|
28
|
+
calibration?: IImageCalibration;
|
|
29
|
+
|
|
27
30
|
/** preScale object */
|
|
28
31
|
preScale?: {
|
|
29
32
|
/** boolean flag to indicate whether the image has been scaled */
|
package/src/types/EventTypes.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { VOIRange } from './voi';
|
|
|
10
10
|
import type VOILUTFunctionType from '../enums/VOILUTFunctionType';
|
|
11
11
|
import type ViewportStatus from '../enums/ViewportStatus';
|
|
12
12
|
import type DisplayArea from './displayArea';
|
|
13
|
+
import IImageCalibration from './IImageCalibration';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* CAMERA_MODIFIED Event's data
|
|
@@ -110,6 +111,16 @@ type ImageVolumeModifiedEventDetail = {
|
|
|
110
111
|
FrameOfReferenceUID: string;
|
|
111
112
|
};
|
|
112
113
|
|
|
114
|
+
/**
|
|
115
|
+
* IMAGE_VOLUME_LOADING_COMPLETED Event's data
|
|
116
|
+
*/
|
|
117
|
+
type ImageVolumeLoadingCompletedEventDetail = {
|
|
118
|
+
/** the loaded volume */
|
|
119
|
+
volumeId: string;
|
|
120
|
+
/** FrameOfReferenceUID where the volume belongs to */
|
|
121
|
+
FrameOfReferenceUID: string;
|
|
122
|
+
};
|
|
123
|
+
|
|
113
124
|
/**
|
|
114
125
|
* IMAGE_LOADED Event's data
|
|
115
126
|
*/
|
|
@@ -228,8 +239,8 @@ type ImageSpacingCalibratedEventDetail = {
|
|
|
228
239
|
viewportId: string;
|
|
229
240
|
renderingEngineId: string;
|
|
230
241
|
imageId: string;
|
|
231
|
-
|
|
232
|
-
|
|
242
|
+
/** calibration contains the scaling information as well as other calibration info */
|
|
243
|
+
calibration: IImageCalibration;
|
|
233
244
|
imageData: vtkImageData;
|
|
234
245
|
worldToIndex: mat4;
|
|
235
246
|
};
|
|
@@ -307,6 +318,14 @@ type ImageRenderedEvent = CustomEventType<ElementEnabledEventDetail>;
|
|
|
307
318
|
*/
|
|
308
319
|
type ImageVolumeModifiedEvent = CustomEventType<ImageVolumeModifiedEventDetail>;
|
|
309
320
|
|
|
321
|
+
/**
|
|
322
|
+
* IMAGE_VOLUME_LOADING_COMPLETED Event type
|
|
323
|
+
* This event is fired when a volume is fully loaded, means all the frames
|
|
324
|
+
* are loaded and cached.
|
|
325
|
+
*/
|
|
326
|
+
type ImageVolumeLoadingCompletedEvent =
|
|
327
|
+
CustomEventType<ImageVolumeLoadingCompletedEventDetail>;
|
|
328
|
+
|
|
310
329
|
/**
|
|
311
330
|
* IMAGE_LOADED Event type
|
|
312
331
|
*/
|
|
@@ -400,6 +419,8 @@ export type {
|
|
|
400
419
|
ImageRenderedEvent,
|
|
401
420
|
ImageVolumeModifiedEvent,
|
|
402
421
|
ImageVolumeModifiedEventDetail,
|
|
422
|
+
ImageVolumeLoadingCompletedEvent,
|
|
423
|
+
ImageVolumeLoadingCompletedEventDetail,
|
|
403
424
|
ImageLoadedEvent,
|
|
404
425
|
ImageLoadedEventDetail,
|
|
405
426
|
ImageLoadedFailedEventDetail,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import CalibrationTypes from '../enums/CalibrationTypes';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* IImageCalibration is an object that stores information about the type
|
|
5
|
+
* of image calibration.
|
|
6
|
+
*/
|
|
7
|
+
export interface IImageCalibration {
|
|
8
|
+
/**
|
|
9
|
+
* The pixel spacing for the image, in mm between pixel centers
|
|
10
|
+
* These are not required, and are deprecated in favour of getting the original
|
|
11
|
+
* image spacing and then applying the transforms. The values here should
|
|
12
|
+
* be identical to original spacing.
|
|
13
|
+
*/
|
|
14
|
+
rowPixelSpacing?: number;
|
|
15
|
+
columnPixelSpacing?: number;
|
|
16
|
+
/** The scaling of measurement values relative to the base pixel spacing (1 if not specified) */
|
|
17
|
+
scale?: number;
|
|
18
|
+
/**
|
|
19
|
+
* The calibration aspect ratio for non-square calibrations.
|
|
20
|
+
* This is the aspect ratio similar to the scale above that applies when
|
|
21
|
+
* the viewport is displaying non-square image pixels as square screen pixels.
|
|
22
|
+
*
|
|
23
|
+
* Defaults to 1 if not specified, and is also 1 if the Viewport has squared
|
|
24
|
+
* up the image pixels so that they are displayed as a square.
|
|
25
|
+
* Not well handled currently as this needs to be incorporated into
|
|
26
|
+
* tools when doing calculations.
|
|
27
|
+
*/
|
|
28
|
+
aspect?: number;
|
|
29
|
+
/** The type of the pixel spacing, distinguishing between various
|
|
30
|
+
* types projection (CR/DX/MG) spacing and volumetric spacing (the type is
|
|
31
|
+
* an empty string as it doesn't get a suffix, but this distinguishes it
|
|
32
|
+
* from other types)
|
|
33
|
+
*/
|
|
34
|
+
type: CalibrationTypes;
|
|
35
|
+
/** A tooltip which can be used to explain the calibration information */
|
|
36
|
+
tooltip?: string;
|
|
37
|
+
/** The DICOM defined ultrasound regions. Used for non-distance spacing units. */
|
|
38
|
+
sequenceOfUltrasoundRegions?: Record<string, unknown>[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default IImageCalibration;
|
package/src/types/IImageData.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { vtkImageData } from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
2
2
|
import { Point3, Scaling, Mat3 } from '../types';
|
|
3
|
+
import IImageCalibration from './IImageCalibration';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* IImageData of an image, which stores actual scalarData and metaData about the image.
|
|
@@ -24,6 +25,9 @@ interface IImageData {
|
|
|
24
25
|
scaling?: Scaling;
|
|
25
26
|
/** whether the image has pixel spacing and it is not undefined */
|
|
26
27
|
hasPixelSpacing?: boolean;
|
|
28
|
+
|
|
29
|
+
calibration?: IImageCalibration;
|
|
30
|
+
|
|
27
31
|
/** preScale object */
|
|
28
32
|
preScale?: {
|
|
29
33
|
/** boolean flag to indicate whether the image has been scaled */
|
package/src/types/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ import type Plane from './Plane';
|
|
|
30
30
|
import type IStreamingImageVolume from './IStreamingImageVolume';
|
|
31
31
|
import type ViewportInputOptions from './ViewportInputOptions';
|
|
32
32
|
import type IImageData from './IImageData';
|
|
33
|
+
import type IImageCalibration from './IImageCalibration';
|
|
33
34
|
import type CPUIImageData from './CPUIImageData';
|
|
34
35
|
import type { CPUImageData } from './CPUIImageData';
|
|
35
36
|
import type IImage from './IImage';
|
|
@@ -102,6 +103,7 @@ export type {
|
|
|
102
103
|
IStreamingImageVolume,
|
|
103
104
|
IImage,
|
|
104
105
|
IImageData,
|
|
106
|
+
IImageCalibration,
|
|
105
107
|
CPUIImageData,
|
|
106
108
|
CPUImageData,
|
|
107
109
|
EventTypes,
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import imageIdToURI from './imageIdToURI';
|
|
2
|
+
import { IImageCalibration } from '../types';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
rowPixelSpacing: number;
|
|
5
|
-
columnPixelSpacing: number;
|
|
6
|
-
// These values get updated by the viewport after the change to record the applied value
|
|
7
|
-
appliedSpacing?: CalibratedPixelValue;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const state: Record<string, CalibratedPixelValue> = {}; // Calibrated pixel spacing per imageId
|
|
4
|
+
const state: Record<string, IImageCalibration> = {}; // Calibrated pixel spacing per imageId
|
|
11
5
|
|
|
12
6
|
/**
|
|
13
7
|
* Simple metadataProvider object to store metadata for calibrated spacings.
|
|
@@ -20,7 +14,7 @@ const metadataProvider = {
|
|
|
20
14
|
* @param imageId - the imageId for the metadata to store
|
|
21
15
|
* @param payload - the payload composed of new calibrated pixel spacings
|
|
22
16
|
*/
|
|
23
|
-
add: (imageId: string, payload:
|
|
17
|
+
add: (imageId: string, payload: IImageCalibration): void => {
|
|
24
18
|
const imageURI = imageIdToURI(imageId);
|
|
25
19
|
state[imageURI] = payload;
|
|
26
20
|
},
|
|
@@ -31,7 +25,7 @@ const metadataProvider = {
|
|
|
31
25
|
* @param imageId - the imageId to enquire about
|
|
32
26
|
* @returns the calibrated pixel spacings for the imageId if it exists, otherwise undefined
|
|
33
27
|
*/
|
|
34
|
-
get: (type: string, imageId: string):
|
|
28
|
+
get: (type: string, imageId: string): IImageCalibration => {
|
|
35
29
|
if (type === 'calibratedPixelSpacing') {
|
|
36
30
|
const imageURI = imageIdToURI(imageId);
|
|
37
31
|
return state[imageURI];
|
|
@@ -23,12 +23,15 @@ export default function imageToWorldCoords(
|
|
|
23
23
|
|
|
24
24
|
const {
|
|
25
25
|
columnCosines,
|
|
26
|
-
columnPixelSpacing,
|
|
27
26
|
rowCosines,
|
|
28
|
-
rowPixelSpacing,
|
|
29
27
|
imagePositionPatient: origin,
|
|
30
28
|
} = imagePlaneModule;
|
|
31
29
|
|
|
30
|
+
let { columnPixelSpacing, rowPixelSpacing } = imagePlaneModule;
|
|
31
|
+
// Use ||= to convert null and 0 as well as undefined to 1
|
|
32
|
+
columnPixelSpacing ||= 1;
|
|
33
|
+
rowPixelSpacing ||= 1;
|
|
34
|
+
|
|
32
35
|
// calculate the image coordinates in the world space
|
|
33
36
|
const imageCoordsInWorld = vec3.create();
|
|
34
37
|
|
|
@@ -27,14 +27,15 @@ function worldToImageCoords(
|
|
|
27
27
|
|
|
28
28
|
const {
|
|
29
29
|
columnCosines,
|
|
30
|
-
columnPixelSpacing,
|
|
31
30
|
rowCosines,
|
|
32
|
-
rowPixelSpacing,
|
|
33
31
|
imagePositionPatient: origin,
|
|
34
|
-
rows,
|
|
35
|
-
columns,
|
|
36
32
|
} = imagePlaneModule;
|
|
37
33
|
|
|
34
|
+
let { columnPixelSpacing, rowPixelSpacing } = imagePlaneModule;
|
|
35
|
+
// Use ||= to convert null and 0 as well as undefined to 1
|
|
36
|
+
columnPixelSpacing ||= 1;
|
|
37
|
+
rowPixelSpacing ||= 1;
|
|
38
|
+
|
|
38
39
|
// The origin is the image position patient, but since image coordinates start
|
|
39
40
|
// from [0,0] for the top left hand of the first pixel, and the origin is at the
|
|
40
41
|
// center of the first pixel, we need to account for this.
|