impy-array 2.2.1__tar.gz → 2.2.2__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.
- impy_array-2.2.2/.gitignore +130 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/PKG-INFO +178 -141
- {impy-array-2.2.1 → impy_array-2.2.2}/README.md +1 -7
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/__init__.py +11 -13
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/__init__.py +10 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_deconv.py +18 -13
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_transform.py +6 -4
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/axesmixin.py +3 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/bases/metaarray.py +2 -2
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/bases/overload.py +35 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/imgarray.py +102 -49
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/labeledarray.py +1 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/lazy.py +1 -1
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/core.py +17 -11
- impy_array-2.2.2/pyproject.toml +57 -0
- impy-array-2.2.1/impy_array.egg-info/PKG-INFO +0 -141
- impy-array-2.2.1/impy_array.egg-info/SOURCES.txt +0 -65
- impy-array-2.2.1/impy_array.egg-info/dependency_links.txt +0 -1
- impy-array-2.2.1/impy_array.egg-info/entry_points.txt +0 -2
- impy-array-2.2.1/impy_array.egg-info/requires.txt +0 -16
- impy-array-2.2.1/impy_array.egg-info/top_level.txt +0 -1
- impy-array-2.2.1/setup.cfg +0 -4
- impy-array-2.2.1/setup.py +0 -36
- {impy-array-2.2.1 → impy_array-2.2.2}/LICENSE +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/__main__.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/_const.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/_types.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/array_api.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_deprecated.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_imshow.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/__init__.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_corr.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_docs.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_filters.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_glcm.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_linalg.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_misc.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_plot.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_process_numba.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_skimage.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/_utils/_structures.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/bases/__init__.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/big.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/label.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/phasearray.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/arrays/specials.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/axes/__init__.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/axes/_axes.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/axes/_axes_tuple.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/axes/_axis.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/axes/_slicer.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/binder.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/collections.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/correlation.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/frame/__init__.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/frame/frames.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/io.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/random.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/roi.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/utils/__init__.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/utils/axesop.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/utils/deco.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/utils/gauss.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/utils/misc.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/utils/slicer.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/utils/utilcls.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/viewer/__init__.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/viewer/utils.py +0 -0
- {impy-array-2.2.1 → impy_array-2.2.2}/impy/viewer/viewer.py +0 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
.vscode/
|
|
4
|
+
*.py[cod]
|
|
5
|
+
*$py.class
|
|
6
|
+
|
|
7
|
+
# C extensions
|
|
8
|
+
*.so
|
|
9
|
+
|
|
10
|
+
# Distribution / packaging
|
|
11
|
+
.Python
|
|
12
|
+
build/
|
|
13
|
+
develop-eggs/
|
|
14
|
+
dist/
|
|
15
|
+
downloads/
|
|
16
|
+
eggs/
|
|
17
|
+
.eggs/
|
|
18
|
+
lib/
|
|
19
|
+
lib64/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
wheels/
|
|
24
|
+
pip-wheel-metadata/
|
|
25
|
+
share/python-wheels/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# PyInstaller
|
|
32
|
+
# Usually these files are written by a python script from a template
|
|
33
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
34
|
+
*.manifest
|
|
35
|
+
*.spec
|
|
36
|
+
|
|
37
|
+
# Installer logs
|
|
38
|
+
pip-log.txt
|
|
39
|
+
pip-delete-this-directory.txt
|
|
40
|
+
|
|
41
|
+
# Unit test / coverage reports
|
|
42
|
+
htmlcov/
|
|
43
|
+
.tox/
|
|
44
|
+
.nox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*.cover
|
|
51
|
+
*.py,cover
|
|
52
|
+
.hypothesis/
|
|
53
|
+
.pytest_cache/
|
|
54
|
+
|
|
55
|
+
# Translations
|
|
56
|
+
*.mo
|
|
57
|
+
*.pot
|
|
58
|
+
|
|
59
|
+
# Django stuff:
|
|
60
|
+
*.log
|
|
61
|
+
local_settings.py
|
|
62
|
+
db.sqlite3
|
|
63
|
+
db.sqlite3-journal
|
|
64
|
+
|
|
65
|
+
# Flask stuff:
|
|
66
|
+
instance/
|
|
67
|
+
.webassets-cache
|
|
68
|
+
|
|
69
|
+
# Scrapy stuff:
|
|
70
|
+
.scrapy
|
|
71
|
+
|
|
72
|
+
# Sphinx documentation
|
|
73
|
+
docs/_build/
|
|
74
|
+
|
|
75
|
+
# PyBuilder
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
.python-version
|
|
87
|
+
|
|
88
|
+
# pipenv
|
|
89
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
90
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
91
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
92
|
+
# install all needed dependencies.
|
|
93
|
+
#Pipfile.lock
|
|
94
|
+
|
|
95
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
96
|
+
__pypackages__/
|
|
97
|
+
|
|
98
|
+
# Celery stuff
|
|
99
|
+
celerybeat-schedule
|
|
100
|
+
celerybeat.pid
|
|
101
|
+
|
|
102
|
+
# SageMath parsed files
|
|
103
|
+
*.sage.py
|
|
104
|
+
|
|
105
|
+
# Environments
|
|
106
|
+
.env
|
|
107
|
+
.venv
|
|
108
|
+
env/
|
|
109
|
+
venv/
|
|
110
|
+
ENV/
|
|
111
|
+
env.bak/
|
|
112
|
+
venv.bak/
|
|
113
|
+
|
|
114
|
+
# Spyder project settings
|
|
115
|
+
.spyderproject
|
|
116
|
+
.spyproject
|
|
117
|
+
|
|
118
|
+
# Rope project settings
|
|
119
|
+
.ropeproject
|
|
120
|
+
|
|
121
|
+
# mkdocs documentation
|
|
122
|
+
/site
|
|
123
|
+
|
|
124
|
+
# mypy
|
|
125
|
+
.mypy_cache/
|
|
126
|
+
.dmypy.json
|
|
127
|
+
dmypy.json
|
|
128
|
+
|
|
129
|
+
# Pyre type checker
|
|
130
|
+
.pyre/
|
|
@@ -1,141 +1,178 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: impy-array
|
|
3
|
-
Version: 2.2.
|
|
4
|
-
Summary: Speed up coding/extending image analysis in Python.
|
|
5
|
-
|
|
6
|
-
Author: Hanjin Liu
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
img
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: impy-array
|
|
3
|
+
Version: 2.2.2
|
|
4
|
+
Summary: Speed up coding/extending image analysis in Python.
|
|
5
|
+
Project-URL: Download, https://github.com/hanjinliu/impy
|
|
6
|
+
Author-email: Hanjin Liu <liuhanjin-sc@g.ecc.u-tokyo.ac.jp>
|
|
7
|
+
License: BSD 3-Clause License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2021, hanjinliu
|
|
10
|
+
All rights reserved.
|
|
11
|
+
|
|
12
|
+
Redistribution and use in source and binary forms, with or without
|
|
13
|
+
modification, are permitted provided that the following conditions are met:
|
|
14
|
+
|
|
15
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
16
|
+
list of conditions and the following disclaimer.
|
|
17
|
+
|
|
18
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
19
|
+
this list of conditions and the following disclaimer in the documentation
|
|
20
|
+
and/or other materials provided with the distribution.
|
|
21
|
+
|
|
22
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
23
|
+
contributors may be used to endorse or promote products derived from
|
|
24
|
+
this software without specific prior written permission.
|
|
25
|
+
|
|
26
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
27
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
28
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
29
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
30
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
31
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
32
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
33
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
34
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
35
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
42
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
43
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
44
|
+
Requires-Python: >=3.8
|
|
45
|
+
Requires-Dist: dask>=2021.6.0
|
|
46
|
+
Requires-Dist: napari>=0.4.17
|
|
47
|
+
Requires-Dist: numpy>=1.22
|
|
48
|
+
Requires-Dist: pandas>=1.3
|
|
49
|
+
Requires-Dist: scikit-image>=0.20.0
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Requires-Dist: mrcfile; extra == 'all'
|
|
52
|
+
Requires-Dist: zarr; extra == 'all'
|
|
53
|
+
Provides-Extra: mrc
|
|
54
|
+
Requires-Dist: mrcfile; extra == 'mrc'
|
|
55
|
+
Provides-Extra: zarr
|
|
56
|
+
Requires-Dist: zarr; extra == 'zarr'
|
|
57
|
+
Description-Content-Type: text/markdown
|
|
58
|
+
|
|
59
|
+
[](https://pepy.tech/project/impy-array)
|
|
60
|
+
[](https://badge.fury.io/py/impy-array)
|
|
61
|
+
|
|
62
|
+
# A numpy extension for efficient and powerful image analysis workflow
|
|
63
|
+
|
|
64
|
+
`impy` is an all-in-one image analysis library, equipped with parallel processing, GPU support, GUI based tools and so on.
|
|
65
|
+
|
|
66
|
+
The core array, `ImgArray`, is a subclass of `numpy.ndarray`, tagged with information such as
|
|
67
|
+
|
|
68
|
+
- image axes
|
|
69
|
+
- scale of each axis
|
|
70
|
+
- directory of the original image
|
|
71
|
+
- and other image metadata
|
|
72
|
+
|
|
73
|
+
## Documentation
|
|
74
|
+
|
|
75
|
+
Documentation is available [here](https://hanjinliu.github.io/impy/).
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
- use pip
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
pip install impy-array
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- from source
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
git clone https://github.com/hanjinliu/impy
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Code as fast as you speak
|
|
92
|
+
|
|
93
|
+
Almost all the functions, such as filtering, deconvolution, labeling, single molecule detection, and even those pure `numpy` functions, are aware of image metadata. They "know" which dimension corresponds to `"z"` axis, which axes they should iterate along or where to save the image. As a result, **your code will be very concise**:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
import impy as ip
|
|
97
|
+
import numpy as np
|
|
98
|
+
|
|
99
|
+
img = ip.imread("path/to/image") # Read images with metadata.
|
|
100
|
+
img["z=3;t=0"].imshow() # Plot image slice at z=3 and t=0.
|
|
101
|
+
img_fil = img.gaussian_filter(sigma=2) # Paralell batch denoising. No more for loop!
|
|
102
|
+
img_prj = np.max(img_fil, axis="z") # Z-projection (numpy is aware of image axes!).
|
|
103
|
+
img_prj.imsave(f"Max-{img.name}") # Save in the same place. Don't spend time on searching for the directory!
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Supported file formats
|
|
107
|
+
|
|
108
|
+
`impy` automatically chooses proper reader/writer according to the extension.
|
|
109
|
+
|
|
110
|
+
- Tiff file (".tif", ".tiff")
|
|
111
|
+
- MRC file (".mrc", ".rec", ".st", ".map", ".map.gz")
|
|
112
|
+
- Zarr file (".zarr")
|
|
113
|
+
- Other image file (".png", ".jpg")
|
|
114
|
+
|
|
115
|
+
### Switch between CPU and GPU
|
|
116
|
+
|
|
117
|
+
`impy` can internally switches the functions between `numpy` and `cupy`.
|
|
118
|
+
You can use GPU for calculation very easily.
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
img.gaussian_filter() # <- CPU
|
|
122
|
+
with ip.use("cupy"):
|
|
123
|
+
img.gaussian_filter() # <- GPU
|
|
124
|
+
ip.Const["RESOURCE"] = "cupy" # <- globally use GPU
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Seamless interface between `napari`
|
|
128
|
+
|
|
129
|
+
[napari](https://github.com/napari/napari) is an interactive viewer for multi-dimensional images. `impy` has a **simple and efficient interface** with it, via the object `ip.gui`. Since `ImgArray` is tagged with image metadata, you don't have to care about axes or scales. Just run
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
ip.gui.add(img)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Extend your function for batch processing
|
|
136
|
+
|
|
137
|
+
Already have a function for `numpy` and `scipy`? Decorate it with `@ip.bind`
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
@ip.bind
|
|
141
|
+
def imfilter(img, param=None):
|
|
142
|
+
# Your function here.
|
|
143
|
+
# Do something on a 2D or 3D image and return image, scalar or labels
|
|
144
|
+
return out
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
and it's ready for batch processing!
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
img.imfilter(param=1.0)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Command line usage
|
|
154
|
+
|
|
155
|
+
`impy` also supports command line based image analysis. All method of `ImgArray` is available
|
|
156
|
+
from commad line, such as
|
|
157
|
+
|
|
158
|
+
```powershell
|
|
159
|
+
impy path/to/image.tif ./output.tif --method gaussian_filter --sigma 2.0
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
which is equivalent to
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
import impy as ip
|
|
166
|
+
img = ip.imread("path/to/image.tif")
|
|
167
|
+
out = img.gaussian_filter(sigma=2.0)
|
|
168
|
+
out.imsave("./output.tif")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
For more complex procedure, it is possible to send image directly to `IPython`
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
impy path/to/image.tif -i
|
|
175
|
+
```
|
|
176
|
+
```python
|
|
177
|
+
thr = img.gaussian_filter().threshold()
|
|
178
|
+
```
|
|
@@ -92,7 +92,7 @@ and it's ready for batch processing!
|
|
|
92
92
|
img.imfilter(param=1.0)
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
###
|
|
95
|
+
### Command line usage
|
|
96
96
|
|
|
97
97
|
`impy` also supports command line based image analysis. All method of `ImgArray` is available
|
|
98
98
|
from commad line, such as
|
|
@@ -118,9 +118,3 @@ impy path/to/image.tif -i
|
|
|
118
118
|
```python
|
|
119
119
|
thr = img.gaussian_filter().threshold()
|
|
120
120
|
```
|
|
121
|
-
|
|
122
|
-
or to `napari`
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
impy path/to/image.tif -n
|
|
126
|
-
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "2.2.
|
|
1
|
+
__version__ = "2.2.2"
|
|
2
2
|
__author__ = "Hanjin Liu"
|
|
3
3
|
__email__ = "liuhanjin-sc@g.ecc.u-tokyo.ac.jp"
|
|
4
4
|
|
|
@@ -15,19 +15,17 @@ from .arrays import ImgArray, LazyImgArray, BigImgArray, Label # for typing
|
|
|
15
15
|
from . import random, io
|
|
16
16
|
from .axes import slicer
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
# Inheritance
|
|
19
|
+
# -----------
|
|
20
|
+
#
|
|
21
|
+
# AxesMixin -----> LazyImgArray ------> BigImgArray
|
|
22
|
+
# |
|
|
23
|
+
# +-----> MetaArray --+--> LabeledArray --+--> ImgArray
|
|
24
|
+
# | | |
|
|
25
|
+
# np.ndarray +--> Label +--> PhaseArray
|
|
26
|
+
# |
|
|
27
|
+
# +--> PropArray
|
|
21
28
|
|
|
22
|
-
AxesMixin -----> LazyImgArray ------> BigImgArray
|
|
23
|
-
|
|
|
24
|
-
+-----> MetaArray --+--> LabeledArray --+--> ImgArray
|
|
25
|
-
| | |
|
|
26
|
-
np.ndarray +--> Label +--> PhaseArray
|
|
27
|
-
|
|
|
28
|
-
+--> PropArray
|
|
29
|
-
|
|
30
|
-
"""
|
|
31
29
|
|
|
32
30
|
logging.getLogger("skimage").setLevel(logging.ERROR)
|
|
33
31
|
logging.getLogger("tifffile").setLevel(logging.ERROR)
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
1
4
|
from functools import partial
|
|
2
5
|
import numpy as np
|
|
3
|
-
from
|
|
6
|
+
from impy.array_api import xp
|
|
4
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from impy.arrays import ImgArray
|
|
10
|
+
|
|
5
11
|
try:
|
|
6
12
|
gradient = xp.gradient
|
|
7
13
|
except AttributeError:
|
|
@@ -11,11 +17,7 @@ except AttributeError:
|
|
|
11
17
|
out = numpy.gradient(a.get(), axis=axis)
|
|
12
18
|
return xp.asarray(out)
|
|
13
19
|
|
|
14
|
-
__all__ = ["wiener",
|
|
15
|
-
"lucy",
|
|
16
|
-
"lucy_tv",
|
|
17
|
-
"check_psf",
|
|
18
|
-
]
|
|
20
|
+
__all__ = ["wiener", "lucy", "lucy_tv", "check_psf"]
|
|
19
21
|
|
|
20
22
|
def wiener(obs, psf_ft, psf_ft_conj, lmd):
|
|
21
23
|
obs = xp.asarray(obs)
|
|
@@ -67,20 +69,23 @@ def richardson_lucy_tv(obs, psf_ft, psf_ft_conj, max_iter, lmd, tol, eps):
|
|
|
67
69
|
return xp.fft.fftshift(est_new)
|
|
68
70
|
|
|
69
71
|
|
|
70
|
-
def _safe_div(a, b, eps=1e-8):
|
|
72
|
+
def _safe_div(a: np.ndarray, b: np.ndarray, eps: float = 1e-8):
|
|
71
73
|
out = xp.zeros(a.shape, dtype=np.float32)
|
|
72
74
|
mask = b > eps
|
|
73
|
-
out[mask] = a[mask]/b[mask]
|
|
75
|
+
out[mask] = a[mask] / b[mask]
|
|
74
76
|
return out
|
|
75
77
|
|
|
76
78
|
|
|
77
|
-
def check_psf(
|
|
79
|
+
def check_psf(img_shape: tuple[int, ...], img_scale: tuple[float, ...], psf):
|
|
80
|
+
if callable(psf):
|
|
81
|
+
psf = psf(img_shape, img_scale)
|
|
78
82
|
psf = xp.asarray(psf, dtype=np.float32)
|
|
79
83
|
psf /= xp.sum(psf)
|
|
80
84
|
|
|
81
|
-
if
|
|
82
|
-
raise ValueError(
|
|
83
|
-
|
|
85
|
+
if img_shape != psf.shape:
|
|
86
|
+
raise ValueError(
|
|
87
|
+
f"observation and PSF have different shape: {img_shape} and {psf.shape}"
|
|
88
|
+
)
|
|
84
89
|
psf_ft = xp.fft.rfftn(psf)
|
|
85
90
|
psf_ft_conj = xp.conjugate(psf_ft)
|
|
86
|
-
return psf_ft, psf_ft_conj
|
|
91
|
+
return psf_ft, psf_ft_conj
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from typing import Iterable, NamedTuple, Sequence, TYPE_CHECKING
|
|
4
|
+
import math
|
|
4
5
|
import numpy as np
|
|
5
6
|
|
|
6
7
|
from ._skimage import sktrans
|
|
@@ -307,8 +308,8 @@ def iradon(
|
|
|
307
308
|
# Reconstruct image by interpolation
|
|
308
309
|
reconstructed = np.zeros(output_shape, dtype=dtype)
|
|
309
310
|
xpr, ypr = np.indices(output_shape)
|
|
310
|
-
xpr
|
|
311
|
-
ypr
|
|
311
|
+
xpr = xpr - output_shape[0] // 2
|
|
312
|
+
ypr = ypr - output_shape[1] // 2
|
|
312
313
|
|
|
313
314
|
from scipy.interpolate import interp1d
|
|
314
315
|
x = np.arange(img_shape) - img_shape // 2 # NOTE: use CPU!
|
|
@@ -322,12 +323,13 @@ def iradon(
|
|
|
322
323
|
# This function is almost ported from `skimage.transform`.
|
|
323
324
|
def get_fourier_filter(size: int, filter_name: str):
|
|
324
325
|
n = xp.concatenate(
|
|
325
|
-
[xp.arange(1, size
|
|
326
|
-
xp.arange(size
|
|
326
|
+
[xp.arange(1, size // 2 + 1, 2, dtype=np.float32),
|
|
327
|
+
xp.arange(size // 2 - 1, 0, -2, dtype=np.float32)]
|
|
327
328
|
)
|
|
328
329
|
f = xp.zeros(size)
|
|
329
330
|
f[0] = 0.25
|
|
330
331
|
f[1::2] = -1 / (np.pi * n[:len(f[1::2])]) ** 2
|
|
332
|
+
|
|
331
333
|
fourier_filter = 2 * xp.real(xp.fft.fft(f)) # ramp filter
|
|
332
334
|
if filter_name == "ramp":
|
|
333
335
|
pass
|
|
@@ -200,6 +200,9 @@ class AxesMixin:
|
|
|
200
200
|
{a: s for a, s in other.scale.items() if a in self.axes} # type: ignore
|
|
201
201
|
)
|
|
202
202
|
|
|
203
|
+
elif isinstance(other, (list, tuple)):
|
|
204
|
+
for a, s in zip(self.axes, other):
|
|
205
|
+
a.scale = s
|
|
203
206
|
else:
|
|
204
207
|
raise TypeError(
|
|
205
208
|
f"'other' must be str or axes supported object, but got {type(other)}"
|
|
@@ -27,7 +27,7 @@ SupportSlicing = Union[
|
|
|
27
27
|
Mapping[str, SupportOneSlicing],
|
|
28
28
|
]
|
|
29
29
|
|
|
30
|
-
class MetaArray(AxesMixin, np.ndarray):
|
|
30
|
+
class MetaArray(AxesMixin, np.ndarray[Any, np.dtype[np.number]]):
|
|
31
31
|
additional_props = ["_source", "_metadata", "_name"]
|
|
32
32
|
NP_DISPATCH = {}
|
|
33
33
|
_name: str
|
|
@@ -747,7 +747,7 @@ class MetaArray(AxesMixin, np.ndarray):
|
|
|
747
747
|
except ImageAxesError:
|
|
748
748
|
self.axes = None
|
|
749
749
|
|
|
750
|
-
return
|
|
750
|
+
return self
|
|
751
751
|
|
|
752
752
|
def _process_output(self, func, args, kwargs):
|
|
753
753
|
# find the largest MetaArray. Largest because of broadcasting.
|