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.
Files changed (501) hide show
  1. melage/__init__.py +16 -0
  2. melage/cli.py +4 -0
  3. melage/graphics/GLGraphicsItem.py +286 -0
  4. melage/graphics/GLViewWidget.py +595 -0
  5. melage/graphics/Transform3D.py +55 -0
  6. melage/graphics/__init__.py +8 -0
  7. melage/graphics/functions.py +101 -0
  8. melage/graphics/items/GLAxisItem.py +149 -0
  9. melage/graphics/items/GLGridItem.py +178 -0
  10. melage/graphics/items/GLPolygonItem.py +77 -0
  11. melage/graphics/items/GLScatterPlotItem.py +135 -0
  12. melage/graphics/items/GLVolumeItem.py +280 -0
  13. melage/graphics/items/GLVolumeItem_b.py +237 -0
  14. melage/graphics/items/__init__.py +0 -0
  15. melage/graphics/shaders.py +202 -0
  16. melage/main.py +270 -0
  17. melage/requirements22.txt +25 -0
  18. melage/requirements_old.txt +28 -0
  19. melage/resource/0circle.png +0 -0
  20. melage/resource/0circle_faded.png +0 -0
  21. melage/resource/3d.png +0 -0
  22. melage/resource/3d.psd +0 -0
  23. melage/resource/3dFaded.png +0 -0
  24. melage/resource/Eraser.png +0 -0
  25. melage/resource/EraserFaded.png +0 -0
  26. melage/resource/EraserX.png +0 -0
  27. melage/resource/EraserXFaded.png +0 -0
  28. melage/resource/Eraser_icon.svg +79 -0
  29. melage/resource/Hand.png +0 -0
  30. melage/resource/HandIcons_0.png +0 -0
  31. melage/resource/Hand_IX.png +0 -0
  32. melage/resource/Hand_IXFaded.png +0 -0
  33. melage/resource/Handsqueezed.png +0 -0
  34. melage/resource/Handwriting (copy).png +0 -0
  35. melage/resource/Handwriting.png +0 -0
  36. melage/resource/HandwritingMinus.png +0 -0
  37. melage/resource/HandwritingMinusX.png +0 -0
  38. melage/resource/HandwritingPlus.png +0 -0
  39. melage/resource/HandwritingPlusX.png +0 -0
  40. melage/resource/Move_icon.svg +8 -0
  41. melage/resource/PngItem_2422924.png +0 -0
  42. melage/resource/about.png +0 -0
  43. melage/resource/about_logo.png +0 -0
  44. melage/resource/about_logo0.png +0 -0
  45. melage/resource/action_check.png +0 -0
  46. melage/resource/action_check_OFF.png +0 -0
  47. melage/resource/arrow).png +0 -0
  48. melage/resource/arrow.png +0 -0
  49. melage/resource/arrowFaded.png +0 -0
  50. melage/resource/arrow_org.png +0 -0
  51. melage/resource/arrow_org.png.png +0 -0
  52. melage/resource/arrows.png +0 -0
  53. melage/resource/authors.mp4 +0 -0
  54. melage/resource/box.png +0 -0
  55. melage/resource/check-image-icon-0.jpg +0 -0
  56. melage/resource/circle.png +0 -0
  57. melage/resource/circle_faded.png +0 -0
  58. melage/resource/circle_or.png +0 -0
  59. melage/resource/close.png +0 -0
  60. melage/resource/close_bg.png +0 -0
  61. melage/resource/color/Simple.txt +18 -0
  62. melage/resource/color/Tissue.txt +24 -0
  63. melage/resource/color/Tissue12.txt +27 -0
  64. melage/resource/color/albert_LUT.txt +102 -0
  65. melage/resource/color/mcrib_LUT.txt +102 -0
  66. melage/resource/color/pediatric1.txt +29 -0
  67. melage/resource/color/pediatric1_old.txt +27 -0
  68. melage/resource/color/pediatric2.txt +87 -0
  69. melage/resource/color/pediatric3.txt +29 -0
  70. melage/resource/color/pediatrics (copy).csv +103 -0
  71. melage/resource/color/tissue_seg.txt +4 -0
  72. melage/resource/contour.png +0 -0
  73. melage/resource/contour.svg +2 -0
  74. melage/resource/contourFaded.png +0 -0
  75. melage/resource/contourX.png +0 -0
  76. melage/resource/contourXFaded.png +0 -0
  77. melage/resource/dti.png +0 -0
  78. melage/resource/dti0.png +0 -0
  79. melage/resource/dti222.png +0 -0
  80. melage/resource/dti_or.png +0 -0
  81. melage/resource/eco.png +0 -0
  82. melage/resource/eco22.png +0 -0
  83. melage/resource/eco_old.png +0 -0
  84. melage/resource/eco_or.png +0 -0
  85. melage/resource/eco_or2.png +0 -0
  86. melage/resource/eco_seg.png +0 -0
  87. melage/resource/eco_seg_old.png +0 -0
  88. melage/resource/export.png +0 -0
  89. melage/resource/hand-grab-icon-10.jpg +0 -0
  90. melage/resource/hand-grab-icon-25.jpg +0 -0
  91. melage/resource/info.png +0 -0
  92. melage/resource/line.png +0 -0
  93. melage/resource/linefaded.png +0 -0
  94. melage/resource/load.png +0 -0
  95. melage/resource/main.ico +0 -0
  96. melage/resource/manual_images/3D_rightc.png +0 -0
  97. melage/resource/manual_images/3D_rightc_goto.png +0 -0
  98. melage/resource/manual_images/3D_rightc_paint.png +0 -0
  99. melage/resource/manual_images/3D_rightc_paint_draw1.png +0 -0
  100. melage/resource/manual_images/3D_rightc_paint_draw2.png +0 -0
  101. melage/resource/manual_images/3D_rightc_paint_render.png +0 -0
  102. melage/resource/manual_images/3D_rightc_paint_render2.png +0 -0
  103. melage/resource/manual_images/3D_rightc_paint_render3.png +0 -0
  104. melage/resource/manual_images/3D_rightc_paint_render4.png +0 -0
  105. melage/resource/manual_images/3D_rightc_paint_render5.png +0 -0
  106. melage/resource/manual_images/3D_rightc_paint_render6.png +0 -0
  107. melage/resource/manual_images/3D_rightc_seg.png +0 -0
  108. melage/resource/manual_images/exit_toolbar.png +0 -0
  109. melage/resource/manual_images/load_image_file.png +0 -0
  110. melage/resource/manual_images/load_image_file_openp.png +0 -0
  111. melage/resource/manual_images/main_page.png +0 -0
  112. melage/resource/manual_images/menu_file.png +0 -0
  113. melage/resource/manual_images/menu_file_export.png +0 -0
  114. melage/resource/manual_images/menu_file_import.png +0 -0
  115. melage/resource/manual_images/menu_file_settings.png +0 -0
  116. melage/resource/manual_images/menu_file_ss.png +0 -0
  117. melage/resource/manual_images/open_save_load.png +0 -0
  118. melage/resource/manual_images/panning_toolbar.png +0 -0
  119. melage/resource/manual_images/segmentation_toolbar.png +0 -0
  120. melage/resource/manual_images/tab_mri.png +0 -0
  121. melage/resource/manual_images/tab_us.png +0 -0
  122. melage/resource/manual_images/tabs.png +0 -0
  123. melage/resource/manual_images/toolbar_tools.png +0 -0
  124. melage/resource/manual_images/tools_basic.png +0 -0
  125. melage/resource/manual_images/tools_bet.png +0 -0
  126. melage/resource/manual_images/tools_cs.png +0 -0
  127. melage/resource/manual_images/tools_deepbet.png +0 -0
  128. melage/resource/manual_images/tools_imageinfo.png +0 -0
  129. melage/resource/manual_images/tools_maskO.png +0 -0
  130. melage/resource/manual_images/tools_masking.png +0 -0
  131. melage/resource/manual_images/tools_n4b.png +0 -0
  132. melage/resource/manual_images/tools_resize.png +0 -0
  133. melage/resource/manual_images/tools_ruler.png +0 -0
  134. melage/resource/manual_images/tools_seg.png +0 -0
  135. melage/resource/manual_images/tools_threshold.png +0 -0
  136. melage/resource/manual_images/tools_tools.png +0 -0
  137. melage/resource/manual_images/widget_color.png +0 -0
  138. melage/resource/manual_images/widget_color_add.png +0 -0
  139. melage/resource/manual_images/widget_color_add2.png +0 -0
  140. melage/resource/manual_images/widget_color_additional.png +0 -0
  141. melage/resource/manual_images/widget_images.png +0 -0
  142. melage/resource/manual_images/widget_images2.png +0 -0
  143. melage/resource/manual_images/widget_images3.png +0 -0
  144. melage/resource/manual_images/widget_marker.png +0 -0
  145. melage/resource/manual_images/widget_mri.png +0 -0
  146. melage/resource/manual_images/widget_mri2.png +0 -0
  147. melage/resource/manual_images/widget_segintensity.png +0 -0
  148. melage/resource/manual_images/widget_tab_mutualview.png +0 -0
  149. melage/resource/manual_images/widget_tab_mutualview2.png +0 -0
  150. melage/resource/manual_images/widget_table.png +0 -0
  151. melage/resource/manual_images/widget_table2.png +0 -0
  152. melage/resource/manual_images/widget_us.png +0 -0
  153. melage/resource/melage_top.ico +0 -0
  154. melage/resource/melage_top.png +0 -0
  155. melage/resource/melage_top0.png +0 -0
  156. melage/resource/melage_top1.png +0 -0
  157. melage/resource/melage_top4.png +0 -0
  158. melage/resource/mri (copy).png +0 -0
  159. melage/resource/mri.png +0 -0
  160. melage/resource/mri0.png +0 -0
  161. melage/resource/mri000.png +0 -0
  162. melage/resource/mri22.png +0 -0
  163. melage/resource/mri_big.png +0 -0
  164. melage/resource/mri_old.png +0 -0
  165. melage/resource/mri_seg.png +0 -0
  166. melage/resource/mri_seg_old.png +0 -0
  167. melage/resource/new.png +0 -0
  168. melage/resource/open.png +0 -0
  169. melage/resource/open2.png +0 -0
  170. melage/resource/pan.png +0 -0
  171. melage/resource/pencil.png +0 -0
  172. melage/resource/pencilFaded.png +0 -0
  173. melage/resource/points.png +0 -0
  174. melage/resource/pointsFaded.png +0 -0
  175. melage/resource/rotate.png +0 -0
  176. melage/resource/ruler.png +0 -0
  177. melage/resource/rulerFaded.png +0 -0
  178. melage/resource/s.png +0 -0
  179. melage/resource/s.psd +0 -0
  180. melage/resource/save.png +0 -0
  181. melage/resource/saveas.png +0 -0
  182. melage/resource/seg_mri.png +0 -0
  183. melage/resource/seg_mri2.png +0 -0
  184. melage/resource/settings.png +0 -0
  185. melage/resource/synch.png +0 -0
  186. melage/resource/synchFaded.png +0 -0
  187. melage/resource/theme/rc/.keep +1 -0
  188. melage/resource/theme/rc/arrow_down.png +0 -0
  189. melage/resource/theme/rc/arrow_down@2x.png +0 -0
  190. melage/resource/theme/rc/arrow_down_disabled.png +0 -0
  191. melage/resource/theme/rc/arrow_down_disabled@2x.png +0 -0
  192. melage/resource/theme/rc/arrow_down_focus.png +0 -0
  193. melage/resource/theme/rc/arrow_down_focus@2x.png +0 -0
  194. melage/resource/theme/rc/arrow_down_pressed.png +0 -0
  195. melage/resource/theme/rc/arrow_down_pressed@2x.png +0 -0
  196. melage/resource/theme/rc/arrow_left.png +0 -0
  197. melage/resource/theme/rc/arrow_left@2x.png +0 -0
  198. melage/resource/theme/rc/arrow_left_disabled.png +0 -0
  199. melage/resource/theme/rc/arrow_left_disabled@2x.png +0 -0
  200. melage/resource/theme/rc/arrow_left_focus.png +0 -0
  201. melage/resource/theme/rc/arrow_left_focus@2x.png +0 -0
  202. melage/resource/theme/rc/arrow_left_pressed.png +0 -0
  203. melage/resource/theme/rc/arrow_left_pressed@2x.png +0 -0
  204. melage/resource/theme/rc/arrow_right.png +0 -0
  205. melage/resource/theme/rc/arrow_right@2x.png +0 -0
  206. melage/resource/theme/rc/arrow_right_disabled.png +0 -0
  207. melage/resource/theme/rc/arrow_right_disabled@2x.png +0 -0
  208. melage/resource/theme/rc/arrow_right_focus.png +0 -0
  209. melage/resource/theme/rc/arrow_right_focus@2x.png +0 -0
  210. melage/resource/theme/rc/arrow_right_pressed.png +0 -0
  211. melage/resource/theme/rc/arrow_right_pressed@2x.png +0 -0
  212. melage/resource/theme/rc/arrow_up.png +0 -0
  213. melage/resource/theme/rc/arrow_up@2x.png +0 -0
  214. melage/resource/theme/rc/arrow_up_disabled.png +0 -0
  215. melage/resource/theme/rc/arrow_up_disabled@2x.png +0 -0
  216. melage/resource/theme/rc/arrow_up_focus.png +0 -0
  217. melage/resource/theme/rc/arrow_up_focus@2x.png +0 -0
  218. melage/resource/theme/rc/arrow_up_pressed.png +0 -0
  219. melage/resource/theme/rc/arrow_up_pressed@2x.png +0 -0
  220. melage/resource/theme/rc/base_icon.png +0 -0
  221. melage/resource/theme/rc/base_icon@2x.png +0 -0
  222. melage/resource/theme/rc/base_icon_disabled.png +0 -0
  223. melage/resource/theme/rc/base_icon_disabled@2x.png +0 -0
  224. melage/resource/theme/rc/base_icon_focus.png +0 -0
  225. melage/resource/theme/rc/base_icon_focus@2x.png +0 -0
  226. melage/resource/theme/rc/base_icon_pressed.png +0 -0
  227. melage/resource/theme/rc/base_icon_pressed@2x.png +0 -0
  228. melage/resource/theme/rc/branch_closed.png +0 -0
  229. melage/resource/theme/rc/branch_closed@2x.png +0 -0
  230. melage/resource/theme/rc/branch_closed_disabled.png +0 -0
  231. melage/resource/theme/rc/branch_closed_disabled@2x.png +0 -0
  232. melage/resource/theme/rc/branch_closed_focus.png +0 -0
  233. melage/resource/theme/rc/branch_closed_focus@2x.png +0 -0
  234. melage/resource/theme/rc/branch_closed_pressed.png +0 -0
  235. melage/resource/theme/rc/branch_closed_pressed@2x.png +0 -0
  236. melage/resource/theme/rc/branch_end.png +0 -0
  237. melage/resource/theme/rc/branch_end@2x.png +0 -0
  238. melage/resource/theme/rc/branch_end_disabled.png +0 -0
  239. melage/resource/theme/rc/branch_end_disabled@2x.png +0 -0
  240. melage/resource/theme/rc/branch_end_focus.png +0 -0
  241. melage/resource/theme/rc/branch_end_focus@2x.png +0 -0
  242. melage/resource/theme/rc/branch_end_pressed.png +0 -0
  243. melage/resource/theme/rc/branch_end_pressed@2x.png +0 -0
  244. melage/resource/theme/rc/branch_line.png +0 -0
  245. melage/resource/theme/rc/branch_line@2x.png +0 -0
  246. melage/resource/theme/rc/branch_line_disabled.png +0 -0
  247. melage/resource/theme/rc/branch_line_disabled@2x.png +0 -0
  248. melage/resource/theme/rc/branch_line_focus.png +0 -0
  249. melage/resource/theme/rc/branch_line_focus@2x.png +0 -0
  250. melage/resource/theme/rc/branch_line_pressed.png +0 -0
  251. melage/resource/theme/rc/branch_line_pressed@2x.png +0 -0
  252. melage/resource/theme/rc/branch_more.png +0 -0
  253. melage/resource/theme/rc/branch_more@2x.png +0 -0
  254. melage/resource/theme/rc/branch_more_disabled.png +0 -0
  255. melage/resource/theme/rc/branch_more_disabled@2x.png +0 -0
  256. melage/resource/theme/rc/branch_more_focus.png +0 -0
  257. melage/resource/theme/rc/branch_more_focus@2x.png +0 -0
  258. melage/resource/theme/rc/branch_more_pressed.png +0 -0
  259. melage/resource/theme/rc/branch_more_pressed@2x.png +0 -0
  260. melage/resource/theme/rc/branch_open.png +0 -0
  261. melage/resource/theme/rc/branch_open@2x.png +0 -0
  262. melage/resource/theme/rc/branch_open_disabled.png +0 -0
  263. melage/resource/theme/rc/branch_open_disabled@2x.png +0 -0
  264. melage/resource/theme/rc/branch_open_focus.png +0 -0
  265. melage/resource/theme/rc/branch_open_focus@2x.png +0 -0
  266. melage/resource/theme/rc/branch_open_pressed.png +0 -0
  267. melage/resource/theme/rc/branch_open_pressed@2x.png +0 -0
  268. melage/resource/theme/rc/checkbox_checked.png +0 -0
  269. melage/resource/theme/rc/checkbox_checked0.png +0 -0
  270. melage/resource/theme/rc/checkbox_checked@2x.png +0 -0
  271. melage/resource/theme/rc/checkbox_checked@2x0.png +0 -0
  272. melage/resource/theme/rc/checkbox_checked@2x000.png.png +0 -0
  273. melage/resource/theme/rc/checkbox_checked_disabled.png +0 -0
  274. melage/resource/theme/rc/checkbox_checked_disabled0.png +0 -0
  275. melage/resource/theme/rc/checkbox_checked_disabled@2x.png +0 -0
  276. melage/resource/theme/rc/checkbox_checked_disabled@2x0.png +0 -0
  277. melage/resource/theme/rc/checkbox_checked_focus.png +0 -0
  278. melage/resource/theme/rc/checkbox_checked_focus0.png +0 -0
  279. melage/resource/theme/rc/checkbox_checked_focus@2x.png +0 -0
  280. melage/resource/theme/rc/checkbox_checked_focus@2x0.png +0 -0
  281. melage/resource/theme/rc/checkbox_checked_pressed.png +0 -0
  282. melage/resource/theme/rc/checkbox_checked_pressed0.png +0 -0
  283. melage/resource/theme/rc/checkbox_checked_pressed@2x.png +0 -0
  284. melage/resource/theme/rc/checkbox_checked_pressed@2x0.png +0 -0
  285. melage/resource/theme/rc/checkbox_indeterminate.png +0 -0
  286. melage/resource/theme/rc/checkbox_indeterminate@2x.png +0 -0
  287. melage/resource/theme/rc/checkbox_indeterminate_disabled.png +0 -0
  288. melage/resource/theme/rc/checkbox_indeterminate_disabled@2x.png +0 -0
  289. melage/resource/theme/rc/checkbox_indeterminate_focus.png +0 -0
  290. melage/resource/theme/rc/checkbox_indeterminate_focus@2x.png +0 -0
  291. melage/resource/theme/rc/checkbox_indeterminate_pressed.png +0 -0
  292. melage/resource/theme/rc/checkbox_indeterminate_pressed@2x.png +0 -0
  293. melage/resource/theme/rc/checkbox_unchecked.png +0 -0
  294. melage/resource/theme/rc/checkbox_unchecked0.png +0 -0
  295. melage/resource/theme/rc/checkbox_unchecked00.png +0 -0
  296. melage/resource/theme/rc/checkbox_unchecked@2x.png +0 -0
  297. melage/resource/theme/rc/checkbox_unchecked@2x0.png +0 -0
  298. melage/resource/theme/rc/checkbox_unchecked@2x00.png +0 -0
  299. melage/resource/theme/rc/checkbox_unchecked_disabled.png +0 -0
  300. melage/resource/theme/rc/checkbox_unchecked_disabled0.png +0 -0
  301. melage/resource/theme/rc/checkbox_unchecked_disabled00.png +0 -0
  302. melage/resource/theme/rc/checkbox_unchecked_disabled@2x.png +0 -0
  303. melage/resource/theme/rc/checkbox_unchecked_disabled@2x0.png +0 -0
  304. melage/resource/theme/rc/checkbox_unchecked_disabled@2x00.png +0 -0
  305. melage/resource/theme/rc/checkbox_unchecked_focus.png +0 -0
  306. melage/resource/theme/rc/checkbox_unchecked_focus0.png +0 -0
  307. melage/resource/theme/rc/checkbox_unchecked_focus00.png +0 -0
  308. melage/resource/theme/rc/checkbox_unchecked_focus@2x.png +0 -0
  309. melage/resource/theme/rc/checkbox_unchecked_focus@2x0.png +0 -0
  310. melage/resource/theme/rc/checkbox_unchecked_focus@2x00.png +0 -0
  311. melage/resource/theme/rc/checkbox_unchecked_pressed.png +0 -0
  312. melage/resource/theme/rc/checkbox_unchecked_pressed0.png +0 -0
  313. melage/resource/theme/rc/checkbox_unchecked_pressed00.png +0 -0
  314. melage/resource/theme/rc/checkbox_unchecked_pressed@2x.png +0 -0
  315. melage/resource/theme/rc/checkbox_unchecked_pressed@2x0.png +0 -0
  316. melage/resource/theme/rc/checkbox_unchecked_pressed@2x00.png +0 -0
  317. melage/resource/theme/rc/line_horizontal.png +0 -0
  318. melage/resource/theme/rc/line_horizontal@2x.png +0 -0
  319. melage/resource/theme/rc/line_horizontal_disabled.png +0 -0
  320. melage/resource/theme/rc/line_horizontal_disabled@2x.png +0 -0
  321. melage/resource/theme/rc/line_horizontal_focus.png +0 -0
  322. melage/resource/theme/rc/line_horizontal_focus@2x.png +0 -0
  323. melage/resource/theme/rc/line_horizontal_pressed.png +0 -0
  324. melage/resource/theme/rc/line_horizontal_pressed@2x.png +0 -0
  325. melage/resource/theme/rc/line_vertical.png +0 -0
  326. melage/resource/theme/rc/line_vertical@2x.png +0 -0
  327. melage/resource/theme/rc/line_vertical_disabled.png +0 -0
  328. melage/resource/theme/rc/line_vertical_disabled@2x.png +0 -0
  329. melage/resource/theme/rc/line_vertical_focus.png +0 -0
  330. melage/resource/theme/rc/line_vertical_focus@2x.png +0 -0
  331. melage/resource/theme/rc/line_vertical_pressed.png +0 -0
  332. melage/resource/theme/rc/line_vertical_pressed@2x.png +0 -0
  333. melage/resource/theme/rc/radio_checked.png +0 -0
  334. melage/resource/theme/rc/radio_checked@2x.png +0 -0
  335. melage/resource/theme/rc/radio_checked_disabled.png +0 -0
  336. melage/resource/theme/rc/radio_checked_disabled@2x.png +0 -0
  337. melage/resource/theme/rc/radio_checked_focus.png +0 -0
  338. melage/resource/theme/rc/radio_checked_focus@2x.png +0 -0
  339. melage/resource/theme/rc/radio_checked_pressed.png +0 -0
  340. melage/resource/theme/rc/radio_checked_pressed@2x.png +0 -0
  341. melage/resource/theme/rc/radio_unchecked.png +0 -0
  342. melage/resource/theme/rc/radio_unchecked@2x.png +0 -0
  343. melage/resource/theme/rc/radio_unchecked_disabled.png +0 -0
  344. melage/resource/theme/rc/radio_unchecked_disabled@2x.png +0 -0
  345. melage/resource/theme/rc/radio_unchecked_focus.png +0 -0
  346. melage/resource/theme/rc/radio_unchecked_focus@2x.png +0 -0
  347. melage/resource/theme/rc/radio_unchecked_pressed.png +0 -0
  348. melage/resource/theme/rc/radio_unchecked_pressed@2x.png +0 -0
  349. melage/resource/theme/rc/toolbar_move_horizontal.png +0 -0
  350. melage/resource/theme/rc/toolbar_move_horizontal@2x.png +0 -0
  351. melage/resource/theme/rc/toolbar_move_horizontal_disabled.png +0 -0
  352. melage/resource/theme/rc/toolbar_move_horizontal_disabled@2x.png +0 -0
  353. melage/resource/theme/rc/toolbar_move_horizontal_focus.png +0 -0
  354. melage/resource/theme/rc/toolbar_move_horizontal_focus@2x.png +0 -0
  355. melage/resource/theme/rc/toolbar_move_horizontal_pressed.png +0 -0
  356. melage/resource/theme/rc/toolbar_move_horizontal_pressed@2x.png +0 -0
  357. melage/resource/theme/rc/toolbar_move_vertical.png +0 -0
  358. melage/resource/theme/rc/toolbar_move_vertical@2x.png +0 -0
  359. melage/resource/theme/rc/toolbar_move_vertical_disabled.png +0 -0
  360. melage/resource/theme/rc/toolbar_move_vertical_disabled@2x.png +0 -0
  361. melage/resource/theme/rc/toolbar_move_vertical_focus.png +0 -0
  362. melage/resource/theme/rc/toolbar_move_vertical_focus@2x.png +0 -0
  363. melage/resource/theme/rc/toolbar_move_vertical_pressed.png +0 -0
  364. melage/resource/theme/rc/toolbar_move_vertical_pressed@2x.png +0 -0
  365. melage/resource/theme/rc/toolbar_separator_horizontal.png +0 -0
  366. melage/resource/theme/rc/toolbar_separator_horizontal@2x.png +0 -0
  367. melage/resource/theme/rc/toolbar_separator_horizontal_disabled.png +0 -0
  368. melage/resource/theme/rc/toolbar_separator_horizontal_disabled@2x.png +0 -0
  369. melage/resource/theme/rc/toolbar_separator_horizontal_focus.png +0 -0
  370. melage/resource/theme/rc/toolbar_separator_horizontal_focus@2x.png +0 -0
  371. melage/resource/theme/rc/toolbar_separator_horizontal_pressed.png +0 -0
  372. melage/resource/theme/rc/toolbar_separator_horizontal_pressed@2x.png +0 -0
  373. melage/resource/theme/rc/toolbar_separator_vertical.png +0 -0
  374. melage/resource/theme/rc/toolbar_separator_vertical@2x.png +0 -0
  375. melage/resource/theme/rc/toolbar_separator_vertical_disabled.png +0 -0
  376. melage/resource/theme/rc/toolbar_separator_vertical_disabled@2x.png +0 -0
  377. melage/resource/theme/rc/toolbar_separator_vertical_focus.png +0 -0
  378. melage/resource/theme/rc/toolbar_separator_vertical_focus@2x.png +0 -0
  379. melage/resource/theme/rc/toolbar_separator_vertical_pressed.png +0 -0
  380. melage/resource/theme/rc/toolbar_separator_vertical_pressed@2x.png +0 -0
  381. melage/resource/theme/rc/transparent.png +0 -0
  382. melage/resource/theme/rc/transparent@2x.png +0 -0
  383. melage/resource/theme/rc/transparent_disabled.png +0 -0
  384. melage/resource/theme/rc/transparent_disabled@2x.png +0 -0
  385. melage/resource/theme/rc/transparent_focus.png +0 -0
  386. melage/resource/theme/rc/transparent_focus@2x.png +0 -0
  387. melage/resource/theme/rc/transparent_pressed.png +0 -0
  388. melage/resource/theme/rc/transparent_pressed@2x.png +0 -0
  389. melage/resource/theme/rc/window_close.png +0 -0
  390. melage/resource/theme/rc/window_close@2x.png +0 -0
  391. melage/resource/theme/rc/window_close_disabled.png +0 -0
  392. melage/resource/theme/rc/window_close_disabled@2x.png +0 -0
  393. melage/resource/theme/rc/window_close_focus.png +0 -0
  394. melage/resource/theme/rc/window_close_focus@2x.png +0 -0
  395. melage/resource/theme/rc/window_close_pressed.png +0 -0
  396. melage/resource/theme/rc/window_close_pressed@2x.png +0 -0
  397. melage/resource/theme/rc/window_grip.png +0 -0
  398. melage/resource/theme/rc/window_grip@2x.png +0 -0
  399. melage/resource/theme/rc/window_grip_disabled.png +0 -0
  400. melage/resource/theme/rc/window_grip_disabled@2x.png +0 -0
  401. melage/resource/theme/rc/window_grip_focus.png +0 -0
  402. melage/resource/theme/rc/window_grip_focus@2x.png +0 -0
  403. melage/resource/theme/rc/window_grip_pressed.png +0 -0
  404. melage/resource/theme/rc/window_grip_pressed@2x.png +0 -0
  405. melage/resource/theme/rc/window_minimize.png +0 -0
  406. melage/resource/theme/rc/window_minimize@2x.png +0 -0
  407. melage/resource/theme/rc/window_minimize_disabled.png +0 -0
  408. melage/resource/theme/rc/window_minimize_disabled@2x.png +0 -0
  409. melage/resource/theme/rc/window_minimize_focus.png +0 -0
  410. melage/resource/theme/rc/window_minimize_focus@2x.png +0 -0
  411. melage/resource/theme/rc/window_minimize_pressed.png +0 -0
  412. melage/resource/theme/rc/window_minimize_pressed@2x.png +0 -0
  413. melage/resource/theme/rc/window_undock.png +0 -0
  414. melage/resource/theme/rc/window_undock@2x.png +0 -0
  415. melage/resource/theme/rc/window_undock_disabled.png +0 -0
  416. melage/resource/theme/rc/window_undock_disabled@2x.png +0 -0
  417. melage/resource/theme/rc/window_undock_focus.png +0 -0
  418. melage/resource/theme/rc/window_undock_focus@2x.png +0 -0
  419. melage/resource/theme/rc/window_undock_pressed.png +0 -0
  420. melage/resource/theme/rc/window_undock_pressed@2x.png +0 -0
  421. melage/resource/theme/style.qss +2223 -0
  422. melage/resource/tract.png +0 -0
  423. melage/resource/view1.png +0 -0
  424. melage/resource/view1_eco.png +0 -0
  425. melage/resource/view1_mri.png +0 -0
  426. melage/resource/view1_seg.png +0 -0
  427. melage/resource/view2.png +0 -0
  428. melage/resource/view2_seg.png +0 -0
  429. melage/resource/w.png +0 -0
  430. melage/resource/zoom_in.png +0 -0
  431. melage/resource/zoom_inFaded.png +0 -0
  432. melage/resource/zoom_out.png +0 -0
  433. melage/resource/zoom_outFaded.png +0 -0
  434. melage/some_notes.txt +3 -0
  435. melage/utils/DispalyIm.py +2788 -0
  436. melage/utils/GMM.py +720 -0
  437. melage/utils/Shaders_120.py +257 -0
  438. melage/utils/Shaders_330.py +314 -0
  439. melage/utils/Shaders_bu.py +314 -0
  440. melage/utils/__init__0.py +7 -0
  441. melage/utils/brain_extraction_helper.py +234 -0
  442. melage/utils/custom_QScrollBar.py +61 -0
  443. melage/utils/glScientific.py +1554 -0
  444. melage/utils/glScientific_bc.py +1585 -0
  445. melage/utils/readData.py +1061 -0
  446. melage/utils/registration.py +512 -0
  447. melage/utils/source_folder.py +18 -0
  448. melage/utils/utils.py +3808 -0
  449. melage/version.txt +1 -0
  450. melage/widgets/ApplyMask.py +212 -0
  451. melage/widgets/ChangeSystem.py +152 -0
  452. melage/widgets/DeepLModels/InfantSegment/Unet.py +464 -0
  453. melage/widgets/DeepLModels/NPP/dataset/mri_dataset_affine.py +149 -0
  454. melage/widgets/DeepLModels/NPP/models/checkpoints/npp_v1.pth.py +0 -0
  455. melage/widgets/DeepLModels/NPP/models/losses.py +146 -0
  456. melage/widgets/DeepLModels/NPP/models/model.py +272 -0
  457. melage/widgets/DeepLModels/NPP/models/utils.py +303 -0
  458. melage/widgets/DeepLModels/NPP/npp.py +116 -0
  459. melage/widgets/DeepLModels/NPP/requirements.txt +8 -0
  460. melage/widgets/DeepLModels/NPP/train/train.py +116 -0
  461. melage/widgets/DeepLModels/Unet3DAtt.py +657 -0
  462. melage/widgets/DeepLModels/Unet3D_basic.py +648 -0
  463. melage/widgets/DeepLModels/new_unet.py +652 -0
  464. melage/widgets/DeepLModels/new_unet_old.py +639 -0
  465. melage/widgets/DeepLModels/new_unet_old2.py +658 -0
  466. melage/widgets/HistImage.py +153 -0
  467. melage/widgets/ImageThresholding.py +222 -0
  468. melage/widgets/MaskOperations.py +147 -0
  469. melage/widgets/N4Dialog.py +241 -0
  470. melage/widgets/Segmentation/FCM.py +1553 -0
  471. melage/widgets/Segmentation/__init__.py +588 -0
  472. melage/widgets/Segmentation/utils.py +417 -0
  473. melage/widgets/SemiAutoSeg.py +666 -0
  474. melage/widgets/Synthstrip.py +141 -0
  475. melage/widgets/__init__0.py +5 -0
  476. melage/widgets/about.py +246 -0
  477. melage/widgets/activation.py +437 -0
  478. melage/widgets/activator.py +147 -0
  479. melage/widgets/be_dl.py +409 -0
  480. melage/widgets/be_dl_unet3d.py +441 -0
  481. melage/widgets/brain_extraction.py +855 -0
  482. melage/widgets/brain_extraction_dl.py +887 -0
  483. melage/widgets/brain_extraction_dl_bu.py +869 -0
  484. melage/widgets/colorwidget.py +100 -0
  485. melage/widgets/dockWidgets.py +2005 -0
  486. melage/widgets/enhanceImWidget.py +109 -0
  487. melage/widgets/fileDialog_widget.py +275 -0
  488. melage/widgets/iminfo.py +346 -0
  489. melage/widgets/mainwindow_widget.py +6775 -0
  490. melage/widgets/melageAbout.py +123 -0
  491. melage/widgets/openglWidgets.py +556 -0
  492. melage/widgets/registrationWidget.py +342 -0
  493. melage/widgets/repeat_widget.py +74 -0
  494. melage/widgets/screenshot_widget.py +138 -0
  495. melage/widgets/settings_widget.py +77 -0
  496. melage/widgets/tranformationWidget.py +275 -0
  497. melage-0.0.65.dist-info/METADATA +742 -0
  498. melage-0.0.65.dist-info/RECORD +501 -0
  499. melage-0.0.65.dist-info/WHEEL +5 -0
  500. melage-0.0.65.dist-info/entry_points.txt +2 -0
  501. melage-0.0.65.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1585 @@
1
+ # -*- coding: utf-8 -*-
2
+ __author__= 'Bahram Jafrasteh'
3
+ import numpy as np
4
+ import sys
5
+ sys.path.append('../')
6
+ from melage.graphics import GLViewWidget, GLAxisItem, GLScatterPlotItem, GLGridItem, GLVolumeItem, GLPolygonItem
7
+ from OpenGL.GL import *
8
+ from collections import defaultdict
9
+ from PyQt5.QtWidgets import QApplication, QWidget, QMenu, QAction, QSlider, QFileDialog
10
+ from PyQt5.QtGui import QVector3D, QMatrix4x4
11
+ from PyQt5.QtCore import Qt
12
+ import cv2
13
+ #from utils.polygontessellator import PolygonTessellator
14
+ from melage.utils.utils import ConvertPointsToPolygons, ConvertPToPolygons, fillInsidePol, Polygon, LargestCC
15
+ from PyQt5.QtCore import pyqtSignal
16
+ from functools import partial
17
+
18
+ class glScientific(GLViewWidget):
19
+ """
20
+
21
+ """
22
+ point3dpos=pyqtSignal(object, object) #qt signal
23
+ def __init__(self, colorsCombinations, parent = None, id =0, source_directory=''):
24
+ """
25
+
26
+ :param colorsCombinations: a dictionary containing color information
27
+ :param parent: parent
28
+ :param id: id of the GL
29
+ :param source_directory: source folder
30
+ """
31
+
32
+ super( glScientific, self).__init__(parent)
33
+ self.traces = dict()
34
+ #self = gl.GLViewWidget()
35
+ #self.installEventFilter()
36
+ self.id = id
37
+ self._lastZ = 1
38
+ self._image = None
39
+ self._image_seg = None
40
+ self._renderMode = 'Img'
41
+ self._threshold = 0
42
+ self._artistic = False
43
+
44
+ self._updatePaint = True
45
+ self._gotoLoc = False
46
+ self.colorsCombinations = colorsCombinations
47
+ self.totalPolyItems = []
48
+ self.maxXYZ = [100, 100, 100]
49
+ self._excluded_inds = np.zeros((100,100,100), bool)
50
+ self.setWindowTitle('3D view')
51
+ self._enabledPolygon = False
52
+ #self.setGeometry(0, 110, 600, 600)
53
+ self.setGeometry(0,0,1000,1000)
54
+ self.el_az_dis.connect(
55
+ lambda points : self.emit_viewport(points)
56
+ )
57
+ self._indices = None
58
+ self._rendered = 'seg'
59
+ self._numPolys = 0
60
+ self.totalpolys = defaultdict(list)
61
+ self.totalpolys_camer = defaultdict(list)
62
+
63
+ self._sPoints = []
64
+ self.intensitySeg = 1.0
65
+ self.totalItems = defaultdict(list)
66
+ self.totalItems['axis'] = []
67
+ self.totalItems['polys'] = []
68
+ self.colorInd = 9876#len(self.colorsCombinations)
69
+ self.colorInds= [9876]
70
+ self.setContextMenuPolicy(Qt.CustomContextMenu) # enable right click
71
+
72
+ self.customContextMenuRequested.connect(self.ShowContextMenu)
73
+
74
+ self.createGridAxis(self.maxXYZ)
75
+ self.source_dir = source_directory
76
+ self.GLV = GLVolumeItem(sliceDensity=1, smooth=True, glOptions='translucent',
77
+ intensity_seg = self.intensitySeg)
78
+ self.GLSC = GLScatterPlotItem(pxMode=True, size=5)
79
+ self.GLPl = GLPolygonItem()
80
+ #self.GLV.smooth = True
81
+ self._UseScatter = False
82
+
83
+ self._verticalSlider_1 = QSlider(self)
84
+ self._verticalSlider_1.setOrientation(Qt.Vertical)
85
+ self._verticalSlider_1.setObjectName("verticalSlider_6")
86
+ self._verticalSlider_1.setRange(1, 50)
87
+ self._verticalSlider_1.setValue(1)
88
+ self._verticalSlider_1.setVisible(False)
89
+ #self.label_1 = QLabel(self)
90
+ #self.label_1.setAlignment(Qt.AlignCenter)
91
+ #self.label_1.setObjectName("label_1")
92
+ #self._verticalSlider_1.valueChanged.connect(self.label_1.setNum)
93
+ self._verticalSlider_1.valueChanged.connect(self.threshold_change)
94
+
95
+ self._seg_im = None
96
+
97
+ #self.opts['bgcolor'] = [0.5, 1, 0.0, 1]
98
+ self.opts['bgcolor'] = [0.3, 0.3, 0.3, 1] # background color
99
+
100
+ def threshold_change(self, value):
101
+ """
102
+ Threshold in 3D rendering
103
+ :param value:
104
+ :return:
105
+ """
106
+ if self._rendered != 'image':
107
+ self._verticalSlider_1.setValue(1)
108
+ return
109
+ self._threshold = value
110
+ self.cmap_image(self._lastmap_type,reset=False)
111
+
112
+ def take_screenshot(self):
113
+ """
114
+ Take screenshot from 3D rendering
115
+ :return:
116
+ """
117
+ if self._seg_im is None:
118
+ return
119
+ filters = "png(*.png)"
120
+ opts = QFileDialog.DontUseNativeDialog
121
+ fileObj = QFileDialog.getSaveFileName(self, "Open File", self.source_dir, filters, options=opts)
122
+ if fileObj[0] == '':
123
+ return
124
+ filename = fileObj[0] + '.png'
125
+ init_width, init_height = self.width(), self.height()
126
+ maxhw = max(init_width, init_height)
127
+ width, height = init_width, init_height
128
+ while maxhw <3000:
129
+ width, height = width*1.5, height*1.5
130
+ maxhw = max(width, height)
131
+ self.setFixedWidth(int(width))
132
+ self.setFixedHeight(int(height))
133
+ maxhw = max(self.width(), self.height())
134
+ #self.setGeometry()
135
+ self.removeItem('scatter_total')
136
+ self.GLV.setData(self._seg_im, self._artistic)
137
+ self.GLV.setDepthValue(10)
138
+ self.addItem(self.GLV, 'vol_total')
139
+ self.showEvent(0)
140
+ maxhw = max(self.width(), self.height())
141
+ img = glReadPixels(0, 0, maxhw, maxhw, GL_RGB, GL_FLOAT)
142
+ img = img[::-1]
143
+ img = img[:self.height(), :self.width(), :]
144
+ from matplotlib.image import imsave
145
+
146
+ imsave(filename, img)
147
+ self.setFixedWidth(init_width)
148
+ self.setFixedHeight(init_height)
149
+
150
+ def initiate_actions(self):
151
+ """
152
+
153
+ :return:
154
+ """
155
+ self.axis_action = QAction("Axis")
156
+ self.axis_action.setCheckable(True)
157
+ self.axis_action.setChecked(True)
158
+ self.axis_action.triggered.connect(self.axis_status)
159
+
160
+
161
+ self.goto_action = QAction("GoTo")
162
+ self.goto_action.setCheckable(True)
163
+ self.goto_action.setChecked(False)
164
+ self.goto_action.triggered.connect(self.goto_status)
165
+
166
+ self.grid_action = QAction("Grid")
167
+ self.grid_action.setCheckable(True)
168
+ self.grid_action.setChecked(True)
169
+ self.grid_action.triggered.connect(self.grid_status)
170
+
171
+
172
+ self.one_third_action = QAction("slice disp.")
173
+ self.one_third_action.setCheckable(True)
174
+ self.one_third_action.setChecked(False)
175
+ self.one_third_action.triggered.connect(self.artistic_status)
176
+
177
+
178
+ self.seg_action = QAction("Show Seg.")
179
+ self.seg_action.setCheckable(True)
180
+ self.seg_action.setChecked(False)
181
+ self.seg_action.triggered.connect(self.seg_status)
182
+
183
+ self.im_seg_action = QAction("Show Img+Seg")
184
+ self.im_seg_action.setCheckable(True)
185
+ self.im_seg_action.setChecked(False)
186
+ self.im_seg_action.triggered.connect(self.im_seg_status)
187
+
188
+
189
+
190
+ self.screenshot_action = QAction("ScreenShot")
191
+ self.screenshot_action.triggered.connect(self.take_screenshot)
192
+
193
+ self.draw_action = QAction("Draw")
194
+ self.draw_action.setCheckable(True)
195
+ self.draw_action.setChecked(False)
196
+ self.draw_action.triggered.connect(self.draw_status)
197
+
198
+
199
+ self.draw_art = QAction("Artistic")
200
+ self.draw_art.setCheckable(True)
201
+ self.draw_art.setChecked(False)
202
+ self.draw_art.triggered.connect(self.draw_art_action)
203
+
204
+ self.clear_action = QAction("Show Total")
205
+ self.clear_action.triggered.connect(self.showTotal)
206
+
207
+
208
+
209
+ def showTotal(self):
210
+ """
211
+ Show all the part of image in 3D
212
+ :return:
213
+ """
214
+ self._excluded_inds[:] = False
215
+ self._artistic = False
216
+
217
+
218
+ def remove_painting(self):
219
+ """
220
+ Excluding 3D ares from demonstration
221
+ :return:
222
+ """
223
+ def filledPoly(poly):
224
+ """
225
+ Fill inside polygons
226
+ Args:
227
+ poly:
228
+
229
+ Returns:
230
+
231
+ """
232
+ from matplotlib.path import Path
233
+
234
+ try:
235
+ coords = np.array(poly.exterior.coords)
236
+
237
+ p = Path(coords)
238
+ xmin, ymin, xmax, ymax = poly.bounds
239
+ x = np.arange(np.floor(xmin), np.ceil(xmax), 1)
240
+ y = np.arange(np.floor(ymin), np.ceil(ymax), 1)
241
+ points = np.transpose([np.tile(x, len(y)), np.repeat(y, len(x))])
242
+ ind_points = p.contains_points(points)
243
+ selected_points = points[ind_points]
244
+
245
+ return selected_points
246
+ except:
247
+ return []
248
+ def adjustVals(selected):
249
+ for i in [0,1,2]:
250
+ ind = selected[:,i]>=self.maxXYZ[i]
251
+ selected[ind, i] = self.maxXYZ[i]-1
252
+ ind = selected[:,i]<=0
253
+ selected[ind, i] = 1
254
+ return selected
255
+ def findIndices(vls):
256
+ pl = Polygon(vls)
257
+ if not pl.is_valid:
258
+ pls = ConvertPToPolygons(vls)
259
+ for ij, pl in enumerate(pls):
260
+ if ij == 0:
261
+ #pl = spline_points(pl)
262
+ selected_points = filledPoly(pl)
263
+ else:
264
+ #pl = spline_points(pl)
265
+ n_points = filledPoly(pl)
266
+ selected_points = np.vstack([selected_points, n_points])
267
+ else:
268
+ #pl = spline_points(pl)
269
+ selected_points = filledPoly(pl)
270
+ return selected_points
271
+ if len(self.totalpolys[0])<5:
272
+ return
273
+ if 'vol_total' in self.items:
274
+ self.SubUpdateSegScatterItem()
275
+ else:
276
+ return
277
+ #points = self._compute_coordinates(self.mousePos)
278
+ if 'scatter_total' in self.items:
279
+
280
+ self.removeItem('scatter_total')
281
+ self.GLV.setData(self._seg_im, self._artistic)
282
+ self.GLV.setDepthValue(20)
283
+ self.addItem(self.GLV, 'vol_total')
284
+
285
+ invM = np.linalg.inv(self.mvpProj.reshape((4, 4)).transpose())
286
+ xmax, ymax, zmax = self.maxCoord
287
+ filled_polygon = np.array(self._sPoints)
288
+ filled_polygon = findIndices(filled_polygon)
289
+ filled_polygon = np.concatenate([filled_polygon, np.ones((len(filled_polygon), 2))], 1)
290
+ filled_polygon[:, 0] = 2 * filled_polygon[:,0] / self.width() - 1
291
+ filled_polygon[:, 1] = 1 - 2 * filled_polygon[:,1] / self.height()
292
+ filled_polygon[:, 3] = 1
293
+ filled_polygon[:, 2] = 2 * 1- 1
294
+
295
+
296
+
297
+ Tpoints = []
298
+ #self._z[self._z>0].min(), #self._z[self._z<1].max()
299
+ opt=1e-4
300
+ #round(self._z[self._z < 1].max() + 0.0001, 4)
301
+ for z in np.arange(0.9985- 0.0006, round(self._z[self._z < 1].max() + 0.0001, 4), 1e-6):
302
+ A = filled_polygon.copy()
303
+ A[:, 2] = 2 * z - 1
304
+
305
+ Tpoints = np.matmul(invM,
306
+ A.T).T
307
+ Tpoints /= Tpoints[:, 3, None]
308
+ # Tpoints = Tpoints.astype('int')
309
+
310
+ selected = Tpoints.astype('int')[:, :3]
311
+
312
+
313
+ selected[:, 2] = self.maxXYZ[0] - selected[:, 2]
314
+ selected[:, 0] = self.maxXYZ[2] - selected[:, 0]
315
+
316
+ ind = 0
317
+ for j, xyzm in enumerate([zmax, ymax, xmax]):
318
+ ind += ((selected[:, j] < xyzm) * (selected[:, j] >= 0))
319
+ ind = ind >= 3
320
+ selected = selected[ind, :]
321
+ selected = selected[:, [2, 1, 0]]
322
+
323
+ self._excluded_inds[selected[:, 0], selected[:, 1], selected[:, 2]] = True
324
+
325
+
326
+ #from scipy.ndimage import binary_fill_holes
327
+ #self._excluded_inds = binary_fill_holes(self._excluded_inds)
328
+ self._indices = (self._indices.astype('int')- self._excluded_inds.astype('int'))>0
329
+ self._seg_im[self._excluded_inds, :] = 0
330
+
331
+ #print('removing')
332
+ self.clear_points()
333
+ self.GLV.setData(self._seg_im, self._artistic)
334
+ self.GLV.update()
335
+ return
336
+
337
+
338
+ def clear_points(self):
339
+ """
340
+ Clear information
341
+ :return:
342
+ """
343
+ self.totalpolys = defaultdict(list)
344
+ self.totalpolys_camer = defaultdict(list)
345
+ self._numPolys = 0
346
+ self._lastZ=1
347
+ self.GLPl.update_points(self.totalpolys)
348
+ self.update()
349
+
350
+
351
+ def paintGL(self, region=None, viewport=None, useItemNames=False):
352
+ """
353
+ Paint GL
354
+ :param region:
355
+ :param viewport:
356
+ :param useItemNames:
357
+ :return:
358
+ """
359
+ super(glScientific, self).paintGL()
360
+ elev = self.opts['elevation'] #* np.pi/180.
361
+ azim = self.opts['azimuth'] #* np.pi/180.
362
+ #print(elev, azim)
363
+
364
+ def _endIMage(self, x, y, z, tol=10): # to check if we are at the end of the image
365
+ zmax, xmax, ymax = self.maxCoord
366
+ zmax, xmax, ymax = zmax+tol, ymax+tol, xmax+tol
367
+ endIm = False
368
+ if x<-tol:
369
+ endIm = True
370
+ x = -tol
371
+ elif x>xmax:
372
+ endIm = True
373
+ x = xmax
374
+ if y <-tol:
375
+ endIm = True
376
+ y = -tol
377
+ elif y > ymax:
378
+ endIm = True
379
+ y = ymax
380
+ if z <-tol:
381
+ endIm = True
382
+ z = -tol
383
+ elif z > zmax:
384
+ endIm = True
385
+ z = zmax
386
+ return endIm, x, y, z
387
+
388
+ def mouseReleaseEvent(self, a0) -> None:
389
+ """
390
+ Mouse events
391
+ :param a0:
392
+ :return:
393
+ """
394
+ if self._enabledPolygon:
395
+ if len(self._sPoints)==0:
396
+ return
397
+ self.totalpolys[self._numPolys].append(self.totalpolys[self._numPolys][0])
398
+ self._sPoints.append(self._sPoints[0])
399
+
400
+ if self.GLV._ax==0:
401
+ self.totalpolys_camer[self._numPolys] = ['sagittal', self.GLV._d]
402
+ elif self.GLV._ax == 1:
403
+ self.totalpolys_camer[self._numPolys] = ['coronal', self.GLV._d]
404
+ elif self.GLV._ax == 2:
405
+ self.totalpolys_camer[self._numPolys] = ['axial', self.GLV._d]
406
+ self._numPolys = 0
407
+ self.GLPl.update_points(self.totalpolys)
408
+
409
+ #polygonC = ConvertPointsToPolygons(self.totalpolys[self._numPolys], width=0)
410
+ #if polygonC.is_valid:
411
+ # Mpl = ConvertPToPolygons(self.totalpolys[self._numPolys])
412
+ try:
413
+ self.remove_painting()
414
+ except Exception as e:
415
+ print(e)
416
+ self._sPoints = []
417
+ self._enabledPolygon = False
418
+ self.draw_action.setChecked(False)
419
+
420
+
421
+ if 'scatter_total' in self.items:
422
+
423
+ self.removeItem('scatter_total')
424
+ self.GLV.setData(self._seg_im, self._artistic)
425
+ self.GLV.setDepthValue(20)
426
+ self.addItem(self.GLV, 'vol_total')
427
+
428
+ def _custom_viewMatrix(self, distance):
429
+ tr = QMatrix4x4()
430
+ tr.translate( 0.0, 0.0, -distance)
431
+ tr.rotate(self.opts['elevation']-90, 1, 0, 0)
432
+ tr.rotate(self.opts['azimuth']+90, 0, 0, -1)
433
+ center = self.opts['center']
434
+ tr.translate(-center.x(), -center.y(), -center.z())
435
+ return tr
436
+
437
+ def _custom_projectionMatrix(self, dist):
438
+
439
+ dpr = self.devicePixelRatio()
440
+ region = (0, 0, self.width() * dpr, self.height() * dpr)
441
+
442
+ x0, y0, w, h = self.getViewport()
443
+
444
+ nearClip = dist * 0.001
445
+ farClip = dist * 1000.
446
+
447
+ r = nearClip * np.tan(self.opts['fov'] * 0.5 * np.pi / 180.)
448
+ t = r * h / w
449
+
450
+ ## Note that X0 and width in these equations must be the values used in viewport
451
+ left = r * ((region[0] - x0) * (2.0 / w) - 1)
452
+ right = r * ((region[0] + region[2] - x0) * (2.0 / w) - 1)
453
+ bottom = t * ((region[1] - y0) * (2.0 / h) - 1)
454
+ top = t * ((region[1] + region[3] - y0) * (2.0 / h) - 1)
455
+
456
+ tr = QMatrix4x4()
457
+ tr.frustum(left, right, bottom, top, nearClip, farClip)
458
+ return tr
459
+
460
+ def _compute_coordinates(self, ev, z=None):
461
+ if z is None:
462
+ self.showEvent(0)
463
+ z = glReadPixels(ev.x(), self.height() - ev.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT)[0][0]
464
+ if z == 0:
465
+ return [0,0,0,0]
466
+ if z==1:
467
+ z=self._lastZ
468
+ #a = np.argwhere(self._z != 1)
469
+ #_y, _x = self.height() - ev.y(), ev.x()
470
+ #ind = np.abs(a-np.array([_y, _x])).sum(-1).argmin()
471
+ #z = self._z[a[ind][0], a[ind][1]]
472
+ self._lastZ = z
473
+
474
+
475
+
476
+ #per = np.array(self.m.copyDataTo()).reshape((4, 4)).transpose().flatten()
477
+ #zFar = 0.5 * per[14] * (1.0 - ((per[10] - 1.0) / (per[10] + 1.0)))
478
+ # zNear = zFar * (per[10] + 1.0) / (per[10] - 1.0)
479
+
480
+ # z = (2.0 * z) - 1.0
481
+ # z = (2.0 * zNear * zFar) / (zFar + zNear - (z * (zFar - zNear)))
482
+
483
+ ndcx = 2 * self.mousePos.x() / self.width() - 1
484
+ ndcy = 1 - 2 * self.mousePos.y() / self.height()
485
+ a= [self.mousePos.x(), self.mousePos.y()]
486
+
487
+ #z=0.998
488
+
489
+ invM = np.linalg.inv(self.mvpProj.reshape((4, 4)).transpose())
490
+
491
+ points = np.matmul(invM,
492
+ np.array([ndcx, ndcy, 2 * z - 1, 1]))
493
+ points /= points[3]
494
+ return points,a
495
+
496
+ def mouseMoveEvent(self, ev):
497
+ #print(self.opts['azimuth'], self.opts['elevation'])
498
+ if not hasattr(self, 'mousePos'):
499
+ return
500
+ diff = ev.pos() - self.mousePos
501
+ self.mousePos = ev.pos()
502
+ if self._enabledPolygon:
503
+
504
+ #self.SubUpdateSegScatterItem()
505
+
506
+ #z = self._z[self.height()-ev.y(), ev.x()]
507
+ z=1.0
508
+ points, _ = self._compute_coordinates(ev, z=z)
509
+ #points[0] -= 1
510
+ #points[-1] -= 1
511
+ # points[1] -= 1
512
+ #points[2] = self.maxXYZ[2] - points[2]
513
+ #points[0] = self.maxXYZ[2] - points[0]
514
+ p1, xo = self._compute_coordinates(ev, 1)
515
+
516
+ # self.points = []
517
+ x,y, z, _ = points
518
+ if z == 0:
519
+ return
520
+ endIm = self._endIMage(x, y, z)
521
+
522
+ if endIm[0]:
523
+ # update x and y
524
+ #return
525
+ x = endIm[1]
526
+ y = endIm[2]
527
+ z = endIm[3]
528
+ endIm2 = self._endIMage(p1[0], p1[2], p1[3])
529
+ self._sPoints.append(xo)
530
+ #if not endIm2[0]:
531
+ # self._sPoints.append(p1)
532
+ self.totalpolys[self._numPolys].append([x, y, z])
533
+ if len(self.totalpolys[self._numPolys]) > 2:
534
+ self.GLPl.update_points(self.totalpolys)
535
+ self.addItem(self.GLPl, 'pol_total')
536
+ self.GLPl.setDepthValue(100)
537
+ #if 'scatter_total' in self.items:
538
+ # self.removeItem('scatter_total')
539
+ # self.GLV.setData(self._seg_im)
540
+ # self.GLV.setDepthValue(0)
541
+ # self.addItem(self.GLV, 'vol_total')
542
+
543
+ else:
544
+ if ev.buttons() == Qt.LeftButton:
545
+ if (ev.modifiers() & Qt.ControlModifier):
546
+ self.pan(diff.x(), diff.y(), 0, relative='view')
547
+ else:
548
+ self.orbit(-diff.x(), diff.y())
549
+ elif ev.buttons() == Qt.MidButton:
550
+ if (ev.modifiers() & Qt.ControlModifier):
551
+ self.pan(diff.x(), 0, diff.y(), relative='view-upright')
552
+ else:
553
+ self.pan(diff.x(), diff.y(), 0, relative='view-upright')
554
+ self.point3dpos.emit([self.opts['elevation'], self.opts['azimuth'], self.opts['distance']],None)
555
+ def emit_viewport(self, points):
556
+ self.point3dpos.emit(points, None)
557
+
558
+ def mousePressEvent(self, ev):
559
+ """
560
+ By Bahram Jafrasteh
561
+ :param ev:
562
+ :return:
563
+ """
564
+ #self.opts['azimuth'] = 0
565
+ #self.opts['elevation'] = 0
566
+
567
+ self.mousePos = ev.localPos()
568
+ if not (self._gotoLoc or self._enabledPolygon):
569
+ return
570
+
571
+ if ev.button()==Qt.RightButton:
572
+ return
573
+ if 'vol_total' in self.items:
574
+ self.SubUpdateSegScatterItem()
575
+ else:
576
+ return
577
+ points, _ = self._compute_coordinates(ev)
578
+
579
+ #points[1] -= 1
580
+ #print(points)
581
+
582
+ if self._enabledPolygon:
583
+ #self.addItem(self.GLPl, 'pol_total')
584
+ #self.points = []
585
+ #points[2] = self.maxXYZ[2] - points[2]
586
+ #points[0] = self.maxXYZ[2] - points[0]
587
+ p1, xo = self._compute_coordinates(ev, 1)
588
+ self._sPoints = []
589
+ self.totalpolys[self._numPolys] =[]
590
+ if points[-2] == 0:
591
+ return
592
+ #print(points)
593
+ x, y, z , _=points
594
+ endIm = self._endIMage(x, y, z)
595
+ if endIm[0]:
596
+ # update x and y
597
+ x = endIm[1]
598
+ y = endIm[2]
599
+ z = endIm[3]
600
+ endIm2 = self._endIMage(p1[0], p1[2], p1[3])
601
+ #if not endIm2[0]:
602
+ # self._sPoints.append(p1)
603
+
604
+ self._sPoints.append(xo)
605
+ self.totalpolys[self._numPolys].append([x, y, z])
606
+ if len(self.totalpolys[self._numPolys])>1:
607
+ self.GLPl.update_points(self.totalpolys)
608
+
609
+
610
+
611
+ #print(points)
612
+ elif self._gotoLoc:
613
+ #points[0] -= 1
614
+ #points[-1] -= 1
615
+ points[2] = self.maxXYZ[0] - points[2]
616
+ points[0] = self.maxXYZ[2] - points[0]
617
+ if self.GLV._ax==0:
618
+ windowName = 'sagittal'
619
+ elif self.GLV._ax == 1:
620
+ windowName = 'coronal'
621
+ elif self.GLV._ax == 2:
622
+ windowName = 'axial'
623
+ self.point3dpos.emit(points, windowName)
624
+ else:
625
+ self.point3dpos.emit(points, None)
626
+ #self.updateSegVolItem(self._seg_im, None)
627
+ if 'scatter_total' in self.items:
628
+
629
+ self.removeItem('scatter_total')
630
+ self.GLV.setData(self._seg_im, self._artistic)
631
+ self.GLV.setDepthValue(20)
632
+ self.addItem(self.GLV, 'vol_total')
633
+
634
+
635
+
636
+ """
637
+
638
+ def changedata(self):
639
+ self._artistic = False
640
+ if self._UseScatter:
641
+ self._UseScatter=False
642
+ #self.paint(self._seg_im)
643
+ self.SubUpdateSegScatterItem()
644
+ elif not self._UseScatter:
645
+ self._UseScatter=True
646
+
647
+ self.update()
648
+ """
649
+ def _localUpdate(self):
650
+
651
+ self.removeItem('scatter_total')
652
+ if self._seg_im is not None:
653
+ self.GLV.setData(self._seg_im.copy(), self._artistic)
654
+ else:
655
+ self.GLV.data = None
656
+ self.GLV.setDepthValue(20)
657
+ self.addItem(self.GLV, 'vol_total')
658
+
659
+ def draw_art_action(self, value):
660
+ self._artistic = False
661
+ if value:
662
+ self._artistic = True
663
+ self.update()
664
+
665
+ def draw_status(self, value):
666
+ try:
667
+ if not value:
668
+ self.removeItem('pol_total')
669
+ self.totalpolys = defaultdict(list)
670
+ totalpolys_camer = defaultdict(list)
671
+ self.GLPl.update_points(self.totalpolys)
672
+ self._enabledPolygon = value
673
+ else:
674
+ self.GLV.setDepthValue(0)
675
+ self._enabledPolygon = value
676
+
677
+
678
+ """
679
+
680
+ if self.GLV._ax==0: #sagittal
681
+ if self.GLV._d==1:
682
+ self.opts['elevation'] = 0
683
+ self.opts['azimuth'] = 0
684
+ else:
685
+ self.opts['elevation'] = 0
686
+ self.opts['azimuth'] = -180
687
+ elif self.GLV._ax==1:#coronal
688
+ if self.GLV._d == 1:
689
+ self.opts['elevation'] = 0
690
+ self.opts['azimuth'] = 90
691
+ else:
692
+ self.opts['elevation'] = 0
693
+ self.opts['azimuth'] = -90
694
+ elif self.GLV._ax==2:#axial
695
+ if self.GLV._d == 1:
696
+ self.opts['elevation'] = 90
697
+ self.opts['azimuth'] = 0
698
+ else:
699
+ self.opts['elevation'] = -90
700
+ self.opts['azimuth'] = 0
701
+ """
702
+ self.SubUpdateSegScatterItem()
703
+ self.showEvent(0)
704
+ self._z = glReadPixels(0, 0, self.height(),self.width(), GL_DEPTH_COMPONENT, GL_FLOAT)
705
+ if 'scatter_total' in self.items:
706
+ self.removeItem('scatter_total')
707
+ self.GLV.setData(self._seg_im, self._artistic)
708
+ self.GLV.setDepthValue(0)
709
+ self.addItem(self.GLV, 'vol_total')
710
+ except Exception as e:
711
+ print(e)
712
+ def axis_status(self, value):
713
+ if not value:
714
+ self.removeItem('ax')
715
+ else:
716
+ self.addItem(self.ax,'ax')
717
+ self.axis_action.setChecked(True)
718
+
719
+ def grid_status(self, value):
720
+ if not value:
721
+ self.removeItem('xyz')
722
+ else:
723
+ self.addItem(self.gx, 'xyz')
724
+ self.grid_action.setChecked(True)
725
+ def artistic_status(self, value):
726
+ self._artistic = True
727
+ if not value:
728
+ self._artistic = False
729
+ self._localUpdate()
730
+
731
+
732
+ def im_seg_status(self, value):
733
+ self.seg_action.setChecked(False)
734
+ if value:
735
+ self._renderMode = 'Seg'
736
+ self._threshold=0
737
+ self.im_seg_action.setChecked(True)
738
+ self.updateSegVolItem(self._image, self._seg_im)
739
+
740
+ #self.removeItem('vol_total')
741
+
742
+ else:
743
+ self._renderMode = 'Img'
744
+ self.im_seg_action.setChecked(False)
745
+
746
+ self.removeItem('vol_total')
747
+ self.paintGL()
748
+
749
+
750
+
751
+ def seg_status(self, value):
752
+ self.im_seg_action.setChecked(False)
753
+
754
+ if value:
755
+ self._renderMode = 'Seg'
756
+ self._threshold=0
757
+
758
+ self.seg_action.setChecked(True)
759
+ #self.removeItem('vol_total')
760
+
761
+ else:
762
+ self._renderMode = 'Img'
763
+ self.seg_action.setChecked(False)
764
+ self.removeItem('vol_total')
765
+ self.paintGL()
766
+ #if hasattr(self, 'GLV'):
767
+ # self.GLV.smooth = value
768
+ # self.GLV._needUpload = True
769
+ # self._localUpdate()
770
+ # self.paintGL()
771
+
772
+
773
+ def goto_status(self, value):
774
+ self._gotoLoc = value
775
+ if not value:
776
+ self.point3dpos.emit(np.array([0,0,0,1]),None)
777
+
778
+
779
+ def changeBG(self, cl):
780
+ self.opts['bgcolor'] = cl
781
+ self._localUpdate()
782
+ self.paintGL()
783
+
784
+ def cmap_image(self, map_type, reset=True):
785
+ if self._image is None:
786
+ return
787
+ if reset:
788
+ self._threshold = 0
789
+ self._renderMode = 'Seg'
790
+ self.seg_action.setChecked(False)
791
+ self._verticalSlider_1.setVisible(True)
792
+ mask = self._image<=(self._image.max()*self._threshold/100)
793
+ if map_type=='original':
794
+ cm = np.repeat(self._image[...,None], 4, -1)
795
+ else:
796
+ import matplotlib.pyplot as plt
797
+ cm = plt.get_cmap(map_type, lut=256)
798
+ cm = cm(self._image / self._image.max()) * 255.0
799
+ #if map_type!='gist_rainbow_r':
800
+ # cm[...,3]=self._image
801
+ self.removeItem('vol_total')
802
+
803
+ self._seg_im = cm
804
+ self._seg_im[mask,:]=0
805
+ #if self._indices is not None:
806
+ self._indices = (1-mask.astype('int'))>0
807
+ self._indices = (self._indices.astype('int') - self._excluded_inds.astype('int')) > 0
808
+ self._seg_im[self._excluded_inds,:]=0
809
+ self.GLV.setData(self._seg_im, self._artistic)
810
+ self.GLV.setDepthValue(20)
811
+ self.addItem(self.GLV, 'vol_total')
812
+ self.paintGL()
813
+ self._lastmap_type = map_type
814
+ self._rendered = 'image'
815
+
816
+ def ShowContextMenu(self, pos):
817
+ # Main Edit Menu
818
+ menu = QMenu("Edit")
819
+
820
+ # Submenu for Background Colors
821
+ self.bgColorMenu = QMenu('Background Color')
822
+
823
+ grc = QAction('Gray')
824
+ gc = QAction("Green")
825
+ oc = QAction("Orange")
826
+ pc = QAction("Pink")
827
+ vc = QAction("Violet")
828
+ rc = QAction("Red")
829
+ bc = QAction("Blue")
830
+ wc = QAction("White")
831
+ yc = QAction("Yellow")
832
+ blc = QAction("Black")
833
+
834
+ gc.triggered.connect(partial(self.changeBG, [0.5, 1, 0.0, 1]))
835
+ oc.triggered.connect(partial(self.changeBG, [1, 0.7, 0.1, 1]))
836
+ pc.triggered.connect(partial(self.changeBG, [1, 0.41, 0.79, 1]))
837
+
838
+ vc.triggered.connect(partial(self.changeBG, [0.93, 0.51, 0.93, 1]))
839
+ wc.triggered.connect(partial(self.changeBG, [0.96, 0.96, 0.86, 1]))
840
+ rc.triggered.connect(partial(self.changeBG, [0.98, 0.5, 0.44, 1]))
841
+ bc.triggered.connect(partial(self.changeBG, [0.25, 0.87, 0.82, 1]))
842
+ yc.triggered.connect(partial(self.changeBG, [1, 0.87, 0.0, 1]))
843
+ blc.triggered.connect(partial(self.changeBG, [0.05, 0.05, 0.05, 1]))
844
+ grc.triggered.connect(partial(self.changeBG, [0.3, 0.3, 0.3, 1]))
845
+ self.bgColorMenu.addAction(gc)
846
+ self.bgColorMenu.addAction(grc)
847
+ self.bgColorMenu.addAction(rc)
848
+ self.bgColorMenu.addAction(bc)
849
+ self.bgColorMenu.addAction(vc)
850
+ self.bgColorMenu.addAction(wc)
851
+ self.bgColorMenu.addAction(oc)
852
+ self.bgColorMenu.addAction(pc)
853
+ self.bgColorMenu.addAction(yc)
854
+ self.bgColorMenu.addAction(blc)
855
+
856
+
857
+ # Submenu for Image Rendering/Colormap Options
858
+ self.imageRenderMenu = QMenu("Image Render")
859
+
860
+ gis_rainbow = QAction("RainBow")
861
+ gis_rainbow.triggered.connect(partial(self.cmap_image, 'gist_rainbow_r'))
862
+
863
+ gray = QAction("Gray")
864
+ gray.triggered.connect(partial(self.cmap_image, 'gray_r'))
865
+
866
+ original = QAction("Original")
867
+ original.triggered.connect(partial(self.cmap_image, 'original'))
868
+
869
+ jet = QAction("JET")
870
+ jet.triggered.connect(partial(self.cmap_image, 'jet_r'))
871
+
872
+ CMRmap = QAction("gnuplot")
873
+ CMRmap.triggered.connect(partial(self.cmap_image, 'gnuplot2'))
874
+
875
+ gnuplot_r = QAction("gnuplot2")
876
+ gnuplot_r.triggered.connect(partial(self.cmap_image, 'gnuplot_r'))
877
+ self.imageRenderMenu.addAction(gis_rainbow)
878
+ self.imageRenderMenu.addAction(gray)
879
+ self.imageRenderMenu.addAction(jet)
880
+ self.imageRenderMenu.addAction(CMRmap)
881
+ self.imageRenderMenu.addAction(gnuplot_r)
882
+ self.imageRenderMenu.addAction(original)
883
+
884
+
885
+ # Submenu for Segmentation Options
886
+ self.segmentationMenu = QMenu('Segmentation')
887
+ self.segmentationMenu.addAction(self.im_seg_action)
888
+ self.segmentationMenu.addAction(self.seg_action)
889
+
890
+ # Submenu for Drawing Options
891
+ self.paintingMenu = QMenu('Painting')
892
+ self.paintingMenu.addAction(self.draw_action)
893
+ self.paintingMenu.addAction(self.draw_art)
894
+ self.paintingMenu.addAction(self.clear_action)
895
+ self.paintingMenu.addMenu(self.imageRenderMenu) # Nested menu for image rendering
896
+
897
+ # View Options (Axis, Grid, Slice)
898
+ self.viewMenu = QMenu("View Options")
899
+ self.viewMenu.addAction(self.axis_action)
900
+ self.viewMenu.addAction(self.grid_action)
901
+ self.viewMenu.addAction(self.one_third_action)
902
+
903
+ # Actions directly in the main menu
904
+ menu.addMenu(self.bgColorMenu) # Background Color
905
+ menu.addMenu(self.paintingMenu) # Painting and Image Rendering
906
+ menu.addMenu(self.segmentationMenu) # Segmentation
907
+ menu.addMenu(self.viewMenu) # View Options
908
+ menu.addAction(self.screenshot_action) # Screenshot
909
+ menu.addAction(self.goto_action) # GoTo
910
+
911
+ menu.exec_(self.mapToGlobal(pos))
912
+
913
+ def ShowContextMenu_old(self, pos):
914
+ menu = QMenu("Edit")
915
+ #remove_action = QAction("Unknown")
916
+ #remove_action.triggered.connect(self.changedata)
917
+
918
+ self.menu1 = QMenu('BG Color')
919
+ self.painting = QMenu('Painting')
920
+ self.menuSeg = QMenu('Show Seg.')
921
+ self.image_action = QMenu("Image Render")
922
+
923
+ gis_rainbow = QAction("RainBow")
924
+ gis_rainbow.triggered.connect(partial(self.cmap_image, 'gist_rainbow_r'))
925
+
926
+ gray = QAction("Gray")
927
+ gray.triggered.connect(partial(self.cmap_image, 'gray_r'))
928
+
929
+ original = QAction("Original")
930
+ original.triggered.connect(partial(self.cmap_image, 'original'))
931
+
932
+ jet = QAction("JET")
933
+ jet.triggered.connect(partial(self.cmap_image, 'jet_r'))
934
+
935
+ CMRmap = QAction("gnuplot")
936
+ CMRmap.triggered.connect(partial(self.cmap_image, 'gnuplot2'))
937
+
938
+ gnuplot_r = QAction("gnuplot2")
939
+ gnuplot_r.triggered.connect(partial(self.cmap_image, 'gnuplot_r'))
940
+ self.image_action.addAction(gis_rainbow)
941
+ self.image_action.addAction(gray)
942
+ self.image_action.addAction(jet)
943
+ self.image_action.addAction(CMRmap)
944
+ self.image_action.addAction(gnuplot_r)
945
+ self.image_action.addAction(original)
946
+ grc = QAction('Gray')
947
+ gc = QAction("Green")
948
+ oc = QAction("Orange")
949
+ pc = QAction("Pink")
950
+ vc = QAction("Violet")
951
+ rc = QAction("Red")
952
+ bc = QAction("Blue")
953
+ wc = QAction("White")
954
+ yc = QAction("Yellow")
955
+ blc = QAction("Black")
956
+ """
957
+
958
+ dict_color = {
959
+ "Green":[0.1, 1, 0.7,1],
960
+ "Yellow":[1, 0.7, 0.1, 1],
961
+ "Violet":[0.7, 0.1, 1, 1],
962
+ "Red":[1, 1, 1.0,1],
963
+ "Blue":[1, 0.1, 0.1, 1],
964
+ "White":[0.0, 0.1, 1, 1]
965
+
966
+ }
967
+ for key in dict_color:
968
+ act = QAction(key)
969
+ act.triggered.connect(partial(self.changeBG, dict_color[key]))
970
+ self.menu1.addAction(act)
971
+ """
972
+
973
+ gc.triggered.connect(partial(self.changeBG, [0.5, 1, 0.0, 1]))
974
+ oc.triggered.connect(partial(self.changeBG, [1, 0.7, 0.1, 1]))
975
+ pc.triggered.connect(partial(self.changeBG, [1, 0.41, 0.79, 1]))
976
+
977
+ vc.triggered.connect(partial(self.changeBG, [0.93, 0.51, 0.93, 1]))
978
+ wc.triggered.connect(partial(self.changeBG, [0.96, 0.96, 0.86, 1]))
979
+ rc.triggered.connect(partial(self.changeBG, [0.98, 0.5, 0.44, 1]))
980
+ bc.triggered.connect(partial(self.changeBG, [0.25, 0.87, 0.82, 1]))
981
+ yc.triggered.connect(partial(self.changeBG, [1, 0.87, 0.0, 1]))
982
+ blc.triggered.connect(partial(self.changeBG, [0.05, 0.05, 0.05, 1]))
983
+ grc.triggered.connect(partial(self.changeBG, [0.3, 0.3, 0.3, 1]))
984
+ self.menu1.addAction(gc)
985
+ self.menu1.addAction(grc)
986
+ self.menu1.addAction(rc)
987
+ self.menu1.addAction(bc)
988
+ self.menu1.addAction(vc)
989
+ self.menu1.addAction(wc)
990
+ self.menu1.addAction(oc)
991
+ self.menu1.addAction(pc)
992
+ self.menu1.addAction(yc)
993
+ self.menu1.addAction(blc)
994
+
995
+ #cb = QtGui.QGuiApplication.clipboard()
996
+ #cb.clear(mode=cb.Clipboard)
997
+ #cb.setText("Clipboard Text", mode=cb.Clipboard)
998
+ #menu.addAction(remove_action)
999
+ menu.addAction(self.goto_action)
1000
+ #menu.addAction(self.draw_action)
1001
+
1002
+
1003
+ self.menuSeg.addSeparator()
1004
+ self.menuSeg.addAction(self.im_seg_action)
1005
+ self.menuSeg.addAction(self.seg_action)
1006
+ menu.addMenu(self.menuSeg)
1007
+
1008
+ menu.addMenu(self.menu1)
1009
+ menu.addMenu(self.painting)
1010
+
1011
+
1012
+
1013
+ self.painting.addAction(self.draw_action)
1014
+ self.painting.addAction(self.draw_art)
1015
+ self.painting.addAction(self.clear_action)
1016
+ self.painting.addMenu(self.image_action)
1017
+
1018
+
1019
+ menu.addAction(self.axis_action)
1020
+ menu.addAction(self.grid_action)
1021
+ menu.addAction(self.one_third_action)
1022
+ menu.addAction(self.screenshot_action)
1023
+ menu.exec_(self.mapToGlobal(pos))
1024
+
1025
+ def changeAxis(self, polygon, axis):
1026
+ if axis == 'coronal':
1027
+ polygon = polygon[:, [0, 2, 1]]
1028
+ # polygon = np.flipud(polygon)
1029
+ polygon[:, 0] = self.maxXYZ[2] - polygon[:, 0]
1030
+ polygon[:, 2] = self.maxXYZ[0] - polygon[:, 2]
1031
+ elif axis == 'sagittal':
1032
+ polygon = polygon[:, [2, 0, 1]]
1033
+ #polygon[:, 1] = self.maxXYZ[2] - polygon[:, 1]
1034
+ polygon[:, 2] = self.maxXYZ[0] - polygon[:, 2]
1035
+ #polygon[:,0] = -polygon[:,0]
1036
+ #polygon[:,2] = -polygon[:,2]
1037
+ elif axis == 'axial':
1038
+ polygon = polygon[:, [0, 1, 2]]
1039
+ polygon[:, 0] = self.maxXYZ[2] - polygon[:, 0]
1040
+ #polygon[:, 2] = self.maxXYZ[2] - polygon[:, 2]
1041
+ return polygon
1042
+
1043
+
1044
+ def updateSegSlice(self, imSeg, edges, currentWidnowName, sliceNum):
1045
+ """
1046
+ :param totalPs: keys of total points
1047
+ :param changedIndice: indices of key name
1048
+ :return:
1049
+ """
1050
+ minimum_area = 2
1051
+ if currentWidnowName.lower() == 'coronal':
1052
+ subim = imSeg[:,sliceNum,:]
1053
+ d = np.where(subim > 0)
1054
+ contours, hierarchy = cv2.findContours(image=subim.astype(np.uint8), mode=cv2.RETR_TREE,
1055
+ method=cv2.CHAIN_APPROX_NONE)
1056
+ if len(contours)==0:
1057
+ item = GLScatterPlotItem(pos=np.empty(shape=(0,3), dtype=np.int64), color=np.empty(shape=(0,4), dtype=np.float64), pxMode=True, size=5)
1058
+ self.addItem(item, 'scatter_{}_{}'.format(currentWidnowName, sliceNum))
1059
+ return
1060
+ else:
1061
+ cnts = []
1062
+ i = 0
1063
+ for contour in contours:
1064
+ if cv2.contourArea(contour)<minimum_area:
1065
+ continue
1066
+ cnt = contour.squeeze()
1067
+ val = subim[cnt[0, 1], cnt[0, 0]]
1068
+ if val > 150:
1069
+ val -= 150
1070
+ subc = subim[cnt[:, 1], cnt[:, 0]]
1071
+ if sum(subc>150)>0:
1072
+ subc[subc>150] = subc[subc>150] - 150
1073
+ subim[cnt[:, 1], cnt[:, 0]] = subc
1074
+ cnts.append([cnt, val])
1075
+ subim[cnt[:, 1], cnt[:, 0]] = 150+subim[cnt[0, 1], cnt[0, 0]]
1076
+ print(np.unique(subim))
1077
+ print(i)
1078
+ i+=1
1079
+ print('')
1080
+ #cnt = contours[0].squeeze()
1081
+
1082
+ #subim[cnt[:, 1], cnt[:, 0]] = 150+subim[cnt[0, 1], cnt[0, 0]]
1083
+ points = np.vstack((d[0], np.repeat(sliceNum,len(d[0])), d[1])).transpose([1,0])[:,[2,1,0]]
1084
+ #cnts = np.vstack((cnt[:, 1], np.repeat(sliceNum, cnt.shape[0]), cnt[:, 0] )).transpose([1, 0])[:, [2, 1, 0]]
1085
+ elif currentWidnowName.lower() == 'sagittal':
1086
+ subim = imSeg[:,:,sliceNum]
1087
+ d = np.where(subim > 0)
1088
+ contours, hierarchy = cv2.findContours(image=subim.astype(np.uint8), mode=cv2.RETR_TREE,
1089
+ method=cv2.CHAIN_APPROX_NONE)
1090
+ if len(contours)==0:
1091
+ item = GLScatterPlotItem(pos=np.empty(shape=(0,3), dtype=np.int64), color=np.empty(shape=(0,4), dtype=np.float64), pxMode=True, size=5)
1092
+ self.addItem(item, 'scatter_{}_{}'.format(currentWidnowName, sliceNum))
1093
+ return
1094
+ else:
1095
+ cnts = []
1096
+ for contour in contours:
1097
+ if cv2.contourArea(contour)<minimum_area:
1098
+ continue
1099
+ cnt = contour.squeeze()
1100
+ val = subim[cnt[0, 1], cnt[0, 0]]
1101
+ if val>150:
1102
+ val -= 150
1103
+ d = subim[cnt[:, 1], cnt[:, 0]]
1104
+ if sum(d>150)>0:
1105
+ d[d>150] = d[d>150] - 150
1106
+ subim[cnt[:, 1], cnt[:, 0]] = d
1107
+ cnts.append([cnt, val] )
1108
+ subim[cnt[:, 1], cnt[:, 0]] = 150+subim[cnt[0, 1], cnt[0, 0]]
1109
+ points = np.vstack((d[0], d[1],np.repeat(sliceNum,len(d[0])))).transpose([1,0])[:,[2,1,0]]
1110
+ #cnts = np.vstack((cnt[:, 1], cnt[:, 0], np.repeat(sliceNum, cnt.shape[0]))).transpose([1, 0])[:, [2, 1, 0]]
1111
+ elif currentWidnowName.lower() == 'axial':
1112
+ subim = imSeg[sliceNum,:,:]
1113
+ d = np.where(subim > 0)
1114
+ contours, hierarchy = cv2.findContours(image=subim.astype(np.uint8), mode=cv2.RETR_TREE,
1115
+ method=cv2.CHAIN_APPROX_NONE)
1116
+ if len(contours)==0:
1117
+ item = GLScatterPlotItem(pos=np.empty(shape=(0,3), dtype=np.int64), color=np.empty(shape=(0,4), dtype=np.float64), pxMode=True, size=5)
1118
+ self.addItem(item, 'scatter_{}_{}'.format(currentWidnowName, sliceNum))
1119
+ return
1120
+ else:
1121
+ cnts = []
1122
+ for contour in contours:
1123
+ if cv2.contourArea(contour)<minimum_area:
1124
+ continue
1125
+ cnt = contour.squeeze()
1126
+ val = subim[cnt[0, 1], cnt[0, 0]]
1127
+ if val > 150:
1128
+ val -= 150
1129
+ d = subim[cnt[:, 1], cnt[:, 0]]
1130
+ if sum(d>150)>0:
1131
+ d[d>150] = d[d>150] - 150
1132
+ subim[cnt[:, 1], cnt[:, 0]] = d
1133
+ cnts.append([cnt, val])
1134
+ subim[cnt[:, 1], cnt[:, 0]] = 150+subim[cnt[0, 1], cnt[0, 0]]
1135
+ #cnt = contours[0].squeeze()
1136
+ #subim[cnt[:, 1], cnt[:, 0]] = 150+subim[cnt[0, 1], cnt[0, 0]]
1137
+ points = np.vstack((np.repeat(sliceNum,len(d[0])),d[0], d[1])).transpose([1,0])[:,[2,1,0]]
1138
+ #cnts = np.vstack((np.repeat(sliceNum, cnt.shape[0]), cnt[:, 1], cnt[:, 0] )).transpose([1, 0])[:, [2, 1, 0]]
1139
+
1140
+
1141
+ #d = np.where(imSeg>0)
1142
+ #if d[0].shape[0]<=1:
1143
+ #return
1144
+ #points = np.vstack((d[0], d[1], d[2])).transpose([1, 0])[:,[2,1,0]]
1145
+
1146
+ points[:, 0] = self.maxXYZ[2] - points[:, 0]
1147
+ points[:, 2] = self.maxXYZ[0] - points[:, 2]
1148
+
1149
+ #cnts[:, 0] = self.maxXYZ[2] - cnts[:, 0]
1150
+ #cnts[:, 2] = self.maxXYZ[0] - cnts[:, 2]
1151
+
1152
+
1153
+ """
1154
+ if windowName == 'coronal':
1155
+ points[:, 0] = self.maxXYZ[2] - points[:, 0]
1156
+ points[:, 2] = self.maxXYZ[0] - points[:, 2]
1157
+ elif windowName == 'sagittal':
1158
+ points[:, 2] = self.maxXYZ[0] - points[:, 2]
1159
+ elif windowName == 'axial':
1160
+ points[:, 0] = self.maxXYZ[2] - points[:, 0]
1161
+ """
1162
+ colors = np.zeros((points.shape[0], 4))
1163
+ #colors[:, 3] = imSeg[tuple(zip(d))].squeeze()
1164
+ #colors[:, 2] = data[tuple(zip(d))].squeeze()
1165
+ #colors[:, 1] = data[tuple(zip(d))].squeeze()
1166
+ colorsInd = subim[tuple(zip(d))].transpose().squeeze()
1167
+ for cl in np.unique(colorsInd[colorsInd<=150]):
1168
+ if cl == 0:
1169
+ continue
1170
+ ind = colorsInd == cl
1171
+ colorval = self.colorsCombinations[int(cl)]
1172
+ colors[ind,:] =colorval
1173
+
1174
+ ind_edge = colorsInd == cl+150
1175
+ colorval_edge = (0.,0.,0.,1.0)
1176
+ colors[ind_edge, :] = colorval_edge
1177
+ for cnt0 in cnts:
1178
+ cnt, cl = cnt0
1179
+ subim[cnt[:, 1], cnt[:, 0]] = cl
1180
+ #colors[:,0] = 255.0
1181
+ #colors = colors/255.0
1182
+ item = GLScatterPlotItem(pos=points, color = colors, pxMode=True, size=5)
1183
+ self.addItem(item, 'scatter_{}_{}'.format(currentWidnowName, sliceNum))
1184
+
1185
+ return
1186
+
1187
+
1188
+ def updateSegVolItem(self, imSeg = None, imOrg = None, currentWidnowName=None, sliceNum = None):
1189
+ """
1190
+ :param totalPs: keys of total points
1191
+ :param changedIndice: indices of key name
1192
+ :return:
1193
+ """
1194
+ self.removeItem('scatter_total')
1195
+ d = np.where(imSeg>0)
1196
+ if d[0].shape[0]<=1:
1197
+ return
1198
+ self.maxXYZ_current = [d[0].max(),d[1].max(),d[2].max()]
1199
+
1200
+ self.minXYZ_current = [d[0].min(),d[1].min(),d[2].min()]
1201
+ if d[0].shape[0]<=1:
1202
+ self.removeItem('scatter_total')
1203
+ return
1204
+
1205
+
1206
+ """
1207
+ if windowName == 'coronal':
1208
+ points[:, 0] = self.maxXYZ[2] - points[:, 0]
1209
+ points[:, 2] = self.maxXYZ[0] - points[:, 2]
1210
+ elif windowName == 'sagittal':
1211
+ points[:, 2] = self.maxXYZ[0] - points[:, 2]
1212
+ elif windowName == 'axial':
1213
+ points[:, 0] = self.maxXYZ[2] - points[:, 0]
1214
+ """
1215
+
1216
+ #colors[:, 3] = imSeg[tuple(zip(d))].squeeze()
1217
+ #colors[:, 2] = data[tuple(zip(d))].squeeze()
1218
+ #colors[:, 1] = data[tuple(zip(d))].squeeze()
1219
+ colorsInd = imSeg[tuple(zip(d))].squeeze()
1220
+ uq = np.unique(colorsInd)
1221
+ if 9876 not in self.colorInds: # len(self.colorsCombinations):
1222
+ selected_ud = self.colorInds
1223
+ else:
1224
+ selected_ud = uq
1225
+ _seg_im = np.zeros((*imSeg.shape, 4))
1226
+ indics = 0
1227
+ for cl in uq:
1228
+ if cl in selected_ud:
1229
+ ind = imSeg == cl
1230
+ indics += ind
1231
+ try:
1232
+ colorval = self.colorsCombinations[int(cl)]
1233
+ _seg_im[ind, :] = colorval
1234
+ except:
1235
+ print('Index {} does not have a representative color.'.format(int(cl)))
1236
+ #colors[:,0] = 255.0
1237
+ #colors = colors/255.0
1238
+ #if self._indices is None:
1239
+ self._indices = indics>self._threshold
1240
+ self._rendered = 'seg'
1241
+ self._verticalSlider_1.setVisible(False)
1242
+ _seg_im *= 255
1243
+ _seg_im[self._excluded_inds,:]=0
1244
+ #im_or = np.repeat(imOrg[..., None], [4], axis=-1)
1245
+ #im_or[indics<=0,:]=0
1246
+ #a = self.intensitySeg * _seg_im + (1 - self.intensitySeg) * im_or
1247
+
1248
+ if self.im_seg_action.isChecked():
1249
+ cm = np.repeat(self._image[..., None], 4, -1)
1250
+ mask = self._image <= (self._image.max() * self._threshold / 100)
1251
+
1252
+ cm_rgb = cm[...,:3]/255.0
1253
+ #cm_rgb[imSeg>0,:]=0 # remove segmented ROIs from the original image
1254
+ cm_alpha = cm[...,3]/255.0
1255
+
1256
+ seg_rgb = _seg_im[...,:3]/255.0
1257
+ seg_alpha = _seg_im[..., 3]/ 255.0
1258
+
1259
+ cm_alpha *=0.02
1260
+ #seg_alpha *= 0.98 # linear
1261
+ seg_alpha = np.sqrt(seg_alpha) # non linear
1262
+
1263
+ composite_alpha = cm_alpha + seg_alpha *(1-cm_alpha)
1264
+
1265
+ composite_alpha_clipped = np.clip(composite_alpha, a_min=1e-10, a_max=None)
1266
+ composite_rgb = (cm_rgb * cm_alpha[..., np.newaxis] + seg_rgb * seg_alpha[..., np.newaxis] * (
1267
+ 1 - cm_alpha[..., np.newaxis])) / composite_alpha_clipped[..., np.newaxis]
1268
+ composite_rgb[composite_alpha == 0] = 0
1269
+ composite_alpha[composite_alpha == 0] = 1
1270
+ _seg_im = np.concatenate((composite_rgb*255.0, composite_alpha[..., np.newaxis] * 255), axis=-1)
1271
+ _seg_im[mask,:] = 0
1272
+ #self._seg_im = _seg_im
1273
+ #self.GLV.setData(_seg_im, self._artistic)
1274
+
1275
+ self._seg_im = _seg_im
1276
+ self.GLV.setData(_seg_im, self._artistic)
1277
+
1278
+ self.GLV.setDepthValue(20)
1279
+ self.addItem(self.GLV, 'vol_total')
1280
+
1281
+ return
1282
+
1283
+
1284
+
1285
+ def SubUpdateSegScatterItem(self):
1286
+ if self._seg_im is None:
1287
+ return
1288
+ if self._indices is None:
1289
+ self._indices = self._image>0
1290
+ self.removeItem('vol_total')
1291
+ d = np.where(self._indices)
1292
+ if d[0].shape[0]<=1:
1293
+ return
1294
+ points = np.vstack((d[0], d[1], d[2])).transpose([1, 0]) # [:,[2,1,0]]
1295
+
1296
+ points[:, 0] = self.maxXYZ[0] - points[:, 0] # axial
1297
+ points[:, 2] = self.maxXYZ[2] - points[:, 2] # sagittal
1298
+ # points[:, 1] = self.maxXYZ[1] - points[:, 1]#coronal
1299
+ points = points[:, [2, 1, 0]]
1300
+ colors = self._seg_im[self._indices]/255.0
1301
+
1302
+ self.GLSC.setData(pos=points, color = colors, pxMode=True, size=5)
1303
+ self.addItem(self.GLSC, 'scatter_total')
1304
+
1305
+ def updateSegScatterItem(self, imSeg, windowName):
1306
+ """
1307
+ :param totalPs: keys of total points
1308
+ :param changedIndice: indices of key name
1309
+ :return:
1310
+ """
1311
+ self.removeItem('vol_total')
1312
+
1313
+ d = np.where(imSeg>0)
1314
+ if d[0].shape[0]<=1:
1315
+ self.removeItem('scatter_total')
1316
+ return
1317
+ points = np.vstack((d[0], d[1], d[2])).transpose([1, 0])#[:,[2,1,0]]
1318
+
1319
+ points[:, 0] = self.maxXYZ[0] - points[:, 0]#axial
1320
+ points[:, 2] = self.maxXYZ[2] - points[:, 2]#sagittal
1321
+ #points[:, 1] = self.maxXYZ[1] - points[:, 1]#coronal
1322
+ points = points[:,[2,1,0]]
1323
+
1324
+ """
1325
+ if windowName == 'coronal':
1326
+ points[:, 0] = self.maxXYZ[2] - points[:, 0]
1327
+ points[:, 2] = self.maxXYZ[0] - points[:, 2]
1328
+ elif windowName == 'sagittal':
1329
+ points[:, 2] = self.maxXYZ[0] - points[:, 2]
1330
+ elif windowName == 'axial':
1331
+ points[:, 0] = self.maxXYZ[2] - points[:, 0]
1332
+ """
1333
+ colors = np.ones((points.shape[0], 4))*10000
1334
+ #colors[:, 3] = imSeg[tuple(zip(d))].squeeze()
1335
+ #colors[:, 2] = data[tuple(zip(d))].squeeze()
1336
+ #colors[:, 1] = data[tuple(zip(d))].squeeze()
1337
+ colorsInd = imSeg[tuple(zip(d))].squeeze()
1338
+ uq = np.unique(colorsInd)
1339
+ if 9876 not in self.colorInds: # len(self.colorsCombinations):
1340
+ selected_ud = self.colorInds
1341
+ else:
1342
+ selected_ud = uq
1343
+
1344
+ for cl in uq:
1345
+ if cl == 0:
1346
+ continue
1347
+ if cl in selected_ud:
1348
+ ind = colorsInd == cl
1349
+ try:
1350
+ colorval = self.colorsCombinations[int(cl)]
1351
+ colors[ind,:] =colorval
1352
+ except:
1353
+ print('Index {} does not have a representative color.'.format(int(cl)))
1354
+ #colors[:,0] = 255.0
1355
+ #colors = colors/255.0
1356
+ ind_non_zero = colors.sum(1)!=10000*4
1357
+ self.GLSC.setData(pos=points[ind_non_zero, :], color = colors[ind_non_zero, :], pxMode=True, size=5)
1358
+ self.addItem(self.GLSC, 'scatter_total')
1359
+ return
1360
+ if len(changedIndice)== 0:
1361
+ return
1362
+
1363
+ for axis in totalPs.keys():
1364
+ for Pls in totalPs[axis].keys():
1365
+ for key in totalPs[axis][Pls].keys():
1366
+ keyName = str(axis) + '_' + str(Pls) + '_' + str(key)
1367
+ if keyName in changedIndice:
1368
+ ind = changedIndice.index(keyName)
1369
+ self.removeItem(keyName)
1370
+ polyg, color = totalPs[axis][Pls][key]
1371
+ polygon = np.array(list(polyg.exterior.coords))
1372
+ polygon = self.changeAxis(polygon, axis)
1373
+ keyName = str(axis) + '_' + str(Pls) + '_' + str(key)
1374
+ polygon = np.array(PolygonTessellator().tessellate(polygon))
1375
+ self.addSegItem(polygon, keyName, color)
1376
+ changedIndice.pop(ind)
1377
+ if len(changedIndice) != 0:
1378
+ for keyName in changedIndice:
1379
+ self.removeItem(keyName)
1380
+
1381
+
1382
+
1383
+
1384
+ #def paint(self, imSeg = None, edges = None, currentWidnowName=None, sliceNum = None):
1385
+ def paint(self, imSeg = None, im = None, currentWidnowName=None, sliceNum = None):
1386
+ if not self._updatePaint:
1387
+ return
1388
+ if not self._renderMode.lower()=='seg':
1389
+ return
1390
+ #self._seg_im = imSeg
1391
+ #if imSeg is not None:
1392
+ #if currentWidnowName is None:
1393
+ #if self._UseScatter:
1394
+ # self.updateSegScatterItem(imSeg, currentWidnowName)
1395
+ #else:
1396
+
1397
+ self.updateSegVolItem(imSeg, currentWidnowName)
1398
+ #else:
1399
+ # self.updateSegSlice(imSeg, edges, currentWidnowName, sliceNum)
1400
+
1401
+ if self.isVisible():
1402
+ self.show()
1403
+
1404
+
1405
+ def load_paint(self, imSeg):
1406
+
1407
+ if hasattr(self,'items_names'):
1408
+ if len(self.items_names)>3:
1409
+ try:
1410
+ total_items = list(set(self.items_names) - set(['scatter_total', 'xyz', 'ax']))
1411
+ for item in total_items:
1412
+ _, currentWidnowName, sliceNum = item.split('_')
1413
+ sliceNum = int(sliceNum)
1414
+ self.updateSegSlice(imSeg, [], currentWidnowName, sliceNum)
1415
+ delattr(self, 'items_names')
1416
+ self.update()
1417
+ except:
1418
+ self.paint(imSeg, None)
1419
+ else:
1420
+ self.paint(imSeg, None)
1421
+ if hasattr(self, 'items_names'):
1422
+ delattr(self, 'items_names')
1423
+
1424
+
1425
+ def createGridAxis(self, maxcoord):
1426
+ self.removeItem('vol_total')
1427
+ #maxcoord = self.testTest()
1428
+ ############# create the background grids #############
1429
+ self.setMaxCoords(maxcoord)
1430
+
1431
+ #self._seg_im = np.zeros((*maxcoord,1)).squeeze()
1432
+ if len(self.totalItems['axis']) != 0:
1433
+ self.removeItem(self.totalItems['axis'][0])
1434
+ self.removeItem(self.totalItems['axis'][1])
1435
+ #self.removeItem(self.totalItems['axis'][2])
1436
+ #self.removeItem(self.totalItems['axis'][3])
1437
+ del self.totalItems['axis']
1438
+ zmax, ymax, xmax = maxcoord
1439
+ self.maxXYZ = [zmax, ymax, xmax]
1440
+ self._excluded_inds = np.zeros((self.maxXYZ[0],self.maxXYZ[1],self.maxXYZ[2]), bool)
1441
+ self._excluded_inds[:]=False
1442
+ xvals = np.arange(0, xmax + xmax/10, xmax/5).astype(np.int64)
1443
+ yvals = np.arange(0, ymax + ymax/10, ymax/5).astype(np.int64)
1444
+ zvals = np.arange(0, zmax + zmax/10, zmax/5).astype(np.int64)
1445
+
1446
+ self.maxXYZ = [zmax, ymax, xmax]
1447
+ self.maxXYZ_current = [zmax, ymax, xmax]
1448
+ self.minXYZ_current = [0, 0, 0]
1449
+ #xvals = -np.arange(0, xmax + xmax/5, xmax/5).astype("int")[::-1]
1450
+ #yvals = -np.arange(0, ymax + ymax/5, ymax/5).astype("int")[::-1]
1451
+ #zvals = -np.arange(0, zmax + zmax/5, zmax/5).astype("int")[::-1]
1452
+
1453
+ zmax = zvals[-1]; ymax = yvals[-1]; xmax=xvals[-1]
1454
+ zmin = zvals[0];ymin = yvals[0];xmin = xvals[0]
1455
+ self.gx = GLGridItem(glOptions='translucent', color=[0,0,0,1])
1456
+ self.gx.setGrid(xvals, yvals, zvals )
1457
+ self.gx.setDepthValue(0)
1458
+
1459
+
1460
+
1461
+
1462
+
1463
+ #gx.translate(-zmax, 0, 0)
1464
+ #gx.rotate(90, 0, 1, 0)
1465
+ #gx.translate(0, 0, zmax)
1466
+ self.totalItems['axis'].append('xyz')
1467
+ self.addItem(self.gx, 'xyz')
1468
+
1469
+ #imxz = np.zeros((xmax, zmax,3))
1470
+ #Imxz = GLImageItem(imxz, color=[1,1,0,1], program=self.program)
1471
+ #Imxz.rotate(90,0,1,0)
1472
+ #self.addItem(Imxz, 'imxz')
1473
+
1474
+ #gy = gl.GLGridItem(glOptions='opaque', program=self.program)
1475
+ #gy.rotate(90, 1, 0, 0)
1476
+ #gy.setGrid(xvals, zvals)
1477
+ #self.totalItems['axis'].append('y')
1478
+ #self.addItem(gy, 'y')
1479
+
1480
+ #gz = gl.GLGridItem(glOptions='opaque', program=self.program)
1481
+ #gz.setGrid(xvals, yvals)
1482
+ #self.totalItems['axis'].append('z')
1483
+ #self.addItem(gz, 'z')
1484
+
1485
+ ############# axis #############
1486
+ self.ax = GLAxisItem(antialias=True, glOptions='translucent')
1487
+ self.ax.setDepthValue(0)
1488
+ self.ax.setGLViewWidget(self)
1489
+ #ax.setSize(0, xmax, 0, ymax, 0, zmax)
1490
+ self.ax.setSize(xmin, xmax, ymin,ymax, zmin, zmax)
1491
+ self.ax.setOriging(maxcoord[2]/2,maxcoord[1]/2,maxcoord[0]/2)
1492
+ self.totalItems['axis'].append('ax')
1493
+ self.addItem(self.ax, 'ax')
1494
+
1495
+ # Switch to 'nearly' orthographic projection.
1496
+ #self.opts['distance'] = 40000
1497
+ self.opts['fov'] = 45
1498
+ self.opts['elevation'] = 45
1499
+ self.opts['azimuth'] = 45
1500
+
1501
+ self.setCameraPosition(pos=QVector3D(maxcoord[2]/2,maxcoord[1]/2,maxcoord[0]/2), rotation=(0,0,1,1),
1502
+ distance= max(xmax, ymax, zmax))
1503
+ #distance=np.sqrt(maxcoord[0]**2+maxcoord[1]**2+maxcoord[2]**2),
1504
+ #)
1505
+ self.totalPolyItems = []
1506
+
1507
+ self._enabledPolygon = False
1508
+ self._indices = None
1509
+ self._rendered = 'seg'
1510
+ self._numPolys = 0
1511
+ self.totalpolys = defaultdict(list)
1512
+ self.totalpolys_camer = defaultdict(list)
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+ # Start Qt event loop unless running in interactive mode.
1520
+ class Ui_Main0():
1521
+ NumRows = 2
1522
+ NumColumns = 3
1523
+
1524
+ def __init__(self):
1525
+ super(Ui_Main0, self).__init__()
1526
+
1527
+ self.glWidgets = []
1528
+
1529
+ def setupUi(self, Main):
1530
+ Main.resize(2000, 1800)
1531
+ self.centralwidget = QWidget(Main)
1532
+ self.centralwidget.setEnabled(True)
1533
+ self.v = glScientific(self.centralwidget)
1534
+
1535
+
1536
+ import pickle
1537
+ #with open('dictionary', 'wb') as output:
1538
+ # pickle.dump(self.colorsCombinations, output, pickle.HIGHEST_PROTOCOL)
1539
+ with open('dictionary', 'rb') as output:
1540
+ r = pickle.load(output)
1541
+
1542
+ self.v.colorsCombinations = r
1543
+ self.v.colorInds = [85,45]
1544
+ #v.animation()
1545
+
1546
+ class MainWindow0(QWidget, Ui_Main0):
1547
+ def __init__(self, *args, obj=None, **kwargs):
1548
+ super(MainWindow0, self).__init__(*args, **kwargs)
1549
+ #QtGui.QWidget.__init__(self)
1550
+ self.setupUi(self)
1551
+ from nibabel import load
1552
+ #nii = load('inp.nii')
1553
+ #data = np.squeeze(nii.get_data())
1554
+
1555
+ data = np.load('aa.npy')
1556
+ data = data.astype("float") # Typecast to float
1557
+ #data = data[:, :, ::-1]
1558
+ self.v._renderMode = 'seg'
1559
+ self.v._excluded_inds = np.zeros_like(data).astype('bool')
1560
+ self.v._excluded_inds[:] = False
1561
+ self.v.createGridAxis(list(data.shape))
1562
+ self.v.paint(data)
1563
+ self.v.show()
1564
+
1565
+ data = np.rot90(data, axes=(1, 2))# x
1566
+ data = np.rot90(data, axes=(0, 2)) #y
1567
+ data = np.rot90(data, axes=(0, 1)) # z
1568
+
1569
+ #data = np.load('ab.npy')
1570
+ #data = data.astype("float") # Typecast to float
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+ if __name__ == '__main__':
1577
+ app = QApplication(sys.argv)
1578
+
1579
+ window = MainWindow0()
1580
+
1581
+ #window.show()
1582
+ sys.exit(app.exec_())
1583
+
1584
+
1585
+