shinestacker 0.3.4__tar.gz → 0.3.5__tar.gz

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.

Potentially problematic release.


This version of shinestacker might be problematic. Click here for more details.

Files changed (134) hide show
  1. {shinestacker-0.3.4 → shinestacker-0.3.5}/.coverage +0 -0
  2. {shinestacker-0.3.4 → shinestacker-0.3.5}/CHANGELOG.md +11 -0
  3. {shinestacker-0.3.4 → shinestacker-0.3.5}/PKG-INFO +10 -4
  4. {shinestacker-0.3.4 → shinestacker-0.3.5}/README.md +9 -3
  5. shinestacker-0.3.5/THIRD_PARTY_LICENSES.txt +80 -0
  6. shinestacker-0.3.5/img/gui-project-new.png +0 -0
  7. shinestacker-0.3.5/src/shinestacker/_version.py +1 -0
  8. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/base_stack_algo.py +1 -2
  9. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/noise_detection.py +0 -3
  10. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/stack.py +1 -2
  11. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/stack_framework.py +8 -2
  12. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/vignetting.py +5 -4
  13. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/help_menu.py +1 -1
  14. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/actions_window.py +4 -7
  15. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/project_editor.py +9 -3
  16. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker.egg-info/PKG-INFO +10 -4
  17. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker.egg-info/SOURCES.txt +1 -0
  18. shinestacker-0.3.4/img/gui-project-new.png +0 -0
  19. shinestacker-0.3.4/src/shinestacker/_version.py +0 -1
  20. {shinestacker-0.3.4 → shinestacker-0.3.5}/.coveragerc +0 -0
  21. {shinestacker-0.3.4 → shinestacker-0.3.5}/.flake8 +0 -0
  22. {shinestacker-0.3.4 → shinestacker-0.3.5}/.github/workflows/ci-multiplatform.yml +0 -0
  23. {shinestacker-0.3.4 → shinestacker-0.3.5}/.github/workflows/pylint.yml +0 -0
  24. {shinestacker-0.3.4 → shinestacker-0.3.5}/.github/workflows/pypi-publish.yml +0 -0
  25. {shinestacker-0.3.4 → shinestacker-0.3.5}/.github/workflows/release.yml +0 -0
  26. {shinestacker-0.3.4 → shinestacker-0.3.5}/.gitignore +0 -0
  27. {shinestacker-0.3.4 → shinestacker-0.3.5}/.pylintrc +0 -0
  28. {shinestacker-0.3.4 → shinestacker-0.3.5}/.readthedocs.yaml +0 -0
  29. {shinestacker-0.3.4 → shinestacker-0.3.5}/LICENSE +0 -0
  30. {shinestacker-0.3.4 → shinestacker-0.3.5}/MANIFEST.in +0 -0
  31. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/alignment.md +0 -0
  32. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/api.md +0 -0
  33. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/balancing.md +0 -0
  34. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/conf.py +0 -0
  35. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/focus_stacking.md +0 -0
  36. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/gui.md +0 -0
  37. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/index.md +0 -0
  38. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/job.md +0 -0
  39. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/main.md +0 -0
  40. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/multilayer.md +0 -0
  41. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/noise.md +0 -0
  42. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/requirements.txt +0 -0
  43. {shinestacker-0.3.4 → shinestacker-0.3.5}/docs/vignetting.md +0 -0
  44. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/coffee.gif +0 -0
  45. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/coffee_stack.jpg +0 -0
  46. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/coins.gif +0 -0
  47. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/coins_stack.jpg +0 -0
  48. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/extreme-vignetting.jpg +0 -0
  49. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/flies.gif +0 -0
  50. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/flies_stack.jpg +0 -0
  51. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/flow-diagram.png +0 -0
  52. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/gui-finder.png +0 -0
  53. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/gui-project-run.png +0 -0
  54. {shinestacker-0.3.4 → shinestacker-0.3.5}/img/gui-retouch.png +0 -0
  55. {shinestacker-0.3.4 → shinestacker-0.3.5}/pyproject.toml +0 -0
  56. {shinestacker-0.3.4 → shinestacker-0.3.5}/requirements.txt +0 -0
  57. {shinestacker-0.3.4 → shinestacker-0.3.5}/scripts/build_release.py +0 -0
  58. {shinestacker-0.3.4 → shinestacker-0.3.5}/scripts/validate-tomli.py +0 -0
  59. {shinestacker-0.3.4 → shinestacker-0.3.5}/setup.cfg +0 -0
  60. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/__init__.py +0 -0
  61. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/__init__.py +0 -0
  62. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/align.py +0 -0
  63. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/balance.py +0 -0
  64. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/core_utils.py +0 -0
  65. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/denoise.py +0 -0
  66. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/depth_map.py +0 -0
  67. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/exif.py +0 -0
  68. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/multilayer.py +0 -0
  69. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/pyramid.py +0 -0
  70. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/sharpen.py +0 -0
  71. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/utils.py +0 -0
  72. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/algorithms/white_balance.py +0 -0
  73. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/__init__.py +0 -0
  74. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/about_dialog.py +0 -0
  75. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/app_config.py +0 -0
  76. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/gui_utils.py +0 -0
  77. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/main.py +0 -0
  78. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/open_frames.py +0 -0
  79. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/project.py +0 -0
  80. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/app/retouch.py +0 -0
  81. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/config/__init__.py +0 -0
  82. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/config/config.py +0 -0
  83. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/config/constants.py +0 -0
  84. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/config/gui_constants.py +0 -0
  85. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/core/__init__.py +0 -0
  86. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/core/colors.py +0 -0
  87. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/core/core_utils.py +0 -0
  88. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/core/exceptions.py +0 -0
  89. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/core/framework.py +0 -0
  90. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/core/logging.py +0 -0
  91. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/__init__.py +0 -0
  92. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/action_config.py +0 -0
  93. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/colors.py +0 -0
  94. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/gui_images.py +0 -0
  95. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/gui_logging.py +0 -0
  96. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/gui_run.py +0 -0
  97. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/ico/focus_stack_bkg.png +0 -0
  98. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/ico/shinestacker.icns +0 -0
  99. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/ico/shinestacker.ico +0 -0
  100. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/ico/shinestacker.png +0 -0
  101. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/img/close-round-line-icon.png +0 -0
  102. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/img/forward-button-icon.png +0 -0
  103. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/img/play-button-round-icon.png +0 -0
  104. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/img/plus-round-line-icon.png +0 -0
  105. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/main_window.py +0 -0
  106. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/new_project.py +0 -0
  107. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/project_converter.py +0 -0
  108. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/gui/project_model.py +0 -0
  109. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/__init__.py +0 -0
  110. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/base_filter.py +0 -0
  111. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/brush.py +0 -0
  112. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/brush_gradient.py +0 -0
  113. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/brush_preview.py +0 -0
  114. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/brush_tool.py +0 -0
  115. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/denoise_filter.py +0 -0
  116. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/display_manager.py +0 -0
  117. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/exif_data.py +0 -0
  118. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/file_loader.py +0 -0
  119. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/filter_manager.py +0 -0
  120. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/image_editor.py +0 -0
  121. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/image_editor_ui.py +0 -0
  122. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/image_filters.py +0 -0
  123. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/image_viewer.py +0 -0
  124. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/io_gui_handler.py +0 -0
  125. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/io_manager.py +0 -0
  126. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/layer_collection.py +0 -0
  127. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/shortcuts_help.py +0 -0
  128. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/undo_manager.py +0 -0
  129. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/unsharp_mask_filter.py +0 -0
  130. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker/retouch/white_balance_filter.py +0 -0
  131. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker.egg-info/dependency_links.txt +0 -0
  132. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker.egg-info/entry_points.txt +0 -0
  133. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker.egg-info/requires.txt +0 -0
  134. {shinestacker-0.3.4 → shinestacker-0.3.5}/src/shinestacker.egg-info/top_level.txt +0 -0
@@ -4,6 +4,17 @@ This page reports the main releases only and the main changes therein.
4
4
 
5
5
  ---
6
6
 
7
+ ## [v0.3.5] - 2025-08-17
8
+ **Bug fixes**
9
+
10
+ ### Changes
11
+
12
+ * fixed a bug that prevented to add sub-actoins
13
+ * vignetting constrains model parameter in order to prevent searching for dark areas at the center of the image instead of at periphery
14
+ * updated sample images and documentation
15
+
16
+ ---
17
+
7
18
  ## [v0.3.4] - 2025-08-16
8
19
  **Code consolidation and fixes**
9
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shinestacker
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: ShineStacker
5
5
  Author-email: Luca Lista <luka.lista@gmail.com>
6
6
  License-Expression: LGPL-3.0
@@ -37,10 +37,11 @@ Dynamic: license-file
37
37
  [![PyPI version](https://img.shields.io/pypi/v/shinestacker?color=success)](https://pypi.org/project/shinestacker/)
38
38
  [![Python Versions](https://img.shields.io/pypi/pyversions/shinestacker)](https://pypi.org/project/shinestacker/)
39
39
  [![Qt Versions](https://img.shields.io/badge/Qt-6-blue.svg?&logo=Qt&logoWidth=18&logoColor=white)](https://www.qt.io/qt-for-python)
40
- [![codecov](https://codecov.io/github/lucalista/shinestacker/graph/badge.svg?token=Y5NKW6VH5G)](https://codecov.io/github/lucalista/shinestacker)
41
40
  [![pylint](https://img.shields.io/badge/PyLint-9.98-yellow?logo=python&logoColor=white)](https://github.com/lucalista/shinestacker/blob/main/.github/workflows/pylint.yml)
42
41
  [![Documentation Status](https://readthedocs.org/projects/shinestacker/badge/?version=latest)](https://shinestacker.readthedocs.io/en/latest/?badge=latest)
43
-
42
+ <!--
43
+ [![codecov](https://codecov.io/github/lucalista/shinestacker/graph/badge.svg?token=Y5NKW6VH5G)](https://codecov.io/github/lucalista/shinestacker)
44
+ -->
44
45
 
45
46
 
46
47
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400" referrerpolicy="no-referrer"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400" referrerpolicy="no-referrer">
@@ -83,9 +84,14 @@ The main pyramid stack algorithm was initially inspired by the [Laplacian pyrami
83
84
  * [Pyramid Methods in Image Processing](https://www.researchgate.net/publication/246727904_Pyramid_Methods_in_Image_Processing), E. H. Adelson, C. H. Anderson, J. R. Bergen, P. J. Burt, J. M. Ogden, RCA Engineer, 29-6, Nov/Dec 1984
84
85
  Pyramid methods in image processing
85
86
  * [A Multi-focus Image Fusion Method Based on Laplacian Pyramid](http://www.jcomputers.us/vol6/jcp0612-07.pdf), Wencheng Wang, Faliang Chang, Journal of Computers 6 (12), 2559, December 2011
86
- * Another [original implementation on GitHub](https://github.com/bznick98/Focus_Stacking) by Zongnan Bao
87
87
 
88
88
  # License
89
89
 
90
90
  The software is provided as is under the [GNU Lesser General Public License v3.0](https://choosealicense.com/licenses/lgpl-3.0/).
91
91
 
92
+ # Attribution request
93
+ 📸 If you publish images created with Shine Stacker, please consider adding a note such as:
94
+
95
+ *Created with Shine Stacker – https://github.com/lucalista/shinestacker*
96
+
97
+ This is not mandatory, but highly appreciated.
@@ -6,10 +6,11 @@
6
6
  [![PyPI version](https://img.shields.io/pypi/v/shinestacker?color=success)](https://pypi.org/project/shinestacker/)
7
7
  [![Python Versions](https://img.shields.io/pypi/pyversions/shinestacker)](https://pypi.org/project/shinestacker/)
8
8
  [![Qt Versions](https://img.shields.io/badge/Qt-6-blue.svg?&logo=Qt&logoWidth=18&logoColor=white)](https://www.qt.io/qt-for-python)
9
- [![codecov](https://codecov.io/github/lucalista/shinestacker/graph/badge.svg?token=Y5NKW6VH5G)](https://codecov.io/github/lucalista/shinestacker)
10
9
  [![pylint](https://img.shields.io/badge/PyLint-9.98-yellow?logo=python&logoColor=white)](https://github.com/lucalista/shinestacker/blob/main/.github/workflows/pylint.yml)
11
10
  [![Documentation Status](https://readthedocs.org/projects/shinestacker/badge/?version=latest)](https://shinestacker.readthedocs.io/en/latest/?badge=latest)
12
-
11
+ <!--
12
+ [![codecov](https://codecov.io/github/lucalista/shinestacker/graph/badge.svg?token=Y5NKW6VH5G)](https://codecov.io/github/lucalista/shinestacker)
13
+ -->
13
14
 
14
15
 
15
16
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400" referrerpolicy="no-referrer"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400" referrerpolicy="no-referrer">
@@ -52,9 +53,14 @@ The main pyramid stack algorithm was initially inspired by the [Laplacian pyrami
52
53
  * [Pyramid Methods in Image Processing](https://www.researchgate.net/publication/246727904_Pyramid_Methods_in_Image_Processing), E. H. Adelson, C. H. Anderson, J. R. Bergen, P. J. Burt, J. M. Ogden, RCA Engineer, 29-6, Nov/Dec 1984
53
54
  Pyramid methods in image processing
54
55
  * [A Multi-focus Image Fusion Method Based on Laplacian Pyramid](http://www.jcomputers.us/vol6/jcp0612-07.pdf), Wencheng Wang, Faliang Chang, Journal of Computers 6 (12), 2559, December 2011
55
- * Another [original implementation on GitHub](https://github.com/bznick98/Focus_Stacking) by Zongnan Bao
56
56
 
57
57
  # License
58
58
 
59
59
  The software is provided as is under the [GNU Lesser General Public License v3.0](https://choosealicense.com/licenses/lgpl-3.0/).
60
60
 
61
+ # Attribution request
62
+ 📸 If you publish images created with Shine Stacker, please consider adding a note such as:
63
+
64
+ *Created with Shine Stacker – https://github.com/lucalista/shinestacker*
65
+
66
+ This is not mandatory, but highly appreciated.
@@ -0,0 +1,80 @@
1
+ THIRD-PARTY LICENSES
2
+ ====================
3
+
4
+ This application bundles several third-party Python packages.
5
+ Each package is copyrighted by its respective authors and distributed under the following licenses.
6
+ Full license texts are reproduced below when required.
7
+
8
+ -------------------------------------------------------------------------------
9
+ matplotlib
10
+ License: PSF license + BSD style
11
+ https://matplotlib.org/stable/users/project/license.html
12
+
13
+ -------------------------------------------------------------------------------
14
+ imagecodecs
15
+ License: BSD-3-Clause
16
+ https://pypi.org/project/imagecodecs/
17
+
18
+ -------------------------------------------------------------------------------
19
+ jsonpickle
20
+ License: BSD-3-Clause
21
+ https://github.com/jsonpickle/jsonpickle
22
+
23
+ -------------------------------------------------------------------------------
24
+ numpy
25
+ License: BSD-3-Clause
26
+ https://numpy.org/
27
+
28
+ -------------------------------------------------------------------------------
29
+ opencv-python
30
+ License: Apache License 2.0
31
+ https://github.com/opencv/opencv-python
32
+
33
+ -------------------------------------------------------------------------------
34
+ pillow
35
+ License: Historical PIL Software License (similar to MIT)
36
+ https://python-pillow.org
37
+
38
+ -------------------------------------------------------------------------------
39
+ psdtags
40
+ License: MIT
41
+ https://pypi.org/project/psdtags/
42
+
43
+ -------------------------------------------------------------------------------
44
+ PySide6
45
+ License: GNU Lesser General Public License v3.0 (LGPL-3.0)
46
+ or commercial license from The Qt Company
47
+ https://doc.qt.io/qtforpython/
48
+
49
+ Full license text follows:
50
+
51
+ --- BEGIN LGPL-3.0 LICENSE ---
52
+ <qui incolla il testo completo della LGPL-3.0>
53
+ --- END LGPL-3.0 LICENSE ---
54
+
55
+ -------------------------------------------------------------------------------
56
+ scipy
57
+ License: BSD-3-Clause
58
+ https://scipy.org/
59
+
60
+ -------------------------------------------------------------------------------
61
+ tifffile
62
+ License: BSD-3-Clause
63
+ https://www.lfd.uci.edu/~gohlke/
64
+
65
+ -------------------------------------------------------------------------------
66
+ tqdm
67
+ License: Mozilla Public License 2.0 (MPL-2.0)
68
+ https://github.com/tqdm/tqdm
69
+
70
+ Full license text follows:
71
+
72
+ --- BEGIN MPL-2.0 LICENSE ---
73
+ <qui incolla il testo completo della MPL-2.0>
74
+ --- END MPL-2.0 LICENSE ---
75
+
76
+ -------------------------------------------------------------------------------
77
+
78
+ NOTE:
79
+ This file is provided for license compliance and attribution purposes.
80
+ Your application code is licensed separately under the GNU Lesser General Public License v3.0.
@@ -0,0 +1 @@
1
+ __version__ = '0.3.5'
@@ -1,6 +1,5 @@
1
1
  # pylint: disable=C0114, C0115, C0116, E0602, R0903
2
2
  import numpy as np
3
- from .. core.colors import color_str
4
3
  from .. core.exceptions import InvalidOptionError, ImageLoadError
5
4
  from .. config.constants import constants
6
5
  from .utils import read_img, get_img_metadata, validate_image
@@ -28,7 +27,7 @@ class BaseStackAlgo:
28
27
  return self._steps_per_frame
29
28
 
30
29
  def print_message(self, msg):
31
- self.process.sub_message_r(color_str(msg, "light_blue"))
30
+ self.process.sub_message_r(msg)
32
31
 
33
32
  def read_image_and_update_metadata(self, img_path, metadata):
34
33
  img = read_img(img_path)
@@ -162,9 +162,6 @@ class MaskNoise(SubAction):
162
162
  else:
163
163
  raise ImageLoadError(path, "file not found.")
164
164
 
165
- def end(self):
166
- pass
167
-
168
165
  def run_frame(self, _idx, _ref_idx, image):
169
166
  self.process.sub_message_r(': mask noisy pixels')
170
167
  if len(image.shape) == 3:
@@ -2,7 +2,6 @@
2
2
  import os
3
3
  import numpy as np
4
4
  from .. config.constants import constants
5
- from .. core.colors import color_str
6
5
  from .. core.framework import JobBase
7
6
  from .. core.exceptions import InvalidOptionError
8
7
  from .utils import write_img
@@ -92,7 +91,7 @@ class FocusStackBunch(ActionList, FocusStackBase):
92
91
  ActionList.end(self)
93
92
 
94
93
  def run_step(self):
95
- self.print_message_r(color_str(f"fusing bunch: {self.count}", "blue"))
94
+ self.print_message_r(f"fusing bunch: {self.count}")
96
95
  self.focus_stack(self._chunks[self.count - 1])
97
96
  self.callback('after_step', self.id, self.name, self.count)
98
97
 
@@ -237,6 +237,12 @@ class SubAction:
237
237
  def __init__(self, enabled=True):
238
238
  self.enabled = enabled
239
239
 
240
+ def begin(self, process):
241
+ pass
242
+
243
+ def end(self):
244
+ pass
245
+
240
246
 
241
247
  class CombinedActions(FramesRefActions):
242
248
  def __init__(self, name, actions=[], enabled=True, **kwargs):
@@ -255,10 +261,10 @@ class CombinedActions(FramesRefActions):
255
261
  filename = self.filenames[idx]
256
262
  img = read_img((self.output_dir
257
263
  if self.step_process else self.input_full_path) + f"/{filename}")
258
- self.dtype = img.dtype
259
- self.shape = img.shape
260
264
  if img is None:
261
265
  raise RuntimeError(f"Invalid file: {self.input_full_path}/{filename}")
266
+ self.dtype = img.dtype
267
+ self.shape = img.shape
262
268
  return img
263
269
 
264
270
  def run_frame(self, idx, ref_idx):
@@ -59,7 +59,8 @@ class Vignetting(SubAction):
59
59
  i_valid, r_valid = intensities[valid_mask], radii[valid_mask]
60
60
  try:
61
61
  res = curve_fit(Vignetting.sigmoid, r_valid, i_valid,
62
- p0=[np.max(i_valid), 0.01, np.median(r_valid)])[0]
62
+ p0=[np.max(i_valid), 0.01, np.median(r_valid)],
63
+ bounds=([0, 0, 0], ['inf', 'inf', 'inf']))[0]
63
64
  except Exception:
64
65
  self.process.sub_message(
65
66
  color_str(": could not find vignetting model", "red"),
@@ -83,7 +84,7 @@ class Vignetting(SubAction):
83
84
  if image.dtype == np.uint8 else 65535).astype(image.dtype)
84
85
 
85
86
  def run_frame(self, idx, _ref_idx, img_0):
86
- self.process.sub_message_r(color_str(": compute vignetting", "light_blue"))
87
+ self.process.sub_message_r(": compute vignetting")
87
88
  img = cv2.cvtColor(img_8bit(img_0), cv2.COLOR_BGR2GRAY)
88
89
  radii, intensities = self.radial_mean_intensity(img)
89
90
  pars = self.fit_sigmoid(radii, intensities)
@@ -92,7 +93,7 @@ class Vignetting(SubAction):
92
93
  self.v0 = Vignetting.sigmoid(0, *pars)
93
94
  i0_fit, k_fit, r0_fit = pars
94
95
  self.process.sub_message(
95
- f": fit parameters: i0={i0_fit:.4f}, k={k_fit:.4f}, r0={r0_fit:.4f}",
96
+ f": vignetting model parameters: i0={i0_fit:.4f}, k={k_fit:.4f}, r0={r0_fit:.4f}",
96
97
  level=logging.DEBUG)
97
98
  if self.plot_correction:
98
99
  plt.figure(figsize=(10, 5))
@@ -116,7 +117,7 @@ class Vignetting(SubAction):
116
117
  self.corrections[i][idx] = fsolve(lambda x: Vignetting.sigmoid(x, *pars) /
117
118
  self.v0 - p, r0_fit)[0]
118
119
  if self.apply_correction:
119
- self.process.sub_message_r(color_str(": correct vignetting", "light_blue"))
120
+ self.process.sub_message_r(": correct vignetting")
120
121
  return self.correct_vignetting(img_0, pars)
121
122
  return img_0
122
123
 
@@ -14,4 +14,4 @@ def add_help_action(app):
14
14
 
15
15
 
16
16
  def browse_website():
17
- webbrowser.open("https://github.com/lucalista/shinestacker/blob/main/README.md")
17
+ webbrowser.open("https://github.com/lucalista/shinestacker/blob/main/docs/gui.md")
@@ -8,7 +8,6 @@ from PySide6.QtWidgets import QMessageBox, QFileDialog, QDialog
8
8
  from .. core.core_utils import get_app_base_path
9
9
  from .. config.constants import constants
10
10
  from .project_model import ActionConfig
11
- from .action_config import ActionConfigDialog
12
11
  from .project_editor import ProjectEditor
13
12
  from .new_project import NewProjectDialog
14
13
  from .project_model import Project
@@ -17,9 +16,6 @@ from .project_model import Project
17
16
  class ActionsWindow(ProjectEditor):
18
17
  def __init__(self):
19
18
  super().__init__()
20
- self._current_file = None
21
- self._current_file_wd = ''
22
- self._modified_project = False
23
19
  self.update_title()
24
20
 
25
21
  def update_title(self):
@@ -197,6 +193,7 @@ class ActionsWindow(ProjectEditor):
197
193
  self._current_file = file_path
198
194
  self._modified_project = False
199
195
  self.update_title()
196
+ os.chdir(os.path.dirname(file_path))
200
197
 
201
198
  def do_save(self, file_path):
202
199
  try:
@@ -229,7 +226,7 @@ class ActionsWindow(ProjectEditor):
229
226
  index = self.job_list.row(item)
230
227
  if 0 <= index < len(self.project.jobs):
231
228
  job = self.project.jobs[index]
232
- dialog = ActionConfigDialog(job, self._current_file_wd, self)
229
+ dialog = self.action_config_dialog(job)
233
230
  if dialog.exec() == QDialog.Accepted:
234
231
  current_row = self.job_list.currentRow()
235
232
  if current_row >= 0:
@@ -262,7 +259,7 @@ class ActionsWindow(ProjectEditor):
262
259
  if not is_sub_action:
263
260
  self.set_enabled_sub_actions_gui(
264
261
  current_action.type_name == constants.ACTION_COMBO)
265
- dialog = ActionConfigDialog(current_action, self._current_file_wd, self)
262
+ dialog = self.action_config_dialog(current_action)
266
263
  if dialog.exec() == QDialog.Accepted:
267
264
  self.on_job_selected(job_index)
268
265
  self.refresh_ui()
@@ -284,7 +281,7 @@ class ActionsWindow(ProjectEditor):
284
281
  self.edit_action(current_action)
285
282
 
286
283
  def edit_action(self, action):
287
- dialog = ActionConfigDialog(action, self._current_file_wd, self)
284
+ dialog = self.action_config_dialog(action)
288
285
  if dialog.exec() == QDialog.Accepted:
289
286
  self.on_job_selected(self.job_list.currentRow())
290
287
  self.mark_as_modified()
@@ -89,6 +89,9 @@ class ProjectEditor(QMainWindow):
89
89
  self.expert_options = False
90
90
  self.script_dir = os.path.dirname(__file__)
91
91
  self.dialog = None
92
+ self._current_file = None
93
+ self._current_file_wd = ''
94
+ self._modified_project = False
92
95
 
93
96
  def set_project(self, project):
94
97
  self.project = project
@@ -300,9 +303,12 @@ class ProjectEditor(QMainWindow):
300
303
  self.delete_element_action.setEnabled(True)
301
304
  return element
302
305
 
306
+ def action_config_dialog(self, action):
307
+ return ActionConfigDialog(action, self._current_file_wd, self)
308
+
303
309
  def add_job(self):
304
310
  job_action = ActionConfig("Job")
305
- self.dialog = ActionConfigDialog(job_action, self)
311
+ self.dialog = self.action_config_dialog(job_action)
306
312
  if self.dialog.exec() == QDialog.Accepted:
307
313
  self.mark_as_modified()
308
314
  self.project.jobs.append(job_action)
@@ -323,7 +329,7 @@ class ProjectEditor(QMainWindow):
323
329
  type_name = self.action_selector.currentText()
324
330
  action = ActionConfig(type_name)
325
331
  action.parent = self.get_current_job()
326
- self.dialog = ActionConfigDialog(action, self)
332
+ self.dialog = self.action_config_dialog(action)
327
333
  if self.dialog.exec() == QDialog.Accepted:
328
334
  self.mark_as_modified()
329
335
  self.project.jobs[current_index].add_sub_action(action)
@@ -365,7 +371,7 @@ class ProjectEditor(QMainWindow):
365
371
  if type_name is False:
366
372
  type_name = self.sub_action_selector.currentText()
367
373
  sub_action = ActionConfig(type_name)
368
- self.dialog = ActionConfigDialog(sub_action, self)
374
+ self.dialog = self.action_config_dialog(sub_action)
369
375
  if self.dialog.exec() == QDialog.Accepted:
370
376
  self.mark_as_modified()
371
377
  action.add_sub_action(sub_action)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shinestacker
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: ShineStacker
5
5
  Author-email: Luca Lista <luka.lista@gmail.com>
6
6
  License-Expression: LGPL-3.0
@@ -37,10 +37,11 @@ Dynamic: license-file
37
37
  [![PyPI version](https://img.shields.io/pypi/v/shinestacker?color=success)](https://pypi.org/project/shinestacker/)
38
38
  [![Python Versions](https://img.shields.io/pypi/pyversions/shinestacker)](https://pypi.org/project/shinestacker/)
39
39
  [![Qt Versions](https://img.shields.io/badge/Qt-6-blue.svg?&logo=Qt&logoWidth=18&logoColor=white)](https://www.qt.io/qt-for-python)
40
- [![codecov](https://codecov.io/github/lucalista/shinestacker/graph/badge.svg?token=Y5NKW6VH5G)](https://codecov.io/github/lucalista/shinestacker)
41
40
  [![pylint](https://img.shields.io/badge/PyLint-9.98-yellow?logo=python&logoColor=white)](https://github.com/lucalista/shinestacker/blob/main/.github/workflows/pylint.yml)
42
41
  [![Documentation Status](https://readthedocs.org/projects/shinestacker/badge/?version=latest)](https://shinestacker.readthedocs.io/en/latest/?badge=latest)
43
-
42
+ <!--
43
+ [![codecov](https://codecov.io/github/lucalista/shinestacker/graph/badge.svg?token=Y5NKW6VH5G)](https://codecov.io/github/lucalista/shinestacker)
44
+ -->
44
45
 
45
46
 
46
47
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400" referrerpolicy="no-referrer"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400" referrerpolicy="no-referrer">
@@ -83,9 +84,14 @@ The main pyramid stack algorithm was initially inspired by the [Laplacian pyrami
83
84
  * [Pyramid Methods in Image Processing](https://www.researchgate.net/publication/246727904_Pyramid_Methods_in_Image_Processing), E. H. Adelson, C. H. Anderson, J. R. Bergen, P. J. Burt, J. M. Ogden, RCA Engineer, 29-6, Nov/Dec 1984
84
85
  Pyramid methods in image processing
85
86
  * [A Multi-focus Image Fusion Method Based on Laplacian Pyramid](http://www.jcomputers.us/vol6/jcp0612-07.pdf), Wencheng Wang, Faliang Chang, Journal of Computers 6 (12), 2559, December 2011
86
- * Another [original implementation on GitHub](https://github.com/bznick98/Focus_Stacking) by Zongnan Bao
87
87
 
88
88
  # License
89
89
 
90
90
  The software is provided as is under the [GNU Lesser General Public License v3.0](https://choosealicense.com/licenses/lgpl-3.0/).
91
91
 
92
+ # Attribution request
93
+ 📸 If you publish images created with Shine Stacker, please consider adding a note such as:
94
+
95
+ *Created with Shine Stacker – https://github.com/lucalista/shinestacker*
96
+
97
+ This is not mandatory, but highly appreciated.
@@ -8,6 +8,7 @@ CHANGELOG.md
8
8
  LICENSE
9
9
  MANIFEST.in
10
10
  README.md
11
+ THIRD_PARTY_LICENSES.txt
11
12
  pyproject.toml
12
13
  requirements.txt
13
14
  .github/workflows/ci-multiplatform.yml
Binary file
@@ -1 +0,0 @@
1
- __version__ = '0.3.4'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes