melage 0.0.65__py3-none-any.whl
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.
- melage/__init__.py +16 -0
- melage/cli.py +4 -0
- melage/graphics/GLGraphicsItem.py +286 -0
- melage/graphics/GLViewWidget.py +595 -0
- melage/graphics/Transform3D.py +55 -0
- melage/graphics/__init__.py +8 -0
- melage/graphics/functions.py +101 -0
- melage/graphics/items/GLAxisItem.py +149 -0
- melage/graphics/items/GLGridItem.py +178 -0
- melage/graphics/items/GLPolygonItem.py +77 -0
- melage/graphics/items/GLScatterPlotItem.py +135 -0
- melage/graphics/items/GLVolumeItem.py +280 -0
- melage/graphics/items/GLVolumeItem_b.py +237 -0
- melage/graphics/items/__init__.py +0 -0
- melage/graphics/shaders.py +202 -0
- melage/main.py +270 -0
- melage/requirements22.txt +25 -0
- melage/requirements_old.txt +28 -0
- melage/resource/0circle.png +0 -0
- melage/resource/0circle_faded.png +0 -0
- melage/resource/3d.png +0 -0
- melage/resource/3d.psd +0 -0
- melage/resource/3dFaded.png +0 -0
- melage/resource/Eraser.png +0 -0
- melage/resource/EraserFaded.png +0 -0
- melage/resource/EraserX.png +0 -0
- melage/resource/EraserXFaded.png +0 -0
- melage/resource/Eraser_icon.svg +79 -0
- melage/resource/Hand.png +0 -0
- melage/resource/HandIcons_0.png +0 -0
- melage/resource/Hand_IX.png +0 -0
- melage/resource/Hand_IXFaded.png +0 -0
- melage/resource/Handsqueezed.png +0 -0
- melage/resource/Handwriting (copy).png +0 -0
- melage/resource/Handwriting.png +0 -0
- melage/resource/HandwritingMinus.png +0 -0
- melage/resource/HandwritingMinusX.png +0 -0
- melage/resource/HandwritingPlus.png +0 -0
- melage/resource/HandwritingPlusX.png +0 -0
- melage/resource/Move_icon.svg +8 -0
- melage/resource/PngItem_2422924.png +0 -0
- melage/resource/about.png +0 -0
- melage/resource/about_logo.png +0 -0
- melage/resource/about_logo0.png +0 -0
- melage/resource/action_check.png +0 -0
- melage/resource/action_check_OFF.png +0 -0
- melage/resource/arrow).png +0 -0
- melage/resource/arrow.png +0 -0
- melage/resource/arrowFaded.png +0 -0
- melage/resource/arrow_org.png +0 -0
- melage/resource/arrow_org.png.png +0 -0
- melage/resource/arrows.png +0 -0
- melage/resource/authors.mp4 +0 -0
- melage/resource/box.png +0 -0
- melage/resource/check-image-icon-0.jpg +0 -0
- melage/resource/circle.png +0 -0
- melage/resource/circle_faded.png +0 -0
- melage/resource/circle_or.png +0 -0
- melage/resource/close.png +0 -0
- melage/resource/close_bg.png +0 -0
- melage/resource/color/Simple.txt +18 -0
- melage/resource/color/Tissue.txt +24 -0
- melage/resource/color/Tissue12.txt +27 -0
- melage/resource/color/albert_LUT.txt +102 -0
- melage/resource/color/mcrib_LUT.txt +102 -0
- melage/resource/color/pediatric1.txt +29 -0
- melage/resource/color/pediatric1_old.txt +27 -0
- melage/resource/color/pediatric2.txt +87 -0
- melage/resource/color/pediatric3.txt +29 -0
- melage/resource/color/pediatrics (copy).csv +103 -0
- melage/resource/color/tissue_seg.txt +4 -0
- melage/resource/contour.png +0 -0
- melage/resource/contour.svg +2 -0
- melage/resource/contourFaded.png +0 -0
- melage/resource/contourX.png +0 -0
- melage/resource/contourXFaded.png +0 -0
- melage/resource/dti.png +0 -0
- melage/resource/dti0.png +0 -0
- melage/resource/dti222.png +0 -0
- melage/resource/dti_or.png +0 -0
- melage/resource/eco.png +0 -0
- melage/resource/eco22.png +0 -0
- melage/resource/eco_old.png +0 -0
- melage/resource/eco_or.png +0 -0
- melage/resource/eco_or2.png +0 -0
- melage/resource/eco_seg.png +0 -0
- melage/resource/eco_seg_old.png +0 -0
- melage/resource/export.png +0 -0
- melage/resource/hand-grab-icon-10.jpg +0 -0
- melage/resource/hand-grab-icon-25.jpg +0 -0
- melage/resource/info.png +0 -0
- melage/resource/line.png +0 -0
- melage/resource/linefaded.png +0 -0
- melage/resource/load.png +0 -0
- melage/resource/main.ico +0 -0
- melage/resource/manual_images/3D_rightc.png +0 -0
- melage/resource/manual_images/3D_rightc_goto.png +0 -0
- melage/resource/manual_images/3D_rightc_paint.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_draw1.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_draw2.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render2.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render3.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render4.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render5.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render6.png +0 -0
- melage/resource/manual_images/3D_rightc_seg.png +0 -0
- melage/resource/manual_images/exit_toolbar.png +0 -0
- melage/resource/manual_images/load_image_file.png +0 -0
- melage/resource/manual_images/load_image_file_openp.png +0 -0
- melage/resource/manual_images/main_page.png +0 -0
- melage/resource/manual_images/menu_file.png +0 -0
- melage/resource/manual_images/menu_file_export.png +0 -0
- melage/resource/manual_images/menu_file_import.png +0 -0
- melage/resource/manual_images/menu_file_settings.png +0 -0
- melage/resource/manual_images/menu_file_ss.png +0 -0
- melage/resource/manual_images/open_save_load.png +0 -0
- melage/resource/manual_images/panning_toolbar.png +0 -0
- melage/resource/manual_images/segmentation_toolbar.png +0 -0
- melage/resource/manual_images/tab_mri.png +0 -0
- melage/resource/manual_images/tab_us.png +0 -0
- melage/resource/manual_images/tabs.png +0 -0
- melage/resource/manual_images/toolbar_tools.png +0 -0
- melage/resource/manual_images/tools_basic.png +0 -0
- melage/resource/manual_images/tools_bet.png +0 -0
- melage/resource/manual_images/tools_cs.png +0 -0
- melage/resource/manual_images/tools_deepbet.png +0 -0
- melage/resource/manual_images/tools_imageinfo.png +0 -0
- melage/resource/manual_images/tools_maskO.png +0 -0
- melage/resource/manual_images/tools_masking.png +0 -0
- melage/resource/manual_images/tools_n4b.png +0 -0
- melage/resource/manual_images/tools_resize.png +0 -0
- melage/resource/manual_images/tools_ruler.png +0 -0
- melage/resource/manual_images/tools_seg.png +0 -0
- melage/resource/manual_images/tools_threshold.png +0 -0
- melage/resource/manual_images/tools_tools.png +0 -0
- melage/resource/manual_images/widget_color.png +0 -0
- melage/resource/manual_images/widget_color_add.png +0 -0
- melage/resource/manual_images/widget_color_add2.png +0 -0
- melage/resource/manual_images/widget_color_additional.png +0 -0
- melage/resource/manual_images/widget_images.png +0 -0
- melage/resource/manual_images/widget_images2.png +0 -0
- melage/resource/manual_images/widget_images3.png +0 -0
- melage/resource/manual_images/widget_marker.png +0 -0
- melage/resource/manual_images/widget_mri.png +0 -0
- melage/resource/manual_images/widget_mri2.png +0 -0
- melage/resource/manual_images/widget_segintensity.png +0 -0
- melage/resource/manual_images/widget_tab_mutualview.png +0 -0
- melage/resource/manual_images/widget_tab_mutualview2.png +0 -0
- melage/resource/manual_images/widget_table.png +0 -0
- melage/resource/manual_images/widget_table2.png +0 -0
- melage/resource/manual_images/widget_us.png +0 -0
- melage/resource/melage_top.ico +0 -0
- melage/resource/melage_top.png +0 -0
- melage/resource/melage_top0.png +0 -0
- melage/resource/melage_top1.png +0 -0
- melage/resource/melage_top4.png +0 -0
- melage/resource/mri (copy).png +0 -0
- melage/resource/mri.png +0 -0
- melage/resource/mri0.png +0 -0
- melage/resource/mri000.png +0 -0
- melage/resource/mri22.png +0 -0
- melage/resource/mri_big.png +0 -0
- melage/resource/mri_old.png +0 -0
- melage/resource/mri_seg.png +0 -0
- melage/resource/mri_seg_old.png +0 -0
- melage/resource/new.png +0 -0
- melage/resource/open.png +0 -0
- melage/resource/open2.png +0 -0
- melage/resource/pan.png +0 -0
- melage/resource/pencil.png +0 -0
- melage/resource/pencilFaded.png +0 -0
- melage/resource/points.png +0 -0
- melage/resource/pointsFaded.png +0 -0
- melage/resource/rotate.png +0 -0
- melage/resource/ruler.png +0 -0
- melage/resource/rulerFaded.png +0 -0
- melage/resource/s.png +0 -0
- melage/resource/s.psd +0 -0
- melage/resource/save.png +0 -0
- melage/resource/saveas.png +0 -0
- melage/resource/seg_mri.png +0 -0
- melage/resource/seg_mri2.png +0 -0
- melage/resource/settings.png +0 -0
- melage/resource/synch.png +0 -0
- melage/resource/synchFaded.png +0 -0
- melage/resource/theme/rc/.keep +1 -0
- melage/resource/theme/rc/arrow_down.png +0 -0
- melage/resource/theme/rc/arrow_down@2x.png +0 -0
- melage/resource/theme/rc/arrow_down_disabled.png +0 -0
- melage/resource/theme/rc/arrow_down_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_down_focus.png +0 -0
- melage/resource/theme/rc/arrow_down_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_down_pressed.png +0 -0
- melage/resource/theme/rc/arrow_down_pressed@2x.png +0 -0
- melage/resource/theme/rc/arrow_left.png +0 -0
- melage/resource/theme/rc/arrow_left@2x.png +0 -0
- melage/resource/theme/rc/arrow_left_disabled.png +0 -0
- melage/resource/theme/rc/arrow_left_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_left_focus.png +0 -0
- melage/resource/theme/rc/arrow_left_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_left_pressed.png +0 -0
- melage/resource/theme/rc/arrow_left_pressed@2x.png +0 -0
- melage/resource/theme/rc/arrow_right.png +0 -0
- melage/resource/theme/rc/arrow_right@2x.png +0 -0
- melage/resource/theme/rc/arrow_right_disabled.png +0 -0
- melage/resource/theme/rc/arrow_right_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_right_focus.png +0 -0
- melage/resource/theme/rc/arrow_right_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_right_pressed.png +0 -0
- melage/resource/theme/rc/arrow_right_pressed@2x.png +0 -0
- melage/resource/theme/rc/arrow_up.png +0 -0
- melage/resource/theme/rc/arrow_up@2x.png +0 -0
- melage/resource/theme/rc/arrow_up_disabled.png +0 -0
- melage/resource/theme/rc/arrow_up_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_up_focus.png +0 -0
- melage/resource/theme/rc/arrow_up_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_up_pressed.png +0 -0
- melage/resource/theme/rc/arrow_up_pressed@2x.png +0 -0
- melage/resource/theme/rc/base_icon.png +0 -0
- melage/resource/theme/rc/base_icon@2x.png +0 -0
- melage/resource/theme/rc/base_icon_disabled.png +0 -0
- melage/resource/theme/rc/base_icon_disabled@2x.png +0 -0
- melage/resource/theme/rc/base_icon_focus.png +0 -0
- melage/resource/theme/rc/base_icon_focus@2x.png +0 -0
- melage/resource/theme/rc/base_icon_pressed.png +0 -0
- melage/resource/theme/rc/base_icon_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_closed.png +0 -0
- melage/resource/theme/rc/branch_closed@2x.png +0 -0
- melage/resource/theme/rc/branch_closed_disabled.png +0 -0
- melage/resource/theme/rc/branch_closed_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_closed_focus.png +0 -0
- melage/resource/theme/rc/branch_closed_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_closed_pressed.png +0 -0
- melage/resource/theme/rc/branch_closed_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_end.png +0 -0
- melage/resource/theme/rc/branch_end@2x.png +0 -0
- melage/resource/theme/rc/branch_end_disabled.png +0 -0
- melage/resource/theme/rc/branch_end_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_end_focus.png +0 -0
- melage/resource/theme/rc/branch_end_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_end_pressed.png +0 -0
- melage/resource/theme/rc/branch_end_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_line.png +0 -0
- melage/resource/theme/rc/branch_line@2x.png +0 -0
- melage/resource/theme/rc/branch_line_disabled.png +0 -0
- melage/resource/theme/rc/branch_line_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_line_focus.png +0 -0
- melage/resource/theme/rc/branch_line_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_line_pressed.png +0 -0
- melage/resource/theme/rc/branch_line_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_more.png +0 -0
- melage/resource/theme/rc/branch_more@2x.png +0 -0
- melage/resource/theme/rc/branch_more_disabled.png +0 -0
- melage/resource/theme/rc/branch_more_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_more_focus.png +0 -0
- melage/resource/theme/rc/branch_more_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_more_pressed.png +0 -0
- melage/resource/theme/rc/branch_more_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_open.png +0 -0
- melage/resource/theme/rc/branch_open@2x.png +0 -0
- melage/resource/theme/rc/branch_open_disabled.png +0 -0
- melage/resource/theme/rc/branch_open_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_open_focus.png +0 -0
- melage/resource/theme/rc/branch_open_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_open_pressed.png +0 -0
- melage/resource/theme/rc/branch_open_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked.png +0 -0
- melage/resource/theme/rc/checkbox_checked0.png +0 -0
- melage/resource/theme/rc/checkbox_checked@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_checked@2x000.png.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate@2x.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_disabled.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_disabled@2x.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_focus.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_focus@2x.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_pressed.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked@2x00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled@2x00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus@2x00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed@2x00.png +0 -0
- melage/resource/theme/rc/line_horizontal.png +0 -0
- melage/resource/theme/rc/line_horizontal@2x.png +0 -0
- melage/resource/theme/rc/line_horizontal_disabled.png +0 -0
- melage/resource/theme/rc/line_horizontal_disabled@2x.png +0 -0
- melage/resource/theme/rc/line_horizontal_focus.png +0 -0
- melage/resource/theme/rc/line_horizontal_focus@2x.png +0 -0
- melage/resource/theme/rc/line_horizontal_pressed.png +0 -0
- melage/resource/theme/rc/line_horizontal_pressed@2x.png +0 -0
- melage/resource/theme/rc/line_vertical.png +0 -0
- melage/resource/theme/rc/line_vertical@2x.png +0 -0
- melage/resource/theme/rc/line_vertical_disabled.png +0 -0
- melage/resource/theme/rc/line_vertical_disabled@2x.png +0 -0
- melage/resource/theme/rc/line_vertical_focus.png +0 -0
- melage/resource/theme/rc/line_vertical_focus@2x.png +0 -0
- melage/resource/theme/rc/line_vertical_pressed.png +0 -0
- melage/resource/theme/rc/line_vertical_pressed@2x.png +0 -0
- melage/resource/theme/rc/radio_checked.png +0 -0
- melage/resource/theme/rc/radio_checked@2x.png +0 -0
- melage/resource/theme/rc/radio_checked_disabled.png +0 -0
- melage/resource/theme/rc/radio_checked_disabled@2x.png +0 -0
- melage/resource/theme/rc/radio_checked_focus.png +0 -0
- melage/resource/theme/rc/radio_checked_focus@2x.png +0 -0
- melage/resource/theme/rc/radio_checked_pressed.png +0 -0
- melage/resource/theme/rc/radio_checked_pressed@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked.png +0 -0
- melage/resource/theme/rc/radio_unchecked@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked_disabled.png +0 -0
- melage/resource/theme/rc/radio_unchecked_disabled@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked_focus.png +0 -0
- melage/resource/theme/rc/radio_unchecked_focus@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked_pressed.png +0 -0
- melage/resource/theme/rc/radio_unchecked_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_focus.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_focus.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_focus.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_focus.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_pressed@2x.png +0 -0
- melage/resource/theme/rc/transparent.png +0 -0
- melage/resource/theme/rc/transparent@2x.png +0 -0
- melage/resource/theme/rc/transparent_disabled.png +0 -0
- melage/resource/theme/rc/transparent_disabled@2x.png +0 -0
- melage/resource/theme/rc/transparent_focus.png +0 -0
- melage/resource/theme/rc/transparent_focus@2x.png +0 -0
- melage/resource/theme/rc/transparent_pressed.png +0 -0
- melage/resource/theme/rc/transparent_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_close.png +0 -0
- melage/resource/theme/rc/window_close@2x.png +0 -0
- melage/resource/theme/rc/window_close_disabled.png +0 -0
- melage/resource/theme/rc/window_close_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_close_focus.png +0 -0
- melage/resource/theme/rc/window_close_focus@2x.png +0 -0
- melage/resource/theme/rc/window_close_pressed.png +0 -0
- melage/resource/theme/rc/window_close_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_grip.png +0 -0
- melage/resource/theme/rc/window_grip@2x.png +0 -0
- melage/resource/theme/rc/window_grip_disabled.png +0 -0
- melage/resource/theme/rc/window_grip_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_grip_focus.png +0 -0
- melage/resource/theme/rc/window_grip_focus@2x.png +0 -0
- melage/resource/theme/rc/window_grip_pressed.png +0 -0
- melage/resource/theme/rc/window_grip_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_minimize.png +0 -0
- melage/resource/theme/rc/window_minimize@2x.png +0 -0
- melage/resource/theme/rc/window_minimize_disabled.png +0 -0
- melage/resource/theme/rc/window_minimize_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_minimize_focus.png +0 -0
- melage/resource/theme/rc/window_minimize_focus@2x.png +0 -0
- melage/resource/theme/rc/window_minimize_pressed.png +0 -0
- melage/resource/theme/rc/window_minimize_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_undock.png +0 -0
- melage/resource/theme/rc/window_undock@2x.png +0 -0
- melage/resource/theme/rc/window_undock_disabled.png +0 -0
- melage/resource/theme/rc/window_undock_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_undock_focus.png +0 -0
- melage/resource/theme/rc/window_undock_focus@2x.png +0 -0
- melage/resource/theme/rc/window_undock_pressed.png +0 -0
- melage/resource/theme/rc/window_undock_pressed@2x.png +0 -0
- melage/resource/theme/style.qss +2223 -0
- melage/resource/tract.png +0 -0
- melage/resource/view1.png +0 -0
- melage/resource/view1_eco.png +0 -0
- melage/resource/view1_mri.png +0 -0
- melage/resource/view1_seg.png +0 -0
- melage/resource/view2.png +0 -0
- melage/resource/view2_seg.png +0 -0
- melage/resource/w.png +0 -0
- melage/resource/zoom_in.png +0 -0
- melage/resource/zoom_inFaded.png +0 -0
- melage/resource/zoom_out.png +0 -0
- melage/resource/zoom_outFaded.png +0 -0
- melage/some_notes.txt +3 -0
- melage/utils/DispalyIm.py +2788 -0
- melage/utils/GMM.py +720 -0
- melage/utils/Shaders_120.py +257 -0
- melage/utils/Shaders_330.py +314 -0
- melage/utils/Shaders_bu.py +314 -0
- melage/utils/__init__0.py +7 -0
- melage/utils/brain_extraction_helper.py +234 -0
- melage/utils/custom_QScrollBar.py +61 -0
- melage/utils/glScientific.py +1554 -0
- melage/utils/glScientific_bc.py +1585 -0
- melage/utils/readData.py +1061 -0
- melage/utils/registration.py +512 -0
- melage/utils/source_folder.py +18 -0
- melage/utils/utils.py +3808 -0
- melage/version.txt +1 -0
- melage/widgets/ApplyMask.py +212 -0
- melage/widgets/ChangeSystem.py +152 -0
- melage/widgets/DeepLModels/InfantSegment/Unet.py +464 -0
- melage/widgets/DeepLModels/NPP/dataset/mri_dataset_affine.py +149 -0
- melage/widgets/DeepLModels/NPP/models/checkpoints/npp_v1.pth.py +0 -0
- melage/widgets/DeepLModels/NPP/models/losses.py +146 -0
- melage/widgets/DeepLModels/NPP/models/model.py +272 -0
- melage/widgets/DeepLModels/NPP/models/utils.py +303 -0
- melage/widgets/DeepLModels/NPP/npp.py +116 -0
- melage/widgets/DeepLModels/NPP/requirements.txt +8 -0
- melage/widgets/DeepLModels/NPP/train/train.py +116 -0
- melage/widgets/DeepLModels/Unet3DAtt.py +657 -0
- melage/widgets/DeepLModels/Unet3D_basic.py +648 -0
- melage/widgets/DeepLModels/new_unet.py +652 -0
- melage/widgets/DeepLModels/new_unet_old.py +639 -0
- melage/widgets/DeepLModels/new_unet_old2.py +658 -0
- melage/widgets/HistImage.py +153 -0
- melage/widgets/ImageThresholding.py +222 -0
- melage/widgets/MaskOperations.py +147 -0
- melage/widgets/N4Dialog.py +241 -0
- melage/widgets/Segmentation/FCM.py +1553 -0
- melage/widgets/Segmentation/__init__.py +588 -0
- melage/widgets/Segmentation/utils.py +417 -0
- melage/widgets/SemiAutoSeg.py +666 -0
- melage/widgets/Synthstrip.py +141 -0
- melage/widgets/__init__0.py +5 -0
- melage/widgets/about.py +246 -0
- melage/widgets/activation.py +437 -0
- melage/widgets/activator.py +147 -0
- melage/widgets/be_dl.py +409 -0
- melage/widgets/be_dl_unet3d.py +441 -0
- melage/widgets/brain_extraction.py +855 -0
- melage/widgets/brain_extraction_dl.py +887 -0
- melage/widgets/brain_extraction_dl_bu.py +869 -0
- melage/widgets/colorwidget.py +100 -0
- melage/widgets/dockWidgets.py +2005 -0
- melage/widgets/enhanceImWidget.py +109 -0
- melage/widgets/fileDialog_widget.py +275 -0
- melage/widgets/iminfo.py +346 -0
- melage/widgets/mainwindow_widget.py +6775 -0
- melage/widgets/melageAbout.py +123 -0
- melage/widgets/openglWidgets.py +556 -0
- melage/widgets/registrationWidget.py +342 -0
- melage/widgets/repeat_widget.py +74 -0
- melage/widgets/screenshot_widget.py +138 -0
- melage/widgets/settings_widget.py +77 -0
- melage/widgets/tranformationWidget.py +275 -0
- melage-0.0.65.dist-info/METADATA +742 -0
- melage-0.0.65.dist-info/RECORD +501 -0
- melage-0.0.65.dist-info/WHEEL +5 -0
- melage-0.0.65.dist-info/entry_points.txt +2 -0
- melage-0.0.65.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Copyright (c) 2021-2022, InterDigital Communications, Inc
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
|
5
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
6
|
+
# below) provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
9
|
+
# this list of conditions and the following disclaimer.
|
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
# and/or other materials provided with the distribution.
|
|
13
|
+
# * Neither the name of InterDigital Communications, Inc nor the names of its
|
|
14
|
+
# contributors may be used to endorse or promote products derived from this
|
|
15
|
+
# software without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
18
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
19
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
|
20
|
+
# NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
21
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
22
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
23
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
24
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
25
|
+
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
26
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
27
|
+
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
28
|
+
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
+
|
|
30
|
+
import torch
|
|
31
|
+
import torch.nn as nn
|
|
32
|
+
import torch.nn.functional as F
|
|
33
|
+
import numpy as np
|
|
34
|
+
|
|
35
|
+
def find_named_module(module, query):
|
|
36
|
+
"""Helper function to find a named module. Returns a `nn.Module` or `None`
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
module (nn.Module): the root module
|
|
40
|
+
query (str): the module name to find
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
nn.Module or None
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
return next((m for n, m in module.named_modules() if n == query), None)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def find_named_buffer(module, query):
|
|
50
|
+
"""Helper function to find a named buffer. Returns a `torch.Tensor` or `None`
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
module (nn.Module): the root module
|
|
54
|
+
query (str): the buffer name to find
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
torch.Tensor or None
|
|
58
|
+
"""
|
|
59
|
+
return next((b for n, b in module.named_buffers() if n == query), None)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _update_registered_buffer(
|
|
63
|
+
module,
|
|
64
|
+
buffer_name,
|
|
65
|
+
state_dict_key,
|
|
66
|
+
state_dict,
|
|
67
|
+
policy="resize_if_empty",
|
|
68
|
+
dtype=torch.int,
|
|
69
|
+
):
|
|
70
|
+
new_size = state_dict[state_dict_key].size()
|
|
71
|
+
registered_buf = find_named_buffer(module, buffer_name)
|
|
72
|
+
|
|
73
|
+
if policy in ("resize_if_empty", "resize"):
|
|
74
|
+
if registered_buf is None:
|
|
75
|
+
raise RuntimeError(f'buffer "{buffer_name}" was not registered')
|
|
76
|
+
|
|
77
|
+
if policy == "resize" or registered_buf.numel() == 0:
|
|
78
|
+
registered_buf.resize_(new_size)
|
|
79
|
+
|
|
80
|
+
elif policy == "register":
|
|
81
|
+
if registered_buf is not None:
|
|
82
|
+
raise RuntimeError(f'buffer "{buffer_name}" was already registered')
|
|
83
|
+
|
|
84
|
+
module.register_buffer(buffer_name, torch.empty(new_size, dtype=dtype).fill_(0))
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
raise ValueError(f'Invalid policy "{policy}"')
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def update_registered_buffers(
|
|
91
|
+
module,
|
|
92
|
+
module_name,
|
|
93
|
+
buffer_names,
|
|
94
|
+
state_dict,
|
|
95
|
+
policy="resize_if_empty",
|
|
96
|
+
dtype=torch.int,
|
|
97
|
+
):
|
|
98
|
+
"""Update the registered buffers in a module according to the tensors sized
|
|
99
|
+
in a state_dict.
|
|
100
|
+
|
|
101
|
+
(There's no way in torch to directly load a buffer with a dynamic size)
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
module (nn.Module): the module
|
|
105
|
+
module_name (str): module name in the state dict
|
|
106
|
+
buffer_names (list(str)): list of the buffer names to resize in the module
|
|
107
|
+
state_dict (dict): the state dict
|
|
108
|
+
policy (str): Update policy, choose from
|
|
109
|
+
('resize_if_empty', 'resize', 'register')
|
|
110
|
+
dtype (dtype): Type of buffer to be registered (when policy is 'register')
|
|
111
|
+
"""
|
|
112
|
+
valid_buffer_names = [n for n, _ in module.named_buffers()]
|
|
113
|
+
for buffer_name in buffer_names:
|
|
114
|
+
if buffer_name not in valid_buffer_names:
|
|
115
|
+
raise ValueError(f'Invalid buffer name "{buffer_name}"')
|
|
116
|
+
|
|
117
|
+
for buffer_name in buffer_names:
|
|
118
|
+
_update_registered_buffer(
|
|
119
|
+
module,
|
|
120
|
+
buffer_name,
|
|
121
|
+
f"{module_name}.{buffer_name}",
|
|
122
|
+
state_dict,
|
|
123
|
+
policy,
|
|
124
|
+
dtype,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def conv(in_channels, out_channels, kernel_size=5, stride=2):
|
|
129
|
+
return nn.Conv2d(
|
|
130
|
+
in_channels,
|
|
131
|
+
out_channels,
|
|
132
|
+
kernel_size=kernel_size,
|
|
133
|
+
stride=stride,
|
|
134
|
+
padding=kernel_size // 2,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def deconv(in_channels, out_channels, kernel_size=5, stride=2):
|
|
139
|
+
return nn.ConvTranspose2d(
|
|
140
|
+
in_channels,
|
|
141
|
+
out_channels,
|
|
142
|
+
kernel_size=kernel_size,
|
|
143
|
+
stride=stride,
|
|
144
|
+
output_padding=stride - 1,
|
|
145
|
+
padding=kernel_size // 2,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def quantize_ste(x):
|
|
150
|
+
"""Differentiable quantization via the Straight-Through-Estimator."""
|
|
151
|
+
# STE (straight-through estimator) trick: x_hard - x_soft.detach() + x_soft
|
|
152
|
+
return (torch.round(x) - x).detach() + x
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def gaussian_kernel1d(
|
|
156
|
+
kernel_size: int, sigma: float, device: torch.device, dtype: torch.dtype
|
|
157
|
+
):
|
|
158
|
+
"""1D Gaussian kernel."""
|
|
159
|
+
khalf = (kernel_size - 1) / 2.0
|
|
160
|
+
x = torch.linspace(-khalf, khalf, steps=kernel_size, dtype=dtype, device=device)
|
|
161
|
+
pdf = torch.exp(-0.5 * (x / sigma).pow(2))
|
|
162
|
+
return pdf / pdf.sum()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def gaussian_kernel2d(
|
|
166
|
+
kernel_size: int, sigma: float, device: torch.device, dtype: torch.dtype
|
|
167
|
+
):
|
|
168
|
+
"""2D Gaussian kernel."""
|
|
169
|
+
kernel = gaussian_kernel1d(kernel_size, sigma, device, dtype)
|
|
170
|
+
return torch.mm(kernel[:, None], kernel[None, :])
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def gaussian_blur(x, kernel=None, kernel_size=None, sigma=None):
|
|
174
|
+
"""Apply a 2D gaussian blur on a given image tensor."""
|
|
175
|
+
if kernel is None:
|
|
176
|
+
if kernel_size is None or sigma is None:
|
|
177
|
+
raise RuntimeError("Missing kernel_size or sigma parameters")
|
|
178
|
+
dtype = x.dtype if torch.is_floating_point(x) else torch.float32
|
|
179
|
+
device = x.device
|
|
180
|
+
kernel = gaussian_kernel2d(kernel_size, sigma, device, dtype)
|
|
181
|
+
|
|
182
|
+
padding = kernel.size(0) // 2
|
|
183
|
+
x = F.pad(x, (padding, padding, padding, padding), mode="replicate")
|
|
184
|
+
x = torch.nn.functional.conv2d(
|
|
185
|
+
x,
|
|
186
|
+
kernel.expand(x.size(1), 1, kernel.size(0), kernel.size(1)),
|
|
187
|
+
groups=x.size(1),
|
|
188
|
+
)
|
|
189
|
+
return x
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def meshgrid2d(N: int, C: int, H: int, W: int, device: torch.device):
|
|
193
|
+
"""Create a 2D meshgrid for interpolation."""
|
|
194
|
+
theta = torch.eye(2, 3, device=device).unsqueeze(0).expand(N, 2, 3)
|
|
195
|
+
return F.affine_grid(theta, (N, C, H, W), align_corners=False)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def getscale(data, dst_min, dst_max, f_low=0.0, f_high=0.999):
|
|
201
|
+
"""
|
|
202
|
+
Function to get offset and scale of image intensities to robustly rescale to range dst_min..dst_max.
|
|
203
|
+
Equivalent to how mri_convert conforms images.
|
|
204
|
+
:param np.ndarray data: image data (intensity values)
|
|
205
|
+
:param float dst_min: future minimal intensity value
|
|
206
|
+
:param float dst_max: future maximal intensity value
|
|
207
|
+
:param f_low: robust cropping at low end (0.0 no cropping)
|
|
208
|
+
:param f_high: robust cropping at higher end (0.999 crop one thousandths of high intensity voxels)
|
|
209
|
+
:return: float src_min: (adjusted) offset
|
|
210
|
+
:return: float scale: scale factor
|
|
211
|
+
"""
|
|
212
|
+
# get min and max from source
|
|
213
|
+
src_min = np.min(data)
|
|
214
|
+
src_max = np.max(data)
|
|
215
|
+
|
|
216
|
+
print("Input: min: " + format(src_min) + " max: " + format(src_max))
|
|
217
|
+
|
|
218
|
+
if f_low == 0.0 and f_high == 1.0:
|
|
219
|
+
return src_min, 1.0
|
|
220
|
+
|
|
221
|
+
# compute non-zeros and total vox num
|
|
222
|
+
nz = (np.abs(data) >= 1e-15).sum()
|
|
223
|
+
voxnum = data.shape[0] * data.shape[1] * data.shape[2]
|
|
224
|
+
|
|
225
|
+
# compute histogram
|
|
226
|
+
histosize = 1000
|
|
227
|
+
bin_size = (src_max - src_min) / histosize
|
|
228
|
+
hist, bin_edges = np.histogram(data, histosize)
|
|
229
|
+
|
|
230
|
+
# compute cummulative sum
|
|
231
|
+
cs = np.concatenate(([0], np.cumsum(hist)))
|
|
232
|
+
|
|
233
|
+
# get lower limit
|
|
234
|
+
nth = int(f_low * voxnum)
|
|
235
|
+
idx = np.where(cs < nth)
|
|
236
|
+
|
|
237
|
+
if len(idx[0]) > 0:
|
|
238
|
+
idx = idx[0][-1] + 1
|
|
239
|
+
|
|
240
|
+
else:
|
|
241
|
+
idx = 0
|
|
242
|
+
|
|
243
|
+
src_min = idx * bin_size + src_min
|
|
244
|
+
|
|
245
|
+
# print("bin min: "+format(idx)+" nth: "+format(nth)+" passed: "+format(cs[idx])+"\n")
|
|
246
|
+
# get upper limit
|
|
247
|
+
nth = voxnum - int((1.0 - f_high) * nz)
|
|
248
|
+
idx = np.where(cs >= nth)
|
|
249
|
+
|
|
250
|
+
if len(idx[0]) > 0:
|
|
251
|
+
idx = idx[0][0] - 2
|
|
252
|
+
|
|
253
|
+
else:
|
|
254
|
+
print('ERROR: rescale upper bound not found')
|
|
255
|
+
|
|
256
|
+
src_max = idx * bin_size + src_min
|
|
257
|
+
# print("bin max: "+format(idx)+" nth: "+format(nth)+" passed: "+format(voxnum-cs[idx])+"\n")
|
|
258
|
+
|
|
259
|
+
# scale
|
|
260
|
+
if src_min == src_max:
|
|
261
|
+
scale = 1.0
|
|
262
|
+
|
|
263
|
+
else:
|
|
264
|
+
scale = (dst_max - dst_min) / (src_max - src_min)
|
|
265
|
+
|
|
266
|
+
print("rescale: min: " + format(src_min) + " max: " + format(src_max) + " scale: " + format(scale))
|
|
267
|
+
|
|
268
|
+
return src_min, scale
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def scalecrop(data, dst_min, dst_max, src_min, scale):
|
|
273
|
+
"""
|
|
274
|
+
Function to crop the intensity ranges to specific min and max values
|
|
275
|
+
:param np.ndarray data: Image data (intensity values)
|
|
276
|
+
:param float dst_min: future minimal intensity value
|
|
277
|
+
:param float dst_max: future maximal intensity value
|
|
278
|
+
:param float src_min: minimal value to consider from source (crops below)
|
|
279
|
+
:param float scale: scale value by which source will be shifted
|
|
280
|
+
:return: np.ndarray data_new: scaled image data
|
|
281
|
+
"""
|
|
282
|
+
data_new = dst_min + scale * (data - src_min)
|
|
283
|
+
|
|
284
|
+
# clip
|
|
285
|
+
data_new = np.clip(data_new, dst_min, dst_max)
|
|
286
|
+
print("Output: min: " + format(data_new.min()) + " max: " + format(data_new.max()))
|
|
287
|
+
|
|
288
|
+
return data_new
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def normalize(img):
|
|
292
|
+
src_min, scale = getscale(img.data, 0, 255)
|
|
293
|
+
|
|
294
|
+
if not img.data.dtype == np.dtype(np.uint8):
|
|
295
|
+
new_data = scalecrop(img.data, 0, 255, src_min, scale)
|
|
296
|
+
else:
|
|
297
|
+
new_data = img.data
|
|
298
|
+
|
|
299
|
+
new_img = img
|
|
300
|
+
new_img.data = new_data/255
|
|
301
|
+
|
|
302
|
+
return new_img
|
|
303
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import torch
|
|
4
|
+
import torch
|
|
5
|
+
import torch.nn as nn
|
|
6
|
+
import numpy as np
|
|
7
|
+
import argparse
|
|
8
|
+
import surfa as sf
|
|
9
|
+
import scipy.ndimage
|
|
10
|
+
from models.model import UNet
|
|
11
|
+
from models.utils import normalize
|
|
12
|
+
|
|
13
|
+
description = '''
|
|
14
|
+
Neural Pre-processing (NPP) converts Head MRI images
|
|
15
|
+
to an intensity-normalized, skull-stripped brain in a standard coordi-
|
|
16
|
+
nate space. If you use NPP in your analysis, please cite:
|
|
17
|
+
'''
|
|
18
|
+
|
|
19
|
+
# os.system(f'python npp.py -i {inputfname} -o {outputdir}')
|
|
20
|
+
|
|
21
|
+
# parse command line
|
|
22
|
+
parser = argparse.ArgumentParser(description=description)
|
|
23
|
+
parser.add_argument('-i', '--image', metavar='file', required=True, help='Input image to pre-processing.')
|
|
24
|
+
parser.add_argument('-o', '--out', metavar='file', help='Save stripped image to path.')
|
|
25
|
+
parser.add_argument('-w', '--weight', metavar='float', help='Smoothness of intensity normalization mapping. The range of smoothness is [-3,2],'
|
|
26
|
+
' where a larger value implies a higher degree of smoothing',default =-1)
|
|
27
|
+
parser.add_argument('-g', '--gpu', action='store_true', help='Use the GPU.')
|
|
28
|
+
|
|
29
|
+
if len(sys.argv) == 1:
|
|
30
|
+
parser.print_help()
|
|
31
|
+
exit(1)
|
|
32
|
+
|
|
33
|
+
args = parser.parse_args()
|
|
34
|
+
|
|
35
|
+
# sanity check on the inputs
|
|
36
|
+
if not args.out:
|
|
37
|
+
sf.system.fatal('Must provide at least --out output flags.')
|
|
38
|
+
elif not os.path.exists(os.path.dirname(args.out)):
|
|
39
|
+
sf.system.fatal('Output directory does not exist.')
|
|
40
|
+
|
|
41
|
+
# check args.weight is in the range and float
|
|
42
|
+
if args.weight:
|
|
43
|
+
args.weight = float(args.weight)
|
|
44
|
+
if args.weight < -3 or args.weight > 2:
|
|
45
|
+
sf.system.fatal('The range of smoothness should within [-3,2], where a larger value implies a higher degree of smoothing')
|
|
46
|
+
|
|
47
|
+
# necessary for speed gains (I think)
|
|
48
|
+
torch.backends.cudnn.benchmark = True
|
|
49
|
+
torch.backends.cudnn.deterministic = True
|
|
50
|
+
|
|
51
|
+
# configure GPU device
|
|
52
|
+
if args.gpu:
|
|
53
|
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
|
54
|
+
device = torch.device('cuda')
|
|
55
|
+
device_name = 'GPU'
|
|
56
|
+
else:
|
|
57
|
+
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
|
|
58
|
+
device = torch.device('cpu')
|
|
59
|
+
device_name = 'CPU'
|
|
60
|
+
|
|
61
|
+
# configure model
|
|
62
|
+
print(f'Configuring model on the {device_name}')
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
with torch.no_grad():
|
|
66
|
+
model = UNet()
|
|
67
|
+
model.to(device)
|
|
68
|
+
model.eval()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
version = '1'
|
|
72
|
+
print(f'Running Neural Pre-processing model version {version}')
|
|
73
|
+
cwd = os.getcwd()
|
|
74
|
+
modelfile = os.path.join(cwd,'models/checkpoints', f'npp_v{version}.pth')
|
|
75
|
+
checkpoint = torch.load(modelfile, map_location=device)
|
|
76
|
+
|
|
77
|
+
model.load_state_dict(checkpoint)
|
|
78
|
+
|
|
79
|
+
# load input volume
|
|
80
|
+
image = sf.load_volume(args.image)
|
|
81
|
+
print(f'Input image read from: {args.image}')
|
|
82
|
+
|
|
83
|
+
# frame check
|
|
84
|
+
if image.nframes > 1:
|
|
85
|
+
sf.system.fatal('Input image cannot have more than 1 frame')
|
|
86
|
+
|
|
87
|
+
#i normalize image to [0, 255] and to [0, 1]
|
|
88
|
+
image = normalize(image)
|
|
89
|
+
|
|
90
|
+
# conform image and fit to shape with factors of 64
|
|
91
|
+
conformed = image.conform(voxsize=1.0, dtype='float32',shape=(256,256,256), method='nearest', orientation='LIA')
|
|
92
|
+
|
|
93
|
+
# predict the surface distance transform
|
|
94
|
+
with torch.no_grad():
|
|
95
|
+
input_tensor = torch.from_numpy(conformed.data[np.newaxis, np.newaxis]).to(device)
|
|
96
|
+
output = model(input_tensor,args.weight)
|
|
97
|
+
mni_norm = output[0].cpu().numpy().squeeze().astype(np.int16)
|
|
98
|
+
norm = output[1].cpu().numpy().squeeze().astype(np.int16)
|
|
99
|
+
scalar_field = output[2].cpu().numpy().squeeze().astype(np.int16)
|
|
100
|
+
|
|
101
|
+
# unconform the sdt and extract mask
|
|
102
|
+
mni_norm = conformed.new(mni_norm)#.resample_like(image,method='nearest', fill=0)
|
|
103
|
+
norm = conformed.new(norm)#.resample_like(image, method='nearest',fill=0)
|
|
104
|
+
scalar_field = conformed.new(scalar_field)#.resample_like(image, method='nearest',fill=0)
|
|
105
|
+
|
|
106
|
+
# write the masked output
|
|
107
|
+
if args.out:
|
|
108
|
+
filename = os.path.basename(args.image)
|
|
109
|
+
filename = filename.split('.')[0]
|
|
110
|
+
mni_norm.save(os.path.join(args.out,filename+'_mni_norm.nii.gz'))
|
|
111
|
+
norm.save(os.path.join(args.out,filename+'_norm.nii.gz'))
|
|
112
|
+
scalar_field.save(os.path.join(args.out,filename+'_scalar_field.nii.gz'))
|
|
113
|
+
|
|
114
|
+
print(f'Results saved to: {args.out}')
|
|
115
|
+
|
|
116
|
+
print('If you use Neural Pre-processing in your analysis, please cite:')
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import random
|
|
3
|
+
import shutil
|
|
4
|
+
import sys
|
|
5
|
+
import os
|
|
6
|
+
import torch
|
|
7
|
+
from torch.utils.data import DataLoader
|
|
8
|
+
from models.model import NPP
|
|
9
|
+
from dataset.mri_dataset_affine import Generate_dataset
|
|
10
|
+
import pytorch_lightning as pl
|
|
11
|
+
from pytorch_lightning.callbacks import LearningRateMonitor, ModelCheckpoint
|
|
12
|
+
from pytorch_lightning.callbacks import RichProgressBar
|
|
13
|
+
import glob
|
|
14
|
+
|
|
15
|
+
def save_checkpoint(state, is_best, filename="checkpoint_dae.pth.tar"):
|
|
16
|
+
torch.save(state, filename)
|
|
17
|
+
if is_best:
|
|
18
|
+
shutil.copyfile(filename, filename+'_best_loss')
|
|
19
|
+
|
|
20
|
+
def parse_args(argv):
|
|
21
|
+
parser = argparse.ArgumentParser(description="Example training script.")
|
|
22
|
+
parser.add_argument(
|
|
23
|
+
"-d", "--dataset", type=str, required=False, help="Training dataset"
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"-e",
|
|
27
|
+
"--epochs",
|
|
28
|
+
default=60,
|
|
29
|
+
type=int,
|
|
30
|
+
help="Number of epochs (default: %(default)s)",
|
|
31
|
+
)
|
|
32
|
+
parser.add_argument(
|
|
33
|
+
"-lr",
|
|
34
|
+
"--learning-rate",
|
|
35
|
+
default=1e-4,
|
|
36
|
+
type=float,
|
|
37
|
+
help="Learning rate (default: %(default)s)",
|
|
38
|
+
)
|
|
39
|
+
parser.add_argument(
|
|
40
|
+
"-n",
|
|
41
|
+
"--num-workers",
|
|
42
|
+
type=int,
|
|
43
|
+
default=8,
|
|
44
|
+
help="Dataloaders threads (default: %(default)s)",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
parser.add_argument("--checkpoint", type=str, help="Path to a checkpoint",default="checkpoint_dae_{quality}.pth.tar".format(quality = 24))
|
|
48
|
+
|
|
49
|
+
args = parser.parse_args(argv)
|
|
50
|
+
return args
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def main(argv):
|
|
54
|
+
args = parse_args(argv)
|
|
55
|
+
|
|
56
|
+
train_dataset,val_dataset = Generate_dataset()
|
|
57
|
+
|
|
58
|
+
train_dataloader = DataLoader(
|
|
59
|
+
train_dataset,
|
|
60
|
+
batch_size=2,
|
|
61
|
+
num_workers=args.num_workers,
|
|
62
|
+
shuffle=True,
|
|
63
|
+
pin_memory=( "cuda"),persistent_workers=True
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
val_dataloader = DataLoader(
|
|
67
|
+
val_dataset,
|
|
68
|
+
batch_size=2,
|
|
69
|
+
num_workers=2,
|
|
70
|
+
shuffle=False,
|
|
71
|
+
pin_memory=( "cuda"),persistent_workers=True
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
root_dir_path = os.path.join('checkpoint', "np_128_tv_hyper6_mean")
|
|
75
|
+
|
|
76
|
+
trainer = pl.Trainer(
|
|
77
|
+
default_root_dir=root_dir_path,
|
|
78
|
+
devices=1,
|
|
79
|
+
max_epochs=args.epochs,
|
|
80
|
+
precision=16, accelerator="gpu",
|
|
81
|
+
callbacks=[
|
|
82
|
+
ModelCheckpoint(mode="max",every_n_epochs = 1),
|
|
83
|
+
LearningRateMonitor("epoch"),RichProgressBar(),
|
|
84
|
+
],
|
|
85
|
+
benchmark=True,
|
|
86
|
+
)
|
|
87
|
+
trainer.logger._log_graph = True # If True, we plot the computation graph in tensorboard
|
|
88
|
+
trainer.logger._default_hp_metric = None # Optional logging argument that we don't need
|
|
89
|
+
|
|
90
|
+
# Check whether pretrained model exists. If yes, load it and skip training
|
|
91
|
+
files = glob.glob('checkpoint/np_128_tv_hyper5_mean/lightning_logs/*/checkpoints/*')
|
|
92
|
+
|
|
93
|
+
sorted_by_mtime_descending = sorted(files, key=lambda t: -os.stat(t).st_mtime)
|
|
94
|
+
if len(sorted_by_mtime_descending)>0:
|
|
95
|
+
pretrained_filename = sorted_by_mtime_descending[0]
|
|
96
|
+
else:
|
|
97
|
+
pretrained_filename = ''
|
|
98
|
+
|
|
99
|
+
resume_path = pretrained_filename
|
|
100
|
+
if os.path.isfile(pretrained_filename):
|
|
101
|
+
print("Found pretrained model at %s, loading..." % pretrained_filename)
|
|
102
|
+
# Automatically loads the model with the saved hyperparameters
|
|
103
|
+
state_dict = torch.load(pretrained_filename)
|
|
104
|
+
model = NPP(args.learning_rate)
|
|
105
|
+
model.load_state_dict(state_dict['state_dict'],strict=False)
|
|
106
|
+
trainer.fit(model, train_dataloader, val_dataloader)
|
|
107
|
+
else:
|
|
108
|
+
pl.seed_everything(42) # To be reproducable
|
|
109
|
+
model = NPP(args.learning_rate)
|
|
110
|
+
trainer.fit(model, train_dataloader, val_dataloader,ckpt_path= resume_path)
|
|
111
|
+
return model
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
#[1,1e-1,1e-2,1e-3]
|
|
116
|
+
main(sys.argv[1:])
|