volview 4.0.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/.browserslistrc +4 -0
- package/.editorconfig +6 -0
- package/.env +6 -0
- package/.eslintrc.js +109 -0
- package/.gitattributes +1 -0
- package/.github/workflows/checks.yml +16 -0
- package/.github/workflows/publish.yml +52 -0
- package/.prettierignore +5 -0
- package/CONTRIBUTING.md +29 -0
- package/LICENSE +202 -0
- package/README.md +44 -0
- package/babel.config.js +3 -0
- package/documentation/config.js +15 -0
- package/documentation/content/KWVolViewLogo.png +0 -0
- package/documentation/content/KWVolViewLogo.svg +35 -0
- package/documentation/content/VolViewLogo.png +0 -0
- package/documentation/content/VolViewLogo.svg +22 -0
- package/documentation/content/doc/index.md +64 -0
- package/documentation/content/doc/loading_data.md +30 -0
- package/documentation/content/doc/mouse_controls.md +34 -0
- package/documentation/content/doc/quick_start_guide.md +75 -0
- package/documentation/content/doc/rendering.md +27 -0
- package/documentation/content/doc/state_files.md +18 -0
- package/documentation/content/doc/toolbar.md +20 -0
- package/documentation/content/doc/welcome_screen.md +23 -0
- package/documentation/content/gallery/01-volview-welcome-notes.jpg +0 -0
- package/documentation/content/gallery/01-volview-welcome.jpg +0 -0
- package/documentation/content/gallery/02-volview-about.jpg +0 -0
- package/documentation/content/gallery/02-volview-notifications.jpg +0 -0
- package/documentation/content/gallery/02-volview-settings.jpg +0 -0
- package/documentation/content/gallery/03-volview-sample-datasets.jpg +0 -0
- package/documentation/content/gallery/04-volview-active-data.jpg +0 -0
- package/documentation/content/gallery/05-volview-select-data-to-delete.jpg +0 -0
- package/documentation/content/gallery/06-volview-corner-annotation.jpg +0 -0
- package/documentation/content/gallery/07-volview-layout-notes.jpg +0 -0
- package/documentation/content/gallery/07-volview-layout.jpg +0 -0
- package/documentation/content/gallery/09-volview-layout-3DPrimary.jpg +0 -0
- package/documentation/content/gallery/10-volview-wl-pan-zoom-notes.jpg +0 -0
- package/documentation/content/gallery/10-volview-wl-pan-zoom.jpg +0 -0
- package/documentation/content/gallery/11-volview-paint-notes.jpg +0 -0
- package/documentation/content/gallery/11-volview-paint.jpg +0 -0
- package/documentation/content/gallery/12-volview-paint-options.jpg +0 -0
- package/documentation/content/gallery/13-volview-crop-notes.jpg +0 -0
- package/documentation/content/gallery/13-volview-crop.jpg +0 -0
- package/documentation/content/gallery/14-volview-ruler.jpg +0 -0
- package/documentation/content/gallery/15-volview-crosshairs.jpg +0 -0
- package/documentation/content/gallery/16-volview-rendering.jpg +0 -0
- package/documentation/content/gallery/17-volview-colormap-notes.jpg +0 -0
- package/documentation/content/gallery/17-volview-colormap.jpg +0 -0
- package/documentation/content/gallery/17-volview-opacity-notes.jpg +0 -0
- package/documentation/content/gallery/17-volview-opacity.jpg +0 -0
- package/documentation/content/gallery/17-volview-opacity2.jpg +0 -0
- package/documentation/content/gallery/18-volview-presets.jpg +0 -0
- package/documentation/content/gallery/19-volview-color.jpg +0 -0
- package/documentation/content/gallery/19-volview-color2.jpg +0 -0
- package/documentation/content/gallery/20-volview-lightfollowcamera0.jpg +0 -0
- package/documentation/content/gallery/20-volview-lightfollowcamera1.jpg +0 -0
- package/documentation/content/gallery/20-volview-lightfollowcamera2.jpg +0 -0
- package/documentation/content/gallery/20-volview-lightfollowcamera3.jpg +0 -0
- package/documentation/content/gallery/21-volview-hybrid-final.jpg +0 -0
- package/documentation/content/gallery/21-volview-hybrid0.0.jpg +0 -0
- package/documentation/content/gallery/21-volview-hybrid0.5.jpg +0 -0
- package/documentation/content/gallery/21-volview-hybrid1.0.jpg +0 -0
- package/documentation/content/gallery/LocalAmbientOcclusion.jpg +0 -0
- package/documentation/content/gallery/Notes.pptx +0 -0
- package/documentation/content/gallery/VolView-Overview.jpg +0 -0
- package/documentation/content/gallery/index.md +53 -0
- package/documentation/content/icon/favicon-16x16.png +0 -0
- package/documentation/content/icon/favicon-196x196.png +0 -0
- package/documentation/content/icon/favicon-32x32.png +0 -0
- package/documentation/content/icon/favicon-96x96.png +0 -0
- package/documentation/content/index.pug +43 -0
- package/documentation/content/logo.png +0 -0
- package/documentation/content/logo.svg +20 -0
- package/documentation/data/menu.yml +3 -0
- package/documentation/themes/navy/layout/partial/footer.swig +22 -0
- package/documentation/tpl/__en__ +31 -0
- package/documentation/tpl/__sidebar__ +11 -0
- package/package.json +96 -0
- package/patches/jsdom-global+3.0.2.patch +12 -0
- package/patches/vue-toastification+1.7.14.patch +41 -0
- package/patches/vuetify+2.6.10.patch +13 -0
- package/prettier.config.js +9 -0
- package/public/favicon.ico +0 -0
- package/public/global.css +20 -0
- package/public/index.html +28 -0
- package/public/pvm-sample.png +0 -0
- package/server/helper.py +147 -0
- package/server/host.js +134 -0
- package/server/serialize.js +111 -0
- package/server/serialize.py +203 -0
- package/server/server.py +84 -0
- package/server/test.py +17 -0
- package/src/assets/KitwareHeadAndNeck.jpg +0 -0
- package/src/assets/logo.png +0 -0
- package/src/assets/logo.svg +20 -0
- package/src/assets/samples/3DUS-Fetus.jpg +0 -0
- package/src/assets/samples/CTA-Head_and_Neck.jpg +0 -0
- package/src/assets/samples/MRA-Head_and_Neck.jpg +0 -0
- package/src/assets/samples/MRI-Cardiac.jpg +0 -0
- package/src/assets/samples/MRI-PROSTATEx.jpg +0 -0
- package/src/components/AboutBox.vue +157 -0
- package/src/components/AiModule.vue +60 -0
- package/src/components/AnnotationsModule.vue +37 -0
- package/src/components/App.vue +539 -0
- package/src/components/ColorFunctionSlider.vue +181 -0
- package/src/components/DataBrowser.vue +173 -0
- package/src/components/DragAndDrop.vue +107 -0
- package/src/components/GroupableItem.vue +30 -0
- package/src/components/ImageDataBrowser.vue +186 -0
- package/src/components/ImageListCard.vue +114 -0
- package/src/components/ItemGroup.vue +74 -0
- package/src/components/LabelmapList.vue +36 -0
- package/src/components/LayoutGrid.vue +96 -0
- package/src/components/MeasurementsList.vue +134 -0
- package/src/components/MessageCenter.vue +189 -0
- package/src/components/MessageItem.vue +83 -0
- package/src/components/MessageNotificationContent.vue +20 -0
- package/src/components/MessageNotifications.vue +84 -0
- package/src/components/ModelBrowser.vue +83 -0
- package/src/components/ModulePanel.vue +137 -0
- package/src/components/PaintControls.vue +174 -0
- package/src/components/PatientBrowser.vue +280 -0
- package/src/components/PatientStudyVolumeBrowser.vue +325 -0
- package/src/components/RenderingModule.vue +49 -0
- package/src/components/ResizableNavDrawer.vue +158 -0
- package/src/components/SampleDataBrowser.vue +198 -0
- package/src/components/SaveSession.vue +57 -0
- package/src/components/Settings.vue +35 -0
- package/src/components/SliceSlider.vue +182 -0
- package/src/components/SpleenModule.vue +101 -0
- package/src/components/ToolButton.vue +58 -0
- package/src/components/ToolStrip.vue +186 -0
- package/src/components/ViewOverlayGrid.vue +84 -0
- package/src/components/VolumePresets.vue +165 -0
- package/src/components/VolumeProperties.vue +171 -0
- package/src/components/VolumeRendering.vue +365 -0
- package/src/components/VtkThreeView.vue +512 -0
- package/src/components/VtkTwoView.vue +665 -0
- package/src/components/__tests__/ResizableNavDrawer.spec.js +32 -0
- package/src/components/__tests__/ToolButton.spec.js +46 -0
- package/src/components/icons/KitwareLogoIcon.vue +54 -0
- package/src/components/icons/VolViewFullLogo.vue +139 -0
- package/src/components/icons/VolViewLogo.vue +78 -0
- package/src/components/styles/utils.css +16 -0
- package/src/components/styles/vtk-view.css +116 -0
- package/src/components/tools/CropTool.vue +61 -0
- package/src/components/tools/CrosshairsTool.vue +93 -0
- package/src/components/tools/MouseManipulatorTool.vue +108 -0
- package/src/components/tools/PaintTool.vue +54 -0
- package/src/components/tools/PanTool.vue +35 -0
- package/src/components/tools/RulerTool.vue +202 -0
- package/src/components/tools/SliceScrollTool.vue +123 -0
- package/src/components/tools/WindowLevelTool.vue +191 -0
- package/src/components/tools/ZoomTool.vue +35 -0
- package/src/components/tools/crop/Crop2D.vue +367 -0
- package/src/components/tools/crop/Crop2DLineHandle.vue +103 -0
- package/src/components/tools/crop/Crop3D.vue +192 -0
- package/src/components/tools/crop/CropControls.vue +38 -0
- package/src/components/tools/crop/types.ts +12 -0
- package/src/components/tools/crosshairs/CrosshairSVG2D.vue +125 -0
- package/src/components/tools/crosshairs/CrosshairsWidget2D.vue +100 -0
- package/src/components/tools/paint/PaintWidget2D.vue +192 -0
- package/src/components/tools/ruler/RulerSVG2D.vue +181 -0
- package/src/components/tools/ruler/RulerWidget2D.vue +154 -0
- package/src/composables/__tests__/useDoubleRecord.spec.ts +57 -0
- package/src/composables/__tests__/useOrientationLabels.spec.ts +29 -0
- package/src/composables/isViewAnimating.ts +25 -0
- package/src/composables/manageVTKSubscription.ts +6 -0
- package/src/composables/onProxyManagerEvent.ts +50 -0
- package/src/composables/proxyManager.ts +13 -0
- package/src/composables/sync/__tests__/createPrimitiveSyncContext.spec.ts +41 -0
- package/src/composables/sync/__tests__/useWindowingSync.spec.ts +51 -0
- package/src/composables/sync/createPrimitiveSyncContext.ts +83 -0
- package/src/composables/sync/useWindowingSync.ts +48 -0
- package/src/composables/useAppLoadingNotifications.ts +73 -0
- package/src/composables/useCameraOrientation.ts +34 -0
- package/src/composables/useCurrentImage.ts +74 -0
- package/src/composables/useCurrentSlice.ts +43 -0
- package/src/composables/useDoubleRecord.ts +77 -0
- package/src/composables/useEventListener.ts +26 -0
- package/src/composables/useGlobalErrorHook.ts +18 -0
- package/src/composables/useMultiSelection.ts +29 -0
- package/src/composables/useOrientationLabels.ts +62 -0
- package/src/composables/usePanels.ts +42 -0
- package/src/composables/usePersistCameraConfig.ts +138 -0
- package/src/composables/useResizeObserver.ts +37 -0
- package/src/composables/useResizeToFit.ts +50 -0
- package/src/composables/useSceneBuilder.ts +96 -0
- package/src/composables/useToast.js +11 -0
- package/src/composables/useVTKCallback.ts +33 -0
- package/src/composables/useVTKWorldToDisplay.ts +141 -0
- package/src/composables/useViewProxy.ts +87 -0
- package/src/composables/useVolumeThumbnailing.ts +173 -0
- package/src/composables/useWebGLWatchdog.ts +32 -0
- package/src/composables/useWidgetManager.ts +41 -0
- package/src/config.ts +182 -0
- package/src/constants.ts +38 -0
- package/src/core/id.ts +18 -0
- package/src/core/provider.ts +31 -0
- package/src/core/proxies.ts +90 -0
- package/src/core/thumbnailers/__tests__/vtk-image.spec.ts +58 -0
- package/src/core/thumbnailers/index.ts +5 -0
- package/src/core/thumbnailers/volume-thumbnailer.ts +130 -0
- package/src/core/thumbnailers/vtk-image.ts +142 -0
- package/src/core/tools/__tests__/paint.spec.ts +101 -0
- package/src/core/tools/__tests__/ruler.spec.ts +73 -0
- package/src/core/tools/paint/brush.ts +20 -0
- package/src/core/tools/paint/ellipse-brush.ts +96 -0
- package/src/core/tools/paint/index.ts +141 -0
- package/src/core/tools/ruler.ts +149 -0
- package/src/global.d.ts +24 -0
- package/src/io/__tests__/io.spec.ts +26 -0
- package/src/io/dicom.ts +187 -0
- package/src/io/index.ts +11 -0
- package/src/io/io.ts +157 -0
- package/src/io/itk/itkConfig.js +8 -0
- package/src/io/itk-dicom/dicom.cpp +327 -0
- package/src/io/itk-dicom/web-build/dicom.js +16 -0
- package/src/io/itk-dicom/web-build/dicom.umd.js +21 -0
- package/src/io/itk-dicom/web-build/dicom.umd.wasm +0 -0
- package/src/io/itk-dicom/web-build/dicom.wasm +0 -0
- package/src/io/manifest.ts +30 -0
- package/src/io/readers.ts +36 -0
- package/src/io/state-file/index.ts +170 -0
- package/src/io/state-file/schema.ts +277 -0
- package/src/io/state-file/utils.ts +33 -0
- package/src/io/types.ts +4 -0
- package/src/io/vtk/async.reader.worker.ts +50 -0
- package/src/io/vtk/async.ts +58 -0
- package/src/io/vtk/async.writer.worker.ts +46 -0
- package/src/io/vtk/common.ts +30 -0
- package/src/io/zip.ts +31 -0
- package/src/main.js +66 -0
- package/src/main.ts +1 -0
- package/src/plugins/vuetify.js +25 -0
- package/src/shims-itk.d.ts +67 -0
- package/src/shims-misc.d.ts +4 -0
- package/src/shims-tsx.d.ts +13 -0
- package/src/shims-vtk.d.ts +1042 -0
- package/src/shims-vue.d.ts +5 -0
- package/src/store/__tests__/datasets.spec.ts +75 -0
- package/src/store/__tests__/messages.spec.ts +74 -0
- package/src/store/__tests__/rulers.spec.ts +77 -0
- package/src/store/__tests__/view-configs.spec.ts +37 -0
- package/src/store/datasets-dicom.ts +398 -0
- package/src/store/datasets-files.ts +35 -0
- package/src/store/datasets-images.ts +118 -0
- package/src/store/datasets-labelmaps.ts +136 -0
- package/src/store/datasets-models.ts +25 -0
- package/src/store/datasets.ts +341 -0
- package/src/store/messages.ts +144 -0
- package/src/store/tools/crop.ts +136 -0
- package/src/store/tools/crosshairs.ts +131 -0
- package/src/store/tools/index.ts +95 -0
- package/src/store/tools/paint.ts +191 -0
- package/src/store/tools/rulers.ts +305 -0
- package/src/store/tools/types.ts +54 -0
- package/src/store/view-configs/camera.ts +51 -0
- package/src/store/view-configs/common.ts +61 -0
- package/src/store/view-configs/slicing.ts +86 -0
- package/src/store/view-configs/types.ts +39 -0
- package/src/store/view-configs/volume-coloring.ts +193 -0
- package/src/store/view-configs/windowing.ts +69 -0
- package/src/store/view-configs.ts +78 -0
- package/src/store/views.ts +130 -0
- package/src/types/index.ts +16 -0
- package/src/types/layout.ts +10 -0
- package/src/types/lps.ts +40 -0
- package/src/types/views.ts +65 -0
- package/src/types/vtk-types.ts +29 -0
- package/src/utils/__tests__/lps.spec.ts +102 -0
- package/src/utils/color.ts +23 -0
- package/src/utils/errors.js +3 -0
- package/src/utils/fetch.ts +101 -0
- package/src/utils/hacks.ts +14 -0
- package/src/utils/index.ts +83 -0
- package/src/utils/lps.ts +129 -0
- package/src/utils/manipulators.ts +35 -0
- package/src/utils/promise-worker.ts +45 -0
- package/src/utils/vtk-helpers.ts +215 -0
- package/src/utils/workerHandler.js +42 -0
- package/src/vtk/ColorMaps.ts +72 -0
- package/src/vtk/CrosshairsWidget/behavior.ts +112 -0
- package/src/vtk/CrosshairsWidget/index.d.ts +22 -0
- package/src/vtk/CrosshairsWidget/index.js +73 -0
- package/src/vtk/CrosshairsWidget/state.ts +51 -0
- package/src/vtk/IJKSliceRepresentationProxy/index.d.ts +9 -0
- package/src/vtk/IJKSliceRepresentationProxy/index.js +59 -0
- package/src/vtk/LPSView2DProxy/index.d.ts +18 -0
- package/src/vtk/LPSView2DProxy/index.js +89 -0
- package/src/vtk/LPSView3DProxy/index.d.ts +16 -0
- package/src/vtk/LPSView3DProxy/index.js +78 -0
- package/src/vtk/LabelMap/index.d.ts +16 -0
- package/src/vtk/LabelMap/index.js +49 -0
- package/src/vtk/LabelMapSliceRepProxy/index.d.ts +6 -0
- package/src/vtk/LabelMapSliceRepProxy/index.js +104 -0
- package/src/vtk/MedicalColorPresets.json +1448 -0
- package/src/vtk/PaintBrushContextRepresentation/index.js +191 -0
- package/src/vtk/PaintWidget/behavior.ts +101 -0
- package/src/vtk/PaintWidget/index.d.ts +28 -0
- package/src/vtk/PaintWidget/index.js +56 -0
- package/src/vtk/PaintWidget/state.ts +41 -0
- package/src/vtk/PiecewiseWidget/index.js +203 -0
- package/src/vtk/RulerWidget/behavior.ts +185 -0
- package/src/vtk/RulerWidget/index.d.ts +25 -0
- package/src/vtk/RulerWidget/index.js +79 -0
- package/src/vtk/RulerWidget/state.ts +63 -0
- package/src/vtk/TreJsonConverter/index.js +150 -0
- package/src/vtk/proxy.js +66 -0
- package/src/vtk/proxyUtils.js +16 -0
- package/src/vtk/webvr-empty.js +1 -0
- package/tests/testUtils.js +12 -0
- package/tsconfig.json +46 -0
- package/vue.config.js +86 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import struct
|
|
3
|
+
import itk
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
JS_TO_NPY_TYPEMAP = {
|
|
7
|
+
'Int8Array': {
|
|
8
|
+
'struct': (1, 'b'),
|
|
9
|
+
'dtype': 'int8',
|
|
10
|
+
},
|
|
11
|
+
'Int16Array': {
|
|
12
|
+
'struct': (2, 'h'),
|
|
13
|
+
'dtype': 'int16',
|
|
14
|
+
},
|
|
15
|
+
'Int32Array': {
|
|
16
|
+
'struct': (4, 'i'),
|
|
17
|
+
'dtype': 'int32',
|
|
18
|
+
},
|
|
19
|
+
'Uint8Array': {
|
|
20
|
+
'struct': (1, 'B'),
|
|
21
|
+
'dtype': 'uint8',
|
|
22
|
+
},
|
|
23
|
+
'Uint16Array': {
|
|
24
|
+
'struct': (2, 'H'),
|
|
25
|
+
'dtype': 'uint16',
|
|
26
|
+
},
|
|
27
|
+
'Uint32Array': {
|
|
28
|
+
'struct': (4, 'I'),
|
|
29
|
+
'dtype': 'uint32',
|
|
30
|
+
},
|
|
31
|
+
'Float32Array': {
|
|
32
|
+
'struct': (4, 'f'),
|
|
33
|
+
'dtype': 'float32',
|
|
34
|
+
},
|
|
35
|
+
'Float64Array': {
|
|
36
|
+
'struct': (8, 'd'),
|
|
37
|
+
'dtype': 'float64',
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ITK_COMP_TO_JS_TYPEMAP = {
|
|
42
|
+
'SC': 'Int8Array',
|
|
43
|
+
'UC': 'Uint8Array',
|
|
44
|
+
'SS': 'Int16Array',
|
|
45
|
+
'US': 'Uint16Array',
|
|
46
|
+
'SI': 'Int32Array',
|
|
47
|
+
'UI': 'Uint32Array',
|
|
48
|
+
'F': 'Float32Array',
|
|
49
|
+
'D': 'Float64Array',
|
|
50
|
+
'B': 'Uint8Array'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def bytebuffer_to_numpy(blob, js_type):
|
|
55
|
+
typeinfo = JS_TO_NPY_TYPEMAP[js_type]
|
|
56
|
+
size, fmt = typeinfo['struct']
|
|
57
|
+
dtype = np.dtype(typeinfo['dtype'])
|
|
58
|
+
|
|
59
|
+
if len(blob) % size != 0:
|
|
60
|
+
raise ValueError('given byte buffer is not aligned to the type')
|
|
61
|
+
|
|
62
|
+
full_fmt = '<{0}{1}'.format(len(blob) // size, fmt)
|
|
63
|
+
return np.array(struct.unpack(full_fmt, blob), dtype=dtype, copy=False)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def itk_image_pixel_type_to_js(itk_image):
|
|
67
|
+
component_str = repr(itk_image).split(
|
|
68
|
+
'itkImagePython.')[1].split(';')[0][8:]
|
|
69
|
+
# TODO handle mangling as per https://github.com/InsightSoftwareConsortium/itk-jupyter-widgets/blob/master/itkwidgets/trait_types.py#L49
|
|
70
|
+
return ITK_COMP_TO_JS_TYPEMAP[component_str[:-1]]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class RpcEncoder(object):
|
|
74
|
+
def __init__(self, encoders=[], extra_args=[], extra_kwargs={}):
|
|
75
|
+
self._encoders = list(encoders)
|
|
76
|
+
self._extra_args = extra_args
|
|
77
|
+
self._extra_kwargs = extra_kwargs
|
|
78
|
+
|
|
79
|
+
def add_encoder(self, encoder):
|
|
80
|
+
self._encoders.append(encoder)
|
|
81
|
+
|
|
82
|
+
def remove_encoder(self, encoder):
|
|
83
|
+
self._encoders.remove(encoder)
|
|
84
|
+
|
|
85
|
+
def run_encoders(self, obj):
|
|
86
|
+
output = obj
|
|
87
|
+
for encoder in self._encoders:
|
|
88
|
+
output = encoder(output, *self._extra_args, **self._extra_kwargs)
|
|
89
|
+
return output
|
|
90
|
+
|
|
91
|
+
def encode(self, obj):
|
|
92
|
+
# run on every possible value
|
|
93
|
+
if isinstance(obj, list):
|
|
94
|
+
return self.run_encoders([self.encode(item) for item in obj])
|
|
95
|
+
if isinstance(obj, dict):
|
|
96
|
+
return self.run_encoders({k: self.encode(v) for k, v in obj.items()})
|
|
97
|
+
else:
|
|
98
|
+
return self.run_encoders(obj)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class RpcDecoder(object):
|
|
102
|
+
def __init__(self, hooks=[], extra_args=[], extra_kwargs={}):
|
|
103
|
+
self._hooks = list(hooks)
|
|
104
|
+
self._extra_args = extra_args
|
|
105
|
+
self._extra_kwargs = extra_kwargs
|
|
106
|
+
|
|
107
|
+
def add_hook(self, hook):
|
|
108
|
+
self._hooks.append(hook)
|
|
109
|
+
|
|
110
|
+
def remove_hook(self, hook):
|
|
111
|
+
self._hooks.remove(hook)
|
|
112
|
+
|
|
113
|
+
def run_hooks(self, val):
|
|
114
|
+
output = val
|
|
115
|
+
for hook in self._hooks:
|
|
116
|
+
output = hook(output, *self._extra_args, **self._extra_kwargs)
|
|
117
|
+
return output
|
|
118
|
+
|
|
119
|
+
def decode(self, obj):
|
|
120
|
+
# only run hooks on dictionaries
|
|
121
|
+
if isinstance(obj, list):
|
|
122
|
+
return [self.decode(item) for item in obj]
|
|
123
|
+
if isinstance(obj, dict):
|
|
124
|
+
return self.run_hooks({k: self.decode(v) for k, v in obj.items()})
|
|
125
|
+
else:
|
|
126
|
+
return obj
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def itk_image_encoder(obj, attach):
|
|
130
|
+
if type(obj).__name__.startswith('itkImage'):
|
|
131
|
+
img = obj
|
|
132
|
+
size = list(img.GetLargestPossibleRegion().GetSize())
|
|
133
|
+
values = itk.GetArrayFromImage(img).flatten(order='C')
|
|
134
|
+
return {
|
|
135
|
+
'vtkClass': 'vtkImageData',
|
|
136
|
+
'dataDescription': 8,
|
|
137
|
+
'direction': list(
|
|
138
|
+
itk.GetArrayFromVnlMatrix(
|
|
139
|
+
img.GetDirection().GetVnlMatrix().as_matrix()
|
|
140
|
+
).flatten()
|
|
141
|
+
),
|
|
142
|
+
'extent': [
|
|
143
|
+
0, size[0] - 1,
|
|
144
|
+
0, size[1] - 1,
|
|
145
|
+
0, size[2] - 1,
|
|
146
|
+
],
|
|
147
|
+
'spacing': list(img.GetSpacing()),
|
|
148
|
+
'origin': list(img.GetOrigin()),
|
|
149
|
+
'pointData': {
|
|
150
|
+
'vtkClass': 'vtkDataSetAttributes',
|
|
151
|
+
'activeScalars': 0, # the index of the only array
|
|
152
|
+
'arrays': [
|
|
153
|
+
{
|
|
154
|
+
'data': {
|
|
155
|
+
'vtkClass': 'vtkDataArray',
|
|
156
|
+
'size': len(values),
|
|
157
|
+
'values': attach(values.tobytes()),
|
|
158
|
+
'dataType': itk_image_pixel_type_to_js(img),
|
|
159
|
+
'numberOfComponents': img.GetNumberOfComponentsPerPixel(),
|
|
160
|
+
'name': 'Scalars',
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return obj
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def itk_image_decode_hook(obj):
|
|
170
|
+
if isinstance(obj, dict) and obj.get('vtkClass', None) == 'vtkImageData':
|
|
171
|
+
data_array = obj['pointData']['arrays'][0]['data']
|
|
172
|
+
pixel_data = bytebuffer_to_numpy(
|
|
173
|
+
data_array['values'], data_array['dataType'])
|
|
174
|
+
|
|
175
|
+
extent = obj['extent']
|
|
176
|
+
# numpy indexes in ZYX order, where X varies the fastest
|
|
177
|
+
dims = [
|
|
178
|
+
extent[5] - extent[4] + 1,
|
|
179
|
+
extent[3] - extent[2] + 1,
|
|
180
|
+
extent[1] - extent[0] + 1,
|
|
181
|
+
]
|
|
182
|
+
direction = np.zeros((3, 3))
|
|
183
|
+
for x in range(3):
|
|
184
|
+
for y in range(3):
|
|
185
|
+
direction[x][y] = obj['direction'][x*3+y]
|
|
186
|
+
|
|
187
|
+
itk_image = itk.GetImageFromArray(np.reshape(pixel_data, dims))
|
|
188
|
+
# https://discourse.itk.org/t/set-image-direction-from-numpy-array/844/10
|
|
189
|
+
vnlmat = itk.GetVnlMatrixFromArray(direction)
|
|
190
|
+
itk_image.GetDirection().GetVnlMatrix().copy_in(vnlmat.data_block())
|
|
191
|
+
itk_image.SetOrigin(obj['origin'])
|
|
192
|
+
itk_image.SetSpacing(obj['spacing'])
|
|
193
|
+
return itk_image
|
|
194
|
+
return obj
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
DEFAULT_DECODERS = [
|
|
198
|
+
itk_image_decode_hook,
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
DEFAULT_ENCODERS = [
|
|
202
|
+
itk_image_encoder,
|
|
203
|
+
]
|
package/server/server.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import webbrowser
|
|
4
|
+
import socket
|
|
5
|
+
import argparse
|
|
6
|
+
import importlib
|
|
7
|
+
|
|
8
|
+
from wslink.websocket import ServerProtocol
|
|
9
|
+
from wslink import server
|
|
10
|
+
from twisted.internet import reactor
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_port():
|
|
14
|
+
# Don't care about race condition here for getting a free port
|
|
15
|
+
# if someone binds the port between get_port() and actually binding,
|
|
16
|
+
# then the server won't start
|
|
17
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
18
|
+
sock.bind(('localhost', 0))
|
|
19
|
+
_, port = sock.getsockname()
|
|
20
|
+
sock.close()
|
|
21
|
+
return port
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def create_protocol(ApiClass):
|
|
25
|
+
class ApiProtocol(ServerProtocol):
|
|
26
|
+
authKey = 'wslink-secret'
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def configure(options):
|
|
30
|
+
ApiProtocol.authKey = options.authKey
|
|
31
|
+
|
|
32
|
+
def initialize(self):
|
|
33
|
+
self.registerLinkProtocol(ApiClass())
|
|
34
|
+
self.updateSecret(ApiProtocol.authKey)
|
|
35
|
+
|
|
36
|
+
return ApiProtocol
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == '__main__':
|
|
40
|
+
# https://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile
|
|
41
|
+
try:
|
|
42
|
+
basepath = sys._MEIPASS
|
|
43
|
+
except:
|
|
44
|
+
basepath = os.path.dirname(os.path.dirname(sys.argv[0]))
|
|
45
|
+
|
|
46
|
+
parser = argparse.ArgumentParser()
|
|
47
|
+
parser.add_argument('-H', '--host', default='localhost',
|
|
48
|
+
help='Hostname for server to listen on')
|
|
49
|
+
parser.add_argument('-P', '--port', default=get_port(),
|
|
50
|
+
help='Port for server to listen on')
|
|
51
|
+
parser.add_argument('-b', '--no-browser', action='store_true',
|
|
52
|
+
help='Do not auto-open the browser')
|
|
53
|
+
parser.add_argument('api_script',
|
|
54
|
+
help='Python file that exposes ServerApi')
|
|
55
|
+
args = parser.parse_args()
|
|
56
|
+
|
|
57
|
+
static_dir = os.path.join(basepath, 'www')
|
|
58
|
+
host = args.host
|
|
59
|
+
port = args.port
|
|
60
|
+
server_args = [
|
|
61
|
+
'--content', static_dir,
|
|
62
|
+
'--host', host,
|
|
63
|
+
'--port', str(port)
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
wsurl = 'ws://{host}:{port}/ws'.format(host=host, port=port)
|
|
67
|
+
full_url = 'http://{host}:{port}/?wsServer={wsurl}'.format(
|
|
68
|
+
host=host, port=port, wsurl=wsurl)
|
|
69
|
+
|
|
70
|
+
def open_webapp():
|
|
71
|
+
webbrowser.open(full_url)
|
|
72
|
+
|
|
73
|
+
# if not args.no_browser:
|
|
74
|
+
# print('If the browser doesn\'t open, navigate to:', full_url)
|
|
75
|
+
# reactor.callLater(0.1, open_webapp)
|
|
76
|
+
|
|
77
|
+
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
|
78
|
+
|
|
79
|
+
spec = importlib.util.spec_from_file_location('Api', args.api_script)
|
|
80
|
+
api_module = importlib.util.module_from_spec(spec)
|
|
81
|
+
spec.loader.exec_module(api_module)
|
|
82
|
+
|
|
83
|
+
server.start(server_args, create_protocol(api_module.Api))
|
|
84
|
+
server.stop_webserver()
|
package/server/test.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import itk
|
|
2
|
+
import json
|
|
3
|
+
from helper import RpcApi, rpc
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Api(RpcApi):
|
|
7
|
+
|
|
8
|
+
@rpc('run')
|
|
9
|
+
def test(self, arg1, arg2):
|
|
10
|
+
print(type(arg1), type(arg2), arg2)
|
|
11
|
+
with open('spleen_10.json', 'r') as fp:
|
|
12
|
+
mm = json.load(fp)
|
|
13
|
+
return {
|
|
14
|
+
'segmentation': itk.imread('spleen_10-label.nrrd'),
|
|
15
|
+
# 'segmentation': itk.imread('/home/forrestli/data/Branch-label.nrrd'),
|
|
16
|
+
'measurements': mm,
|
|
17
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<svg width="35" height="34" viewBox="0 0 35 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<g clip-path="url(#clip0_137_213)">
|
|
3
|
+
<path d="M33.2403 22.7281C33.189 22.8061 33.1376 22.91 33.0606 22.988C31.7509 24.7549 29.0545 25.4824 25.6905 25.0147C25.5364 24.9887 25.3823 24.9628 25.2282 24.9368C23.1995 24.599 20.9911 23.8454 18.7826 22.7281C17.4729 22.0525 16.1633 21.221 14.905 20.2596C13.5439 19.2202 12.3113 18.1029 11.2584 16.9076C9.58926 15.0628 8.35663 13.1139 7.56056 11.2431C6.25089 8.15095 6.25089 5.39662 7.53488 3.6037C8.84455 1.83677 11.4125 1.16118 14.6225 1.65488C16.2146 1.88874 17.9609 2.43441 19.7584 3.23992C21.5303 4.04543 23.3536 5.11079 25.1255 6.46197C28.6693 9.13835 31.34 12.3864 32.7781 15.4525C34.1648 18.3628 34.3445 20.9612 33.2403 22.7281Z" fill="#3EAE2B"/>
|
|
4
|
+
<path d="M33.2404 22.7281C33.189 22.8061 33.1377 22.91 33.0606 22.9879C31.7509 24.7549 29.0546 25.4824 25.6905 25.0147C25.5364 24.9887 25.3824 24.9627 25.2283 24.9368C23.3537 24.547 21.1966 23.8454 18.7827 22.7281C17.473 22.0525 16.1633 21.221 14.905 20.2596C13.544 19.2202 12.3114 18.1029 11.2585 16.9076C8.69052 12.6202 9.2298 7.29345 10.7706 5.60448C12.6452 3.52574 16.9337 3.05802 23.6361 7.60526C29.5425 11.6068 33.7796 19.3761 33.2404 22.7281Z" fill="black" fill-opacity="0.15"/>
|
|
5
|
+
<path d="M30.1331 18.3627C30.1331 18.8564 30.0304 19.2982 29.8506 19.6879C29.7993 19.8179 29.7222 19.9478 29.6195 20.0777C29.2086 20.6493 28.541 21.0131 27.6422 21.195C26.7434 21.3769 25.6648 21.3249 24.4579 21.0911C22.044 20.6234 19.2706 19.3501 16.831 17.5312C16.8053 17.5053 16.7539 17.4793 16.7283 17.4533C14.3657 15.6344 12.5681 13.4257 11.5666 11.373C10.5394 9.26825 10.4624 7.42336 11.3098 6.28006C12.1316 5.13675 13.9035 4.79895 16.189 5.26667C18.4745 5.73439 21.1195 7.00762 23.5334 8.8525C25.9473 10.6974 27.9503 12.932 29.1059 15.0367C29.7993 16.258 30.1331 17.4013 30.1331 18.3627Z" fill="#3EAE2B"/>
|
|
6
|
+
<path d="M29.8506 19.688C29.7992 19.8179 29.7222 19.9479 29.6195 20.0778C29.2086 20.6494 28.5409 21.0132 27.6421 21.1951C26.7433 21.377 25.6648 21.325 24.4578 21.0912C22.0439 20.6234 19.2705 19.3502 16.831 17.5313C16.8053 17.5053 16.7539 17.4793 16.7282 17.4534C13.8778 14.5691 13.7494 9.9699 14.905 8.67069C16.2146 7.5014 18.5258 7.52738 22.763 10.3856C26.3068 12.8022 29.5681 17.2975 29.8506 19.688Z" fill="black" fill-opacity="0.15"/>
|
|
7
|
+
<path d="M26.3068 17.6092C26.1271 17.8431 25.8189 17.999 25.3567 18.077C24.8944 18.1289 24.3038 18.1029 23.6105 17.9211C22.2494 17.5833 20.6059 16.8037 19.0651 15.6344C17.5243 14.4652 16.3431 13.14 15.6754 11.9187C15.3416 11.3211 15.1618 10.7754 15.0848 10.3077C15.0334 9.83996 15.1105 9.52814 15.2902 9.29429C15.47 9.06043 15.7524 8.87854 16.2147 8.82657C16.6512 8.7746 17.2162 8.80059 17.8839 8.95649C18.5259 9.1124 19.2706 9.39822 20.0153 9.78799C20.76 10.1778 21.5561 10.6715 22.3008 11.2691C23.8416 12.4384 25.0742 13.7636 25.7932 14.9589C26.1528 15.5565 26.3582 16.1022 26.4352 16.5699C26.5379 17.0636 26.4609 17.4014 26.3068 17.6092Z" fill="#3EAE2B"/>
|
|
8
|
+
<path d="M27.0001 17.921C26.769 18.5186 26.5379 18.9604 26.1527 19.506C23.8415 22.6241 19.0137 23.0659 15.624 20.4934C12.2343 17.921 11.3612 13.1139 13.6467 9.9958C14.1089 9.42415 14.4427 9.03438 14.982 8.59265C14.8793 8.6706 14.8022 8.74856 14.7252 8.85249C14.3914 9.29423 14.3143 9.8399 14.3914 10.4115C14.4684 10.9832 14.6995 11.6328 15.059 12.2824C15.7781 13.5816 17.0364 15.0108 18.6542 16.232C20.272 17.4533 21.9926 18.2848 23.482 18.6226C24.2267 18.8045 24.9201 18.8564 25.485 18.7785C26.0757 18.7005 26.5893 18.4667 26.9231 18.0249C26.9488 18.0249 26.9745 17.973 27.0001 17.921Z" fill="#0068C7"/>
|
|
9
|
+
<path d="M30.5696 20.1297C30.2615 21.0651 29.1316 22.7801 28.4382 23.5596C24.7917 28.4706 17.1391 29.3281 11.6436 25.1706C6.17386 21.0911 5.17235 12.8021 8.81888 7.86512C9.38383 7.11157 10.334 5.9163 11.1557 5.21472C10.976 5.37063 10.7962 5.55252 10.6421 5.76039C9.51223 7.29346 9.76903 9.52811 10.8219 11.7368C11.9004 13.9714 13.8264 16.31 16.3174 18.2068C17.5757 19.1683 18.911 19.9738 20.272 20.5974C21.6331 21.221 22.9941 21.6887 24.2524 21.9226C25.5364 22.1824 26.7177 22.2344 27.7449 22.0265C28.7721 21.8187 29.6452 21.3769 30.2358 20.5974C30.3899 20.4415 30.4926 20.2856 30.5696 20.1297Z" fill="#0068C7"/>
|
|
10
|
+
<path d="M34.2675 22.5203C33.7025 24.0534 32.6497 25.9502 31.1859 27.6652C25.2796 34.473 15.059 35.7463 7.71463 30.1597C0.395901 24.625 -1.32464 14.4652 3.47747 6.74784C4.55602 5.0069 6.63608 2.95414 7.86871 2.07068C7.84303 2.09666 7.14968 2.74627 6.8672 3.13603C5.30074 5.26674 5.42913 8.41084 6.79016 11.5809C8.15119 14.803 10.7705 18.1809 14.3914 20.9352C16.2146 22.3124 18.1149 23.4037 20.0152 24.2352C21.9155 25.0667 23.8158 25.5864 25.5621 25.8463C29.0545 26.314 32.1361 25.6384 33.7026 23.5077C33.9337 23.1959 34.1391 22.8581 34.2675 22.5203Z" fill="#0068C7"/>
|
|
11
|
+
<path d="M33.5228 15.0888C32.0077 11.8928 29.2343 8.54078 25.6135 5.78645C22.0183 3.03212 18.115 1.34315 14.7509 0.82346C13.544 0.64157 12.3627 0.615586 11.3098 0.745507C11.2585 0.745507 11.2071 0.745507 11.1814 0.771492C11.0274 0.797476 10.8476 0.82346 10.6935 0.849444C10.6679 0.849444 10.6422 0.849444 10.5908 0.875429C10.4881 0.901413 10.3854 0.927397 10.3083 0.953381C10.2056 0.979366 10.1286 1.00535 10.0515 1.03133C9.9745 1.05732 9.89746 1.0833 9.82042 1.10929C9.07571 1.34315 8.40803 1.70692 7.8174 2.17464C7.45788 2.43448 7.14973 2.74629 6.86725 3.13606C5.30078 5.26677 5.42918 8.41086 6.79021 11.5809C8.15124 14.803 10.7706 18.1809 14.3914 20.9353C16.2147 22.3124 18.115 23.4038 20.0153 24.2353C21.9156 25.0668 23.8159 25.5865 25.5621 25.8463C29.0546 26.314 32.1361 25.6384 33.7026 23.5077C33.9337 23.2219 34.1135 22.8841 34.2675 22.5463C35.2177 20.4676 34.8068 17.7912 33.5228 15.0888ZM33.2404 22.7282C33.189 22.8061 33.1376 22.9101 33.0606 22.988C31.7509 24.755 29.0546 25.4825 25.6905 25.0148C25.5364 24.9888 25.3824 24.9628 25.2283 24.9368C23.1996 24.5991 20.9911 23.8455 18.7827 22.7282C17.473 22.0526 16.1633 21.2211 14.905 20.2597C13.544 19.2203 12.3114 18.103 11.2585 16.9077C9.5893 15.0628 8.35667 13.114 7.5606 11.2431C6.25093 8.15102 6.25093 5.39669 7.53492 3.60378C8.84459 1.83685 11.4126 1.16126 14.6225 1.65496C16.2147 1.88881 17.9609 2.43448 19.7585 3.24C21.5304 4.04551 23.3537 5.11086 25.1256 6.46204C28.6694 9.13842 31.3401 12.3865 32.7781 15.4526C34.1648 18.3628 34.3446 20.9613 33.2404 22.7282Z" fill="white"/>
|
|
12
|
+
<path d="M29.8506 14.621C28.6436 12.4124 26.5636 10.0738 24.0726 8.17692C21.5817 6.28007 18.834 4.95487 16.3944 4.46117C14.5711 4.07141 12.8506 4.14936 11.618 4.9029C11.5923 4.9029 11.5666 4.92889 11.5666 4.92889C11.5666 4.92889 11.5409 4.92889 11.5409 4.95487C11.4896 4.98085 11.4382 5.00684 11.4125 5.05881C11.3355 5.11078 11.2584 5.18873 11.1814 5.2407C11.0016 5.3966 10.8219 5.57849 10.6678 5.78637C9.5379 7.31944 9.79469 9.55408 10.8476 11.7627C11.9261 13.9974 13.8521 16.336 16.343 18.2328C17.6013 19.1942 18.9367 19.9998 20.2977 20.6234C21.6587 21.247 23.0198 21.7147 24.2781 21.9486C25.5621 22.2084 26.7433 22.2604 27.7705 22.0525C28.7977 21.8446 29.6708 21.4029 30.2615 20.6234C30.3642 20.4935 30.4669 20.3375 30.5439 20.1816C31.3657 18.6226 30.9291 16.5958 29.8506 14.621ZM29.6195 20.0777C29.2086 20.6494 28.5409 21.0131 27.6421 21.195C26.7433 21.3769 25.6648 21.3249 24.4578 21.0911C22.0439 20.6234 19.2705 19.3501 16.8309 17.5312C14.4171 15.7124 12.5681 13.4517 11.5666 11.373C10.5394 9.26826 10.4624 7.42337 11.3098 6.28007C12.1316 5.13676 13.9035 4.79897 16.189 5.26668C18.4745 5.7344 21.1195 7.00763 23.5334 8.85251C25.9473 10.6974 27.9503 12.932 29.1059 15.0368C29.7992 16.284 30.1331 17.4273 30.1331 18.3887C30.1331 19.0383 29.979 19.61 29.6195 20.0777Z" fill="white"/>
|
|
13
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.2056 16.4658C27.1029 15.8942 26.8461 15.2446 26.4609 14.595C25.6905 13.2958 24.4065 11.8926 22.7887 10.6714C21.1965 9.4501 19.5274 8.59262 18.0893 8.25483C17.3703 8.07294 16.7026 8.02097 16.1376 8.09892C15.7011 8.15089 15.2902 8.33278 14.982 8.59262C14.8793 8.67057 14.8023 8.74853 14.7252 8.85246C14.3914 9.2942 14.3144 9.83987 14.3914 10.4115C14.4684 10.9832 14.6996 11.6328 15.0591 12.2824C15.7781 13.5816 17.0364 15.0107 18.6542 16.232C20.2721 17.4533 21.9926 18.2847 23.482 18.6225C24.2268 18.8044 24.9201 18.8564 25.4851 18.7784C26.0757 18.7005 26.5893 18.4666 26.9231 18.0249C26.9488 17.9729 26.9745 17.947 27.0002 17.895C27.2313 17.5052 27.2826 16.9855 27.2056 16.4658ZM26.3068 17.6092C26.1271 17.843 25.8189 17.9989 25.3567 18.0769C24.8944 18.1288 24.3038 18.1029 23.6104 17.921C22.2494 17.5832 20.6059 16.8036 19.0651 15.6344C17.5243 14.4651 16.3431 13.1399 15.6754 11.9186C15.3416 11.321 15.1618 10.7753 15.0848 10.3076C15.0334 9.83987 15.1104 9.52806 15.2902 9.2942C15.47 9.06034 15.7524 8.87845 16.2147 8.82648C16.6512 8.77451 17.2162 8.8005 17.8839 8.9564C18.5259 9.11231 19.2706 9.39813 20.0153 9.7879C20.76 10.1777 21.5561 10.6714 22.3008 11.269C23.8416 12.4383 25.0742 13.7635 25.7932 14.9588C26.1527 15.5564 26.3582 16.1021 26.4352 16.5698C26.5379 17.0635 26.4609 17.4013 26.3068 17.6092Z" fill="white"/>
|
|
14
|
+
</g>
|
|
15
|
+
<defs>
|
|
16
|
+
<clipPath id="clip0_137_213">
|
|
17
|
+
<rect width="34" height="33" fill="white" transform="translate(0.781128 0.66748)"/>
|
|
18
|
+
</clipPath>
|
|
19
|
+
</defs>
|
|
20
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card>
|
|
3
|
+
<v-card-title class="d-flex flex-row justify-center">
|
|
4
|
+
<vol-view-full-logo />
|
|
5
|
+
</v-card-title>
|
|
6
|
+
<v-card-text>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img
|
|
9
|
+
src="../assets/KitwareHeadAndNeck.jpg"
|
|
10
|
+
alt="Head and neck CT rendering"
|
|
11
|
+
style="width: 200px"
|
|
12
|
+
align="center"
|
|
13
|
+
/><br />
|
|
14
|
+
</p>
|
|
15
|
+
<p>
|
|
16
|
+
<a
|
|
17
|
+
rel="noopener noreferrer"
|
|
18
|
+
target="_blank"
|
|
19
|
+
href="https://volview.kitware.com/"
|
|
20
|
+
>
|
|
21
|
+
VolView
|
|
22
|
+
</a>
|
|
23
|
+
is an open-source web application developed at
|
|
24
|
+
<a
|
|
25
|
+
rel="noopener noreferrer"
|
|
26
|
+
target="_blank"
|
|
27
|
+
href="https://kitware.com/"
|
|
28
|
+
>
|
|
29
|
+
Kitware
|
|
30
|
+
</a>
|
|
31
|
+
for visualizing and annotating medical images. It key features include:
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
<ul>
|
|
35
|
+
<li>Fast: Drag-and-drop DICOM files for quick viewing</li>
|
|
36
|
+
<li>
|
|
37
|
+
Beautiful: Cinematic volume rendering to generate high-quality 3D
|
|
38
|
+
visualizations
|
|
39
|
+
</li>
|
|
40
|
+
<li>
|
|
41
|
+
Friendly: Familiar radiological image visualization and annotation
|
|
42
|
+
tools
|
|
43
|
+
</li>
|
|
44
|
+
<li>
|
|
45
|
+
Secure: Your data stays on your machine. No cloud services or data
|
|
46
|
+
servers are used.
|
|
47
|
+
</li>
|
|
48
|
+
</ul>
|
|
49
|
+
<br />
|
|
50
|
+
VolView is freely available for research, educational, and commercial
|
|
51
|
+
applications. It is built using a variety of open-source toolks created by
|
|
52
|
+
Kitware, such as
|
|
53
|
+
<a
|
|
54
|
+
rel="noopener noreferrer"
|
|
55
|
+
target="_blank"
|
|
56
|
+
href="https://github.com/InsightSoftwareConsortium/itk-wasm/"
|
|
57
|
+
>
|
|
58
|
+
itk-wasm
|
|
59
|
+
</a>
|
|
60
|
+
for DICOM I/O and image processing, and
|
|
61
|
+
<a
|
|
62
|
+
rel="noopener noreferrer"
|
|
63
|
+
target="_blank"
|
|
64
|
+
href="https://github.com/Kitware/vtk-js"
|
|
65
|
+
>
|
|
66
|
+
vtk.js
|
|
67
|
+
</a>
|
|
68
|
+
for in-browser scientific visualization.
|
|
69
|
+
<br />
|
|
70
|
+
<br />
|
|
71
|
+
Want help customizing VolView or creating a new web-based visualization
|
|
72
|
+
application?
|
|
73
|
+
<a
|
|
74
|
+
rel-="noopener noreferrer"
|
|
75
|
+
target="_blank"
|
|
76
|
+
href="https://www.kitware.com/contact/project/"
|
|
77
|
+
>Contact Kitware!</a
|
|
78
|
+
>
|
|
79
|
+
<br />
|
|
80
|
+
<br />
|
|
81
|
+
VolView source code:
|
|
82
|
+
<ul>
|
|
83
|
+
<li>
|
|
84
|
+
<a
|
|
85
|
+
rel="noopener noreferrer"
|
|
86
|
+
target="_blank"
|
|
87
|
+
href="https://github.com/Kitware/VolView"
|
|
88
|
+
>
|
|
89
|
+
https://github.com/Kitware/VolView
|
|
90
|
+
</a>
|
|
91
|
+
</li>
|
|
92
|
+
</ul>
|
|
93
|
+
<br />
|
|
94
|
+
VolView bug reports and feature requests:
|
|
95
|
+
<ul>
|
|
96
|
+
<li>
|
|
97
|
+
<a
|
|
98
|
+
rel="noopener noreferrer"
|
|
99
|
+
target="_blank"
|
|
100
|
+
href="https://github.com/Kitware/VolView/issues"
|
|
101
|
+
>
|
|
102
|
+
https://github.com/Kitware/VolView/issues
|
|
103
|
+
</a>
|
|
104
|
+
</li>
|
|
105
|
+
</ul>
|
|
106
|
+
<br />
|
|
107
|
+
This work was funded, in part, by the NIH via NIBIB and NIGMS R01EB021396,
|
|
108
|
+
NIBIB R01EB014955, NCI R01CA220681, and NINDS R42NS086295
|
|
109
|
+
<br />
|
|
110
|
+
<br />
|
|
111
|
+
Sample data provided by the following sources:
|
|
112
|
+
<ul>
|
|
113
|
+
<li>
|
|
114
|
+
PROSTATEx Challenge Data: Geert Litjens, Oscar Debats, Jelle Barentsz,
|
|
115
|
+
Nico Karssemeijer, and Henkjan Huisman. "ProstateX Challenge data",
|
|
116
|
+
The Cancer Imaging Archive (2017). DOI: 10.7937/K9TCIA.2017.MURS5CL
|
|
117
|
+
(<a
|
|
118
|
+
rel="noopener noreferrer"
|
|
119
|
+
target="_blank"
|
|
120
|
+
href="https://wiki.cancerimagingarchive.net/pages/viewpage.action?pageId=23691656"
|
|
121
|
+
>TCIA</a
|
|
122
|
+
>)
|
|
123
|
+
</li>
|
|
124
|
+
<li>
|
|
125
|
+
MRA Head and Neck: Test case 98890234 from the "Patient Contributed
|
|
126
|
+
Image Repository" (<a
|
|
127
|
+
rel="noopener noreferrer"
|
|
128
|
+
target="_blank"
|
|
129
|
+
href="http://www.pcir.org/researchers/98890234_20030505_MR.html"
|
|
130
|
+
>PCIR.org</a
|
|
131
|
+
>)
|
|
132
|
+
</li>
|
|
133
|
+
<li>
|
|
134
|
+
3D ultrasound of a fetus: Sample data from
|
|
135
|
+
<a
|
|
136
|
+
rel="noopener noreferrer"
|
|
137
|
+
target="_blank"
|
|
138
|
+
href="http://tomovision.comi"
|
|
139
|
+
>tomovision.com</a
|
|
140
|
+
>
|
|
141
|
+
</li>
|
|
142
|
+
</ul>
|
|
143
|
+
</v-card-text>
|
|
144
|
+
</v-card>
|
|
145
|
+
</template>
|
|
146
|
+
|
|
147
|
+
<script>
|
|
148
|
+
import { defineComponent } from '@vue/composition-api';
|
|
149
|
+
import VolViewFullLogo from './icons/VolViewFullLogo.vue';
|
|
150
|
+
|
|
151
|
+
export default defineComponent({
|
|
152
|
+
name: 'AboutBox',
|
|
153
|
+
components: {
|
|
154
|
+
VolViewFullLogo,
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
</script>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div id="ai-module" class="mx-2 fill-height">
|
|
3
|
+
<div id="submodule-select">
|
|
4
|
+
<v-select
|
|
5
|
+
v-model="currentSubModule"
|
|
6
|
+
:items="subModules"
|
|
7
|
+
item-text="name"
|
|
8
|
+
return-object
|
|
9
|
+
dense
|
|
10
|
+
filled
|
|
11
|
+
single-line
|
|
12
|
+
hide-details
|
|
13
|
+
placeholder="Select a module"
|
|
14
|
+
class="no-select"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
<div id="component">
|
|
18
|
+
<template v-if="currentSubModule">
|
|
19
|
+
<component :is="currentSubModule.component" />
|
|
20
|
+
</template>
|
|
21
|
+
<div v-else>No submodule selected</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script>
|
|
27
|
+
import { defineComponent, ref } from '@vue/composition-api';
|
|
28
|
+
|
|
29
|
+
import SpleenModule from './SpleenModule.vue';
|
|
30
|
+
|
|
31
|
+
export default defineComponent({
|
|
32
|
+
name: 'AiModule',
|
|
33
|
+
setup() {
|
|
34
|
+
const currentSubModule = ref(null);
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
currentSubModule,
|
|
38
|
+
subModules: [{ name: 'Spleen Segmentation', component: SpleenModule }],
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<style scoped>
|
|
45
|
+
#ai-module {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-flow: column;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#submodule-select {
|
|
51
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
|
52
|
+
padding-bottom: 12px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#component {
|
|
56
|
+
flex: 2;
|
|
57
|
+
margin-top: 12px;
|
|
58
|
+
overflow-y: auto;
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { defineComponent } from '@vue/composition-api';
|
|
3
|
+
import MeasurementsList from './MeasurementsList.vue';
|
|
4
|
+
import LabelmapList from './LabelmapList.vue';
|
|
5
|
+
|
|
6
|
+
export default defineComponent({
|
|
7
|
+
components: {
|
|
8
|
+
MeasurementsList,
|
|
9
|
+
LabelmapList,
|
|
10
|
+
},
|
|
11
|
+
setup() {},
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<div class="overflow-y-auto mx-2 fill-height">
|
|
17
|
+
<v-list dense>
|
|
18
|
+
<v-subheader class="annot-subheader">Measurements</v-subheader>
|
|
19
|
+
<measurements-list />
|
|
20
|
+
<v-subheader class="annot-subheader">Labelmaps</v-subheader>
|
|
21
|
+
<labelmap-list />
|
|
22
|
+
</v-list>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<style scoped>
|
|
27
|
+
.annot-subheader {
|
|
28
|
+
margin: 8px 0;
|
|
29
|
+
}
|
|
30
|
+
.theme--dark.annot-subheader {
|
|
31
|
+
background: rgba(255, 255, 255, 0.08);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.theme--light.annot-subheader {
|
|
35
|
+
background: rgba(0, 0, 0, 0.08);
|
|
36
|
+
}
|
|
37
|
+
</style>
|