1
1
import { pubSubServiceInterface } from '@ohif/core' ;
2
- import {
3
- EVENTS as CS_EVENTS ,
4
- eventTarget as CornerstoneEventTarget ,
5
- getEnabledElement ,
6
- cache ,
7
- Enums as CSCORE_ENUMS
2
+ import {
3
+ EVENTS as CS_EVENTS ,
4
+ eventTarget as CornerstoneEventTarget ,
5
+ getEnabledElement ,
6
+ cache ,
7
+ Enums as CSCORE_ENUMS ,
8
8
} from '@cornerstonejs/core' ;
9
9
import { Enums as CSTOOLS_ENUMS } from '@cornerstonejs/tools' ;
10
10
@@ -16,181 +16,173 @@ import {
16
16
import { getSegDisplaysetsOfReferencedImagesIds } from '../utils' ;
17
17
18
18
const EVENTS = {
19
- CROP_DISPLAY_AREA_INIT : 'event::gradienthealth::CropDisplayAreaService:init' ,
19
+ CROP_DISPLAY_AREA_INIT : 'event::gradienthealth::CropDisplayAreaService:init' ,
20
20
} ;
21
21
22
22
export default class CropDisplayAreaService {
23
- private serviceManager ;
24
- private listeners ;
25
- public EVENTS ;
26
-
27
- constructor ( serviceManager ) {
28
- this . serviceManager = serviceManager ;
29
- this . listeners = { } ;
30
- this . EVENTS = EVENTS ;
31
- window . tf = tf ;
32
- Object . assign ( this , pubSubServiceInterface ) ;
33
- }
23
+ private serviceManager ;
24
+ private listeners ;
25
+ public EVENTS ;
26
+
27
+ constructor ( serviceManager ) {
28
+ this . serviceManager = serviceManager ;
29
+ this . listeners = { } ;
30
+ this . EVENTS = EVENTS ;
31
+ window . tf = tf ;
32
+ Object . assign ( this , pubSubServiceInterface ) ;
33
+ }
34
34
35
- init ( ) {
36
- CornerstoneEventTarget . addEventListener ( CS_EVENTS . STACK_VIEWPORT_NEW_STACK , ( evt ) => {
37
- const { HangingProtocolService } = this . serviceManager . services
38
- if ( HangingProtocolService . protocol . id === 'breast' ) this . handleBreastDensityHP ( evt )
39
- } )
35
+ init ( ) {
36
+ CornerstoneEventTarget . addEventListener (
37
+ CS_EVENTS . STACK_VIEWPORT_NEW_STACK ,
38
+ ( evt ) => {
39
+ const { HangingProtocolService } = this . serviceManager . services ;
40
+ if ( HangingProtocolService . protocol . id === 'breast' )
41
+ this . handleBreastDensityHP ( evt ) ;
42
+ }
43
+ ) ;
44
+ }
45
+
46
+ private handleBreastDensityHP ( evt ) {
47
+ const { HangingProtocolService, cornerstoneViewportService } =
48
+ this . serviceManager . services ;
49
+ const { element, viewportId } = evt . detail ;
50
+ const enabledElement = getEnabledElement ( element ) ;
51
+ const viewport = enabledElement ?. viewport ;
52
+ if ( ! viewport ) return ;
53
+
54
+ const { voiRange, invert } = ( viewport as IStackViewport ) . getProperties ( ) ;
55
+ const cutoff = invert ? voiRange ?. upper : voiRange ?. lower ;
56
+ if ( cutoff === undefined || cutoff === null ) {
57
+ return ;
40
58
}
41
59
42
- private handleBreastDensityHP ( evt ) {
43
- const { HangingProtocolService, cornerstoneViewportService } =
44
- this . serviceManager . services ;
45
- const { element, viewportId } = evt . detail ;
46
- const enabledElement = getEnabledElement ( element ) ;
47
- const viewport = enabledElement ?. viewport ;
48
- if ( ! viewport ) return ;
49
-
50
- const { voiRange, invert } = ( viewport as IStackViewport ) . getProperties ( ) ;
51
- let cutoff ;
52
- if ( voiRange ?. lower && ! invert ) {
53
- cutoff = voiRange ?. lower ;
54
- }
55
- if ( voiRange ?. upper && invert ) {
56
- cutoff = voiRange ?. upper ;
57
- }
58
- if ( ! cutoff ) {
59
- return ;
60
- }
60
+ const viewportInfo = cornerstoneViewportService . getViewportInfo ( viewportId ) ;
61
+ const matchedDisplaySets = Array . from (
62
+ HangingProtocolService . displaySetMatchDetails . values ( )
63
+ ) ;
64
+ const matchedDisplaySetIndex = matchedDisplaySets . findIndex (
65
+ ( displayset ) =>
66
+ displayset . displaySetInstanceUID ===
67
+ viewportInfo . viewportData . data . displaySetInstanceUID
68
+ ) ;
61
69
62
- const viewportInfo =
63
- cornerstoneViewportService . getViewportInfo ( viewportId ) ;
64
- const matchedDisplaySets = Array . from (
65
- HangingProtocolService . displaySetMatchDetails . values ( )
66
- ) ;
67
- const matchedDisplaySetIndex = matchedDisplaySets . findIndex (
68
- ( displayset ) =>
69
- displayset . displaySetInstanceUID ===
70
- viewportInfo . viewportData . data . displaySetInstanceUID
71
- ) ;
70
+ const matchedDisplaySetKeys = Array . from (
71
+ HangingProtocolService . displaySetMatchDetails . keys ( )
72
+ ) ;
73
+ const matchedDisplaySet = matchedDisplaySetKeys [ matchedDisplaySetIndex ] ;
74
+ if ( ! matchedDisplaySet ) return ;
75
+
76
+ const imageData = viewport . getImageData ( ) ;
77
+ const scalarData = imageData ?. scalarData ;
78
+ const dimensions = imageData ?. dimensions ;
79
+ if ( ! scalarData || ! dimensions ) return ;
80
+
81
+ // probably will need to account for
82
+ // imageData.direction
83
+ // interesting that dim[1], dim[0] are reversed for vtk.js => tf.js
84
+ // assume this direction does not change
85
+ const { bboxWidth, bboxHeight, width, height } = tf . tidy ( ( ) => {
86
+ const tensor = tf . tensor2d ( new Float32Array ( scalarData ) , [
87
+ dimensions [ 1 ] ,
88
+ dimensions [ 0 ] ,
89
+ ] ) ;
90
+ const mask = tensor . greater ( cutoff ) ; // get boolean
91
+ const widthBool = mask . any ( 0 ) ; // height?
92
+ const heightBool = mask . any ( 1 ) ; // width?
93
+
94
+ // get bbox
95
+ const left = widthBool . argMax ( ) ;
96
+ const right = widthBool . reverse ( ) . argMax ( ) . mul ( - 1 ) . add ( widthBool . size ) ;
97
+ const top = heightBool . argMax ( ) ;
98
+ const bottom = heightBool . reverse ( ) . argMax ( ) . mul ( - 1 ) . add ( heightBool . size ) ;
99
+
100
+ // get percentage difference in width and height
101
+ const bboxWidth = right . sub ( left ) . dataSync ( ) [ 0 ] ;
102
+ const bboxHeight = bottom . sub ( top ) . dataSync ( ) [ 0 ] ;
103
+ const width = widthBool . size ;
104
+ const height = heightBool . size ;
105
+
106
+ return {
107
+ bboxWidth,
108
+ bboxHeight,
109
+ width,
110
+ height,
111
+ } ;
112
+ } ) ;
72
113
73
- const matchedDisplaySetKeys = Array . from (
74
- HangingProtocolService . displaySetMatchDetails . keys ( )
75
- ) ;
76
- const matchedDisplaySet = matchedDisplaySetKeys [ matchedDisplaySetIndex ] ;
77
- if ( ! matchedDisplaySet ) return ;
78
-
79
- const imageData = viewport . getImageData ( ) ;
80
- const scalarData = imageData ?. scalarData ;
81
- const dimensions = imageData ?. dimensions ;
82
- if ( ! scalarData || ! dimensions ) return ;
83
-
84
- // probably will need to account for
85
- // imageData.direction
86
- // interesting that dim[1], dim[0] are reversed for vtk.js => tf.js
87
- // assume this direction does not change
88
- const { bboxWidth, bboxHeight, width, height } = tf . tidy ( ( ) => {
89
- const tensor = tf . tensor2d ( new Float32Array ( scalarData ) , [
90
- dimensions [ 1 ] ,
91
- dimensions [ 0 ] ,
92
- ] ) ;
93
- const mask = tensor . greater ( cutoff ) ; // get boolean
94
- const widthBool = mask . any ( 0 ) ; // height?
95
- const heightBool = mask . any ( 1 ) ; // width?
96
-
97
- // get bbox
98
- const left = widthBool . argMax ( ) ;
99
- const right = widthBool . reverse ( ) . argMax ( ) . mul ( - 1 ) . add ( widthBool . size ) ;
100
- const top = heightBool . argMax ( ) ;
101
- const bottom = heightBool
102
- . reverse ( )
103
- . argMax ( )
104
- . mul ( - 1 )
105
- . add ( heightBool . size ) ;
106
-
107
- // get percentage difference in width and height
108
- const bboxWidth = right . sub ( left ) . dataSync ( ) [ 0 ] ;
109
- const bboxHeight = bottom . sub ( top ) . dataSync ( ) [ 0 ] ;
110
- const width = widthBool . size ;
111
- const height = heightBool . size ;
112
-
113
- return {
114
- bboxWidth,
115
- bboxHeight,
116
- width,
117
- height,
118
- } ;
119
- } ) ;
120
-
121
- const bboxAspectRatio = bboxWidth / bboxHeight ;
122
- const canvasAspectRatio = viewport . sWidth / viewport . sHeight ;
123
- // console.log({bboxAspectRatio, canvasAspectRatio})
124
- // if(bboxAspectRatio > canvasAspectRatio){
125
- // bboxWidth = canvasAspectRatio*bboxHeight
126
- // bboxAspectRatio = bboxWidth/bboxHeight
127
- // console.log('changed', {bboxAspectRatio, canvasAspectRatio})
128
- // }
129
-
130
- const bboxWidthPercentage = bboxWidth / width ; // add buffer
131
- const bboxHeightPercentage = bboxHeight / height ;
132
-
133
- // TODO do not hard code, pick the max between bboxwidth and aspect ratio height
134
- const areaZoom = bboxWidthPercentage ;
135
- //const panAmount = (1 - areaZoom) / 2;
136
-
137
- if ( matchedDisplaySet === 'LMLO' ) {
138
- viewport . setDisplayArea (
139
- {
140
- imageArea : [ areaZoom , areaZoom ] ,
141
- imageCanvasPoint : {
142
- canvasPoint : [ 0 , 0.5 ] ,
143
- imagePoint : [ 0 , 0.5 ] ,
144
- } ,
145
- storeAsInitialCamera : true ,
114
+ const bboxAspectRatio = bboxWidth / bboxHeight ;
115
+ const canvasAspectRatio = viewport . sWidth / viewport . sHeight ;
116
+ // console.log({bboxAspectRatio, canvasAspectRatio})
117
+ // if(bboxAspectRatio > canvasAspectRatio){
118
+ // bboxWidth = canvasAspectRatio*bboxHeight
119
+ // bboxAspectRatio = bboxWidth/bboxHeight
120
+ // console.log('changed', {bboxAspectRatio, canvasAspectRatio})
121
+ // }
122
+
123
+ const bboxWidthPercentage = bboxWidth / width ; // add buffer
124
+ const bboxHeightPercentage = bboxHeight / height ;
125
+
126
+ // TODO do not hard code, pick the max between bboxwidth and aspect ratio height
127
+ const areaZoom = bboxWidthPercentage ;
128
+ //const panAmount = (1 - areaZoom) / 2;
129
+
130
+ if ( matchedDisplaySet === 'LMLO' ) {
131
+ viewport . setDisplayArea (
132
+ {
133
+ imageArea : [ areaZoom , areaZoom ] ,
134
+ imageCanvasPoint : {
135
+ canvasPoint : [ 0 , 0.5 ] ,
136
+ imagePoint : [ 0 , 0.5 ] ,
146
137
} ,
147
- true
148
- ) ;
149
- }
150
- if ( matchedDisplaySet === 'RMLO' ) {
151
- viewport . setDisplayArea (
152
- {
153
- imageArea : [ areaZoom , areaZoom ] ,
154
- imageCanvasPoint : {
155
- canvasPoint : [ 1 , 0.5 ] ,
156
- imagePoint : [ 1 , 0.5 ] ,
157
- } ,
158
- storeAsInitialCamera : true ,
138
+ storeAsInitialCamera : true ,
139
+ } ,
140
+ true
141
+ ) ;
142
+ }
143
+ if ( matchedDisplaySet === 'RMLO' ) {
144
+ viewport . setDisplayArea (
145
+ {
146
+ imageArea : [ areaZoom , areaZoom ] ,
147
+ imageCanvasPoint : {
148
+ canvasPoint : [ 1 , 0.5 ] ,
149
+ imagePoint : [ 1 , 0.5 ] ,
159
150
} ,
151
+ storeAsInitialCamera : true ,
152
+ } ,
160
153
161
- true
162
- ) ;
163
- }
164
- if ( matchedDisplaySet === 'LCC' ) {
165
- viewport . setDisplayArea (
166
- {
167
- imageArea : [ areaZoom , areaZoom ] ,
168
- imageCanvasPoint : {
169
- canvasPoint : [ 0 , 0.5 ] ,
170
- imagePoint : [ 0 , 0.5 ] ,
171
- } ,
172
- storeAsInitialCamera : true ,
154
+ true
155
+ ) ;
156
+ }
157
+ if ( matchedDisplaySet === 'LCC' ) {
158
+ viewport . setDisplayArea (
159
+ {
160
+ imageArea : [ areaZoom , areaZoom ] ,
161
+ imageCanvasPoint : {
162
+ canvasPoint : [ 0 , 0.5 ] ,
163
+ imagePoint : [ 0 , 0.5 ] ,
173
164
} ,
174
- true
175
- ) ;
176
- }
177
- if ( matchedDisplaySet === 'RCC' ) {
178
- viewport . setDisplayArea (
179
- {
180
- imageArea : [ areaZoom , areaZoom ] ,
181
- imageCanvasPoint : {
182
- canvasPoint : [ 1 , 0.5 ] ,
183
- imagePoint : [ 1 , 0.5 ] ,
184
- } ,
185
- storeAsInitialCamera : true ,
165
+ storeAsInitialCamera : true ,
166
+ } ,
167
+ true
168
+ ) ;
169
+ }
170
+ if ( matchedDisplaySet === 'RCC' ) {
171
+ viewport . setDisplayArea (
172
+ {
173
+ imageArea : [ areaZoom , areaZoom ] ,
174
+ imageCanvasPoint : {
175
+ canvasPoint : [ 1 , 0.5 ] ,
176
+ imagePoint : [ 1 , 0.5 ] ,
186
177
} ,
187
- true
188
- ) ;
189
- }
178
+ storeAsInitialCamera : true ,
179
+ } ,
180
+ true
181
+ ) ;
190
182
}
183
+ }
191
184
192
- destroy ( ) {
193
- }
185
+ destroy ( ) { }
194
186
195
187
public async focusToSegment ( segmentationId , segmentIndex ) {
196
188
const {
@@ -201,7 +193,9 @@ export default class CropDisplayAreaService {
201
193
} = this . serviceManager . services ;
202
194
203
195
const segmentation = segmentationService . getSegmentation ( segmentationId ) ;
204
- const segDisplayset = displaySetService . getDisplaySetByUID ( segmentation . displaySetInstanceUID ) ;
196
+ const segDisplayset = displaySetService . getDisplaySetByUID (
197
+ segmentation . displaySetInstanceUID
198
+ ) ;
205
199
if ( segDisplayset . Modality !== 'SEG' ) {
206
200
return ;
207
201
}
@@ -271,11 +265,16 @@ export default class CropDisplayAreaService {
271
265
return { xMax, yMax, xMin, yMin } ;
272
266
} ) ;
273
267
274
- const referencedDisplaySetInstanceUID = segDisplayset . referencedDisplaySetInstanceUID ;
268
+ const referencedDisplaySetInstanceUID =
269
+ segDisplayset . referencedDisplaySetInstanceUID ;
275
270
const { viewports, activeViewportId } = viewportGridService . getState ( ) ;
276
271
const viewportsWithSegmentation : IStackViewport | IVolumeViewport = [ ] ;
277
272
viewports . forEach ( ( viewport ) => {
278
- if ( viewport . displaySetInstanceUIDs . includes ( referencedDisplaySetInstanceUID ) ) {
273
+ if (
274
+ viewport . displaySetInstanceUIDs . includes (
275
+ referencedDisplaySetInstanceUID
276
+ )
277
+ ) {
279
278
viewportsWithSegmentation . push (
280
279
cornerstoneViewportService . getCornerstoneViewport ( viewport . viewportId )
281
280
) ;
@@ -402,4 +401,4 @@ const correctZoomFactors = (
402
401
403
402
zoomFactors . x /= zoomOutPercentatage / 100 ;
404
403
zoomFactors . y /= zoomOutPercentatage / 100 ;
405
- } ;
404
+ } ;
0 commit comments