11import { 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
88} from '@cornerstonejs/core' ;
99import { Enums as CSTOOLS_ENUMS } from '@cornerstonejs/tools' ;
1010
@@ -16,180 +16,174 @@ import {
1616import { getSegDisplaysetsOfReferencedImagesIds } from '../utils' ;
1717
1818const EVENTS = {
19- CROP_DISPLAY_AREA_INIT : 'event::gradienthealth::CropDisplayAreaService:init' ,
19+ CROP_DISPLAY_AREA_INIT : 'event::gradienthealth::CropDisplayAreaService:init' ,
2020} ;
2121
2222export 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+ }
3434
35- init ( ) {
36- CornerstoneEventTarget . addEventListener ( CS_EVENTS . STACK_VIEWPORT_NEW_STACK , ( evt ) => {
35+ init ( ) {
36+ CornerstoneEventTarget . addEventListener ( CS_EVENTS . STACK_VIEWPORT_NEW_STACK , ( evt ) => {
3737 const { HangingProtocolService } = this . serviceManager . services
3838 if ( HangingProtocolService . protocol . id === 'breast' ) this . handleBreastDensityHP ( evt )
3939 } )
40- }
40+ }
4141
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- }
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+ const cutoff = invert ? voiRange ?. upper : voiRange ?. lower ;
52+ if ( cutoff === undefined || cutoff === null ) {
53+ return ;
54+ }
6155
62- const viewportInfo =
56+ const viewportInfo =
6357 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- ) ;
58+ const matchedDisplaySets = Array . from (
59+ HangingProtocolService . displaySetMatchDetails . values ( )
60+ ) ;
61+ const matchedDisplaySetIndex = matchedDisplaySets . findIndex (
62+ ( displayset ) =>
63+ displayset . displaySetInstanceUID ===
64+ viewportInfo . viewportData . data . displaySetInstanceUID
65+ ) ;
7266
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
67+ const matchedDisplaySetKeys = Array . from (
68+ HangingProtocolService . displaySetMatchDetails . keys ( )
69+ ) ;
70+ const matchedDisplaySet = matchedDisplaySetKeys [ matchedDisplaySetIndex ] ;
71+ if ( ! matchedDisplaySet ) return ;
72+
73+ const imageData = viewport . getImageData ( ) ;
74+ const scalarData = imageData ?. scalarData ;
75+ const dimensions = imageData ?. dimensions ;
76+ if ( ! scalarData || ! dimensions ) return ;
77+
78+ // probably will need to account for
79+ // imageData.direction
80+ // interesting that dim[1], dim[0] are reversed for vtk.js => tf.js
81+ // assume this direction does not change
82+ const { bboxWidth, bboxHeight, width, height } = tf . tidy ( ( ) => {
83+ const tensor = tf . tensor2d ( new Float32Array ( scalarData ) , [
84+ dimensions [ 1 ] ,
85+ dimensions [ 0 ] ,
86+ ] ) ;
87+ const mask = tensor . greater ( cutoff ) ; // get boolean
88+ const widthBool = mask . any ( 0 ) ; // height?
89+ const heightBool = mask . any ( 1 ) ; // width?
90+
91+ // get bbox
92+ const left = widthBool . argMax ( ) ;
93+ const right = widthBool . reverse ( ) . argMax ( ) . mul ( - 1 ) . add ( widthBool . size ) ;
94+ const top = heightBool . argMax ( ) ;
95+ const bottom = heightBool
10296 . reverse ( )
10397 . argMax ( )
10498 . mul ( - 1 )
10599 . add ( heightBool . size ) ;
106100
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 ,
101+ // get percentage difference in width and height
102+ const bboxWidth = right . sub ( left ) . dataSync ( ) [ 0 ] ;
103+ const bboxHeight = bottom . sub ( top ) . dataSync ( ) [ 0 ] ;
104+ const width = widthBool . size ;
105+ const height = heightBool . size ;
106+
107+ return {
108+ bboxWidth,
109+ bboxHeight,
110+ width,
111+ height,
112+ } ;
113+ } ) ;
114+
115+ const bboxAspectRatio = bboxWidth / bboxHeight ;
116+ const canvasAspectRatio = viewport . sWidth / viewport . sHeight ;
117+ // console.log({bboxAspectRatio, canvasAspectRatio})
118+ // if(bboxAspectRatio > canvasAspectRatio){
119+ // bboxWidth = canvasAspectRatio*bboxHeight
120+ // bboxAspectRatio = bboxWidth/bboxHeight
121+ // console.log('changed', {bboxAspectRatio, canvasAspectRatio})
122+ // }
123+
124+ const bboxWidthPercentage = bboxWidth / width ; // add buffer
125+ const bboxHeightPercentage = bboxHeight / height ;
126+
127+ // TODO do not hard code, pick the max between bboxwidth and aspect ratio height
128+ const areaZoom = bboxWidthPercentage ;
129+ //const panAmount = (1 - areaZoom) / 2;
130+
131+ if ( matchedDisplaySet === 'LMLO' ) {
132+ viewport . setDisplayArea (
133+ {
134+ imageArea : [ areaZoom , areaZoom ] ,
135+ imageCanvasPoint : {
136+ canvasPoint : [ 0 , 0.5 ] ,
137+ imagePoint : [ 0 , 0.5 ] ,
146138 } ,
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 ,
139+ storeAsInitialCamera : true ,
140+ } ,
141+ true
142+ ) ;
143+ }
144+ if ( matchedDisplaySet === 'RMLO' ) {
145+ viewport . setDisplayArea (
146+ {
147+ imageArea : [ areaZoom , areaZoom ] ,
148+ imageCanvasPoint : {
149+ canvasPoint : [ 1 , 0.5 ] ,
150+ imagePoint : [ 1 , 0.5 ] ,
159151 } ,
152+ storeAsInitialCamera : true ,
153+ } ,
160154
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 ,
155+ true
156+ ) ;
157+ }
158+ if ( matchedDisplaySet === 'LCC' ) {
159+ viewport . setDisplayArea (
160+ {
161+ imageArea : [ areaZoom , areaZoom ] ,
162+ imageCanvasPoint : {
163+ canvasPoint : [ 0 , 0.5 ] ,
164+ imagePoint : [ 0 , 0.5 ] ,
173165 } ,
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 ,
166+ storeAsInitialCamera : true ,
167+ } ,
168+ true
169+ ) ;
170+ }
171+ if ( matchedDisplaySet === 'RCC' ) {
172+ viewport . setDisplayArea (
173+ {
174+ imageArea : [ areaZoom , areaZoom ] ,
175+ imageCanvasPoint : {
176+ canvasPoint : [ 1 , 0.5 ] ,
177+ imagePoint : [ 1 , 0.5 ] ,
186178 } ,
187- true
188- ) ;
189- }
179+ storeAsInitialCamera : true ,
180+ } ,
181+ true
182+ ) ;
190183 }
184+ }
191185
192- destroy ( ) {
186+ destroy ( ) {
193187 }
194188
195189 public async focusToSegment ( segmentationId , segmentIndex ) {
0 commit comments