impy-array 2.3.2__tar.gz → 2.4.0__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.
Files changed (65) hide show
  1. {impy_array-2.3.2 → impy_array-2.4.0}/PKG-INFO +39 -9
  2. {impy_array-2.3.2 → impy_array-2.4.0}/README.md +24 -7
  3. {impy_array-2.3.2 → impy_array-2.4.0}/impy/__init__.py +11 -11
  4. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_deconv.py +10 -14
  5. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_filters.py +12 -12
  6. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_glcm.py +15 -15
  7. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_misc.py +5 -5
  8. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_structures.py +4 -4
  9. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/imgarray.py +708 -681
  10. {impy_array-2.3.2 → impy_array-2.4.0}/impy/io.py +160 -65
  11. impy_array-2.4.0/impy/lazy/__init__.py +2 -0
  12. {impy_array-2.3.2 → impy_array-2.4.0}/impy/lazy/core.py +42 -34
  13. {impy_array-2.3.2 → impy_array-2.4.0}/impy/random.py +26 -27
  14. {impy_array-2.3.2 → impy_array-2.4.0}/pyproject.toml +21 -1
  15. impy_array-2.3.2/impy/lazy/__init__.py +0 -2
  16. {impy_array-2.3.2 → impy_array-2.4.0}/.gitignore +0 -0
  17. {impy_array-2.3.2 → impy_array-2.4.0}/LICENSE +0 -0
  18. {impy_array-2.3.2 → impy_array-2.4.0}/impy/__main__.py +0 -0
  19. {impy_array-2.3.2 → impy_array-2.4.0}/impy/_const.py +0 -0
  20. {impy_array-2.3.2 → impy_array-2.4.0}/impy/_types.py +0 -0
  21. {impy_array-2.3.2 → impy_array-2.4.0}/impy/array_api.py +0 -0
  22. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/__init__.py +0 -0
  23. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_imshow.py +0 -0
  24. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/__init__.py +0 -0
  25. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_corr.py +0 -0
  26. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_docs.py +0 -0
  27. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_linalg.py +0 -0
  28. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_plot.py +0 -0
  29. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_process_numba.py +0 -0
  30. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_skimage.py +0 -0
  31. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/_utils/_transform.py +0 -0
  32. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/axesmixin.py +0 -0
  33. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/bases/__init__.py +0 -0
  34. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/bases/metaarray.py +0 -0
  35. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/bases/overload.py +0 -0
  36. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/big.py +0 -0
  37. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/label.py +0 -0
  38. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/labeledarray.py +0 -0
  39. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/lazy.py +0 -0
  40. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/phasearray.py +0 -0
  41. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/specials.py +0 -0
  42. {impy_array-2.3.2 → impy_array-2.4.0}/impy/arrays/tiled.py +0 -0
  43. {impy_array-2.3.2 → impy_array-2.4.0}/impy/axes/__init__.py +0 -0
  44. {impy_array-2.3.2 → impy_array-2.4.0}/impy/axes/_axes.py +0 -0
  45. {impy_array-2.3.2 → impy_array-2.4.0}/impy/axes/_axes_tuple.py +0 -0
  46. {impy_array-2.3.2 → impy_array-2.4.0}/impy/axes/_axis.py +0 -0
  47. {impy_array-2.3.2 → impy_array-2.4.0}/impy/axes/_slicer.py +0 -0
  48. {impy_array-2.3.2 → impy_array-2.4.0}/impy/binder.py +0 -0
  49. {impy_array-2.3.2 → impy_array-2.4.0}/impy/collections.py +0 -0
  50. {impy_array-2.3.2 → impy_array-2.4.0}/impy/core.py +0 -0
  51. {impy_array-2.3.2 → impy_array-2.4.0}/impy/correlation.py +0 -0
  52. {impy_array-2.3.2 → impy_array-2.4.0}/impy/frame/__init__.py +0 -0
  53. {impy_array-2.3.2 → impy_array-2.4.0}/impy/frame/frames.py +0 -0
  54. {impy_array-2.3.2 → impy_array-2.4.0}/impy/lazy/random.py +0 -0
  55. {impy_array-2.3.2 → impy_array-2.4.0}/impy/roi.py +0 -0
  56. {impy_array-2.3.2 → impy_array-2.4.0}/impy/utils/__init__.py +0 -0
  57. {impy_array-2.3.2 → impy_array-2.4.0}/impy/utils/axesop.py +0 -0
  58. {impy_array-2.3.2 → impy_array-2.4.0}/impy/utils/deco.py +0 -0
  59. {impy_array-2.3.2 → impy_array-2.4.0}/impy/utils/gauss.py +0 -0
  60. {impy_array-2.3.2 → impy_array-2.4.0}/impy/utils/misc.py +0 -0
  61. {impy_array-2.3.2 → impy_array-2.4.0}/impy/utils/slicer.py +0 -0
  62. {impy_array-2.3.2 → impy_array-2.4.0}/impy/utils/utilcls.py +0 -0
  63. {impy_array-2.3.2 → impy_array-2.4.0}/impy/viewer/__init__.py +0 -0
  64. {impy_array-2.3.2 → impy_array-2.4.0}/impy/viewer/utils.py +0 -0
  65. {impy_array-2.3.2 → impy_array-2.4.0}/impy/viewer/viewer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: impy-array
3
- Version: 2.3.2
3
+ Version: 2.4.0
4
4
  Summary: Speed up coding/extending image analysis in Python.
5
5
  Project-URL: Download, https://github.com/hanjinliu/impy
6
6
  Author-email: Hanjin Liu <liuhanjin-sc@g.ecc.u-tokyo.ac.jp>
@@ -43,28 +43,42 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
43
43
  Classifier: Programming Language :: Python :: Implementation :: PyPy
44
44
  Requires-Python: >=3.9
45
45
  Requires-Dist: dask>=2021.6.0
46
- Requires-Dist: napari>=0.4.17
47
46
  Requires-Dist: numpy>=1.22
48
47
  Requires-Dist: pandas>=1.3
49
48
  Requires-Dist: scikit-image>=0.20.0
50
49
  Requires-Dist: scipy>=1.7
51
50
  Provides-Extra: all
52
51
  Requires-Dist: mrcfile; extra == 'all'
52
+ Requires-Dist: napari>=0.4.17; extra == 'all'
53
+ Requires-Dist: roifile; extra == 'all'
54
+ Requires-Dist: tifffile; extra == 'all'
53
55
  Requires-Dist: zarr; extra == 'all'
54
56
  Provides-Extra: mrc
55
57
  Requires-Dist: mrcfile; extra == 'mrc'
58
+ Provides-Extra: napari
59
+ Requires-Dist: napari>=0.4.17; extra == 'napari'
60
+ Provides-Extra: testing
61
+ Requires-Dist: dask-image; extra == 'testing'
62
+ Requires-Dist: mrcfile; extra == 'testing'
63
+ Requires-Dist: pytest; extra == 'testing'
64
+ Requires-Dist: roifile; extra == 'testing'
65
+ Requires-Dist: tifffile; extra == 'testing'
66
+ Requires-Dist: zarr; extra == 'testing'
67
+ Provides-Extra: tiff
68
+ Requires-Dist: tifffile; extra == 'tiff'
56
69
  Provides-Extra: zarr
57
70
  Requires-Dist: zarr; extra == 'zarr'
58
71
  Description-Content-Type: text/markdown
59
72
 
60
- [![Downloads](https://pepy.tech/badge/impy-array/month)](https://pepy.tech/project/impy-array)
73
+ [![BSD 3-Clause License](https://img.shields.io/pypi/l/impy-array.svg?color=green)](https://github.com/hanjinliu/impy/blob/main/LICENSE)
74
+ [![Python package index download statistics](https://img.shields.io/pypi/dm/impy-array.svg)](https://pypistats.org/packages/impy-array)
61
75
  [![PyPI version](https://badge.fury.io/py/impy-array.svg)](https://badge.fury.io/py/impy-array)
62
76
 
63
77
  # A numpy extension for efficient and powerful image analysis workflow
64
78
 
65
79
  `impy` is an all-in-one image analysis library, equipped with parallel processing, GPU support, GUI based tools and so on.
66
80
 
67
- The core array, `ImgArray`, is a subclass of `numpy.ndarray`, tagged with information such as
81
+ The core array, `ImgArray`, is a subclass of `numpy.ndarray`, tagged with information such as
68
82
 
69
83
  - image axes
70
84
  - scale of each axis
@@ -79,8 +93,12 @@ Documentation is available [here](https://hanjinliu.github.io/impy/).
79
93
 
80
94
  - use pip
81
95
 
82
- ```
96
+ ``` sh
83
97
  pip install impy-array
98
+ pip install impy-array[tiff] # with supports for reading/writing .tif files
99
+ pip install impy-array[mrc] # with supports for reading/writing .mrc files
100
+ pip install impy-array[napari] # viewer support
101
+ pip install impy-array[all] # install everything
84
102
  ```
85
103
 
86
104
  - from source
@@ -104,7 +122,7 @@ img_prj = np.max(img_fil, axis="z") # Z-projection (numpy is aware of image a
104
122
  img_prj.imsave(f"Max-{img.name}") # Save in the same place. Don't spend time on searching for the directory!
105
123
  ```
106
124
 
107
- ### Supported file formats
125
+ ### Supports many file formats
108
126
 
109
127
  `impy` automatically chooses proper reader/writer according to the extension.
110
128
 
@@ -113,10 +131,22 @@ img_prj.imsave(f"Max-{img.name}") # Save in the same place. Don't spend tim
113
131
  - Zarr file (".zarr")
114
132
  - Other image file (".png", ".jpg")
115
133
 
134
+ ### Lazy loading
135
+
136
+ With the `lazy` submodule, you can easily make image processing workflows for large
137
+ images.
138
+
139
+ ```python
140
+ import impy as ip
141
+
142
+ img = ip.lazy.imread("path/to/very-large-image.tif")
143
+ out = img.gaussian_filter()
144
+ out.imsave("image_filtered.tif")
145
+ ```
146
+
116
147
  ### Switch between CPU and GPU
117
148
 
118
149
  `impy` can internally switches the functions between `numpy` and `cupy`.
119
- You can use GPU for calculation very easily.
120
150
 
121
151
  ```python
122
152
  img.gaussian_filter() # <- CPU
@@ -127,7 +157,7 @@ ip.Const["RESOURCE"] = "cupy" # <- globally use GPU
127
157
 
128
158
  ### Seamless interface between `napari`
129
159
 
130
- [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
160
+ [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
131
161
 
132
162
  ```python
133
163
  ip.gui.add(img)
@@ -156,7 +186,7 @@ img.imfilter(param=1.0)
156
186
  `impy` also supports command line based image analysis. All method of `ImgArray` is available
157
187
  from commad line, such as
158
188
 
159
- ```powershell
189
+ ```shell
160
190
  impy path/to/image.tif ./output.tif --method gaussian_filter --sigma 2.0
161
191
  ```
162
192
 
@@ -1,11 +1,12 @@
1
- [![Downloads](https://pepy.tech/badge/impy-array/month)](https://pepy.tech/project/impy-array)
1
+ [![BSD 3-Clause License](https://img.shields.io/pypi/l/impy-array.svg?color=green)](https://github.com/hanjinliu/impy/blob/main/LICENSE)
2
+ [![Python package index download statistics](https://img.shields.io/pypi/dm/impy-array.svg)](https://pypistats.org/packages/impy-array)
2
3
  [![PyPI version](https://badge.fury.io/py/impy-array.svg)](https://badge.fury.io/py/impy-array)
3
4
 
4
5
  # A numpy extension for efficient and powerful image analysis workflow
5
6
 
6
7
  `impy` is an all-in-one image analysis library, equipped with parallel processing, GPU support, GUI based tools and so on.
7
8
 
8
- The core array, `ImgArray`, is a subclass of `numpy.ndarray`, tagged with information such as
9
+ The core array, `ImgArray`, is a subclass of `numpy.ndarray`, tagged with information such as
9
10
 
10
11
  - image axes
11
12
  - scale of each axis
@@ -20,8 +21,12 @@ Documentation is available [here](https://hanjinliu.github.io/impy/).
20
21
 
21
22
  - use pip
22
23
 
23
- ```
24
+ ``` sh
24
25
  pip install impy-array
26
+ pip install impy-array[tiff] # with supports for reading/writing .tif files
27
+ pip install impy-array[mrc] # with supports for reading/writing .mrc files
28
+ pip install impy-array[napari] # viewer support
29
+ pip install impy-array[all] # install everything
25
30
  ```
26
31
 
27
32
  - from source
@@ -45,7 +50,7 @@ img_prj = np.max(img_fil, axis="z") # Z-projection (numpy is aware of image a
45
50
  img_prj.imsave(f"Max-{img.name}") # Save in the same place. Don't spend time on searching for the directory!
46
51
  ```
47
52
 
48
- ### Supported file formats
53
+ ### Supports many file formats
49
54
 
50
55
  `impy` automatically chooses proper reader/writer according to the extension.
51
56
 
@@ -54,10 +59,22 @@ img_prj.imsave(f"Max-{img.name}") # Save in the same place. Don't spend tim
54
59
  - Zarr file (".zarr")
55
60
  - Other image file (".png", ".jpg")
56
61
 
62
+ ### Lazy loading
63
+
64
+ With the `lazy` submodule, you can easily make image processing workflows for large
65
+ images.
66
+
67
+ ```python
68
+ import impy as ip
69
+
70
+ img = ip.lazy.imread("path/to/very-large-image.tif")
71
+ out = img.gaussian_filter()
72
+ out.imsave("image_filtered.tif")
73
+ ```
74
+
57
75
  ### Switch between CPU and GPU
58
76
 
59
77
  `impy` can internally switches the functions between `numpy` and `cupy`.
60
- You can use GPU for calculation very easily.
61
78
 
62
79
  ```python
63
80
  img.gaussian_filter() # <- CPU
@@ -68,7 +85,7 @@ ip.Const["RESOURCE"] = "cupy" # <- globally use GPU
68
85
 
69
86
  ### Seamless interface between `napari`
70
87
 
71
- [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
88
+ [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
72
89
 
73
90
  ```python
74
91
  ip.gui.add(img)
@@ -97,7 +114,7 @@ img.imfilter(param=1.0)
97
114
  `impy` also supports command line based image analysis. All method of `ImgArray` is available
98
115
  from commad line, such as
99
116
 
100
- ```powershell
117
+ ```shell
101
118
  impy path/to/image.tif ./output.tif --method gaussian_filter --sigma 2.0
102
119
  ```
103
120
 
@@ -1,19 +1,19 @@
1
- __version__ = "2.3.2"
1
+ __version__ = "2.4.0"
2
2
  __author__ = "Hanjin Liu"
3
3
  __email__ = "liuhanjin-sc@g.ecc.u-tokyo.ac.jp"
4
4
 
5
5
  import logging
6
6
 
7
- from ._const import Const, SetConst, use
7
+ from ._const import Const, SetConst, use # noqa
8
8
 
9
- from .collections import DataList, DataDict
10
- from .core import *
11
- from .binder import bind
12
- from .viewer import gui
13
- from .correlation import *
14
- from .arrays import ImgArray, LazyImgArray, BigImgArray, Label # for typing
15
- from . import random, io, lazy
16
- from .axes import slicer
9
+ from .collections import DataList, DataDict # noqa
10
+ from .core import * # noqa
11
+ from .binder import bind # noqa
12
+ from .viewer import gui # noqa
13
+ from .correlation import * # noqa
14
+ from .arrays import ImgArray, LazyImgArray, BigImgArray, Label # noqa
15
+ from . import random, io, lazy # noqa
16
+ from .axes import slicer # noqa
17
17
 
18
18
  # Inheritance
19
19
  # -----------
@@ -34,7 +34,7 @@ logging.getLogger("tifffile").setLevel(logging.ERROR)
34
34
  del logging
35
35
 
36
36
  # dtypes
37
- from numpy import (
37
+ from numpy import ( # noqa
38
38
  uint8, uint16, uint32, uint64,
39
39
  int8, int16, int32, int64,
40
40
  float16, float32, float64,
@@ -1,13 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING
4
3
  from functools import partial
5
4
  import numpy as np
6
5
  from impy.array_api import xp
7
6
 
8
- if TYPE_CHECKING:
9
- from impy.arrays import ImgArray
10
-
11
7
  try:
12
8
  gradient = xp.gradient
13
9
  except AttributeError:
@@ -17,18 +13,18 @@ except AttributeError:
17
13
  out = numpy.gradient(a.get(), axis=axis)
18
14
  return xp.asarray(out)
19
15
 
20
- __all__ = ["wiener", "lucy", "lucy_tv", "check_psf"]
16
+ __all__ = ["wiener", "richardson_lucy", "richardson_lucy_tv", "check_psf"]
21
17
 
22
18
  def wiener(obs, psf_ft, psf_ft_conj, lmd):
23
19
  obs = xp.asarray(obs)
24
20
  fft = xp.fft.rfftn
25
21
  ifft = partial(xp.fft.irfftn, s=obs.shape)
26
-
22
+
27
23
  img_ft = fft(obs)
28
-
24
+
29
25
  estimated = xp.real(ifft(img_ft*psf_ft_conj / (psf_ft*psf_ft_conj + lmd)))
30
26
  return xp.fft.fftshift(estimated)
31
-
27
+
32
28
  def richardson_lucy(obs, psf_ft, psf_ft_conj, niter, eps):
33
29
  # Identical to the algorithm in Deconvolution.jl of Julia.
34
30
  obs = xp.asarray(obs)
@@ -36,12 +32,12 @@ def richardson_lucy(obs, psf_ft, psf_ft_conj, niter, eps):
36
32
  ifft = partial(xp.fft.irfftn, s=obs.shape)
37
33
  conv = factor = xp.empty(obs.shape, dtype=xp.float32) # placeholder
38
34
  estimated = xp.real(ifft(fft(obs) * psf_ft)) # initialization
39
-
35
+
40
36
  for _ in range(niter):
41
37
  conv[:] = ifft(fft(estimated) * psf_ft).real
42
38
  factor[:] = ifft(fft(_safe_div(obs, conv, eps=eps)) * psf_ft_conj).real
43
39
  estimated *= factor
44
-
40
+
45
41
  return xp.fft.fftshift(estimated)
46
42
 
47
43
  def richardson_lucy_tv(obs, psf_ft, psf_ft_conj, max_iter, lmd, tol, eps):
@@ -51,21 +47,21 @@ def richardson_lucy_tv(obs, psf_ft, psf_ft_conj, max_iter, lmd, tol, eps):
51
47
  est_old = ifft(fft(obs) * psf_ft).real
52
48
  est_new = xp.empty(obs.shape, dtype=xp.float32)
53
49
  conv = factor = norm = gg = xp.empty(obs.shape, dtype=np.float32) # placeholder
54
-
50
+
55
51
  for _ in range(max_iter):
56
52
  conv[:] = ifft(fft(est_old) * psf_ft).real
57
53
  factor[:] = ifft(fft(_safe_div(obs, conv, eps=eps)) * psf_ft_conj).real
58
54
  est_new[:] = est_old * factor
59
55
  grad = gradient(est_old)
60
56
  norm[:] = xp.sqrt(sum(g**2 for g in grad))
61
- gg[:] = sum(gradient(_safe_div(grad[i], norm, eps=1e-8), axis=i)
57
+ gg[:] = sum(gradient(_safe_div(grad[i], norm, eps=1e-8), axis=i)
62
58
  for i in range(obs.ndim))
63
59
  est_new /= (1 - lmd * gg)
64
60
  gain = xp.sum(xp.abs(est_new - est_old))/xp.sum(xp.abs(est_old))
65
61
  if gain < tol:
66
62
  break
67
63
  est_old[:] = est_new
68
-
64
+
69
65
  return xp.fft.fftshift(est_new)
70
66
 
71
67
 
@@ -81,7 +77,7 @@ def check_psf(img_shape: tuple[int, ...], img_scale: tuple[float, ...], psf):
81
77
  psf = psf(img_shape, img_scale)
82
78
  psf = xp.asarray(psf, dtype=np.float32)
83
79
  psf /= xp.sum(psf)
84
-
80
+
85
81
  if img_shape != psf.shape:
86
82
  raise ValueError(
87
83
  f"observation and PSF have different shape: {img_shape} and {psf.shape}"
@@ -4,16 +4,16 @@ from ._linalg import hessian_eigval
4
4
  from impy.array_api import xp, cupy_dispatcher
5
5
  from scipy import ndimage as scipy_ndi
6
6
 
7
-
7
+
8
8
  __all__ = ["binary_erosion",
9
- "erosion"
9
+ "erosion",
10
10
  "binary_dilation",
11
11
  "dilation",
12
12
  "binary_opening",
13
13
  "opening",
14
14
  "binary_closing",
15
15
  "closing",
16
- "gaussian_filter",
16
+ "gaussian_filter",
17
17
  "gaussian_filter_fourier",
18
18
  "median_filter",
19
19
  "convolve",
@@ -124,7 +124,7 @@ def coef_filter(data, selem, mode="reflect", cval=0.0):
124
124
  x2 = convolve(data**2, selem, mode=mode, cval=cval)
125
125
  out = _safe_sqrt(xp.asnumpy(x2 - x1**2), fill=0)/xp.asnumpy(x1)
126
126
  return out
127
-
127
+
128
128
  def dog_filter(img, low_sigma, high_sigma, mode="reflect", cval=0.0):
129
129
  filt_l = gaussian_filter(img, low_sigma, mode=mode, cval=cval)
130
130
  filt_h = gaussian_filter(img, high_sigma, mode=mode, cval=cval)
@@ -164,23 +164,23 @@ def population(img, selem):
164
164
  # See skimage/feature/template.py
165
165
  def ncc_filter(img: np.ndarray, template: np.ndarray, bg=0, mode="constant"):
166
166
  from scipy.signal import fftconvolve
167
- from skimage import feature
167
+ from skimage.feature import template as skimage_template
168
168
  ndim = template.ndim
169
- _win_sum = feature.template._window_sum_2d if ndim == 2 else feature.template._window_sum_3d
169
+ _win_sum = skimage_template._window_sum_2d if ndim == 2 else skimage_template._window_sum_3d
170
170
  pad_width = [(w, w) for w in template.shape]
171
171
  padimg = np.pad(img, pad_width=pad_width, mode=mode, constant_values=bg)
172
-
172
+
173
173
  corr = fftconvolve(padimg, template[(slice(None,None,-1),)*ndim], mode="valid")[(slice(1,-1,None),)*ndim]
174
-
174
+
175
175
  win_sum1 = _win_sum(padimg, template.shape)
176
176
  win_sum2 = _win_sum(padimg**2, template.shape)
177
-
177
+
178
178
  template_mean = np.mean(template)
179
179
  template_volume = np.prod(template.shape)
180
180
  template_ssd = np.sum((template - template_mean)**2)
181
-
181
+
182
182
  var = (win_sum2 - win_sum1**2/template_volume) * template_ssd
183
-
183
+
184
184
  # zero division happens when perfectly matched
185
185
  response = np.ones_like(corr)
186
186
  mask = var > np.finfo(np.float32).eps
@@ -192,7 +192,7 @@ def ncc_filter(img: np.ndarray, template: np.ndarray, bg=0, mode="constant"):
192
192
  slices.append(slice(d0, d1))
193
193
  out = response[tuple(slices)]
194
194
  return out
195
-
195
+
196
196
  def _safe_sqrt(a: np.ndarray, fill=0):
197
197
  out = np.full(a.shape, fill, dtype=np.float32)
198
198
  out = np.zeros_like(a)
@@ -1,6 +1,6 @@
1
1
  import numpy as np
2
- from ...collections import DataDict
3
2
  import scipy
3
+ from impy.collections import DataDict
4
4
 
5
5
  __all__ = ["glcm_props_", "check_glcm"]
6
6
 
@@ -15,7 +15,7 @@ def asm_(glcm, ref, nei):
15
15
 
16
16
  def idm_(glcm, ref, nei):
17
17
  return np.sum(glcm/(1+(ref-nei)**2), axis=(0,1))
18
-
18
+
19
19
  def energy_(glcm, ref, nei):
20
20
  return np.sqrt(np.sum(glcm**2, axis=(0,1)))
21
21
 
@@ -29,11 +29,11 @@ def entropy_(glcm, ref, nei):
29
29
  def correlation_(glcm, ref, nei):
30
30
  diffy = ref - np.sum(glcm * ref, axis=(0,1))
31
31
  diffx = nei - np.sum(glcm * nei, axis=(0,1))
32
-
32
+
33
33
  stdy = np.sqrt(np.sum(glcm*diffy**2, axis=(0,1)))
34
34
  stdx = np.sqrt(np.sum(glcm*diffx**2, axis=(0,1)))
35
35
  cov = np.sum(glcm*diffx*diffy, axis=(0,1))
36
-
36
+
37
37
  out = np.empty(glcm.shape[2:], dtype=np.float32)
38
38
  mask_0 = np.logical_or(stdx<1e-15, stdy<1e-15)
39
39
  mask_1 = ~mask_0
@@ -73,7 +73,7 @@ propdict = {"contrast": contrast_,
73
73
  def glcm_props_(data, distances, angles, levels, radius, properties):
74
74
  outshape = (len(distances), len(angles)) + \
75
75
  (data.shape[0]-2*radius, data.shape[1]-2*radius)
76
-
76
+
77
77
  propout = DataDict()
78
78
  for prop in properties:
79
79
  if isinstance(prop, str):
@@ -82,13 +82,13 @@ def glcm_props_(data, distances, angles, levels, radius, properties):
82
82
  propout[prop.__name__] = np.empty(outshape, dtype=np.float32)
83
83
  # placeholder
84
84
  glcm = np.empty((levels, levels, len(distances), len(angles)), dtype=np.float32)
85
-
85
+
86
86
  ref, nei = np.indices((levels, levels), dtype=np.float32)
87
87
  ref = ref[:, :, np.newaxis, np.newaxis]
88
88
  nei = nei[:, :, np.newaxis, np.newaxis]
89
-
89
+
90
90
  from ._process_numba import _calc_glcm
91
-
91
+
92
92
  for x in range(outshape[3]):
93
93
  for y in range(outshape[2]):
94
94
  # calc glcm
@@ -101,7 +101,7 @@ def glcm_props_(data, distances, angles, levels, radius, properties):
101
101
  else:
102
102
  # only callable
103
103
  propout[prop.__name__][:,:,y,x] = prop(glcm, ref, nei)
104
-
104
+
105
105
  return propout
106
106
 
107
107
  def check_glcm(self, bins, rescale_max):
@@ -112,22 +112,22 @@ def check_glcm(self, bins, rescale_max):
112
112
  bins = 256
113
113
  elif bins > 256:
114
114
  raise ValueError("`bins` must be smaller than 256.")
115
-
115
+
116
116
  if self.dtype == np.uint16:
117
117
  self = self.as_uint8()
118
118
  elif self.dtype == np.uint8:
119
119
  pass
120
120
  else:
121
121
  raise TypeError(f"Cannot calculate comatrix of {self.dtype} image.")
122
-
122
+
123
123
  imax = np.iinfo(self.dtype).max
124
-
124
+
125
125
  if rescale_max:
126
126
  scale = int(imax/self.max())
127
127
  self *= scale
128
-
128
+
129
129
  if (imax+1) % bins != 0 or bins > imax+1:
130
130
  raise ValueError(f"`bins` must be a divisor of {imax+1} (max value of {self.dtype}).")
131
131
  self = self // ((imax+1) // bins)
132
-
133
- return self, bins, rescale_max
132
+
133
+ return self, bins, rescale_max
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
  import numpy as np
3
- from ...array_api import xp
3
+ from impy.array_api import xp
4
4
 
5
5
  def adjust_bin(
6
6
  img: np.ndarray,
@@ -44,12 +44,12 @@ def make_rotated_axis(src, dst):
44
44
  def make_pad(pad_width, dims, all_axes, **kwargs):
45
45
  """More flexible padding than `np.pad`."""
46
46
  pad_width_ = []
47
-
47
+
48
48
  # for consistency with scipy-format
49
49
  if "cval" in kwargs.keys():
50
50
  kwargs["constant_values"] = kwargs["cval"]
51
51
  kwargs.pop("cval")
52
-
52
+
53
53
  if hasattr(pad_width, "__iter__") and len(pad_width) == len(dims):
54
54
  pad_iter = iter(pad_width)
55
55
  for a in all_axes:
@@ -57,7 +57,7 @@ def make_pad(pad_width, dims, all_axes, **kwargs):
57
57
  pad_width_.append(next(pad_iter))
58
58
  else:
59
59
  pad_width_.append((0, 0))
60
-
60
+
61
61
  elif isinstance(pad_width, int):
62
62
  for a in all_axes:
63
63
  if a in dims:
@@ -66,7 +66,7 @@ def make_pad(pad_width, dims, all_axes, **kwargs):
66
66
  pad_width_.append((0, 0))
67
67
  else:
68
68
  raise TypeError(f"pad_width must be iterable or int, but got {type(pad_width)}")
69
-
69
+
70
70
  return pad_width_
71
71
 
72
72
  def dft(img: xp.ndarray, exps: list[xp.ndarray] = None):
@@ -1,5 +1,5 @@
1
1
  import numpy as np
2
- from ...array_api import xp
2
+ from impy.array_api import xp
3
3
 
4
4
  def circle(radius, shape, dtype="bool"):
5
5
  x = xp.arange(-(shape[0] - 1) / 2, (shape[0] - 1) / 2 + 1)
@@ -10,7 +10,7 @@ def circle(radius, shape, dtype="bool"):
10
10
  def ball_like(radius, ndim:int):
11
11
  half_int = int(2*radius)/2
12
12
  L = xp.arange(-half_int, half_int + 1)
13
-
13
+
14
14
  if ndim == 1:
15
15
  return xp.ones(int(radius)*2+1, dtype=np.uint8)
16
16
  elif ndim == 2:
@@ -32,9 +32,9 @@ def ball_like_odd(radius, ndim):
32
32
  [1, 1, 1, 1],
33
33
  [0, 1, 1, 0]]
34
34
  This is not suitable for specify().
35
- """
35
+ """
36
36
  xc = int(radius)
37
37
  l = xc*2 + 1
38
38
  coords = xp.indices((l,)*ndim)
39
39
  s = xp.sum((a-xc)**2 for a in coords)
40
- return xp.array(s <= radius*radius, dtype=bool)
40
+ return xp.array(s <= radius*radius, dtype=bool)