PaIRS-UniNa 0.2.10__cp313-cp313-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 +347 -0
  2. PaIRS_UniNa/Changes.txt +174 -0
  3. PaIRS_UniNa/Custom_Top.py +303 -0
  4. PaIRS_UniNa/Explorer.py +3322 -0
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +829 -0
  7. PaIRS_UniNa/Input_Tab_CalVi.py +787 -0
  8. PaIRS_UniNa/Input_Tab_tools.py +3026 -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 +1374 -0
  14. PaIRS_UniNa/Process_Tab.py +1761 -0
  15. PaIRS_UniNa/Process_Tab_CalVi.py +313 -0
  16. PaIRS_UniNa/Process_Tab_Disp.py +170 -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 +298 -0
  21. PaIRS_UniNa/TabTools.py +1413 -0
  22. PaIRS_UniNa/Vis_Tab.py +2176 -0
  23. PaIRS_UniNa/Vis_Tab_CalVi.py +982 -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 +1633 -0
  29. PaIRS_UniNa/calib.py +1488 -0
  30. PaIRS_UniNa/calibView.py +833 -0
  31. PaIRS_UniNa/gPaIRS.py +3957 -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 +4 -0
  330. pairs_unina-0.2.10.dist-info/METADATA +159 -0
  331. pairs_unina-0.2.10.dist-info/RECORD +333 -0
  332. pairs_unina-0.2.10.dist-info/WHEEL +5 -0
  333. pairs_unina-0.2.10.dist-info/top_level.txt +2 -0
@@ -0,0 +1,787 @@
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
+ menu.setStyleSheet(self.gui.ui.menu.styleSheet())
182
+ buttons=['import', 'import_plane',
183
+ -1,'down','up',
184
+ -1,'delete','clean']
185
+ name=[]
186
+ act=[]
187
+ fun=[]
188
+ for _,nb in enumerate(buttons):
189
+ if type(nb)==str:
190
+ b:QPushButton=getattr(self.ui,'button_'+nb)
191
+ if b.isVisible() and b.isEnabled():
192
+ if hasattr(self,'button_'+nb+'_callback'):
193
+ name.append(nb)
194
+ act.append(QAction(b.icon(),toPlainText(b.toolTip().split('.')[0]),list_images))
195
+ menu.addAction(act[-1])
196
+ callback=getattr(self,'button_'+nb+'_callback')
197
+ fun.append(callback)
198
+ else:
199
+ if len(act): menu.addSeparator()
200
+
201
+ if len(act):
202
+ pri.Callback.yellow(f'||| Opening image list context menu |||')
203
+ action = menu.exec(list_images.mapToGlobal(event.pos()))
204
+ for nb,a,f in zip(name,act,fun):
205
+ if a==action:
206
+ TABpar.FlagSettingPar=False
207
+ f()
208
+ break
209
+
210
+ #*************************************************** Adjusting parameters
211
+ def adjustINPpar(self):
212
+ self.INPpar.path=myStandardPath(self.INPpar.path)
213
+ self.setOptionValidPath()
214
+
215
+ self.INPpar.FlagOptPlane=self.INPpar.CalibProcType>0
216
+ self.check_cams()
217
+
218
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['FlagCam']):
219
+ self.adjustCam()
220
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['path','FlagCam','cams','filenames']):
221
+ self.adjust_list_images()
222
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imageFile']):
223
+ self.adjust_image_sizes()
224
+ if len(self.INPpar_old.filenames)==0 and len(self.INPpar.filenames)>0:
225
+ self.button_resize_action()
226
+ l=len(self.INPpar.filenames)
227
+ if l>0:
228
+ self.INPpar.row=min([max([self.INPpar.row,0]),l-1])
229
+ self.INPpar.col=max([self.INPpar.col,0])
230
+
231
+ if self.INPpar.FlagSame_as_input: self.INPpar.path_out=self.INPpar.path
232
+ #if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['path_out','FlagSame_as_input']):
233
+ self.INPpar.path_out=myStandardPath(self.INPpar.path_out)
234
+ self.setOptionValidPathOut()
235
+ #if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['root_out']):
236
+ self.INPpar.root_out=myStandardRoot(self.INPpar.root_out)
237
+ self.setOptionValidRootOut()
238
+
239
+ if not self.INPpar.FlagInit:
240
+ self.adjust_list_images()
241
+ return
242
+
243
+ def check_cams(self):
244
+ if len(self.INPpar.cams)>1 and self.INPpar.CalibProcType==0:
245
+ warningDialog(self,'Standard calibration can be performed only one camera at once! The first camera identification number will be retained for the current configuration.')
246
+ self.INPpar.cams=[self.INPpar.cams[0]]
247
+
248
+ #*************************************************** Layout
249
+ def setINPlayout(self):
250
+ self.setPathLabel()
251
+ self.setPathCompleter()
252
+
253
+ self.ui.w_InputImg.setVisible(self.INPpar.FlagCam)
254
+
255
+ flagSelect=self.INPpar.row>-1
256
+ self.ui.button_down.setEnabled(flagSelect)
257
+ self.ui.button_up.setEnabled(flagSelect)
258
+ self.ui.button_delete.setEnabled(flagSelect)
259
+ FlagImages=len(self.INPpar.filenames)>0
260
+ self.ui.button_import_plane.setEnabled(FlagImages)
261
+ self.ui.button_clean.setEnabled(FlagImages)
262
+
263
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['filenames','imList','imEx','plapar','FlagImages']) or not self.INPpar.FlagInit:
264
+ self.set_list_images_items()
265
+ item=self.ui.list_images.item(self.INPpar.row,self.INPpar.col)
266
+ if item: self.ui.list_images.setCurrentItem(item)
267
+ for r,c in zip(self.INPpar.rows,self.INPpar.cols):
268
+ item=self.ui.list_images.item(r,c)
269
+ if item: item.setSelected(True)
270
+
271
+ self.errorMessage()
272
+ self.ui.list_images.resizeInfoLabel()
273
+
274
+ self.ui.w_SizeImg.setVisible(FlagImages)
275
+ self.setMinMaxSpinxywh()
276
+
277
+ self.setPathOutLabel()
278
+ self.setRootOutLabel()
279
+ self.ui.w_OutputFolder.setEnabled(not self.INPpar.FlagSame_as_input)
280
+ self.ui.w_button_path_out.setEnabled(not self.INPpar.FlagSame_as_input)
281
+
282
+ self.setRunCalViButtonText()
283
+ self.ui.list_images.itemList=[self.INPpar.filenames,self.INPpar.imList,self.INPpar.imEx,self.INPpar.plapar,self.INPpar.FlagImages]
284
+
285
+
286
+ #*************************************************** Path
287
+ #******************** Actions
288
+ def line_edit_path_changing(self):
289
+ self.ui.label_check_path.setPixmap(QPixmap())
290
+
291
+ def line_edit_path_preaction(self):
292
+ currpath=myStandardPath(self.ui.line_edit_path.text())
293
+ self.FlagScanPath=os.path.normpath(self.INPpar.path)!=currpath
294
+ currpath=relativizePath(currpath)
295
+ if os.path.exists(currpath) and currpath!='./':
296
+ pathCompleter=INPpar_CalVi.pathCompleter
297
+ if currpath in pathCompleter: pathCompleter.remove(currpath)
298
+ pathCompleter.insert(0,currpath)
299
+ if len(pathCompleter)>pathCompleterLength:
300
+ INPpar_CalVi.pathCompleter=pathCompleter[:pathCompleterLength]
301
+ self.ui.line_edit_path.setText(currpath)
302
+
303
+ def button_path_action(self):
304
+ directory = str(QFileDialog.getExistingDirectory(self,\
305
+ "Choose an input folder", dir=self.INPpar.path,options=optionNativeDialog))
306
+ currpath='{}'.format(directory)
307
+ if not currpath=='':
308
+ currpath=myStandardPath(currpath)
309
+ self.ui.line_edit_path.setText(currpath)
310
+ self.INPpar.path=self.ui.line_edit_path.text()
311
+ self.line_edit_path_preaction()
312
+
313
+ def line_edit_cameras_action(self):
314
+ text=self.ui.line_edit_cameras.text()
315
+ split_text=re.findall(r'(\d+)', text)
316
+ self.INPpar.cams=[]
317
+ for s in split_text:
318
+ i=int(s)
319
+ if i not in self.INPpar.cams:
320
+ self.INPpar.cams.append(i)
321
+ return
322
+
323
+ #******************** Settings
324
+ def setOptionValidPath(self):
325
+ self.INPpar.OptionValidPath=int(os.path.exists(self.INPpar.path))
326
+ return
327
+
328
+ def setPathCompleter(self):
329
+ self.edit_path_completer=QCompleter(self.INPpar.pathCompleter)
330
+ self.edit_path_completer.setCompletionMode(QCompleter.CompletionMode(1))
331
+ self.edit_path_completer.setModelSorting(QCompleter.ModelSorting(2))
332
+ self.edit_path_completer.setWidget(self.ui.line_edit_path)
333
+ if self.INPpar.path in self.INPpar.pathCompleter:
334
+ k=self.INPpar.pathCompleter.index(self.INPpar.path)
335
+ self.edit_path_completer.setCurrentRow(k)
336
+ self.ui.line_edit_path.setCompleter(self.edit_path_completer)
337
+ self.ui.line_edit_path.FlagCompleter=True
338
+
339
+ def line_edit_cameras_set(self):
340
+ text=", ".join([str(c) for c in self.INPpar.cams])
341
+ self.ui.line_edit_cameras.setText(text)
342
+
343
+ #******************** Layout
344
+ def setPathLabel(self):
345
+ #Clickable label: no need for setStatusTip
346
+ if self.INPpar.OptionValidPath:
347
+ self.ui.label_check_path.setPixmap(self.pixmap_v)
348
+ self.ui.label_check_path.setToolTip("The specified path of the input folder exists!")
349
+ else:
350
+ self.ui.label_check_path.setPixmap(self.pixmap_x)
351
+ self.ui.label_check_path.setToolTip("The specified path of the input folder does not exist!")
352
+ self.edit_path_label=self.ui.label_check_path.pixmap()
353
+
354
+ #*************************************************** Images
355
+ #******************** Actions
356
+ def button_import_action(self):
357
+ filenames, _ = QFileDialog.getOpenFileNames(self,\
358
+ "Select an image file of the sequence", filter=text_filter, dir=self.INPpar.path,\
359
+ options=optionNativeDialog)
360
+ if len(filenames)==0: return
361
+ currpath=self.INPpar.path
362
+ f_new=[]
363
+ f_warning=[]
364
+ for filename in filenames:
365
+ if not filename: continue
366
+ f=os.path.basename(filename)
367
+ FlagWarn=False
368
+ if self.INPpar.FlagCam:
369
+ fsplitted=re.split(r'_cam\d+', f)
370
+ if len(fsplitted)>1:
371
+ fsplitted.insert(-1,'_cam*')
372
+ f="".join(fsplitted)
373
+ else:
374
+ f_warning.append(f) #redundant
375
+ FlagWarn=True
376
+ if f not in self.INPpar.filenames and f not in f_new and not FlagWarn:
377
+ f_new.append(f)
378
+ if len(f_new)>0:
379
+ for t in f_new:
380
+ self.INPpar.filenames.append(t)
381
+ if self.INPpar.FlagOptPlane:
382
+ self.INPpar.plapar.append([float(0)]*6)
383
+ else:
384
+ self.INPpar.plapar.append([float(0)])
385
+ self.INPpar.path, _ = os.path.split(filenames[0])
386
+ if len(f_warning):
387
+ list_img_warn=';\n'.join(f_warning)
388
+ 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}.'
389
+ warningDialog(self,Message)
390
+ return
391
+
392
+ def button_import_plane_action(self):
393
+ if len(self.INPpar.rows)>1:
394
+ self.INPpar.rows=[self.INPpar.row]
395
+ self.INPpar.cols=[1]
396
+ self.INPpar.col=1
397
+ self.ui.list_images.clearSelection()
398
+ item=self.ui.list_images.item(self.INPpar.row,self.INPpar.col)
399
+ item.setSelected(True)
400
+ plaparName, _ = QFileDialog.getOpenFileName(self,\
401
+ "Select a plane parameter file", filter=f'*{outExt.pla}',\
402
+ dir=self.INPpar.path,\
403
+ options=optionNativeDialog)
404
+ if not plaparName: return
405
+ try:
406
+ if os.path.exists(plaparName):
407
+ with open(plaparName, 'r') as file:
408
+ data=file.read()
409
+ dp=eval(data)
410
+ pass
411
+ except:
412
+ WarningMessage=f'Error with loading the file: {plaparName}\n'
413
+ warningDialog(self,WarningMessage)
414
+ else:
415
+ try:
416
+ if len(self.INPpar.plapar[self.INPpar.row])==1:
417
+ self.INPpar.plapar[self.INPpar.row]=[round(dp['z (mm)'],3)]
418
+ else:
419
+ self.INPpar.plapar[self.INPpar.row]=[round(p,3) for p in list(dp.values())]
420
+ except:
421
+ WarningMessage=f'Error with setting the plane parameters read from file: {plaparName}\n'
422
+ warningDialog(self,WarningMessage)
423
+
424
+ def button_delete_action(self):
425
+ source_rows=[]
426
+ [source_rows.append(i.row()) for i in self.ui.list_images.selectedItems() if i.row() not in source_rows and i.row()>-1]
427
+ source_rows.sort(reverse=True)
428
+ for k in source_rows:
429
+ self.INPpar.filenames.pop(k)
430
+ self.INPpar.plapar.pop(k)
431
+ self.INPpar.rows=[]
432
+ self.INPpar.cols=[]
433
+ self.INPpar.row=-1
434
+ self.INPpar.col=-1
435
+
436
+ def button_clean_action(self):
437
+ self.INPpar.filenames=[]
438
+ self.INPpar.plapar=[]
439
+ self.INPpar.x = self.INPpar.y = 0
440
+ self.INPpar.w = self.INPpar.h = 1
441
+ self.INPpar.W = self.INPpar.H = 1
442
+ self.INPpar.row = -1
443
+ self.INPpar.col = -1
444
+ return
445
+
446
+ def button_updown_action(self,d):
447
+ source_rows=[]
448
+ [source_rows.append(i.row()) for i in self.ui.list_images.selectedItems() if i.row() not in source_rows and i.row()>-1]
449
+ source_rows.sort(reverse=d>0)
450
+
451
+ for row in source_rows:
452
+ if d==-1 and row==0: return
453
+ if d==+1 and row==len(self.INPpar.filenames)-1: return
454
+ filename=self.INPpar.filenames.pop(row)
455
+ self.INPpar.filenames.insert(row+d,filename)
456
+ par=self.INPpar.plapar.pop(row)
457
+ self.INPpar.plapar.insert(row+d,par)
458
+ source_rows.sort(reverse=d>0)
459
+ self.INPpar.rows=[]
460
+ self.INPpar.cols=[]
461
+ for row in source_rows:
462
+ for col in range(self.ui.list_images.columnCount()):
463
+ self.INPpar.rows.append(row+d)
464
+ self.INPpar.cols.append(col)
465
+ self.INPpar.row+=d
466
+ self.ui.list_images.setFocus()
467
+ return
468
+
469
+ def button_down_action(self):
470
+ self.button_updown_action(+1)
471
+
472
+ def button_up_action(self):
473
+ self.button_updown_action(-1)
474
+
475
+ def list_selection(self):
476
+ selectedItems=self.ui.list_images.selectedItems()
477
+ if selectedItems:
478
+ self.INPpar.rows=[i.row() for i in selectedItems]
479
+ self.INPpar.cols=[i.column() for i in selectedItems]
480
+ self.INPpar.row=self.INPpar.rows[-1]
481
+ self.INPpar.col=self.INPpar.cols[-1]
482
+ else:
483
+ self.INPpar.rows=[-1]
484
+ self.INPpar.cols=[-1]
485
+ self.INPpar.row=-1
486
+ self.INPpar.col=-1
487
+ return
488
+
489
+ def updatePlanePar(self):
490
+ if self.ui.list_images.currentColumn()==1:
491
+ r=self.ui.list_images.currentRow()
492
+ item=self.ui.list_images.item(r,1)
493
+ text=item.text()
494
+ oldtext=", ".join([str(s) for s in self.INPpar.plapar[r]])
495
+ if text!=oldtext:
496
+ #fex=re.compile('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')
497
+ if self.INPpar.FlagOptPlane:
498
+ tsplitted=re.split(',',text)
499
+ #pri.Callback.white(tsplitted)
500
+ if len(tsplitted)==6 and all([isfloat(p) for p in tsplitted]):
501
+ self.INPpar.plapar[r]=[float(p) for p in tsplitted]
502
+ else:
503
+ if isfloat(text):
504
+ self.INPpar.plapar[r]=[float(text)]
505
+ pri.Callback.green(f'***** new par {", ".join([str(s) for s in self.INPpar.plapar[r]])}')
506
+
507
+ #******************** Adjusting
508
+ def adjustCam(self):
509
+ if self.INPpar.FlagCam and len(self.INPpar.cams)==0:
510
+ ncam=0
511
+ for f in self.INPpar.filenames:
512
+ pats=re.findall(r'_cam\d+', f)
513
+ if len(pats):
514
+ ncam=int(pats[-1].replace("_cam",""))
515
+ break
516
+ self.INPpar.cams=[ncam]
517
+ elif not self.INPpar.FlagCam and len(self.INPpar.cams)>0:
518
+ scam=str(self.INPpar.cams[0])
519
+ self.INPpar.filenames=[f.replace('*',scam) for f in self.INPpar.filenames]
520
+ self.INPpar.cams=[]
521
+
522
+ def adjust_list_images(self):
523
+ #deleting filenames not compatible with the option _cam* in the filename
524
+ ind_del=[]
525
+ for k,f in enumerate(self.INPpar.filenames):
526
+ if (not '_cam' in f and self.INPpar.FlagCam) or\
527
+ ('_cam*' in f and not self.INPpar.FlagCam):
528
+ ind_del.append(k)
529
+ for kk in range(len(ind_del)-1,-1,-1):
530
+ k=ind_del[kk]
531
+ self.INPpar.filenames.pop(k)
532
+ self.INPpar.plapar.pop(k)
533
+
534
+ #check that the filename contains * and not an identifier number
535
+ if self.INPpar.FlagCam:
536
+ for k,f in enumerate(self.INPpar.filenames):
537
+ if '_cam*' in f: continue
538
+ fsplitted=re.split(r'_cam\d+', f)
539
+ fsplitted.insert(-1,'_cam*')
540
+ f="".join(fsplitted)
541
+ self.INPpar.filenames[k]=f
542
+ f_unique=[]
543
+ plapar_unique=[]
544
+ for f,p in zip(self.INPpar.filenames,self.INPpar.plapar):
545
+ if not f in f_unique:
546
+ f_unique.append(f)
547
+ plapar_unique.append(p)
548
+ self.INPpar.filenames=f_unique
549
+ self.INPpar.plapar=plapar_unique
550
+
551
+ self.INPpar.row=min([len(self.INPpar.filenames),self.INPpar.row])
552
+ if self.INPpar.FlagCam:
553
+ self.INPpar.imList=[[] for _ in range(len(self.INPpar.cams))]
554
+ self.INPpar.imEx=[[] for _ in range(len(self.INPpar.cams))]
555
+ for k,c in enumerate(self.INPpar.cams):
556
+ self.INPpar.imList[k]=[self.INPpar.path+f.replace("*",str(c)) for f in self.INPpar.filenames]
557
+ self.INPpar.imEx[k]=[os.path.exists(fk) for fk in self.INPpar.imList[k]]
558
+ else:
559
+ self.INPpar.imList=[[self.INPpar.path+f for f in self.INPpar.filenames]]
560
+ self.INPpar.imEx=[[os.path.exists(fk) for fk in self.INPpar.imList[0]]]
561
+
562
+
563
+ self.INPpar.imageFile=''
564
+ if len(self.INPpar.imList):
565
+ if len(self.INPpar.imList[0]):
566
+ self.INPpar.imageFile=self.INPpar.imList[0][0]
567
+ return
568
+
569
+ def adjust_image_sizes(self):
570
+ if not self.INPpar.imageFile or not os.path.exists(self.INPpar.imageFile): return
571
+ try:
572
+ im = Image.open(self.INPpar.imageFile)
573
+ self.INPpar.ext=os.path.splitext(self.INPpar.imageFile)[-1]
574
+ pri.Info.blue(f'File extension: {self.INPpar.ext}')
575
+ except:
576
+ pri.Error.blue(f'Error opening image file: {self.INPpar.imageFile}.\n{traceback.format_exc()}\n')
577
+ else:
578
+ self.INPpar.W,self.INPpar.H=im.size
579
+ if self.INPpar.w<1 or self.INPpar.w>self.INPpar.W:
580
+ self.INPpar.w=self.INPpar.W
581
+ if self.INPpar.h<1 or self.INPpar.H>self.INPpar.H:
582
+ self.INPpar.h=self.INPpar.H
583
+ if self.INPpar.x<0: self.INPpar.x=0
584
+ elif self.INPpar.x>self.INPpar.W-self.INPpar.w: self.INPpar.x=self.INPpar.W-self.INPpar.w
585
+ if self.INPpar.y<0: self.INPpar.y=0
586
+ elif self.INPpar.y>self.INPpar.H-self.INPpar.h: self.INPpar.y=self.INPpar.H-self.INPpar.h
587
+ return
588
+
589
+ #******************** Layout
590
+ def set_list_images_items(self):
591
+ self.ui.list_images.setRowCount(0)
592
+ self.INPpar.FlagImages=[0]*len(self.INPpar.filenames)
593
+ for k,f in enumerate(self.INPpar.filenames):
594
+ c=self.ui.list_images.rowCount()
595
+ self.ui.list_images.insertRow(c)
596
+ list_eim_camk=[ex[k] for ex in self.INPpar.imEx]
597
+
598
+ item_filename=QTableWidgetItem(f)
599
+ item_filename.setFlags(item_filename.flags() & ~Qt.ItemIsEditable)
600
+ item_filename.setToolTip(f)
601
+ item_filename.setStatusTip(f)
602
+ self.ui.list_images.setItem(c, 0, item_filename)
603
+ if self.INPpar.FlagOptPlane:
604
+ tiptext='Plane parameters: \u03B2 (°), \u03B1 (°), \u03B3 (°), x (mm), y (mm), z (mm)'
605
+ else:
606
+ tiptext='Plane parameters: z (mm)'
607
+ tooltip=QLabel()
608
+ tooltip.setTextFormat(Qt.TextFormat.RichText)
609
+ tooltip.setText(tiptext)
610
+
611
+ item_parameters=QTableWidgetItem(", ".join([str(s) for s in self.INPpar.plapar[k]]))
612
+ item_parameters.setToolTip(tooltip.text())
613
+ item_parameters.setStatusTip(tooltip.text())
614
+ self.ui.list_images.setItem(c, 1, item_parameters)
615
+
616
+ message=''
617
+ tiptext=[]
618
+ if len(self.INPpar.plapar[k])==0:
619
+ message+="⚠"
620
+ tiptext+=[f"⚠︎: Corresponding plane parameters are not defined!"]
621
+ self.INPpar.FlagImages[k]|=1
622
+ for q in range(k):
623
+ if self.INPpar.plapar[k]==self.INPpar.plapar[q]:
624
+ message+="⚠"
625
+ tiptext+=[f"⚠︎: Plane parameters are coincident with those of plane {'#'} ({q})!"]
626
+ self.INPpar.FlagImages[k]|=2
627
+ break
628
+ if not all(list_eim_camk):
629
+ message+="❌"
630
+ if len(self.INPpar.cams):
631
+ cams=",".join([str(self.INPpar.cams[kk]) for kk,e in enumerate(list_eim_camk) if not e])
632
+ tiptext+=[f"❌: Image files for cameras {'#'} ({cams}) are missing!"]
633
+ else:
634
+ tiptext+=[f"❌: Image files is missing!"]
635
+ self.INPpar.FlagImages[k]|=4
636
+ if tiptext:
637
+ tiptext=f"<br>".join(tiptext)
638
+ else:
639
+ message="✅"
640
+ tiptext='✅: Check if the values of the plane parameters are correct!'
641
+ tooltip=QLabel()
642
+ tooltip.setTextFormat(Qt.TextFormat.RichText)
643
+ tooltip.setText(tiptext)
644
+
645
+ item_message=QTableWidgetItem(message)
646
+ item_message.setFlags(item_message.flags() & ~Qt.ItemIsEditable)
647
+ item_message.setToolTip(tooltip.text())
648
+ item_message.setStatusTip(tooltip.text())
649
+ self.ui.list_images.setItem(c, 2, item_message)
650
+ return
651
+
652
+ def listClear(self):
653
+ self.ui.list_images.clear()
654
+ nRow=self.ui.list_images.rowCount()
655
+ for k in range(nRow):
656
+ self.ui.list_images.removeRow(self.ui.list_images.rowAt(k))
657
+ self.ui.list_images.setHorizontalHeaderLabels(self.tableHeaders)
658
+
659
+ def errorMessage(self):
660
+ self.INPpar.errorMessage=''
661
+ if not len(self.INPpar.FlagImages):
662
+ self.INPpar.errorMessage+='Select a valid set of target image files!\n\n'
663
+ if not self.INPpar.OptionValidPathOut:
664
+ self.INPpar.errorMessage+='Choose a valid path for the output folder!\n\n'
665
+ if not self.INPpar.OptionValidRootOut:
666
+ self.INPpar.errorMessage+='Specify a valid root for the name of the output files!\n\n'
667
+ if any(self.INPpar.FlagImages):
668
+ errorFiles=[[],[]]
669
+ for k,f in enumerate(self.INPpar.FlagImages):
670
+ if f&3: errorFiles[0].append(self.INPpar.filenames[k])
671
+ elif f&4: errorFiles[1].append(self.INPpar.filenames[k])
672
+ if len(errorFiles[0]) or len(errorFiles[1]):
673
+ errorMessage=''
674
+ if len(errorFiles[0]):
675
+ errList=f";\n ".join(errorFiles[0])
676
+ errorMessage+=f'Define appropriately the plane parameters for the following images:\n {errList}.\n\n'
677
+ if len(errorFiles[1]):
678
+ errList=f";\n ".join(errorFiles[1])
679
+ errorMessage+=f'Check for missing files related to the following images:\n {errList}.'
680
+ #pri.Error.blue(errorMessage)
681
+ self.INPpar.errorMessage+=errorMessage
682
+ if self.INPpar.errorMessage:
683
+ self.INPpar.errorMessage='Please check the following issues before starting calibration!\n\n'+self.INPpar.errorMessage
684
+
685
+ #*************************************************** Output path
686
+ #******************** Actions
687
+ def radio_Same_as_input_action(self):
688
+ self.INPpar.path_out=self.INPpar.path
689
+
690
+ def line_edit_path_out_changing(self):
691
+ self.ui.label_check_path_out.setPixmap(QPixmap())
692
+
693
+ def line_edit_path_out_preaction(self):
694
+ currpath=myStandardPath(self.ui.line_edit_path_out.text())
695
+ currpath=relativizePath(currpath)
696
+ self.ui.line_edit_path_out.setText(currpath)
697
+
698
+ def button_path_out_action(self):
699
+ directory = str(QFileDialog.getExistingDirectory(self,\
700
+ "Choose a folder", dir=self.INPpar.path_out,options=optionNativeDialog))
701
+ currpath='{}'.format(directory)
702
+ if not currpath=='':
703
+ self.ui.line_edit_path_out.setText(currpath)
704
+ self.line_edit_path_out_preaction()
705
+ self.INPpar.path_out=self.ui.line_edit_path_out.text()
706
+
707
+ #******************** Settings
708
+ def setPathOutLabel(self):
709
+ #Clickable label: no need for setStatusTip
710
+ if self.INPpar.OptionValidPathOut:
711
+ self.ui.label_check_path_out.setPixmap(self.pixmap_v)
712
+ self.ui.label_check_path_out.setToolTip("The specified path of the output folder exists!")
713
+ else:
714
+ self.ui.label_check_path_out.setPixmap(self.pixmap_x)
715
+ self.ui.label_check_path_out.setToolTip("The specified path of the output folder does not exist!")
716
+
717
+ #******************** Layout
718
+ def setOptionValidPathOut(self):
719
+ self.INPpar.OptionValidPathOut=int(os.path.exists(self.INPpar.path_out))
720
+
721
+ #*************************************************** Output root
722
+ #******************** Actions
723
+ def line_edit_root_out_changing(self):
724
+ self.ui.label_check_root.setPixmap(QPixmap())
725
+
726
+ def line_edit_root_out_preaction(self):
727
+ entry=myStandardRoot(self.ui.line_edit_root_out.text())
728
+ self.ui.line_edit_root_out.setText(entry)
729
+
730
+ #******************** Settings
731
+ def setRootOutLabel(self):
732
+ #Clickable label: no need for setStatusTip
733
+ if self.INPpar.OptionValidRootOut==-2:
734
+ if not self.INPpar.FlagReadCalib:
735
+ self.ui.label_check_root.setPixmap(self.pixmap_warn)
736
+ self.ui.label_check_root.setToolTip("Files with the same root name already exist in the selected output folder!")
737
+ else:
738
+ self.ui.label_check_root.setPixmap(self.pixmap_v)
739
+ self.ui.label_check_root.setToolTip("The root of the output filenames is admitted!")
740
+ elif self.INPpar.OptionValidRootOut==0:
741
+ self.ui.label_check_root.setPixmap(self.pixmap_x)
742
+ self.ui.label_check_root.setToolTip("The root of the output filenames is not admitted!")
743
+ if self.INPpar.OptionValidRootOut==1:
744
+ self.ui.label_check_root.setPixmap(self.pixmap_v)
745
+ self.ui.label_check_root.setToolTip("The root of the output filenames is admitted!")
746
+
747
+ #******************** Layout
748
+ def setOptionValidRootOut(self):
749
+ INP=self.INPpar
750
+ ext='.cal'
751
+ FlagExistPath=INP.OptionValidPathOut
752
+ if FlagExistPath:
753
+ currpath=myStandardPath(INP.path_out)
754
+ else:
755
+ currpath='./'
756
+ pattern=myStandardRoot(currpath+INP.root_out)+'*'+ext
757
+ FlagExist=False
758
+ if FlagExistPath:
759
+ files=findFiles_sorted(pattern)
760
+ FlagExist=len(files)>0
761
+ if FlagExist:
762
+ INP.OptionValidRootOut=-2
763
+ else:
764
+ try:
765
+ filename=pattern.replace('*','a0')+'.delmeplease'
766
+ open(filename,'w')
767
+ except:
768
+ FlagDeleteFile=False
769
+ INP.OptionValidRootOut=0
770
+ else:
771
+ FlagDeleteFile=True
772
+ INP.OptionValidRootOut=1
773
+ finally:
774
+ if FlagDeleteFile:
775
+ os.remove(filename)
776
+
777
+
778
+ if __name__ == "__main__":
779
+ import sys
780
+ app=QApplication.instance()
781
+ if not app:app = QApplication(sys.argv)
782
+ app.setStyle('Fusion')
783
+ object = Input_Tab_CalVi(None)
784
+ object.show()
785
+ app.exec()
786
+ app.quit()
787
+ app=None