PaIRS-UniNa 0.2.9__cp310-cp310-macosx_11_0_universal2.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 (333) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +346 -0
  2. PaIRS_UniNa/Changes.txt +162 -0
  3. PaIRS_UniNa/Custom_Top.py +303 -0
  4. PaIRS_UniNa/Explorer.py +3168 -0
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +831 -0
  7. PaIRS_UniNa/Input_Tab_CalVi.py +786 -0
  8. PaIRS_UniNa/Input_Tab_tools.py +3022 -0
  9. PaIRS_UniNa/Log_Tab.py +110 -0
  10. PaIRS_UniNa/Output_Tab.py +922 -0
  11. PaIRS_UniNa/PaIRS.py +18 -0
  12. PaIRS_UniNa/PaIRS_PIV.py +873 -0
  13. PaIRS_UniNa/PaIRS_pypacks.py +1421 -0
  14. PaIRS_UniNa/Process_Tab.py +1757 -0
  15. PaIRS_UniNa/Process_Tab_CalVi.py +313 -0
  16. PaIRS_UniNa/Process_Tab_Disp.py +163 -0
  17. PaIRS_UniNa/Process_Tab_Min.py +120 -0
  18. PaIRS_UniNa/ResizePopup.py +55 -0
  19. PaIRS_UniNa/SPIVCalHelp.py +155 -0
  20. PaIRS_UniNa/Saving_tools.py +296 -0
  21. PaIRS_UniNa/TabTools.py +1254 -0
  22. PaIRS_UniNa/Vis_Tab.py +2169 -0
  23. PaIRS_UniNa/Vis_Tab_CalVi.py +983 -0
  24. PaIRS_UniNa/Whatsnew.py +130 -0
  25. PaIRS_UniNa/_PaIRS_PIV.so +0 -0
  26. PaIRS_UniNa/__init__.py +6 -0
  27. PaIRS_UniNa/__main__.py +45 -0
  28. PaIRS_UniNa/addwidgets_ps.py +1133 -0
  29. PaIRS_UniNa/calib.py +1488 -0
  30. PaIRS_UniNa/calibView.py +833 -0
  31. PaIRS_UniNa/gPaIRS.py +3914 -0
  32. PaIRS_UniNa/gPalette.py +189 -0
  33. PaIRS_UniNa/icons/abort.png +0 -0
  34. PaIRS_UniNa/icons/about.png +0 -0
  35. PaIRS_UniNa/icons/align_all.png +0 -0
  36. PaIRS_UniNa/icons/announcement.png +0 -0
  37. PaIRS_UniNa/icons/automatic_levels_off.png +0 -0
  38. PaIRS_UniNa/icons/automatic_levels_on.png +0 -0
  39. PaIRS_UniNa/icons/automatic_off.png +0 -0
  40. PaIRS_UniNa/icons/automatic_on.png +0 -0
  41. PaIRS_UniNa/icons/automatic_size_off.png +0 -0
  42. PaIRS_UniNa/icons/automatic_size_on.png +0 -0
  43. PaIRS_UniNa/icons/axes.png +0 -0
  44. PaIRS_UniNa/icons/background.png +0 -0
  45. PaIRS_UniNa/icons/background_vectors.png +0 -0
  46. PaIRS_UniNa/icons/bin_off.png +0 -0
  47. PaIRS_UniNa/icons/bin_on.png +0 -0
  48. PaIRS_UniNa/icons/browse_file_c.png +0 -0
  49. PaIRS_UniNa/icons/browse_folder_c.png +0 -0
  50. PaIRS_UniNa/icons/brush_cursor.png +0 -0
  51. PaIRS_UniNa/icons/bugfix.png +0 -0
  52. PaIRS_UniNa/icons/cal_proc.png +0 -0
  53. PaIRS_UniNa/icons/cal_proc_off.png +0 -0
  54. PaIRS_UniNa/icons/cal_step.png +0 -0
  55. PaIRS_UniNa/icons/cal_step_off.png +0 -0
  56. PaIRS_UniNa/icons/calibrate.png +0 -0
  57. PaIRS_UniNa/icons/calibration_logo.png +0 -0
  58. PaIRS_UniNa/icons/change_folder.png +0 -0
  59. PaIRS_UniNa/icons/change_folder_off.png +0 -0
  60. PaIRS_UniNa/icons/checklist.png +0 -0
  61. PaIRS_UniNa/icons/clean.png +0 -0
  62. PaIRS_UniNa/icons/clean_run.png +0 -0
  63. PaIRS_UniNa/icons/close.png +0 -0
  64. PaIRS_UniNa/icons/close_all.png +0 -0
  65. PaIRS_UniNa/icons/close_project.png +0 -0
  66. PaIRS_UniNa/icons/close_workspace.png +0 -0
  67. PaIRS_UniNa/icons/colormap.png +0 -0
  68. PaIRS_UniNa/icons/colormaps/Accent.png +0 -0
  69. PaIRS_UniNa/icons/colormaps/BrBG.png +0 -0
  70. PaIRS_UniNa/icons/colormaps/Dark2.png +0 -0
  71. PaIRS_UniNa/icons/colormaps/PRGn.png +0 -0
  72. PaIRS_UniNa/icons/colormaps/Paired.png +0 -0
  73. PaIRS_UniNa/icons/colormaps/Pastel1.png +0 -0
  74. PaIRS_UniNa/icons/colormaps/Pastel2.png +0 -0
  75. PaIRS_UniNa/icons/colormaps/PiYG.png +0 -0
  76. PaIRS_UniNa/icons/colormaps/PuOr.png +0 -0
  77. PaIRS_UniNa/icons/colormaps/RdBu.png +0 -0
  78. PaIRS_UniNa/icons/colormaps/RdGy.png +0 -0
  79. PaIRS_UniNa/icons/colormaps/RdYlBu.png +0 -0
  80. PaIRS_UniNa/icons/colormaps/RdYlGn.png +0 -0
  81. PaIRS_UniNa/icons/colormaps/Set1.png +0 -0
  82. PaIRS_UniNa/icons/colormaps/Set2.png +0 -0
  83. PaIRS_UniNa/icons/colormaps/Set3.png +0 -0
  84. PaIRS_UniNa/icons/colormaps/Spectral.png +0 -0
  85. PaIRS_UniNa/icons/colormaps/Wistia.png +0 -0
  86. PaIRS_UniNa/icons/colormaps/afmhot.png +0 -0
  87. PaIRS_UniNa/icons/colormaps/autumn.png +0 -0
  88. PaIRS_UniNa/icons/colormaps/binary.png +0 -0
  89. PaIRS_UniNa/icons/colormaps/blackVector.png +0 -0
  90. PaIRS_UniNa/icons/colormaps/blueVector.png +0 -0
  91. PaIRS_UniNa/icons/colormaps/bone.png +0 -0
  92. PaIRS_UniNa/icons/colormaps/brg.png +0 -0
  93. PaIRS_UniNa/icons/colormaps/bwr.png +0 -0
  94. PaIRS_UniNa/icons/colormaps/cividis.png +0 -0
  95. PaIRS_UniNa/icons/colormaps/cool.png +0 -0
  96. PaIRS_UniNa/icons/colormaps/coolwarm.png +0 -0
  97. PaIRS_UniNa/icons/colormaps/copper.png +0 -0
  98. PaIRS_UniNa/icons/colormaps/cubehelix.png +0 -0
  99. PaIRS_UniNa/icons/colormaps/cyanVector.png +0 -0
  100. PaIRS_UniNa/icons/colormaps/flag.png +0 -0
  101. PaIRS_UniNa/icons/colormaps/gist_heat.png +0 -0
  102. PaIRS_UniNa/icons/colormaps/gray.png +0 -0
  103. PaIRS_UniNa/icons/colormaps/greenVector.png +0 -0
  104. PaIRS_UniNa/icons/colormaps/hot.png +0 -0
  105. PaIRS_UniNa/icons/colormaps/hsv.png +0 -0
  106. PaIRS_UniNa/icons/colormaps/inferno.png +0 -0
  107. PaIRS_UniNa/icons/colormaps/jet.png +0 -0
  108. PaIRS_UniNa/icons/colormaps/magentaVector.png +0 -0
  109. PaIRS_UniNa/icons/colormaps/magma.png +0 -0
  110. PaIRS_UniNa/icons/colormaps/ocean.png +0 -0
  111. PaIRS_UniNa/icons/colormaps/pink.png +0 -0
  112. PaIRS_UniNa/icons/colormaps/plasma.png +0 -0
  113. PaIRS_UniNa/icons/colormaps/prism.png +0 -0
  114. PaIRS_UniNa/icons/colormaps/rainbow.png +0 -0
  115. PaIRS_UniNa/icons/colormaps/redVector.png +0 -0
  116. PaIRS_UniNa/icons/colormaps/seismic.png +0 -0
  117. PaIRS_UniNa/icons/colormaps/spring.png +0 -0
  118. PaIRS_UniNa/icons/colormaps/summer.png +0 -0
  119. PaIRS_UniNa/icons/colormaps/tab10.png +0 -0
  120. PaIRS_UniNa/icons/colormaps/tab20.png +0 -0
  121. PaIRS_UniNa/icons/colormaps/tab20b.png +0 -0
  122. PaIRS_UniNa/icons/colormaps/tab20c.png +0 -0
  123. PaIRS_UniNa/icons/colormaps/terrain.png +0 -0
  124. PaIRS_UniNa/icons/colormaps/twilight.png +0 -0
  125. PaIRS_UniNa/icons/colormaps/viridis.png +0 -0
  126. PaIRS_UniNa/icons/colormaps/whiteVector.png +0 -0
  127. PaIRS_UniNa/icons/colormaps/winter.png +0 -0
  128. PaIRS_UniNa/icons/colormaps/yellowVector.png +0 -0
  129. PaIRS_UniNa/icons/common_region.png +0 -0
  130. PaIRS_UniNa/icons/common_region_off.png +0 -0
  131. PaIRS_UniNa/icons/completed.png +0 -0
  132. PaIRS_UniNa/icons/contourf_off.png +0 -0
  133. PaIRS_UniNa/icons/contourf_on.png +0 -0
  134. PaIRS_UniNa/icons/copy.png +0 -0
  135. PaIRS_UniNa/icons/copy_process.png +0 -0
  136. PaIRS_UniNa/icons/copy_process_off.png +0 -0
  137. PaIRS_UniNa/icons/copygrid.png +0 -0
  138. PaIRS_UniNa/icons/cursor_lamp.png +0 -0
  139. PaIRS_UniNa/icons/cut.png +0 -0
  140. PaIRS_UniNa/icons/cut_warnings.png +0 -0
  141. PaIRS_UniNa/icons/darkmode.png +0 -0
  142. PaIRS_UniNa/icons/debug_run.png +0 -0
  143. PaIRS_UniNa/icons/delete.png +0 -0
  144. PaIRS_UniNa/icons/deleteErr.png +0 -0
  145. PaIRS_UniNa/icons/disp_step.png +0 -0
  146. PaIRS_UniNa/icons/disp_step_off.png +0 -0
  147. PaIRS_UniNa/icons/down.png +0 -0
  148. PaIRS_UniNa/icons/edit_list.png +0 -0
  149. PaIRS_UniNa/icons/editing.png +0 -0
  150. PaIRS_UniNa/icons/example_list.png +0 -0
  151. PaIRS_UniNa/icons/find_all_planes.png +0 -0
  152. PaIRS_UniNa/icons/find_plane.png +0 -0
  153. PaIRS_UniNa/icons/flaticon_PaIRS.png +0 -0
  154. PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
  155. PaIRS_UniNa/icons/flaticon_PaIRS_download.png +0 -0
  156. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  157. PaIRS_UniNa/icons/flip_y_off.png +0 -0
  158. PaIRS_UniNa/icons/flip_y_on.png +0 -0
  159. PaIRS_UniNa/icons/focusErrr.png +0 -0
  160. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  161. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  162. PaIRS_UniNa/icons/gear.gif +0 -0
  163. PaIRS_UniNa/icons/gear.png +0 -0
  164. PaIRS_UniNa/icons/ger.png +0 -0
  165. PaIRS_UniNa/icons/greenv.png +0 -0
  166. PaIRS_UniNa/icons/guide.png +0 -0
  167. PaIRS_UniNa/icons/icon_CalVi.png +0 -0
  168. PaIRS_UniNa/icons/icon_PaIRS.png +0 -0
  169. PaIRS_UniNa/icons/import.png +0 -0
  170. PaIRS_UniNa/icons/import_set.png +0 -0
  171. PaIRS_UniNa/icons/information.png +0 -0
  172. PaIRS_UniNa/icons/information2.png +0 -0
  173. PaIRS_UniNa/icons/input_logo.png +0 -0
  174. PaIRS_UniNa/icons/issue.png +0 -0
  175. PaIRS_UniNa/icons/laser_NTR.png +0 -0
  176. PaIRS_UniNa/icons/laser_TR_double.png +0 -0
  177. PaIRS_UniNa/icons/laser_TR_single.png +0 -0
  178. PaIRS_UniNa/icons/link.png +0 -0
  179. PaIRS_UniNa/icons/linked.png +0 -0
  180. PaIRS_UniNa/icons/loaded.png +0 -0
  181. PaIRS_UniNa/icons/loading_2.gif +0 -0
  182. PaIRS_UniNa/icons/log_logo.png +0 -0
  183. PaIRS_UniNa/icons/logo_CalVi.png +0 -0
  184. PaIRS_UniNa/icons/logo_CalVi_completo.png +0 -0
  185. PaIRS_UniNa/icons/logo_CalVi_party.png +0 -0
  186. PaIRS_UniNa/icons/logo_PaIRS.png +0 -0
  187. PaIRS_UniNa/icons/logo_PaIRS_completo.png +0 -0
  188. PaIRS_UniNa/icons/logo_PaIRS_download.png +0 -0
  189. PaIRS_UniNa/icons/logo_PaIRS_party_rect.png +0 -0
  190. PaIRS_UniNa/icons/logo_PaIRS_rect.png +0 -0
  191. PaIRS_UniNa/icons/logo_opaco.png +0 -0
  192. PaIRS_UniNa/icons/mask.png +0 -0
  193. PaIRS_UniNa/icons/measure.png +0 -0
  194. PaIRS_UniNa/icons/measure_off.png +0 -0
  195. PaIRS_UniNa/icons/min_proc.png +0 -0
  196. PaIRS_UniNa/icons/min_proc_off.png +0 -0
  197. PaIRS_UniNa/icons/min_step.png +0 -0
  198. PaIRS_UniNa/icons/min_step_off.png +0 -0
  199. PaIRS_UniNa/icons/minus.png +0 -0
  200. PaIRS_UniNa/icons/mirror_u.png +0 -0
  201. PaIRS_UniNa/icons/mirror_v.png +0 -0
  202. PaIRS_UniNa/icons/mirror_x.png +0 -0
  203. PaIRS_UniNa/icons/mirror_y.png +0 -0
  204. PaIRS_UniNa/icons/mtplt.png +0 -0
  205. PaIRS_UniNa/icons/new.png +0 -0
  206. PaIRS_UniNa/icons/new_workspace.png +0 -0
  207. PaIRS_UniNa/icons/news.png +0 -0
  208. PaIRS_UniNa/icons/normal_run.png +0 -0
  209. PaIRS_UniNa/icons/open.png +0 -0
  210. PaIRS_UniNa/icons/open_image.png +0 -0
  211. PaIRS_UniNa/icons/open_new_window.png +0 -0
  212. PaIRS_UniNa/icons/open_result.png +0 -0
  213. PaIRS_UniNa/icons/open_workspace.png +0 -0
  214. PaIRS_UniNa/icons/output_logo.png +0 -0
  215. PaIRS_UniNa/icons/paste_above.png +0 -0
  216. PaIRS_UniNa/icons/paste_below.png +0 -0
  217. PaIRS_UniNa/icons/pause.png +0 -0
  218. PaIRS_UniNa/icons/paused.png +0 -0
  219. PaIRS_UniNa/icons/pencil_bw.png +0 -0
  220. PaIRS_UniNa/icons/piv_proc.png +0 -0
  221. PaIRS_UniNa/icons/piv_proc_off.png +0 -0
  222. PaIRS_UniNa/icons/piv_step.png +0 -0
  223. PaIRS_UniNa/icons/piv_step_off.png +0 -0
  224. PaIRS_UniNa/icons/plane.png +0 -0
  225. PaIRS_UniNa/icons/play.png +0 -0
  226. PaIRS_UniNa/icons/plus.png +0 -0
  227. PaIRS_UniNa/icons/process_logo.png +0 -0
  228. PaIRS_UniNa/icons/process_loop.png +0 -0
  229. PaIRS_UniNa/icons/project.png +0 -0
  230. PaIRS_UniNa/icons/pylog.png +0 -0
  231. PaIRS_UniNa/icons/python_warning.png +0 -0
  232. PaIRS_UniNa/icons/queue.png +0 -0
  233. PaIRS_UniNa/icons/quit.png +0 -0
  234. PaIRS_UniNa/icons/read.png +0 -0
  235. PaIRS_UniNa/icons/read_list.png +0 -0
  236. PaIRS_UniNa/icons/redo.png +0 -0
  237. PaIRS_UniNa/icons/redx.png +0 -0
  238. PaIRS_UniNa/icons/reset.png +0 -0
  239. PaIRS_UniNa/icons/reset_levels.png +0 -0
  240. PaIRS_UniNa/icons/resize_icon.png +0 -0
  241. PaIRS_UniNa/icons/restore.png +0 -0
  242. PaIRS_UniNa/icons/restore_undo.png +0 -0
  243. PaIRS_UniNa/icons/rotate_clock.png +0 -0
  244. PaIRS_UniNa/icons/rotate_counter.png +0 -0
  245. PaIRS_UniNa/icons/rotate_v_clock.png +0 -0
  246. PaIRS_UniNa/icons/rotate_v_counter.png +0 -0
  247. PaIRS_UniNa/icons/running.gif +0 -0
  248. PaIRS_UniNa/icons/running.png +0 -0
  249. PaIRS_UniNa/icons/running_warn.png +0 -0
  250. PaIRS_UniNa/icons/sandglass.png +0 -0
  251. PaIRS_UniNa/icons/save.png +0 -0
  252. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  253. PaIRS_UniNa/icons/save_cfg.png +0 -0
  254. PaIRS_UniNa/icons/saveas.png +0 -0
  255. PaIRS_UniNa/icons/saveas_workspace.png +0 -0
  256. PaIRS_UniNa/icons/scale_all.png +0 -0
  257. PaIRS_UniNa/icons/scale_down.png +0 -0
  258. PaIRS_UniNa/icons/scale_up.png +0 -0
  259. PaIRS_UniNa/icons/scan_list.png +0 -0
  260. PaIRS_UniNa/icons/scan_path.png +0 -0
  261. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  262. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  263. PaIRS_UniNa/icons/search.png +0 -0
  264. PaIRS_UniNa/icons/showIW_off.png +0 -0
  265. PaIRS_UniNa/icons/showIW_on.png +0 -0
  266. PaIRS_UniNa/icons/show_all.png +0 -0
  267. PaIRS_UniNa/icons/sort.png +0 -0
  268. PaIRS_UniNa/icons/sort_reversed.png +0 -0
  269. PaIRS_UniNa/icons/spiv_proc.png +0 -0
  270. PaIRS_UniNa/icons/spiv_proc_off.png +0 -0
  271. PaIRS_UniNa/icons/spiv_setup_no.png +0 -0
  272. PaIRS_UniNa/icons/spiv_setup_ok.png +0 -0
  273. PaIRS_UniNa/icons/star.png +0 -0
  274. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  275. PaIRS_UniNa/icons/subMIN_off.png +0 -0
  276. PaIRS_UniNa/icons/subMIN_on.png +0 -0
  277. PaIRS_UniNa/icons/tom.png +0 -0
  278. PaIRS_UniNa/icons/trash.png +0 -0
  279. PaIRS_UniNa/icons/undo.png +0 -0
  280. PaIRS_UniNa/icons/unedited.png +0 -0
  281. PaIRS_UniNa/icons/unina_dii.png +0 -0
  282. PaIRS_UniNa/icons/uninitialized.png +0 -0
  283. PaIRS_UniNa/icons/unlink.png +0 -0
  284. PaIRS_UniNa/icons/unwrap_items.png +0 -0
  285. PaIRS_UniNa/icons/up.png +0 -0
  286. PaIRS_UniNa/icons/updating_import.gif +0 -0
  287. PaIRS_UniNa/icons/updating_pairs.gif +0 -0
  288. PaIRS_UniNa/icons/vectorColor.png +0 -0
  289. PaIRS_UniNa/icons/vettore.png +0 -0
  290. PaIRS_UniNa/icons/view.png +0 -0
  291. PaIRS_UniNa/icons/view_off.png +0 -0
  292. PaIRS_UniNa/icons/vis_logo.png +0 -0
  293. PaIRS_UniNa/icons/waiting_circle.png +0 -0
  294. PaIRS_UniNa/icons/warning.png +0 -0
  295. PaIRS_UniNa/icons/warning_circle.png +0 -0
  296. PaIRS_UniNa/icons/window.png +0 -0
  297. PaIRS_UniNa/icons/workspace.png +0 -0
  298. PaIRS_UniNa/icons/wrap_items.png +0 -0
  299. PaIRS_UniNa/icons/write_list.png +0 -0
  300. PaIRS_UniNa/listLib.py +303 -0
  301. PaIRS_UniNa/mtfPIV.py +256 -0
  302. PaIRS_UniNa/parForMulti.py +435 -0
  303. PaIRS_UniNa/parForWorkers.py +593 -0
  304. PaIRS_UniNa/pivParFor.py +235 -0
  305. PaIRS_UniNa/plt_util.py +141 -0
  306. PaIRS_UniNa/preProcParFor.py +155 -0
  307. PaIRS_UniNa/procTools.py +1439 -0
  308. PaIRS_UniNa/readcfg.py +52 -0
  309. PaIRS_UniNa/rqrdpckgs.txt +9 -0
  310. PaIRS_UniNa/stereoPivParFor.py +227 -0
  311. PaIRS_UniNa/tAVarie.py +215 -0
  312. PaIRS_UniNa/tabSplitter.py +612 -0
  313. PaIRS_UniNa/ui_Calibration_Tab.py +578 -0
  314. PaIRS_UniNa/ui_Custom_Top.py +296 -0
  315. PaIRS_UniNa/ui_Input_Tab.py +1101 -0
  316. PaIRS_UniNa/ui_Input_Tab_CalVi.py +1283 -0
  317. PaIRS_UniNa/ui_Log_Tab.py +263 -0
  318. PaIRS_UniNa/ui_Output_Tab.py +2362 -0
  319. PaIRS_UniNa/ui_Process_Tab.py +3810 -0
  320. PaIRS_UniNa/ui_Process_Tab_CalVi.py +1549 -0
  321. PaIRS_UniNa/ui_Process_Tab_Disp.py +1141 -0
  322. PaIRS_UniNa/ui_Process_Tab_Min.py +437 -0
  323. PaIRS_UniNa/ui_ResizePopup.py +204 -0
  324. PaIRS_UniNa/ui_Vis_Tab.py +1628 -0
  325. PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1251 -0
  326. PaIRS_UniNa/ui_Whatsnew.py +132 -0
  327. PaIRS_UniNa/ui_gPairs.py +877 -0
  328. PaIRS_UniNa/ui_infoPaIRS.py +551 -0
  329. PaIRS_UniNa/whatsnew.txt +6 -0
  330. pairs_unina-0.2.9.dist-info/METADATA +166 -0
  331. pairs_unina-0.2.9.dist-info/RECORD +333 -0
  332. pairs_unina-0.2.9.dist-info/WHEEL +5 -0
  333. pairs_unina-0.2.9.dist-info/top_level.txt +2 -0
@@ -0,0 +1,786 @@
1
+ import PySide6.QtGui
2
+ from .ui_Input_Tab_CalVi import*
3
+ from .TabTools import*
4
+
5
+ #bufferSizeLimit=2000*1e6 #bytes
6
+ spin_tips={
7
+ 'x' : 'First column of image area to process',
8
+ 'y' : 'First row of image',
9
+ 'w' : 'Width of image area to process',
10
+ 'h' : 'Height of image area to process',
11
+ }
12
+ check_tips={}
13
+ radio_tips={
14
+ 'Cam' : '_cam* in filename',
15
+ 'Same_as_input' : 'Output folder path same as input',
16
+ }
17
+ line_edit_tips={
18
+ 'path' : 'Input folder path',
19
+ 'cameras' : 'Input camera numbers',
20
+ 'path_out' : 'Output folder path',
21
+ 'root_out' : 'Root of output files',
22
+ }
23
+ button_tips={
24
+ 'data' : 'Download example data',
25
+ 'path' : 'Input folder path',
26
+ 'import' : 'Import of target images',
27
+ 'import_plane' : 'Import of plane parameters',
28
+ 'down' : 'Order of target images',
29
+ 'up' : 'Order of target images',
30
+ 'delete' : 'Deletion of target images',
31
+ 'clean' : 'Cleaning of the image list',
32
+ 'resize' : 'Reset of image sizes',
33
+ 'path_out' : 'Output folder path',
34
+ }
35
+ combo_tips={}
36
+ class INPpar_CalVi(TABpar):
37
+ pathCompleter=basefold_DEBUGOptions
38
+
39
+ def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
40
+ self.setup(Process,Step)
41
+ super().__init__('INPpar_CalVi','Input_CalVi')
42
+ self.unchecked_fields+=['OptionValidPath','OptionValidPathOut','OptionValidRootOut','row','col','rows','cols','pathCompleter']
43
+
44
+ def setup(self,Process,Step):
45
+ self.Process = Process
46
+ self.Step = Step
47
+
48
+ self.path = './'
49
+ self.OptionValidPath = 1
50
+
51
+ self.ext = ''
52
+ self.FlagCam = False
53
+ self.cams = []
54
+ self.filenames = []
55
+ self.FlagImages = []
56
+ self.plapar = []
57
+
58
+ self.imageFile = None
59
+ self.x = 0
60
+ self.y = 0
61
+ self.w = 1
62
+ self.h = 1
63
+ self.W = 1
64
+ self.H = 1
65
+
66
+ self.row = -1
67
+ self.col = -1
68
+ self.rows = []
69
+ self.cols = []
70
+ self.imList = [[]]
71
+ self.imEx = [[]]
72
+
73
+ self.FlagOptPlane = False
74
+ self.CalibProcType = 1
75
+
76
+ self.FlagSame_as_input = True
77
+ self.path_out = './'
78
+ self.OptionValidPathOut = 1
79
+ self.root_out = 'pyCal'
80
+ self.OptionValidRootOut = 1
81
+
82
+ self.errorMessage = ''
83
+ self.FlagReadCalib = False
84
+
85
+ class Input_Tab_CalVi(gPaIRS_Tab):
86
+
87
+ class Import_Tab_Signals(gPaIRS_Tab.Tab_Signals):
88
+ list_selection=Signal()
89
+ pass
90
+
91
+ def __init__(self,parent: QWidget =None, flagInit= __name__ == "__main__"):
92
+ super().__init__(parent,Ui_InputTab_CalVi,INPpar_CalVi)
93
+ self.signals=self.Import_Tab_Signals(self)
94
+
95
+ #------------------------------------- Graphical interface: widget
96
+ self.TABname='Input_CalVi'
97
+ self.ui: Ui_InputTab_CalVi
98
+ self.ui.spin_x.addwid=[self.ui.spin_w]
99
+ self.ui.spin_y.addwid=[self.ui.spin_h]
100
+
101
+ #necessary to change the name and the order of the items
102
+ for g in list(globals()):
103
+ if '_items' in g or '_ord' in g or '_tips' in g:
104
+ #pri.Info.blue(f'Adding {g} to {self.name_tab}')
105
+ setattr(self,g,eval(g))
106
+
107
+ if __name__ == "__main__":
108
+ self.app=app
109
+ setAppGuiPalette(self)
110
+
111
+ #------------------------------------- Graphical interface: miscellanea
112
+ self.pixmap_x = QPixmap(''+ icons_path +'redx.png')
113
+ self.pixmap_v = QPixmap(''+ icons_path +'greenv.png')
114
+ self.pixmap_wait = QPixmap(''+ icons_path +'sandglass.png')
115
+ self.pixmap_warn = QPixmap(u""+ icons_path +"warning.png")
116
+
117
+ self.edit_path_label=QPixmap()
118
+ self.edit_cams_label=QPixmap()
119
+
120
+ self.tableHeaders = [self.ui.list_images.horizontalHeaderItem(i).text() for i in range(self.ui.list_images.columnCount())]
121
+ header = self.ui.list_images.horizontalHeader()
122
+ header.setSectionResizeMode(0, QHeaderView.ResizeMode.Interactive)
123
+ header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
124
+ header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
125
+ #header.setMinimumSectionSize(int(self.minimumWidth()/2))
126
+ #header.setMaximumSectionSize(int(self.maximumWidth()/2))
127
+ self.ui.list_images.InfoLabel=self.ui.label_info
128
+ self.ui.list_images.DeleteButton=self.ui.button_delete
129
+ #self.ui.list_images.addfuncreturn['plapar']=self.updatePlanePar
130
+ #self.ui.list_images.addfuncout['plapar']=self.updatePlanePar
131
+ self.ui.label_info.hide()
132
+ self.ui.list_images.setupRowBehaviour()
133
+
134
+ #------------------------------------- Declaration of parameters
135
+ self.INPpar_base=INPpar_CalVi()
136
+ self.INPpar:INPpar_CalVi=self.TABpar
137
+ self.INPpar_old:INPpar_CalVi=self.TABpar_old
138
+
139
+ self.bufferImg = {}
140
+ self.bufferSize = 0
141
+
142
+ #------------------------------------- Callbacks
143
+ self.defineWidgets()
144
+ self.setupWid() #---------------- IMPORTANT
145
+
146
+ self.defineCallbacks()
147
+ self.connectCallbacks()
148
+ self.defineFurtherCallbacks()
149
+
150
+ self.defineSettings()
151
+
152
+ self.adjustTABpar=self.adjustINPpar
153
+ self.setTABlayout=self.setINPlayout
154
+
155
+ self.setRunCalViButtonText=lambda: None
156
+
157
+ #------------------------------------- Initializing
158
+ if flagInit:
159
+ self.initialize()
160
+
161
+ def initialize(self):
162
+ pri.Info.yellow(f'{"*"*20} INPUT CalVi initialization {"*"*20}')
163
+ self.INPpar.path=basefold_DEBUG if __name__ == "__main__" else basefold
164
+ #self.cleanPrevs(self.INPpar.ind,FlagAllPrev=True)
165
+ self.ui.line_edit_path.setText(self.INPpar.path)
166
+ self.line_edit_path_callback()
167
+ return
168
+
169
+ def defineFurtherCallbacks(self):
170
+ #Callbacks
171
+ self.ui.button_data.clicked.connect(lambda: downloadExampleData(self,'https://www.pairs.unina.it/web/Calibration_data.zip'))
172
+
173
+ self.ui.list_images.contextMenuEvent=lambda e: self.listContextMenuEvent(self.ui.list_images,e)
174
+ #self.ui.list_images.itemSelectionChanged.connect(self.wrappedCallback('Item selection',self.list_selection))
175
+ self.ui.list_images.currentItemChanged.connect(self.wrappedCallback('Item selection',self.list_selection))
176
+ self.ui.list_images.cellChanged.connect(self.wrappedCallback('Plane parameters',self.updatePlanePar))
177
+ self.ui.list_images.signals.updateLists.connect(self.fullCallback)
178
+
179
+ def listContextMenuEvent(self, list_images:QTableWidget, event):
180
+ menu=QMenu(list_images)
181
+ buttons=['import', 'import_plane',
182
+ -1,'down','up',
183
+ -1,'delete','clean']
184
+ name=[]
185
+ act=[]
186
+ fun=[]
187
+ for _,nb in enumerate(buttons):
188
+ if type(nb)==str:
189
+ b:QPushButton=getattr(self.ui,'button_'+nb)
190
+ if b.isVisible() and b.isEnabled():
191
+ if hasattr(self,'button_'+nb+'_callback'):
192
+ name.append(nb)
193
+ act.append(QAction(b.icon(),toPlainText(b.toolTip().split('.')[0]),list_images))
194
+ menu.addAction(act[-1])
195
+ callback=getattr(self,'button_'+nb+'_callback')
196
+ fun.append(callback)
197
+ else:
198
+ if len(act): menu.addSeparator()
199
+
200
+ if len(act):
201
+ pri.Callback.yellow(f'||| Opening image list context menu |||')
202
+ action = menu.exec(list_images.mapToGlobal(event.pos()))
203
+ for nb,a,f in zip(name,act,fun):
204
+ if a==action:
205
+ TABpar.FlagSettingPar=False
206
+ f()
207
+ break
208
+
209
+ #*************************************************** Adjusting parameters
210
+ def adjustINPpar(self):
211
+ self.INPpar.path=myStandardPath(self.INPpar.path)
212
+ self.setOptionValidPath()
213
+
214
+ self.INPpar.FlagOptPlane=self.INPpar.CalibProcType>0
215
+ self.check_cams()
216
+
217
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['FlagCam']):
218
+ self.adjustCam()
219
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['path','FlagCam','cams','filenames']):
220
+ self.adjust_list_images()
221
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imageFile']):
222
+ self.adjust_image_sizes()
223
+ if len(self.INPpar_old.filenames)==0 and len(self.INPpar.filenames)>0:
224
+ self.button_resize_action()
225
+ l=len(self.INPpar.filenames)
226
+ if l>0:
227
+ self.INPpar.row=min([max([self.INPpar.row,0]),l-1])
228
+ self.INPpar.col=max([self.INPpar.col,0])
229
+
230
+ if self.INPpar.FlagSame_as_input: self.INPpar.path_out=self.INPpar.path
231
+ #if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['path_out','FlagSame_as_input']):
232
+ self.INPpar.path_out=myStandardPath(self.INPpar.path_out)
233
+ self.setOptionValidPathOut()
234
+ #if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['root_out']):
235
+ self.INPpar.root_out=myStandardRoot(self.INPpar.root_out)
236
+ self.setOptionValidRootOut()
237
+
238
+ if not self.INPpar.FlagInit:
239
+ self.adjust_list_images()
240
+ return
241
+
242
+ def check_cams(self):
243
+ if len(self.INPpar.cams)>1 and self.INPpar.CalibProcType==0:
244
+ warningDialog(self,'Standard calibration can be performed only one camera at once! The first camera identification number will be retained for the current configuration.')
245
+ self.INPpar.cams=[self.INPpar.cams[0]]
246
+
247
+ #*************************************************** Layout
248
+ def setINPlayout(self):
249
+ self.setPathLabel()
250
+ self.setPathCompleter()
251
+
252
+ self.ui.w_InputImg.setVisible(self.INPpar.FlagCam)
253
+
254
+ flagSelect=self.INPpar.row>-1
255
+ self.ui.button_down.setEnabled(flagSelect)
256
+ self.ui.button_up.setEnabled(flagSelect)
257
+ self.ui.button_delete.setEnabled(flagSelect)
258
+ FlagImages=len(self.INPpar.filenames)>0
259
+ self.ui.button_import_plane.setEnabled(FlagImages)
260
+ self.ui.button_clean.setEnabled(FlagImages)
261
+
262
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['filenames','imList','imEx','plapar','FlagImages']) or not self.INPpar.FlagInit:
263
+ self.set_list_images_items()
264
+ item=self.ui.list_images.item(self.INPpar.row,self.INPpar.col)
265
+ if item: self.ui.list_images.setCurrentItem(item)
266
+ for r,c in zip(self.INPpar.rows,self.INPpar.cols):
267
+ item=self.ui.list_images.item(r,c)
268
+ if item: item.setSelected(True)
269
+
270
+ self.errorMessage()
271
+ self.ui.list_images.resizeInfoLabel()
272
+
273
+ self.ui.w_SizeImg.setVisible(FlagImages)
274
+ self.setMinMaxSpinxywh()
275
+
276
+ self.setPathOutLabel()
277
+ self.setRootOutLabel()
278
+ self.ui.w_OutputFolder.setEnabled(not self.INPpar.FlagSame_as_input)
279
+ self.ui.w_button_path_out.setEnabled(not self.INPpar.FlagSame_as_input)
280
+
281
+ self.setRunCalViButtonText()
282
+ self.ui.list_images.itemList=[self.INPpar.filenames,self.INPpar.imList,self.INPpar.imEx,self.INPpar.plapar,self.INPpar.FlagImages]
283
+
284
+
285
+ #*************************************************** Path
286
+ #******************** Actions
287
+ def line_edit_path_changing(self):
288
+ self.ui.label_check_path.setPixmap(QPixmap())
289
+
290
+ def line_edit_path_preaction(self):
291
+ currpath=myStandardPath(self.ui.line_edit_path.text())
292
+ self.FlagScanPath=os.path.normpath(self.INPpar.path)!=currpath
293
+ currpath=relativizePath(currpath)
294
+ if os.path.exists(currpath) and currpath!='./':
295
+ pathCompleter=INPpar_CalVi.pathCompleter
296
+ if currpath in pathCompleter: pathCompleter.remove(currpath)
297
+ pathCompleter.insert(0,currpath)
298
+ if len(pathCompleter)>pathCompleterLength:
299
+ INPpar_CalVi.pathCompleter=pathCompleter[:pathCompleterLength]
300
+ self.ui.line_edit_path.setText(currpath)
301
+
302
+ def button_path_action(self):
303
+ directory = str(QFileDialog.getExistingDirectory(self,\
304
+ "Choose an input folder", dir=self.INPpar.path,options=optionNativeDialog))
305
+ currpath='{}'.format(directory)
306
+ if not currpath=='':
307
+ currpath=myStandardPath(currpath)
308
+ self.ui.line_edit_path.setText(currpath)
309
+ self.INPpar.path=self.ui.line_edit_path.text()
310
+ self.line_edit_path_preaction()
311
+
312
+ def line_edit_cameras_action(self):
313
+ text=self.ui.line_edit_cameras.text()
314
+ split_text=re.findall(r'(\d+)', text)
315
+ self.INPpar.cams=[]
316
+ for s in split_text:
317
+ i=int(s)
318
+ if i not in self.INPpar.cams:
319
+ self.INPpar.cams.append(i)
320
+ return
321
+
322
+ #******************** Settings
323
+ def setOptionValidPath(self):
324
+ self.INPpar.OptionValidPath=int(os.path.exists(self.INPpar.path))
325
+ return
326
+
327
+ def setPathCompleter(self):
328
+ self.edit_path_completer=QCompleter(self.INPpar.pathCompleter)
329
+ self.edit_path_completer.setCompletionMode(QCompleter.CompletionMode(1))
330
+ self.edit_path_completer.setModelSorting(QCompleter.ModelSorting(2))
331
+ self.edit_path_completer.setWidget(self.ui.line_edit_path)
332
+ if self.INPpar.path in self.INPpar.pathCompleter:
333
+ k=self.INPpar.pathCompleter.index(self.INPpar.path)
334
+ self.edit_path_completer.setCurrentRow(k)
335
+ self.ui.line_edit_path.setCompleter(self.edit_path_completer)
336
+ self.ui.line_edit_path.FlagCompleter=True
337
+
338
+ def line_edit_cameras_set(self):
339
+ text=", ".join([str(c) for c in self.INPpar.cams])
340
+ self.ui.line_edit_cameras.setText(text)
341
+
342
+ #******************** Layout
343
+ def setPathLabel(self):
344
+ #Clickable label: no need for setStatusTip
345
+ if self.INPpar.OptionValidPath:
346
+ self.ui.label_check_path.setPixmap(self.pixmap_v)
347
+ self.ui.label_check_path.setToolTip("The specified path of the input folder exists!")
348
+ else:
349
+ self.ui.label_check_path.setPixmap(self.pixmap_x)
350
+ self.ui.label_check_path.setToolTip("The specified path of the input folder does not exist!")
351
+ self.edit_path_label=self.ui.label_check_path.pixmap()
352
+
353
+ #*************************************************** Images
354
+ #******************** Actions
355
+ def button_import_action(self):
356
+ filenames, _ = QFileDialog.getOpenFileNames(self,\
357
+ "Select an image file of the sequence", filter=text_filter, dir=self.INPpar.path,\
358
+ options=optionNativeDialog)
359
+ if len(filenames)==0: return
360
+ currpath=self.INPpar.path
361
+ f_new=[]
362
+ f_warning=[]
363
+ for filename in filenames:
364
+ if not filename: continue
365
+ f=os.path.basename(filename)
366
+ FlagWarn=False
367
+ if self.INPpar.FlagCam:
368
+ fsplitted=re.split(r'_cam\d+', f)
369
+ if len(fsplitted)>1:
370
+ fsplitted.insert(-1,'_cam*')
371
+ f="".join(fsplitted)
372
+ else:
373
+ f_warning.append(f) #redundant
374
+ FlagWarn=True
375
+ if f not in self.INPpar.filenames and f not in f_new and not FlagWarn:
376
+ f_new.append(f)
377
+ if len(f_new)>0:
378
+ for t in f_new:
379
+ self.INPpar.filenames.append(t)
380
+ if self.INPpar.FlagOptPlane:
381
+ self.INPpar.plapar.append([float(0)]*6)
382
+ else:
383
+ self.INPpar.plapar.append([float(0)])
384
+ self.INPpar.path, _ = os.path.split(filenames[0])
385
+ if len(f_warning):
386
+ list_img_warn=';\n'.join(f_warning)
387
+ Message=f'The following files located in the path {currpath} do not contain the pattern _cam* in their name and will not be included in the list of image files for the calibration process:\n{list_img_warn}.'
388
+ warningDialog(self,Message)
389
+ return
390
+
391
+ def button_import_plane_action(self):
392
+ if len(self.INPpar.rows)>1:
393
+ self.INPpar.rows=[self.INPpar.row]
394
+ self.INPpar.cols=[1]
395
+ self.INPpar.col=1
396
+ self.ui.list_images.clearSelection()
397
+ item=self.ui.list_images.item(self.INPpar.row,self.INPpar.col)
398
+ item.setSelected(True)
399
+ plaparName, _ = QFileDialog.getOpenFileName(self,\
400
+ "Select a plane parameter file", filter=f'*{outExt.pla}',\
401
+ dir=self.INPpar.path,\
402
+ options=optionNativeDialog)
403
+ if not plaparName: return
404
+ try:
405
+ if os.path.exists(plaparName):
406
+ with open(plaparName, 'r') as file:
407
+ data=file.read()
408
+ dp=eval(data)
409
+ pass
410
+ except:
411
+ WarningMessage=f'Error with loading the file: {plaparName}\n'
412
+ warningDialog(self,WarningMessage)
413
+ else:
414
+ try:
415
+ if len(self.INPpar.plapar[self.INPpar.row])==1:
416
+ self.INPpar.plapar[self.INPpar.row]=[round(dp['z (mm)'],3)]
417
+ else:
418
+ self.INPpar.plapar[self.INPpar.row]=[round(p,3) for p in list(dp.values())]
419
+ except:
420
+ WarningMessage=f'Error with setting the plane parameters read from file: {plaparName}\n'
421
+ warningDialog(self,WarningMessage)
422
+
423
+ def button_delete_action(self):
424
+ source_rows=[]
425
+ [source_rows.append(i.row()) for i in self.ui.list_images.selectedItems() if i.row() not in source_rows and i.row()>-1]
426
+ source_rows.sort(reverse=True)
427
+ for k in source_rows:
428
+ self.INPpar.filenames.pop(k)
429
+ self.INPpar.plapar.pop(k)
430
+ self.INPpar.rows=[]
431
+ self.INPpar.cols=[]
432
+ self.INPpar.row=-1
433
+ self.INPpar.col=-1
434
+
435
+ def button_clean_action(self):
436
+ self.INPpar.filenames=[]
437
+ self.INPpar.plapar=[]
438
+ self.INPpar.x = self.INPpar.y = 0
439
+ self.INPpar.w = self.INPpar.h = 1
440
+ self.INPpar.W = self.INPpar.H = 1
441
+ self.INPpar.row = -1
442
+ self.INPpar.col = -1
443
+ return
444
+
445
+ def button_updown_action(self,d):
446
+ source_rows=[]
447
+ [source_rows.append(i.row()) for i in self.ui.list_images.selectedItems() if i.row() not in source_rows and i.row()>-1]
448
+ source_rows.sort(reverse=d>0)
449
+
450
+ for row in source_rows:
451
+ if d==-1 and row==0: return
452
+ if d==+1 and row==len(self.INPpar.filenames)-1: return
453
+ filename=self.INPpar.filenames.pop(row)
454
+ self.INPpar.filenames.insert(row+d,filename)
455
+ par=self.INPpar.plapar.pop(row)
456
+ self.INPpar.plapar.insert(row+d,par)
457
+ source_rows.sort(reverse=d>0)
458
+ self.INPpar.rows=[]
459
+ self.INPpar.cols=[]
460
+ for row in source_rows:
461
+ for col in range(self.ui.list_images.columnCount()):
462
+ self.INPpar.rows.append(row+d)
463
+ self.INPpar.cols.append(col)
464
+ self.INPpar.row+=d
465
+ self.ui.list_images.setFocus()
466
+ return
467
+
468
+ def button_down_action(self):
469
+ self.button_updown_action(+1)
470
+
471
+ def button_up_action(self):
472
+ self.button_updown_action(-1)
473
+
474
+ def list_selection(self):
475
+ selectedItems=self.ui.list_images.selectedItems()
476
+ if selectedItems:
477
+ self.INPpar.rows=[i.row() for i in selectedItems]
478
+ self.INPpar.cols=[i.column() for i in selectedItems]
479
+ self.INPpar.row=self.INPpar.rows[-1]
480
+ self.INPpar.col=self.INPpar.cols[-1]
481
+ else:
482
+ self.INPpar.rows=[-1]
483
+ self.INPpar.cols=[-1]
484
+ self.INPpar.row=-1
485
+ self.INPpar.col=-1
486
+ return
487
+
488
+ def updatePlanePar(self):
489
+ if self.ui.list_images.currentColumn()==1:
490
+ r=self.ui.list_images.currentRow()
491
+ item=self.ui.list_images.item(r,1)
492
+ text=item.text()
493
+ oldtext=", ".join([str(s) for s in self.INPpar.plapar[r]])
494
+ if text!=oldtext:
495
+ #fex=re.compile('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')
496
+ if self.INPpar.FlagOptPlane:
497
+ tsplitted=re.split(',',text)
498
+ #pri.Callback.white(tsplitted)
499
+ if len(tsplitted)==6 and all([isfloat(p) for p in tsplitted]):
500
+ self.INPpar.plapar[r]=[float(p) for p in tsplitted]
501
+ else:
502
+ if isfloat(text):
503
+ self.INPpar.plapar[r]=[float(text)]
504
+ pri.Callback.green(f'***** new par {", ".join([str(s) for s in self.INPpar.plapar[r]])}')
505
+
506
+ #******************** Adjusting
507
+ def adjustCam(self):
508
+ if self.INPpar.FlagCam and len(self.INPpar.cams)==0:
509
+ ncam=0
510
+ for f in self.INPpar.filenames:
511
+ pats=re.findall(r'_cam\d+', f)
512
+ if len(pats):
513
+ ncam=int(pats[-1].replace("_cam",""))
514
+ break
515
+ self.INPpar.cams=[ncam]
516
+ elif not self.INPpar.FlagCam and len(self.INPpar.cams)>0:
517
+ scam=str(self.INPpar.cams[0])
518
+ self.INPpar.filenames=[f.replace('*',scam) for f in self.INPpar.filenames]
519
+ self.INPpar.cams=[]
520
+
521
+ def adjust_list_images(self):
522
+ #deleting filenames not compatible with the option _cam* in the filename
523
+ ind_del=[]
524
+ for k,f in enumerate(self.INPpar.filenames):
525
+ if (not '_cam' in f and self.INPpar.FlagCam) or\
526
+ ('_cam*' in f and not self.INPpar.FlagCam):
527
+ ind_del.append(k)
528
+ for kk in range(len(ind_del)-1,-1,-1):
529
+ k=ind_del[kk]
530
+ self.INPpar.filenames.pop(k)
531
+ self.INPpar.plapar.pop(k)
532
+
533
+ #check that the filename contains * and not an identifier number
534
+ if self.INPpar.FlagCam:
535
+ for k,f in enumerate(self.INPpar.filenames):
536
+ if '_cam*' in f: continue
537
+ fsplitted=re.split(r'_cam\d+', f)
538
+ fsplitted.insert(-1,'_cam*')
539
+ f="".join(fsplitted)
540
+ self.INPpar.filenames[k]=f
541
+ f_unique=[]
542
+ plapar_unique=[]
543
+ for f,p in zip(self.INPpar.filenames,self.INPpar.plapar):
544
+ if not f in f_unique:
545
+ f_unique.append(f)
546
+ plapar_unique.append(p)
547
+ self.INPpar.filenames=f_unique
548
+ self.INPpar.plapar=plapar_unique
549
+
550
+ self.INPpar.row=min([len(self.INPpar.filenames),self.INPpar.row])
551
+ if self.INPpar.FlagCam:
552
+ self.INPpar.imList=[[] for _ in range(len(self.INPpar.cams))]
553
+ self.INPpar.imEx=[[] for _ in range(len(self.INPpar.cams))]
554
+ for k,c in enumerate(self.INPpar.cams):
555
+ self.INPpar.imList[k]=[self.INPpar.path+f.replace("*",str(c)) for f in self.INPpar.filenames]
556
+ self.INPpar.imEx[k]=[os.path.exists(fk) for fk in self.INPpar.imList[k]]
557
+ else:
558
+ self.INPpar.imList=[[self.INPpar.path+f for f in self.INPpar.filenames]]
559
+ self.INPpar.imEx=[[os.path.exists(fk) for fk in self.INPpar.imList[0]]]
560
+
561
+
562
+ self.INPpar.imageFile=''
563
+ if len(self.INPpar.imList):
564
+ if len(self.INPpar.imList[0]):
565
+ self.INPpar.imageFile=self.INPpar.imList[0][0]
566
+ return
567
+
568
+ def adjust_image_sizes(self):
569
+ if not self.INPpar.imageFile or not os.path.exists(self.INPpar.imageFile): return
570
+ try:
571
+ im = Image.open(self.INPpar.imageFile)
572
+ self.INPpar.ext=os.path.splitext(self.INPpar.imageFile)[-1]
573
+ pri.Info.blue(f'File extension: {self.INPpar.ext}')
574
+ except:
575
+ pri.Error.blue(f'Error opening image file: {self.INPpar.imageFile}.\n{traceback.format_exc()}\n')
576
+ else:
577
+ self.INPpar.W,self.INPpar.H=im.size
578
+ if self.INPpar.w<1 or self.INPpar.w>self.INPpar.W:
579
+ self.INPpar.w=self.INPpar.W
580
+ if self.INPpar.h<1 or self.INPpar.H>self.INPpar.H:
581
+ self.INPpar.h=self.INPpar.H
582
+ if self.INPpar.x<0: self.INPpar.x=0
583
+ elif self.INPpar.x>self.INPpar.W-self.INPpar.w: self.INPpar.x=self.INPpar.W-self.INPpar.w
584
+ if self.INPpar.y<0: self.INPpar.y=0
585
+ elif self.INPpar.y>self.INPpar.H-self.INPpar.h: self.INPpar.y=self.INPpar.H-self.INPpar.h
586
+ return
587
+
588
+ #******************** Layout
589
+ def set_list_images_items(self):
590
+ self.ui.list_images.setRowCount(0)
591
+ self.INPpar.FlagImages=[0]*len(self.INPpar.filenames)
592
+ for k,f in enumerate(self.INPpar.filenames):
593
+ c=self.ui.list_images.rowCount()
594
+ self.ui.list_images.insertRow(c)
595
+ list_eim_camk=[ex[k] for ex in self.INPpar.imEx]
596
+
597
+ item_filename=QTableWidgetItem(f)
598
+ item_filename.setFlags(item_filename.flags() & ~Qt.ItemIsEditable)
599
+ item_filename.setToolTip(f)
600
+ item_filename.setStatusTip(f)
601
+ self.ui.list_images.setItem(c, 0, item_filename)
602
+ if self.INPpar.FlagOptPlane:
603
+ tiptext='Plane parameters: \u03B2 (°), \u03B1 (°), \u03B3 (°), x (mm), y (mm), z (mm)'
604
+ else:
605
+ tiptext='Plane parameters: z (mm)'
606
+ tooltip=QLabel()
607
+ tooltip.setTextFormat(Qt.TextFormat.RichText)
608
+ tooltip.setText(tiptext)
609
+
610
+ item_parameters=QTableWidgetItem(", ".join([str(s) for s in self.INPpar.plapar[k]]))
611
+ item_parameters.setToolTip(tooltip.text())
612
+ item_parameters.setStatusTip(tooltip.text())
613
+ self.ui.list_images.setItem(c, 1, item_parameters)
614
+
615
+ message=''
616
+ tiptext=[]
617
+ if len(self.INPpar.plapar[k])==0:
618
+ message+="⚠"
619
+ tiptext+=[f"⚠︎: Corresponding plane parameters are not defined!"]
620
+ self.INPpar.FlagImages[k]|=1
621
+ for q in range(k):
622
+ if self.INPpar.plapar[k]==self.INPpar.plapar[q]:
623
+ message+="⚠"
624
+ tiptext+=[f"⚠︎: Plane parameters are coincident with those of plane {'#'} ({q})!"]
625
+ self.INPpar.FlagImages[k]|=2
626
+ break
627
+ if not all(list_eim_camk):
628
+ message+="❌"
629
+ if len(self.INPpar.cams):
630
+ cams=",".join([str(self.INPpar.cams[kk]) for kk,e in enumerate(list_eim_camk) if not e])
631
+ tiptext+=[f"❌: Image files for cameras {'#'} ({cams}) are missing!"]
632
+ else:
633
+ tiptext+=[f"❌: Image files is missing!"]
634
+ self.INPpar.FlagImages[k]|=4
635
+ if tiptext:
636
+ tiptext=f"<br>".join(tiptext)
637
+ else:
638
+ message="✅"
639
+ tiptext='✅: Check if the values of the plane parameters are correct!'
640
+ tooltip=QLabel()
641
+ tooltip.setTextFormat(Qt.TextFormat.RichText)
642
+ tooltip.setText(tiptext)
643
+
644
+ item_message=QTableWidgetItem(message)
645
+ item_message.setFlags(item_message.flags() & ~Qt.ItemIsEditable)
646
+ item_message.setToolTip(tooltip.text())
647
+ item_message.setStatusTip(tooltip.text())
648
+ self.ui.list_images.setItem(c, 2, item_message)
649
+ return
650
+
651
+ def listClear(self):
652
+ self.ui.list_images.clear()
653
+ nRow=self.ui.list_images.rowCount()
654
+ for k in range(nRow):
655
+ self.ui.list_images.removeRow(self.ui.list_images.rowAt(k))
656
+ self.ui.list_images.setHorizontalHeaderLabels(self.tableHeaders)
657
+
658
+ def errorMessage(self):
659
+ self.INPpar.errorMessage=''
660
+ if not len(self.INPpar.FlagImages):
661
+ self.INPpar.errorMessage+='Select a valid set of target image files!\n\n'
662
+ if not self.INPpar.OptionValidPathOut:
663
+ self.INPpar.errorMessage+='Choose a valid path for the output folder!\n\n'
664
+ if not self.INPpar.OptionValidRootOut:
665
+ self.INPpar.errorMessage+='Specify a valid root for the name of the output files!\n\n'
666
+ if any(self.INPpar.FlagImages):
667
+ errorFiles=[[],[]]
668
+ for k,f in enumerate(self.INPpar.FlagImages):
669
+ if f&3: errorFiles[0].append(self.INPpar.filenames[k])
670
+ elif f&4: errorFiles[1].append(self.INPpar.filenames[k])
671
+ if len(errorFiles[0]) or len(errorFiles[1]):
672
+ errorMessage=''
673
+ if len(errorFiles[0]):
674
+ errList=f";\n ".join(errorFiles[0])
675
+ errorMessage+=f'Define appropriately the plane parameters for the following images:\n {errList}.\n\n'
676
+ if len(errorFiles[1]):
677
+ errList=f";\n ".join(errorFiles[1])
678
+ errorMessage+=f'Check for missing files related to the following images:\n {errList}.'
679
+ #pri.Error.blue(errorMessage)
680
+ self.INPpar.errorMessage+=errorMessage
681
+ if self.INPpar.errorMessage:
682
+ self.INPpar.errorMessage='Please check the following issues before starting calibration!\n\n'+self.INPpar.errorMessage
683
+
684
+ #*************************************************** Output path
685
+ #******************** Actions
686
+ def radio_Same_as_input_action(self):
687
+ self.INPpar.path_out=self.INPpar.path
688
+
689
+ def line_edit_path_out_changing(self):
690
+ self.ui.label_check_path_out.setPixmap(QPixmap())
691
+
692
+ def line_edit_path_out_preaction(self):
693
+ currpath=myStandardPath(self.ui.line_edit_path_out.text())
694
+ currpath=relativizePath(currpath)
695
+ self.ui.line_edit_path_out.setText(currpath)
696
+
697
+ def button_path_out_action(self):
698
+ directory = str(QFileDialog.getExistingDirectory(self,\
699
+ "Choose a folder", dir=self.INPpar.path_out,options=optionNativeDialog))
700
+ currpath='{}'.format(directory)
701
+ if not currpath=='':
702
+ self.ui.line_edit_path_out.setText(currpath)
703
+ self.line_edit_path_out_preaction()
704
+ self.INPpar.path_out=self.ui.line_edit_path_out.text()
705
+
706
+ #******************** Settings
707
+ def setPathOutLabel(self):
708
+ #Clickable label: no need for setStatusTip
709
+ if self.INPpar.OptionValidPathOut:
710
+ self.ui.label_check_path_out.setPixmap(self.pixmap_v)
711
+ self.ui.label_check_path_out.setToolTip("The specified path of the output folder exists!")
712
+ else:
713
+ self.ui.label_check_path_out.setPixmap(self.pixmap_x)
714
+ self.ui.label_check_path_out.setToolTip("The specified path of the output folder does not exist!")
715
+
716
+ #******************** Layout
717
+ def setOptionValidPathOut(self):
718
+ self.INPpar.OptionValidPathOut=int(os.path.exists(self.INPpar.path_out))
719
+
720
+ #*************************************************** Output root
721
+ #******************** Actions
722
+ def line_edit_root_out_changing(self):
723
+ self.ui.label_check_root.setPixmap(QPixmap())
724
+
725
+ def line_edit_root_out_preaction(self):
726
+ entry=myStandardRoot(self.ui.line_edit_root_out.text())
727
+ self.ui.line_edit_root_out.setText(entry)
728
+
729
+ #******************** Settings
730
+ def setRootOutLabel(self):
731
+ #Clickable label: no need for setStatusTip
732
+ if self.INPpar.OptionValidRootOut==-2:
733
+ if not self.INPpar.FlagReadCalib:
734
+ self.ui.label_check_root.setPixmap(self.pixmap_warn)
735
+ self.ui.label_check_root.setToolTip("Files with the same root name already exist in the selected output folder!")
736
+ else:
737
+ self.ui.label_check_root.setPixmap(self.pixmap_v)
738
+ self.ui.label_check_root.setToolTip("The root of the output filenames is admitted!")
739
+ elif self.INPpar.OptionValidRootOut==0:
740
+ self.ui.label_check_root.setPixmap(self.pixmap_x)
741
+ self.ui.label_check_root.setToolTip("The root of the output filenames is not admitted!")
742
+ if self.INPpar.OptionValidRootOut==1:
743
+ self.ui.label_check_root.setPixmap(self.pixmap_v)
744
+ self.ui.label_check_root.setToolTip("The root of the output filenames is admitted!")
745
+
746
+ #******************** Layout
747
+ def setOptionValidRootOut(self):
748
+ INP=self.INPpar
749
+ ext='.cal'
750
+ FlagExistPath=INP.OptionValidPathOut
751
+ if FlagExistPath:
752
+ currpath=myStandardPath(INP.path_out)
753
+ else:
754
+ currpath='./'
755
+ pattern=myStandardRoot(currpath+INP.root_out)+'*'+ext
756
+ FlagExist=False
757
+ if FlagExistPath:
758
+ files=findFiles_sorted(pattern)
759
+ FlagExist=len(files)>0
760
+ if FlagExist:
761
+ INP.OptionValidRootOut=-2
762
+ else:
763
+ try:
764
+ filename=pattern.replace('*','a0')+'.delmeplease'
765
+ open(filename,'w')
766
+ except:
767
+ FlagDeleteFile=False
768
+ INP.OptionValidRootOut=0
769
+ else:
770
+ FlagDeleteFile=True
771
+ INP.OptionValidRootOut=1
772
+ finally:
773
+ if FlagDeleteFile:
774
+ os.remove(filename)
775
+
776
+
777
+ if __name__ == "__main__":
778
+ import sys
779
+ app=QApplication.instance()
780
+ if not app:app = QApplication(sys.argv)
781
+ app.setStyle('Fusion')
782
+ object = Input_Tab_CalVi(None)
783
+ object.show()
784
+ app.exec()
785
+ app.quit()
786
+ app=None