shinestacker 0.2.0.post1.dev1__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.
- shinestacker-0.2.0.post1.dev1/.flake8 +4 -0
- shinestacker-0.2.0.post1.dev1/.github/workflows/ci-multiplatform.yml +39 -0
- shinestacker-0.2.0.post1.dev1/.github/workflows/release.yml +73 -0
- shinestacker-0.2.0.post1.dev1/.gitignore +23 -0
- shinestacker-0.2.0.post1.dev1/CHANGELOG.md +55 -0
- shinestacker-0.2.0.post1.dev1/LICENSE +1 -0
- shinestacker-0.2.0.post1.dev1/PKG-INFO +55 -0
- shinestacker-0.2.0.post1.dev1/README.md +26 -0
- shinestacker-0.2.0.post1.dev1/docs/alignment.md +74 -0
- shinestacker-0.2.0.post1.dev1/docs/balancing.md +25 -0
- shinestacker-0.2.0.post1.dev1/docs/focus_stacking.md +54 -0
- shinestacker-0.2.0.post1.dev1/docs/gui.md +131 -0
- shinestacker-0.2.0.post1.dev1/docs/job.md +33 -0
- shinestacker-0.2.0.post1.dev1/docs/main.md +116 -0
- shinestacker-0.2.0.post1.dev1/docs/multilayer.md +13 -0
- shinestacker-0.2.0.post1.dev1/docs/noise.md +47 -0
- shinestacker-0.2.0.post1.dev1/docs/vignetting.md +20 -0
- shinestacker-0.2.0.post1.dev1/examples/balance-only.fsp +1 -0
- shinestacker-0.2.0.post1.dev1/examples/complete-project.fsp +1 -0
- shinestacker-0.2.0.post1.dev1/examples/focus-stack-1.ipynb +163 -0
- shinestacker-0.2.0.post1.dev1/examples/focus-stack-2.ipynb +174 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-jpg/0000.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-jpg/0001.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-jpg/0002.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-jpg/0003.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-jpg/0004.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-jpg/0005.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-noise/0001.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-noise/0002.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-noise/0003.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-noise/0004.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-noise/0005.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-noise/0006.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-tif/0000.tif +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-tif/0001.tif +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-tif/0002.tif +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-tif/0003.tif +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-tif/0004.tif +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-tif/0005.tif +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-vignetted/vig-0000.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-vignetted/vig-0001.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-vignetted/vig-0002.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/input/img-vignetted/vig-0003.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/examples/stack-comparison.fsp +1 -0
- shinestacker-0.2.0.post1.dev1/examples/stack-from-frames.fsp +1 -0
- shinestacker-0.2.0.post1.dev1/examples/vignetting.fsp +1 -0
- shinestacker-0.2.0.post1.dev1/ico/focus_stack_bkg.png +0 -0
- shinestacker-0.2.0.post1.dev1/ico/shinestacker.icns +0 -0
- shinestacker-0.2.0.post1.dev1/ico/shinestacker.ico +0 -0
- shinestacker-0.2.0.post1.dev1/ico/shinestacker.png +0 -0
- shinestacker-0.2.0.post1.dev1/img/flies.gif +0 -0
- shinestacker-0.2.0.post1.dev1/img/flies_stack.jpg +0 -0
- shinestacker-0.2.0.post1.dev1/img/flow-diagram.png +0 -0
- shinestacker-0.2.0.post1.dev1/img/gui-finder.png +0 -0
- shinestacker-0.2.0.post1.dev1/img/gui-project-new.png +0 -0
- shinestacker-0.2.0.post1.dev1/img/gui-project-run.png +0 -0
- shinestacker-0.2.0.post1.dev1/img/gui-retouch.png +0 -0
- shinestacker-0.2.0.post1.dev1/pyproject.toml +65 -0
- shinestacker-0.2.0.post1.dev1/sandbox/pypi-publish.yml +37 -0
- shinestacker-0.2.0.post1.dev1/sandbox/test_alignment_multiple.py +124 -0
- shinestacker-0.2.0.post1.dev1/scripts/build_release.py +49 -0
- shinestacker-0.2.0.post1.dev1/scripts/validate-tomli.py +20 -0
- shinestacker-0.2.0.post1.dev1/setup.cfg +4 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/__init__.py +3 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/_version.py +1 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/__init__.py +14 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/align.py +307 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/balance.py +367 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/core_utils.py +22 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/depth_map.py +164 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/exif.py +238 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/multilayer.py +187 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/noise_detection.py +182 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/pyramid.py +176 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/stack.py +112 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/stack_framework.py +248 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/utils.py +71 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/algorithms/vignetting.py +137 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/__init__.py +0 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/about_dialog.py +24 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/app_config.py +39 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/gui_utils.py +35 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/help_menu.py +16 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/main.py +176 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/open_frames.py +39 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/project.py +91 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/app/retouch.py +82 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/config/__init__.py +4 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/config/config.py +53 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/config/constants.py +174 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/config/gui_constants.py +85 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/core/__init__.py +5 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/core/colors.py +60 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/core/core_utils.py +52 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/core/exceptions.py +50 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/core/framework.py +210 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/core/logging.py +89 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/__init__.py +0 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/action_config.py +879 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/actions_window.py +283 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/colors.py +57 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/gui_images.py +152 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/gui_logging.py +213 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/gui_run.py +393 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/img/close-round-line-icon.png +0 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/img/forward-button-icon.png +0 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/img/play-button-round-icon.png +0 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/img/plus-round-line-icon.png +0 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/main_window.py +599 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/new_project.py +170 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/project_converter.py +148 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/project_editor.py +539 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/gui/project_model.py +138 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/__init__.py +0 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/brush.py +9 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/brush_controller.py +57 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/brush_preview.py +126 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/exif_data.py +65 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/file_loader.py +104 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/image_editor.py +651 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/image_editor_ui.py +380 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/image_viewer.py +356 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/shortcuts_help.py +98 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker/retouch/undo_manager.py +38 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker.egg-info/PKG-INFO +55 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker.egg-info/SOURCES.txt +161 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker.egg-info/dependency_links.txt +1 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker.egg-info/entry_points.txt +4 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker.egg-info/requires.txt +17 -0
- shinestacker-0.2.0.post1.dev1/src/shinestacker.egg-info/top_level.txt +1 -0
- shinestacker-0.2.0.post1.dev1/tests/test-align-balance.ipynb +282 -0
- shinestacker-0.2.0.post1.dev1/tests/test-align.ipynb +242 -0
- shinestacker-0.2.0.post1.dev1/tests/test-balance.ipynb +918 -0
- shinestacker-0.2.0.post1.dev1/tests/test-exif.ipynb +121 -0
- shinestacker-0.2.0.post1.dev1/tests/test-job.ipynb +79 -0
- shinestacker-0.2.0.post1.dev1/tests/test-logging.ipynb +93 -0
- shinestacker-0.2.0.post1.dev1/tests/test-multilayer.ipynb +72 -0
- shinestacker-0.2.0.post1.dev1/tests/test-noise-detection.ipynb +110 -0
- shinestacker-0.2.0.post1.dev1/tests/test-stack.ipynb +97 -0
- shinestacker-0.2.0.post1.dev1/tests/test-vignetting.ipynb +154 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0000_logging.py +66 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0001_colors.py +32 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0005_make_test_img.py +18 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0010_job.py +49 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0020_noise_detection.py +61 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0030_align.py +62 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0031_align_precision.py +111 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0032_align_methods.py +60 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0040_balance.py +90 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0050_align_balance.py +59 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0060_stack.py +51 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0070_multilayer.py +60 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0080_exif.py +90 -0
- shinestacker-0.2.0.post1.dev1/tests/test_0090_vignetting.py +17 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1000_brush_mask.py +13 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1010_gui.py +42 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1020_gui_images.py +128 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1030_gui_logging.py +118 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1040_action_config.py +120 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1050_project_converter.py +157 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1060_gui_run.py +136 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1070_project_editor.py +180 -0
- shinestacker-0.2.0.post1.dev1/tests/test_1080_actions_window.py +138 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
name: CI multiplatform
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: [main]
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-and-test:
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
pull-requests: write
|
|
16
|
+
runs-on: ${{ matrix.os }}
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
20
|
+
python-version: ["3.12"]
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout repo
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Set up Python
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.12"
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: |
|
|
33
|
+
python -m pip install --upgrade pip setuptools
|
|
34
|
+
pip install -e .[dev]
|
|
35
|
+
|
|
36
|
+
- name: Run non-GUI tests (test_00*.py)
|
|
37
|
+
working-directory: tests
|
|
38
|
+
run: >
|
|
39
|
+
python3 -c "import glob, pytest, sys; sys.exit(pytest.main(glob.glob('test_00*.py') + ['-v', '--disable-warnings']))"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
name: Create new release
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
contents: write
|
|
7
|
+
packages: write
|
|
8
|
+
pull-requests: write
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
tags:
|
|
13
|
+
- v**
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
publish-release:
|
|
17
|
+
runs-on: ${{ matrix.os }}
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
21
|
+
python-version: ["3.12"]
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- name: Checkout repo
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: |
|
|
34
|
+
python -m pip install --upgrade pip
|
|
35
|
+
pip install pyinstaller
|
|
36
|
+
pip install -e .[dev]
|
|
37
|
+
|
|
38
|
+
- name: Build and package release
|
|
39
|
+
working-directory: scripts
|
|
40
|
+
run: |
|
|
41
|
+
python build_release.py
|
|
42
|
+
|
|
43
|
+
- name: Upload artifact
|
|
44
|
+
uses: actions/upload-artifact@v4
|
|
45
|
+
with:
|
|
46
|
+
name: shinestacker-${{ matrix.os }}
|
|
47
|
+
path: dist/shinestacker-release.zip
|
|
48
|
+
|
|
49
|
+
create-release:
|
|
50
|
+
needs: publish-release
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
steps:
|
|
53
|
+
- name: Download all artifacts
|
|
54
|
+
uses: actions/download-artifact@v4
|
|
55
|
+
with:
|
|
56
|
+
path: artifacts
|
|
57
|
+
|
|
58
|
+
- name: Prepare release assets
|
|
59
|
+
run: |
|
|
60
|
+
mkdir -p release_assets
|
|
61
|
+
cp artifacts/shinestacker-ubuntu-latest/shinestacker-release.zip release_assets/shinestacker-ubuntu.zip
|
|
62
|
+
cp artifacts/shinestacker-windows-latest/shinestacker-release.zip release_assets/shinestacker-windows.zip
|
|
63
|
+
cp artifacts/shinestacker-macos-latest/shinestacker-release.zip release_assets/shinestacker-macos.zip
|
|
64
|
+
ls -la release_assets/
|
|
65
|
+
|
|
66
|
+
- name: Create release
|
|
67
|
+
uses: softprops/action-gh-release@v1
|
|
68
|
+
with:
|
|
69
|
+
draft: true
|
|
70
|
+
files: |
|
|
71
|
+
release_assets/shinestacker-ubuntu.zip
|
|
72
|
+
release_assets/shinestacker-windows.zip
|
|
73
|
+
release_assets/shinestacker-macos.zip
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
__pycache__/*
|
|
2
|
+
*/__pycache__/*
|
|
3
|
+
*.pyc
|
|
4
|
+
.ipynb_checkpoints/*
|
|
5
|
+
*/.ipynb_checkpoints/*
|
|
6
|
+
*/*/.ipynb_checkpoints/*
|
|
7
|
+
*/*/*/.ipynb_checkpoints/*
|
|
8
|
+
anaconda_projects
|
|
9
|
+
tests/output/*
|
|
10
|
+
tests/plots/*
|
|
11
|
+
tests/noise-map/*
|
|
12
|
+
sandbox/img-test/*
|
|
13
|
+
*/logs/*
|
|
14
|
+
.DS_Store
|
|
15
|
+
.virtual_documents
|
|
16
|
+
*.egg-info/
|
|
17
|
+
build/
|
|
18
|
+
dist/
|
|
19
|
+
.eggs/
|
|
20
|
+
src/focusstack/_version.py
|
|
21
|
+
*~
|
|
22
|
+
*.spec
|
|
23
|
+
logs
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
This page reports the main releases only and the main changes therein.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## [v0.2.0] - 2025-07-27
|
|
8
|
+
**Stability improvements and new package name**
|
|
9
|
+
|
|
10
|
+
### Changes
|
|
11
|
+
|
|
12
|
+
* first release with new name ShineStacker
|
|
13
|
+
* added BRISK detector/descriptor alignment method
|
|
14
|
+
* improved stability by adding more validation controls to alignment configuration
|
|
15
|
+
* some bug fixes
|
|
16
|
+
* minor restyling
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## [v0.1.4] - 2025-07-23
|
|
21
|
+
**Bug fixes and alignment improvements**
|
|
22
|
+
|
|
23
|
+
### Changes
|
|
24
|
+
|
|
25
|
+
* fixed recently introduced bugs in the alignment module
|
|
26
|
+
* disabled ECC refinement, too unstable
|
|
27
|
+
* improvement rigid alignment with more precise matrix
|
|
28
|
+
* some minor bug fixes
|
|
29
|
+
* removed dependence on termcolor external module
|
|
30
|
+
* some internal code cleanup
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## [v0.1.1] - 2025-07-20
|
|
35
|
+
**Optimized image alignment**
|
|
36
|
+
|
|
37
|
+
### Changes
|
|
38
|
+
|
|
39
|
+
* Faster alignment with image subsample enables
|
|
40
|
+
* Alignment refinement via ECC transform enabled
|
|
41
|
+
* GUI opens new project dialog at startup
|
|
42
|
+
* fixed color logging for windowed app
|
|
43
|
+
* bug fixes
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## [v0.1.0] - 2025-07-19
|
|
48
|
+
**First relatively stable and usable GUI release**
|
|
49
|
+
|
|
50
|
+
### Changes
|
|
51
|
+
- several stability improvements
|
|
52
|
+
- several bug fixes
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
---
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
The software is provided as is under the GNU Lesser General Public License v3.0.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shinestacker
|
|
3
|
+
Version: 0.2.0.post1.dev1
|
|
4
|
+
Summary: ShineStacker
|
|
5
|
+
Author-email: Luca Lista <luka.lista@gmail.com>
|
|
6
|
+
License-Expression: LGPL-3.0
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: argparse
|
|
13
|
+
Requires-Dist: imagecodecs
|
|
14
|
+
Requires-Dist: ipywidgets
|
|
15
|
+
Requires-Dist: jsonpickle
|
|
16
|
+
Requires-Dist: matplotlib
|
|
17
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: opencv_python
|
|
19
|
+
Requires-Dist: pillow
|
|
20
|
+
Requires-Dist: psdtags
|
|
21
|
+
Requires-Dist: PySide6
|
|
22
|
+
Requires-Dist: scipy
|
|
23
|
+
Requires-Dist: tifffile
|
|
24
|
+
Requires-Dist: tqdm
|
|
25
|
+
Requires-Dist: setuptools-scm
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# Shine Stacker Processing Framework
|
|
31
|
+
|
|
32
|
+
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
33
|
+
|
|
34
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400">
|
|
35
|
+
|
|
36
|
+
## Documentation
|
|
37
|
+
|
|
38
|
+
📖 [Main documentation](https://github.com/lucalista/shinestacker/blob/main/docs/main.md) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Credits:
|
|
42
|
+
|
|
43
|
+
The main pyramid stack algorithm was inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar. The latest implementation was rewritten from the original code that was used under permission of the author for initial versions of this package.
|
|
44
|
+
|
|
45
|
+
# Resources
|
|
46
|
+
|
|
47
|
+
* [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
|
|
48
|
+
Pyramid methods in image processing
|
|
49
|
+
* [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
|
|
50
|
+
* Another [original implementation on GitHub](https://github.com/bznick98/Focus_Stacking) by Zongnan Bao
|
|
51
|
+
|
|
52
|
+
# License
|
|
53
|
+
|
|
54
|
+
The software is provided as is under the [GNU Lesser General Public License v3.0](https://choosealicense.com/licenses/lgpl-3.0/).
|
|
55
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Shine Stacker Processing Framework
|
|
2
|
+
|
|
3
|
+
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
4
|
+
|
|
5
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400">
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
📖 [Main documentation](https://github.com/lucalista/shinestacker/blob/main/docs/main.md) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Credits:
|
|
13
|
+
|
|
14
|
+
The main pyramid stack algorithm was inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar. The latest implementation was rewritten from the original code that was used under permission of the author for initial versions of this package.
|
|
15
|
+
|
|
16
|
+
# Resources
|
|
17
|
+
|
|
18
|
+
* [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
|
|
19
|
+
Pyramid methods in image processing
|
|
20
|
+
* [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
|
|
21
|
+
* Another [original implementation on GitHub](https://github.com/bznick98/Focus_Stacking) by Zongnan Bao
|
|
22
|
+
|
|
23
|
+
# License
|
|
24
|
+
|
|
25
|
+
The software is provided as is under the [GNU Lesser General Public License v3.0](https://choosealicense.com/licenses/lgpl-3.0/).
|
|
26
|
+
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Alignment and registration: scale, tanslation and rotation correction, or full perspective correction
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
job.add_action(Actions("align", [AlignFrames(*options)])
|
|
5
|
+
```
|
|
6
|
+
Arguments for the constructor ```AlignFrames``` of are:
|
|
7
|
+
* ```feature_config``` (optional, default: ```None```): a dictionary specifying the following parameters, with the corresponding default values:
|
|
8
|
+
```python
|
|
9
|
+
{
|
|
10
|
+
'detector': DETECTOR_SIFT,
|
|
11
|
+
'descriptor': DESCRIPTOR_SIFT
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
* ```detector``` (optional): the feature detector is used to find matches. See [Feature Detection and Description](https://docs.opencv.org/4.x/db/d27/tutorial_py_table_of_contents_feature2d.html) for more details. Possible values are:
|
|
15
|
+
* ```DETECTOR_SIFT``` (default): [Scale-Invariant Feature Transform](https://docs.opencv.org/4.x/da/df5/tutorial_py_sift_intro.html)]
|
|
16
|
+
* ```DETECTOR_ORB```: [Oriented FAST and Rotated BRIEF](https://docs.opencv.org/4.x/d1/d89/tutorial_py_orb.html)
|
|
17
|
+
* ```DETECTOR_SURF```: [Speeded-Up Robust Features](https://docs.opencv.org/3.4/df/dd2/tutorial_py_surf_intro.html)
|
|
18
|
+
* ```DETECTOR_AKAZE```: [AKAZE local features matching](https://docs.opencv.org/3.4/db/d70/tutorial_akaze_matching.html)
|
|
19
|
+
* ```DETECTOR_BRISK```: [Binary Robust Invariant Scalable Keypoints](https://medium.com/analytics-vidhya/feature-matching-using-brisk-277c47539e8)
|
|
20
|
+
* ```descriptor``` (optional): the feature descriptor is used to find matches. Possible values are:
|
|
21
|
+
* ```DESCRIPTOR_SIFT``` (default)
|
|
22
|
+
* ```DESCRIPTOR_ORB```
|
|
23
|
+
* ```DESCRIPTOR_AKAZE```
|
|
24
|
+
* ```DESCRIPTPR_BRISK```
|
|
25
|
+
|
|
26
|
+
For a more quantitative comparison of performances of the different methods, consult the publication: [S. A. K. Tareen and Z. Saleem, "A comparative analysis of SIFT, SURF, KAZE, AKAZE, ORB, and BRISK", doi:10.1109/ICOMET.2018.8346440](https://ieeexplore.ieee.org/document/8346440)
|
|
27
|
+
|
|
28
|
+
```matching_config``` (optional, default; ```None```): a dictionary specifying the following parameters, with the corresponding default values:
|
|
29
|
+
```python
|
|
30
|
+
{
|
|
31
|
+
'match_method': MATCHING_KNN,
|
|
32
|
+
'flann_idx_kdtree': 2,
|
|
33
|
+
'flann_trees': 5,
|
|
34
|
+
'flann_checks': 50,
|
|
35
|
+
'threshold': 0.75
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
* ```match_method``` (optional): the method used to find matches. See [Feature Matching](https://docs.opencv.org/4.x/dc/dc3/tutorial_py_matcher.html) for more details. Possible values are:
|
|
39
|
+
* ```MATCHING_KNN``` (default): [Feature Matching with FLANN](https://docs.opencv.org/3.4/d5/d6f/tutorial_feature_flann_matcher.html)
|
|
40
|
+
* ```MATCHING_NORM_HAMMING```: [Use Hamming distance](https://docs.opencv.org/4.x/d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa4b063afd04aebb8dd07085a1207da727)
|
|
41
|
+
* ```flann_idx_kdtree``` (optional, default: 2): parameter used by the FLANN matching algorithm.
|
|
42
|
+
* ```flann_tree``` (optional, default: 5): parameter used by the FLANN matching algorithm.
|
|
43
|
+
* ```flann_checks``` (optional, default: 50): parameter used by the FLANN matching algorithm.
|
|
44
|
+
* ```threshold``` (optional, default: 0.75): parameter used to select good matches. See [Feature Matching](https://docs.opencv.org/4.x/dc/dc3/tutorial_py_matcher.html) for more details.
|
|
45
|
+
|
|
46
|
+
* ```alignment_config``` (optional, default; ```None```): a dictionary specifying the following parameters, with the corresponding default values:
|
|
47
|
+
```python
|
|
48
|
+
{
|
|
49
|
+
'transform': ALIGN_RIGID,
|
|
50
|
+
'align_methid': RANSAC,
|
|
51
|
+
'rans_threshold': 5.0,
|
|
52
|
+
'border_mode': BORDER_REPLICATE_BLUR,
|
|
53
|
+
'border_value': (0, 0, 0, 0),
|
|
54
|
+
'border_blur': 50
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
* ```transform``` (optional): the transformation applied to register images. Possible values are:
|
|
58
|
+
* ```ALIGN_RIGID``` (default): allow scale, tanslation and rotation correction. This should be used for image acquired with tripode or microscope.
|
|
59
|
+
* ```ALIGN_HOMOGRAPHY```: allow full perspective correction. This should be used for images taken with hand camera.
|
|
60
|
+
* ```align_method``` (optional): the method used to find matches. Valid options are:
|
|
61
|
+
* ```RANSAC``` (*Random Sample Consensus*)
|
|
62
|
+
* ```LMEDS``` (*Least Medians of Squares*)
|
|
63
|
+
* ```rans_threshold``` (optional, default: 5.0): parameter used if ```ALIGN_HOMOGRAPHY``` is choosen as tansformation, see [Feature Matching + Homography to find Objects](https://docs.opencv.org/3.4/d1/de0/tutorial_py_feature_homography.html) for more details.
|
|
64
|
+
* ```subsample``` (optional, default: 4): subsample image for faster alignment. Faster, but alignment could be less accurate.
|
|
65
|
+
* ```fast_subsampling``` (optiona, default: ```False```): perform fast image subsampling without interpolation. Used if ```subsample``` is set to ```True```.
|
|
66
|
+
* ```border_mode``` (optional, default: ```BORDER_REPLICATE_BLUR```): border mode. See [Adding borders to your images](https://docs.opencv.org/3.4/dc/da3/tutorial_copyMakeBorder.html) for more details. Possible values are:
|
|
67
|
+
* ```BORDER_CONSTANT```: pad the image with a constant value. The border value is specified with the parameter ```border_value```.
|
|
68
|
+
* ```BORDER_REPLICATE```: the rows and columns at the very edge of the original are replicated to the extra border.
|
|
69
|
+
* ```BORDER_REPLICATE_BLUR``` (default): same as above, but the border is blurred. The amount of blurring is specified by the parameter ```border_blur```.
|
|
70
|
+
* ```border_value``` (optional, default: ```(0, 0, 0, 0)```): border value. See [Adding borders to your images](https://docs.opencv.org/3.4/dc/da3/tutorial_copyMakeBorder.html) for more details.
|
|
71
|
+
* ```border_blur``` (optional, default: ```50```): amount of border blurring, in pixels. Only applied if ```border_mode``` is set to ```BORDER_REPLICATE_BLUR```, which is the default option.
|
|
72
|
+
* ```plot_summary``` (optional, default: ```False```): if ```True```, plot a summary histogram with number of matches in each frame. May be useful for inspection and debugging.
|
|
73
|
+
* ```plot_matches``` (optional, default: ```False```): if ```True```, for each image matches with reference frame are drawn. May be useful for inspection and debugging.
|
|
74
|
+
* ```enabled``` (optional, default: ```True```): allows to switch on and off this module.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Luminosity and color balance
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
job.add_action(Actions("balance", [BalanceFrames(*options)])
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Arguments for the constructor of ```BalanceFrames``` are:
|
|
8
|
+
*```channel``` (optional, default: BALANCE_LUMI): channels to be balanced. Possible values are: ```BALANCE_LUMI``` (default): balance equally for R, G and B channels, should be reasonably fine for most of the cases; ```BALANCE_RGB```: balance luminosity separately for R, G and B channels, it may be needed if some but not all of the images have a undesired color dominance; ```BALANCE_HSV```: balance saturation a luminosity value in the HSV (Hue, Saturation, brightness Value) representation, it may be needed in cases of extreme luminosity variation that affects saturation; ```BALANCE_HLS```: balance saturation a luminosity value in the HLS (Hue, Lightness, Saturation) representation, it may be needed in cases of extreme luminosity variation that affects saturation. Note that ```BALANCE_HSV``` and ```BALANCE_HLS``` are only supported for 8-bit images.
|
|
9
|
+
* ```mask_size``` (optional): if specified, luminosity and color balance is only applied to pixels within a circle of radius equal to the minimum between the image width and height times ```mask_size```, i.e: 0.8 means 80% of a portrait image width or landscape image height. It may beuseful for images with vignetting, in order to avoid including in the balance processing the outer darker pixels.
|
|
10
|
+
* ```intensity_interval``` (optional): if specifies, only pixels with intensity within the specified range are used. It may be useful to remove very dark areas or very light areas. Not used if ```MATCH_HIST``` is specified as value for ```corr_map```. The argument has to be a dictionary where one or both values corresponding to the keys ```min``` and ```max``` can be specified. The default values are:
|
|
11
|
+
```python
|
|
12
|
+
{
|
|
13
|
+
'min': 0,
|
|
14
|
+
'max': -1
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
Note that for 8-bit images the maximum intensity is 255, while for 16-bit images the maximum intensity is 65536.
|
|
18
|
+
* ```subsample``` (optional, default: 8): extracts intensity histogram using every n-th pixel in each dimension in order to reduce processing time. By default, it takes one every 8 pixels in horizontal and vertical directions, i.e.: one every 100 pixels in total. This option is not ised if ```corr_map``` is equal to ```BALANCE_MATCH_HIST```.
|
|
19
|
+
* ```corr_map``` (optional, default: ```BALANCE_LINEAR```, possible values: ```BALANCE_LINEAR```, ```BALANCE_GAMMA``` and ```MATCH_HIST```): specifies the type of intensity correction.
|
|
20
|
+
* ```BALANCE_LINEAR```: a linear correction is applied in order to balance the average intensity of the corrected images to the reference image in the specified channels.
|
|
21
|
+
* ```BALANCE_GAMMA```: a gamma correction, i.e.: a power law, is applied in order to balance the average intensity of the corrected images to reference image in the specified channels. The gamma correction avoids saturation of low or high intensity pixels which may occur for a linear coorection, but may introduce more distortion than a linear mapping.
|
|
22
|
+
* ```BALANCE_MATCH_HIST```: the intensity histogram of the corrected image matches the histogram of the reference image in the specified channels. This options shoudl better be used with the value ```BALANCE_RGB``` for the ```channel``` option. If this option is specified, the options ```intensity_interval``` and ```subsample```are not used. This option may be somewhat slow for 16-bit images.
|
|
23
|
+
* ```plot_histograms``` (optional, default: ```False```): if ```True```, plot hisograms for each image and for the reference frame.
|
|
24
|
+
* ```plot_summary``` (optional, default: ```False```): if ```True```, plot a summary of the corrections.
|
|
25
|
+
* ```enabled``` (optional, default: ```True```): allows to switch on and off this module.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Focus Stacking
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
job.add_action(FocusStack(name, stacker, *options))
|
|
5
|
+
```
|
|
6
|
+
Arguments for the constructor of ```FocusStack``` are:
|
|
7
|
+
* ```name```: the name of the action, used for printout, and possibly for output path
|
|
8
|
+
* ```stacker```: an object defining the focus stacking algorithm. Can be ```PyramidStack```, ```PyramidBlock``` or ```DepthMapStack```, see below for possible algorithms.
|
|
9
|
+
* ```input_path``` (optional): the subdirectory within ```working_path``` that contains input images to be processed. If not specified, the last output path is used, or, if this is the first action, the ```input_path``` specified with the ```StackJob``` construction is used. If the ```StackJob``` specifies no ```input_path```, at least the first action must specify an ```input_path```.
|
|
10
|
+
* ```output_path``` (optional): the subdirectory within ```working_path``` where aligned images are written. If not specified, it is equal to ```name```.
|
|
11
|
+
* ```working_path```: the directory that contains input and output image subdirectories. If not specified, it is the same as ```job.working_path```.
|
|
12
|
+
* ```exif_path``` (optional): if specified, EXIF data are copied to the output file from file in the specified directory. If not specified, it is the source directory used as input for the first action. If set equal to ```''``` no EXIF data is saved.
|
|
13
|
+
* ```denoise``` (optoinal): if specified, a denois algorithm is applied. A value of 0.75 to 1.00 does not reduce details in an appreciable way, and is suitable for modest noise reduction. denoise may be useful for 8-bit images, or for images taken at large ISO. 16-bits images at low ISO usually don't require denoise. See [Image Denoising](https://docs.opencv.org/3.4/d5/d69/tutorial_py_non_local_means.html) for more details.
|
|
14
|
+
* ```prefix``` (optional): if specified, the specified string is pre-pended to the file name. May be useful if more algorithms are ran, and different file names are used for the output of different algorithms.
|
|
15
|
+
* ```enabled``` (optional, default: ``True```): allows to switch on and off this module.
|
|
16
|
+
|
|
17
|
+
## Focus Stacking in bunches of frames
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
job.add_action(FocusStackBunch(name, stacker, *options))
|
|
21
|
+
```
|
|
22
|
+
Arguments for the constructor of ```FocusStackBunch``` are:
|
|
23
|
+
* ```name```: the name of the action, used for printout, and possibly for output path
|
|
24
|
+
* ```stacker```: an object defining the focus stacking algorithm. Can be ```PyramidStack```, ```PyramidStack``` or ```DepthMapStack```, see below for possible algorithms.
|
|
25
|
+
* ```input_path``` (optional): the subdirectory within ```working_path``` that contains input images to be processed. If not specified, the last output path is used, or, if this is the first action, the ```input_path``` specified with the ```StackJob``` construction is used. If the ```StackJob``` specifies no ```input_path```, at least the first action must specify an ```input_path```.
|
|
26
|
+
* * ```output_path``` (optional): the subdirectory within ```working_path``` where aligned images are written. If not specified, it is equal to ```name```.
|
|
27
|
+
* ```working_path```: the directory that contains input and output image subdirectories. If not specified, it is the same as ```job.working_path```.
|
|
28
|
+
* ```exif_path``` (optional): if specified, EXIF data are copied to the output file from file in the specified directory. If not specified, it is the source directory used as * ```frames``` (optional, default: 10): the number of frames in each bunch that are stacked together.
|
|
29
|
+
* ```frames``` (optional, default: 10): the number of frames that are fused together.
|
|
30
|
+
* ```overlap``` (optional, default: 0): the number of overlapping frames between a bunch and the following one.
|
|
31
|
+
* ```denoise``` (optoinal): if specified, a denois algorithm is applied. A value of 0.75 to 1.00 does not reduce details in an appreciable way, and is suitable for modest noise reduction. See [Image Denoising](https://docs.opencv.org/3.4/d5/d69/tutorial_py_non_local_means.html) for more details
|
|
32
|
+
* ```prefix``` (optional): if specified, the specified string is pre-pended to the file name. May be useful if more algorithms are ran, and different file names are used for the output of different algorithms.
|
|
33
|
+
* ```enabled``` (optional, default: ```True```): allows to switch on and off this module.
|
|
34
|
+
|
|
35
|
+
## Stack algorithms
|
|
36
|
+
|
|
37
|
+
```PyramidStack```, Laplacian pyramid focus stacking algorithm, optimized implementation
|
|
38
|
+
|
|
39
|
+
Arguments for the constructor are:
|
|
40
|
+
* ```pyramid_min_size``` (optional, default: 32)
|
|
41
|
+
* ```kernel_size``` (optional, default: 5)
|
|
42
|
+
* ```gen_kernel``` (optional, default: 0.4)
|
|
43
|
+
* ```float_type``` (optional, default: ```FLOAT_32```, possible values: ```FLOAT_32```, ```FLOAT_64```): precision for internal image representation
|
|
44
|
+
|
|
45
|
+
```DepthMapStack```, Depth map focus stacking algorithm
|
|
46
|
+
|
|
47
|
+
Arguments for the constructor are:
|
|
48
|
+
* ```map_type``` (optional), possible values are ```MAP_MAX``` (default) and ```MAP_AVERAGE```. ```MAP_MAX``` select for wach pixel the layer which has the best focus. ```MAP_AVERAGE``` performs for each pixel an average of all layers weighted by the quality of focus.
|
|
49
|
+
* ```energy``` (optional), possible values are ```ENERGY_LAPLACIAN``` (default) and ```ENERGY_SOBEL```.
|
|
50
|
+
* ```kernel_size``` (optional, default: 5) size in pixels of Laplacian kernel.
|
|
51
|
+
* ```blur_size``` (optional, default: 5) size in pixels of the pre-Laplacian Gaussian blur.
|
|
52
|
+
* ```smooth_size``` (optional, default: 15) size of energy smoothing.
|
|
53
|
+
* ```temperature``` (optional, default: 0.1) controls fision transition: lower value means sharper transitions.
|
|
54
|
+
* ```levels``` (optional, defauls: 3) number of levels for the Laplacian pyramid.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Graphical User Interface
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
FocusStack processes focus-bracketed images in two phases:
|
|
5
|
+
* **Project**: Batch processing (alignment/balancing/stacking)
|
|
6
|
+
* **Retouch**: Layer-based refinement
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
> Advanced processing details in [main documentation](main.md).
|
|
9
|
+
|
|
10
|
+
The batch processing supports image alignment, color and luminosity balance, vignetting removal,
|
|
11
|
+
noisy pixel masking.
|
|
12
|
+
|
|
13
|
+
## Starting
|
|
14
|
+
|
|
15
|
+
* If the python package is donwloaded and installed, the GUI can start either from a console command line :
|
|
16
|
+
|
|
17
|
+
```console
|
|
18
|
+
> focusstack
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
* If the app is dowloaded from the [releases page](https://github.com/lucalista/focusstack/releases), after the ```zip``` archive is uncompressed, just double-click the app icon.
|
|
22
|
+
|
|
23
|
+
<img src='../img/gui-finder.png' width="300">
|
|
24
|
+
|
|
25
|
+
**Platform Tip**: Windows apps are inside `/focusstack/`, macOS/Linux apps are directly in the uncompressed folder.
|
|
26
|
+
|
|
27
|
+
The GUI has two main working areas:
|
|
28
|
+
|
|
29
|
+
* *Project*
|
|
30
|
+
* *Retouch*
|
|
31
|
+
|
|
32
|
+
Switching from *Project* to *Retouch* can be done from the *FocusStack* main menu.
|
|
33
|
+
|
|
34
|
+
## Project area
|
|
35
|
+
|
|
36
|
+
When the app starts, it proposes to create a new project.
|
|
37
|
+
|
|
38
|
+
<img src='../img/gui-project-new.png' width="600">
|
|
39
|
+
|
|
40
|
+
### Creating Projects
|
|
41
|
+
1. Select source folder (JPEG/TIFF 8/16-bit)
|
|
42
|
+
2. Configure job actions (auto-saved in project file)
|
|
43
|
+
3. Run processing:
|
|
44
|
+
- Real-time logs & progress bar
|
|
45
|
+
- Thumbnail previews for each stage
|
|
46
|
+
|
|
47
|
+
<img src='../img/flow-diagram.png' width="900" alt="FocusStack workflow: Source images → Alignment → Balancing → Stacking">
|
|
48
|
+
|
|
49
|
+
> **Large Set Tip**: For 100+ images:
|
|
50
|
+
> - Split into 10-15 image "bunches"
|
|
51
|
+
> - Set frame overlap (default: 2 frames)
|
|
52
|
+
> - Combine intermediate results later
|
|
53
|
+
|
|
54
|
+
> 💡 **RAM Warning**: >15 images may need 16GB+ RAM. Use smaller batches if needed.
|
|
55
|
+
|
|
56
|
+
The newly created project consists of a single job that contains more actions.
|
|
57
|
+
Each action produces a folder as output that has, by default, the action's name.
|
|
58
|
+
Some actions can be combined in order to produce a single intermediate output (alignment, balancing, etc.).
|
|
59
|
+
|
|
60
|
+
**Action Outputs**: 📁 `aligned-balanced/` | 📁 `bunches/` | 📁 `stacked/`
|
|
61
|
+
|
|
62
|
+
> **Pro Tip**: Duplicate jobs when processing similar image sets to save configuration time. You can run multiple jobs in sequence.
|
|
63
|
+
|
|
64
|
+
It is possible to run a single job, or all jobs within a project.
|
|
65
|
+
|
|
66
|
+
<img src='../img/gui-project-run.png' width="600">
|
|
67
|
+
|
|
68
|
+
### Project Run Tabs
|
|
69
|
+
|
|
70
|
+
1. Job progress bar
|
|
71
|
+
2. Real-time log viewer
|
|
72
|
+
3. Retouch button (enabled after processing)
|
|
73
|
+
|
|
74
|
+
When the job finishes, a *Retouch* button is enabled, which opens the output image into the retouch area.
|
|
75
|
+
|
|
76
|
+
## Retouch area
|
|
77
|
+
|
|
78
|
+
<img src='../img/gui-retouch.png' width="600">
|
|
79
|
+
|
|
80
|
+
### Brush Properties
|
|
81
|
+
Adjust in the top toolbar:
|
|
82
|
+
- **Size**: Brush diameter (px)
|
|
83
|
+
- **Hardness**: Edge softness (0-100%)
|
|
84
|
+
- **Opacity**: Paint transparency
|
|
85
|
+
- **Flow**: Paint accumulation rate
|
|
86
|
+
|
|
87
|
+
> 💡 Pro Tip: Use low opacity/flow (20-40%) for subtle corrections
|
|
88
|
+
|
|
89
|
+
### Retouch Workflow
|
|
90
|
+
|
|
91
|
+
1. **Navigate**:
|
|
92
|
+
- Zoom/pan to defect area
|
|
93
|
+
- Toggle between master/source (`X`)
|
|
94
|
+
2. **Correct defects/artifacts**:**:
|
|
95
|
+
- Select source layer with clean area
|
|
96
|
+
- Adjust brush properties (size/hardness/opacity)
|
|
97
|
+
- Paint over defects
|
|
98
|
+
- Use `Ctrl+Z` to undo strokes
|
|
99
|
+
3. **Verify**:
|
|
100
|
+
- Toggle master view (`M`) to check results
|
|
101
|
+
- Compare before/after with `L`/`M` toggle
|
|
102
|
+
3. **Export**:
|
|
103
|
+
- ✅ Final image: Single TIFF/JPEG
|
|
104
|
+
- 🗂️ Editable: Multilayer TIFF (large)
|
|
105
|
+
|
|
106
|
+
| Action | Shortcut |
|
|
107
|
+
|---------------------|---------------------------|
|
|
108
|
+
| Zoom in/out | `Ctrl` + `+`/`- or mouse wheel |
|
|
109
|
+
| Reset view | `Ctrl` + `0` |
|
|
110
|
+
| Pan | `Space` + mouse drag |
|
|
111
|
+
| Prev./next layer | `Up`/`Down` arrows |
|
|
112
|
+
| View master layer | `M` |
|
|
113
|
+
| View source layer | `L` |
|
|
114
|
+
| Toggle master ↔ source | `X` |
|
|
115
|
+
|
|
116
|
+
See help menu for complete list of shortcuts.
|
|
117
|
+
|
|
118
|
+
**Export Formats**:
|
|
119
|
+
- Single TIFF: Final image (highest quality)
|
|
120
|
+
- Single JPEG: For web and quick preview (lower quality)
|
|
121
|
+
- Multilayer TIFF: Preserves all layers (large file)
|
|
122
|
+
|
|
123
|
+
**EXIF metadata**:
|
|
124
|
+
* EXIF data can be imported from source images and saved with final file.
|
|
125
|
+
|
|
126
|
+
## Final retouch
|
|
127
|
+
|
|
128
|
+
The final retouch, including color and luminosity balance, sharpness enhancement and
|
|
129
|
+
so on can be applied with your favorite image processing application, like [GIMP](https://www.gimp.org/)
|
|
130
|
+
or other.
|
|
131
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Job creation
|
|
2
|
+
|
|
3
|
+
Create a job, then schedule the desired actions in a job, then run the job.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
job = StackJob(name, working_path [, input_path])
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Arguments are:
|
|
10
|
+
* ```working_path```: the directory that contains input and output images, organized in subdirectories as specified by each action
|
|
11
|
+
* ```name```: the name of the job, used for printout
|
|
12
|
+
* ```input_path``` (optional): the subdirectory within ```working_path``` that contains input images for subsequent action. If not specified, at least the first action must specify an ```input_path```.
|
|
13
|
+
* ```callbacks``` (optional, default: ```None```): dictionary of callback functions for internal use. If equal to ```'tqdm'```, a progress bar is shown in either text mode or jupyter notebook.
|
|
14
|
+
* ```enabled``` (optional, default: ```True```): allows to switch on and off all actions within a job.
|
|
15
|
+
|
|
16
|
+
# Schedule multiple actions based on a reference image: align and/or balance images
|
|
17
|
+
|
|
18
|
+
The class ```CombinedActions``` runs multiple actions on each of the frames appearing in a path.
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
job.add_action(CombinedActions(name, [...], *options))
|
|
22
|
+
```
|
|
23
|
+
Arguments for the constructor of ```CombinedActions``` are for the :
|
|
24
|
+
* ```name```: the name of the action, used for printout, and possibly for output path.
|
|
25
|
+
* ```actions```: array of action object to be applied in cascade.
|
|
26
|
+
* ```input_path``` (optional): the subdirectory within ```working_path``` that contains input images to be processed. If not specified, the last output path is used, or, if this is the first action, the ```input_path``` specified with the ```StackJob``` construction is used. If the ```StackJob``` specifies no ```input_path```, at least the first action must specify an ```input_path```.
|
|
27
|
+
* ```output_path``` (optional): the subdirectory within ```working_path``` where aligned images are written. If not specified, it is equal to ```name```.
|
|
28
|
+
* ```working_path``` (optional): the directory that contains input and output image subdirectories. If not specified, it is the same as ```job.working_path```.
|
|
29
|
+
* ```plot_path``` (optional, default: ```plots```): the directory within ```working_path``` that contains plots produced by the different actions.
|
|
30
|
+
* ```resample``` (optional, default: 1): take every *n*<sup>th</sup> frame in the selected directory. Default: take all frames.
|
|
31
|
+
* ```ref_idx``` (optional): the index of the image used as reference. Images are numbered starting from zero. If not specified, it is the index of the middle image.
|
|
32
|
+
* ```step_process``` (optional): if equal to ```True``` (default), each image is processed with respect to the previous or next image, depending if its file is placed in alphabetic order after or befor the reference image.
|
|
33
|
+
* ```enabled``` (optional, default: ```True```): allows to switch on and off this module.
|