sigima 0.0.1.dev0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sigima/__init__.py +142 -2
- sigima/client/__init__.py +105 -0
- sigima/client/base.py +780 -0
- sigima/client/remote.py +469 -0
- sigima/client/stub.py +814 -0
- sigima/client/utils.py +90 -0
- sigima/config.py +444 -0
- sigima/data/logo/Sigima.svg +135 -0
- sigima/data/tests/annotations.json +798 -0
- sigima/data/tests/curve_fitting/exponential_fit.txt +511 -0
- sigima/data/tests/curve_fitting/gaussian_fit.txt +100 -0
- sigima/data/tests/curve_fitting/piecewiseexponential_fit.txt +1022 -0
- sigima/data/tests/curve_fitting/polynomial_fit.txt +100 -0
- sigima/data/tests/curve_fitting/twohalfgaussian_fit.txt +1000 -0
- sigima/data/tests/curve_formats/bandwidth.txt +201 -0
- sigima/data/tests/curve_formats/boxcar.npy +0 -0
- sigima/data/tests/curve_formats/datetime.txt +1001 -0
- sigima/data/tests/curve_formats/dynamic_parameters.txt +4000 -0
- sigima/data/tests/curve_formats/fw1e2.txt +301 -0
- sigima/data/tests/curve_formats/fwhm.txt +319 -0
- sigima/data/tests/curve_formats/multiple_curves.csv +29 -0
- sigima/data/tests/curve_formats/noised_saw.mat +0 -0
- sigima/data/tests/curve_formats/oscilloscope.csv +111 -0
- sigima/data/tests/curve_formats/other/other2/recursive2.txt +5 -0
- sigima/data/tests/curve_formats/other/recursive1.txt +5 -0
- sigima/data/tests/curve_formats/paracetamol.npy +0 -0
- sigima/data/tests/curve_formats/paracetamol.txt +1010 -0
- sigima/data/tests/curve_formats/paracetamol_dx_dy.csv +1000 -0
- sigima/data/tests/curve_formats/paracetamol_dy.csv +1001 -0
- sigima/data/tests/curve_formats/pulse1.npy +0 -0
- sigima/data/tests/curve_formats/pulse2.npy +0 -0
- sigima/data/tests/curve_formats/simple.txt +5 -0
- sigima/data/tests/curve_formats/spectrum.mca +2139 -0
- sigima/data/tests/curve_formats/square2.npy +0 -0
- sigima/data/tests/curve_formats/step.npy +0 -0
- sigima/data/tests/fabry-perot1.jpg +0 -0
- sigima/data/tests/fabry-perot2.jpg +0 -0
- sigima/data/tests/flower.npy +0 -0
- sigima/data/tests/image_formats/NF 180338201.scor-data +11003 -0
- sigima/data/tests/image_formats/binary_image.npy +0 -0
- sigima/data/tests/image_formats/binary_image.png +0 -0
- sigima/data/tests/image_formats/centroid_test.npy +0 -0
- sigima/data/tests/image_formats/coordinated_text/complex_image.txt +10011 -0
- sigima/data/tests/image_formats/coordinated_text/complex_ref_image.txt +10010 -0
- sigima/data/tests/image_formats/coordinated_text/image.txt +15 -0
- sigima/data/tests/image_formats/coordinated_text/image2.txt +14 -0
- sigima/data/tests/image_formats/coordinated_text/image_no_unit_no_label.txt +14 -0
- sigima/data/tests/image_formats/coordinated_text/image_with_nan.txt +15 -0
- sigima/data/tests/image_formats/coordinated_text/image_with_unit.txt +14 -0
- sigima/data/tests/image_formats/fiber.csv +480 -0
- sigima/data/tests/image_formats/fiber.jpg +0 -0
- sigima/data/tests/image_formats/fiber.png +0 -0
- sigima/data/tests/image_formats/fiber.txt +480 -0
- sigima/data/tests/image_formats/gaussian_spot_with_noise.npy +0 -0
- sigima/data/tests/image_formats/mr-brain.dcm +0 -0
- sigima/data/tests/image_formats/noised_gaussian.mat +0 -0
- sigima/data/tests/image_formats/sif_reader/nd_lum_image_no_glue.sif +0 -0
- sigima/data/tests/image_formats/sif_reader/raman1.sif +0 -0
- sigima/data/tests/image_formats/tiling.txt +10 -0
- sigima/data/tests/image_formats/uint16.tiff +0 -0
- sigima/data/tests/image_formats/uint8.tiff +0 -0
- sigima/data/tests/laser_beam/TEM00_z_13.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_18.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_23.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_30.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_35.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_40.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_45.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_50.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_55.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_60.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_65.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_70.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_75.jpg +0 -0
- sigima/data/tests/laser_beam/TEM00_z_80.jpg +0 -0
- sigima/enums.py +195 -0
- sigima/io/__init__.py +123 -0
- sigima/io/base.py +311 -0
- sigima/io/common/__init__.py +5 -0
- sigima/io/common/basename.py +164 -0
- sigima/io/common/converters.py +189 -0
- sigima/io/common/objmeta.py +181 -0
- sigima/io/common/textreader.py +58 -0
- sigima/io/convenience.py +157 -0
- sigima/io/enums.py +17 -0
- sigima/io/ftlab.py +395 -0
- sigima/io/image/__init__.py +9 -0
- sigima/io/image/base.py +177 -0
- sigima/io/image/formats.py +1016 -0
- sigima/io/image/funcs.py +414 -0
- sigima/io/signal/__init__.py +9 -0
- sigima/io/signal/base.py +129 -0
- sigima/io/signal/formats.py +290 -0
- sigima/io/signal/funcs.py +723 -0
- sigima/objects/__init__.py +260 -0
- sigima/objects/base.py +937 -0
- sigima/objects/image/__init__.py +88 -0
- sigima/objects/image/creation.py +556 -0
- sigima/objects/image/object.py +524 -0
- sigima/objects/image/roi.py +904 -0
- sigima/objects/scalar/__init__.py +57 -0
- sigima/objects/scalar/common.py +215 -0
- sigima/objects/scalar/geometry.py +502 -0
- sigima/objects/scalar/table.py +784 -0
- sigima/objects/shape.py +290 -0
- sigima/objects/signal/__init__.py +133 -0
- sigima/objects/signal/constants.py +27 -0
- sigima/objects/signal/creation.py +1428 -0
- sigima/objects/signal/object.py +444 -0
- sigima/objects/signal/roi.py +274 -0
- sigima/params.py +405 -0
- sigima/proc/__init__.py +96 -0
- sigima/proc/base.py +381 -0
- sigima/proc/decorator.py +330 -0
- sigima/proc/image/__init__.py +513 -0
- sigima/proc/image/arithmetic.py +335 -0
- sigima/proc/image/base.py +260 -0
- sigima/proc/image/detection.py +519 -0
- sigima/proc/image/edges.py +329 -0
- sigima/proc/image/exposure.py +406 -0
- sigima/proc/image/extraction.py +458 -0
- sigima/proc/image/filtering.py +219 -0
- sigima/proc/image/fourier.py +147 -0
- sigima/proc/image/geometry.py +661 -0
- sigima/proc/image/mathops.py +340 -0
- sigima/proc/image/measurement.py +195 -0
- sigima/proc/image/morphology.py +155 -0
- sigima/proc/image/noise.py +107 -0
- sigima/proc/image/preprocessing.py +182 -0
- sigima/proc/image/restoration.py +235 -0
- sigima/proc/image/threshold.py +217 -0
- sigima/proc/image/transformations.py +393 -0
- sigima/proc/signal/__init__.py +376 -0
- sigima/proc/signal/analysis.py +206 -0
- sigima/proc/signal/arithmetic.py +551 -0
- sigima/proc/signal/base.py +262 -0
- sigima/proc/signal/extraction.py +60 -0
- sigima/proc/signal/features.py +310 -0
- sigima/proc/signal/filtering.py +484 -0
- sigima/proc/signal/fitting.py +276 -0
- sigima/proc/signal/fourier.py +259 -0
- sigima/proc/signal/mathops.py +420 -0
- sigima/proc/signal/processing.py +580 -0
- sigima/proc/signal/stability.py +175 -0
- sigima/proc/title_formatting.py +227 -0
- sigima/proc/validation.py +272 -0
- sigima/tests/__init__.py +7 -0
- sigima/tests/common/__init__.py +0 -0
- sigima/tests/common/arithmeticparam_unit_test.py +26 -0
- sigima/tests/common/basename_unit_test.py +126 -0
- sigima/tests/common/client_unit_test.py +412 -0
- sigima/tests/common/converters_unit_test.py +77 -0
- sigima/tests/common/decorator_unit_test.py +176 -0
- sigima/tests/common/examples_unit_test.py +104 -0
- sigima/tests/common/kernel_normalization_unit_test.py +242 -0
- sigima/tests/common/roi_basic_unit_test.py +73 -0
- sigima/tests/common/roi_geometry_unit_test.py +171 -0
- sigima/tests/common/scalar_builder_unit_test.py +142 -0
- sigima/tests/common/scalar_unit_test.py +991 -0
- sigima/tests/common/shape_unit_test.py +183 -0
- sigima/tests/common/stat_unit_test.py +138 -0
- sigima/tests/common/title_formatting_unit_test.py +338 -0
- sigima/tests/common/tools_coordinates_unit_test.py +60 -0
- sigima/tests/common/transformations_unit_test.py +178 -0
- sigima/tests/common/validation_unit_test.py +205 -0
- sigima/tests/conftest.py +129 -0
- sigima/tests/data.py +998 -0
- sigima/tests/env.py +280 -0
- sigima/tests/guiutils.py +163 -0
- sigima/tests/helpers.py +532 -0
- sigima/tests/image/__init__.py +28 -0
- sigima/tests/image/binning_unit_test.py +128 -0
- sigima/tests/image/blob_detection_unit_test.py +312 -0
- sigima/tests/image/centroid_unit_test.py +170 -0
- sigima/tests/image/check_2d_array_unit_test.py +63 -0
- sigima/tests/image/contour_unit_test.py +172 -0
- sigima/tests/image/convolution_unit_test.py +178 -0
- sigima/tests/image/datatype_unit_test.py +67 -0
- sigima/tests/image/edges_unit_test.py +155 -0
- sigima/tests/image/enclosingcircle_unit_test.py +88 -0
- sigima/tests/image/exposure_unit_test.py +223 -0
- sigima/tests/image/fft2d_unit_test.py +189 -0
- sigima/tests/image/filtering_unit_test.py +166 -0
- sigima/tests/image/geometry_unit_test.py +654 -0
- sigima/tests/image/hough_circle_unit_test.py +147 -0
- sigima/tests/image/imageobj_unit_test.py +737 -0
- sigima/tests/image/morphology_unit_test.py +71 -0
- sigima/tests/image/noise_unit_test.py +57 -0
- sigima/tests/image/offset_correction_unit_test.py +72 -0
- sigima/tests/image/operation_unit_test.py +518 -0
- sigima/tests/image/peak2d_limits_unit_test.py +41 -0
- sigima/tests/image/peak2d_unit_test.py +133 -0
- sigima/tests/image/profile_unit_test.py +159 -0
- sigima/tests/image/projections_unit_test.py +121 -0
- sigima/tests/image/restoration_unit_test.py +141 -0
- sigima/tests/image/roi2dparam_unit_test.py +53 -0
- sigima/tests/image/roi_advanced_unit_test.py +588 -0
- sigima/tests/image/roi_grid_unit_test.py +279 -0
- sigima/tests/image/spectrum2d_unit_test.py +40 -0
- sigima/tests/image/threshold_unit_test.py +91 -0
- sigima/tests/io/__init__.py +0 -0
- sigima/tests/io/addnewformat_unit_test.py +125 -0
- sigima/tests/io/convenience_funcs_unit_test.py +470 -0
- sigima/tests/io/coordinated_text_format_unit_test.py +495 -0
- sigima/tests/io/datetime_csv_unit_test.py +198 -0
- sigima/tests/io/imageio_formats_test.py +41 -0
- sigima/tests/io/ioregistry_unit_test.py +69 -0
- sigima/tests/io/objmeta_unit_test.py +87 -0
- sigima/tests/io/readobj_unit_test.py +130 -0
- sigima/tests/io/readwriteobj_unit_test.py +67 -0
- sigima/tests/signal/__init__.py +0 -0
- sigima/tests/signal/analysis_unit_test.py +135 -0
- sigima/tests/signal/check_1d_arrays_unit_test.py +169 -0
- sigima/tests/signal/convolution_unit_test.py +404 -0
- sigima/tests/signal/datetime_unit_test.py +176 -0
- sigima/tests/signal/fft1d_unit_test.py +303 -0
- sigima/tests/signal/filters_unit_test.py +403 -0
- sigima/tests/signal/fitting_unit_test.py +929 -0
- sigima/tests/signal/fwhm_unit_test.py +111 -0
- sigima/tests/signal/noise_unit_test.py +128 -0
- sigima/tests/signal/offset_correction_unit_test.py +34 -0
- sigima/tests/signal/operation_unit_test.py +489 -0
- sigima/tests/signal/peakdetection_unit_test.py +145 -0
- sigima/tests/signal/processing_unit_test.py +657 -0
- sigima/tests/signal/pulse/__init__.py +112 -0
- sigima/tests/signal/pulse/crossing_times_unit_test.py +123 -0
- sigima/tests/signal/pulse/plateau_detection_unit_test.py +102 -0
- sigima/tests/signal/pulse/pulse_unit_test.py +1824 -0
- sigima/tests/signal/roi_advanced_unit_test.py +392 -0
- sigima/tests/signal/signalobj_unit_test.py +603 -0
- sigima/tests/signal/stability_unit_test.py +431 -0
- sigima/tests/signal/uncertainty_unit_test.py +611 -0
- sigima/tests/vistools.py +1030 -0
- sigima/tools/__init__.py +59 -0
- sigima/tools/checks.py +290 -0
- sigima/tools/coordinates.py +308 -0
- sigima/tools/datatypes.py +26 -0
- sigima/tools/image/__init__.py +97 -0
- sigima/tools/image/detection.py +451 -0
- sigima/tools/image/exposure.py +77 -0
- sigima/tools/image/extraction.py +48 -0
- sigima/tools/image/fourier.py +260 -0
- sigima/tools/image/geometry.py +190 -0
- sigima/tools/image/preprocessing.py +165 -0
- sigima/tools/signal/__init__.py +86 -0
- sigima/tools/signal/dynamic.py +254 -0
- sigima/tools/signal/features.py +135 -0
- sigima/tools/signal/filtering.py +171 -0
- sigima/tools/signal/fitting.py +1171 -0
- sigima/tools/signal/fourier.py +466 -0
- sigima/tools/signal/interpolation.py +70 -0
- sigima/tools/signal/peakdetection.py +126 -0
- sigima/tools/signal/pulse.py +1626 -0
- sigima/tools/signal/scaling.py +50 -0
- sigima/tools/signal/stability.py +258 -0
- sigima/tools/signal/windowing.py +90 -0
- sigima/worker.py +79 -0
- sigima-1.0.0.dist-info/METADATA +233 -0
- sigima-1.0.0.dist-info/RECORD +262 -0
- {sigima-0.0.1.dev0.dist-info → sigima-1.0.0.dist-info}/licenses/LICENSE +29 -29
- sigima-0.0.1.dev0.dist-info/METADATA +0 -60
- sigima-0.0.1.dev0.dist-info/RECORD +0 -6
- {sigima-0.0.1.dev0.dist-info → sigima-1.0.0.dist-info}/WHEEL +0 -0
- {sigima-0.0.1.dev0.dist-info → sigima-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Exposure computation module
|
|
5
|
+
---------------------------
|
|
6
|
+
|
|
7
|
+
This module provides tools for adjusting and analyzing image exposure and contrast.
|
|
8
|
+
|
|
9
|
+
Main features include:
|
|
10
|
+
|
|
11
|
+
- Histogram computation and equalization
|
|
12
|
+
- Contrast adjustment and normalization
|
|
13
|
+
- Logarithmic and gamma correction
|
|
14
|
+
|
|
15
|
+
Exposure processing improves the visual quality and interpretability of images,
|
|
16
|
+
especially under variable lighting conditions.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
20
|
+
|
|
21
|
+
# Note:
|
|
22
|
+
# ----
|
|
23
|
+
# - All `guidata.dataset.DataSet` parameter classes must also be imported
|
|
24
|
+
# in the `sigima.params` module.
|
|
25
|
+
# - All functions decorated by `computation_function` must be imported in the upper
|
|
26
|
+
# level `sigima.proc.image` module.
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import guidata.dataset as gds
|
|
31
|
+
import numpy as np
|
|
32
|
+
from skimage import exposure
|
|
33
|
+
|
|
34
|
+
import sigima.enums
|
|
35
|
+
import sigima.tools.image
|
|
36
|
+
from sigima.config import _
|
|
37
|
+
from sigima.objects.base import BaseProcParam
|
|
38
|
+
from sigima.objects.image import ImageObj, ROI2DParam
|
|
39
|
+
from sigima.objects.signal import SignalObj
|
|
40
|
+
from sigima.proc.base import (
|
|
41
|
+
ClipParam,
|
|
42
|
+
HistogramParam,
|
|
43
|
+
NormalizeParam,
|
|
44
|
+
dst_1_to_1,
|
|
45
|
+
dst_2_to_1,
|
|
46
|
+
new_signal_result,
|
|
47
|
+
)
|
|
48
|
+
from sigima.proc.decorator import computation_function
|
|
49
|
+
from sigima.proc.image.base import Wrap1to1Func, restore_data_outside_roi
|
|
50
|
+
|
|
51
|
+
# NOTE: Only parameter classes DEFINED in this module should be included in __all__.
|
|
52
|
+
# Parameter classes imported from other modules (like sigima.proc.base) should NOT
|
|
53
|
+
# be re-exported to avoid Sphinx cross-reference conflicts. The sigima.params module
|
|
54
|
+
# serves as the central API point that imports and re-exports all parameter classes.
|
|
55
|
+
__all__ = [
|
|
56
|
+
"AdjustGammaParam",
|
|
57
|
+
"AdjustLogParam",
|
|
58
|
+
"AdjustSigmoidParam",
|
|
59
|
+
"EqualizeAdaptHistParam",
|
|
60
|
+
"EqualizeHistParam",
|
|
61
|
+
"FlatFieldParam",
|
|
62
|
+
"RescaleIntensityParam",
|
|
63
|
+
"adjust_gamma",
|
|
64
|
+
"adjust_log",
|
|
65
|
+
"adjust_sigmoid",
|
|
66
|
+
"clip",
|
|
67
|
+
"equalize_adapthist",
|
|
68
|
+
"equalize_hist",
|
|
69
|
+
"flatfield",
|
|
70
|
+
"histogram",
|
|
71
|
+
"normalize",
|
|
72
|
+
"offset_correction",
|
|
73
|
+
"rescale_intensity",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class AdjustGammaParam(gds.DataSet):
|
|
78
|
+
"""Gamma adjustment parameters"""
|
|
79
|
+
|
|
80
|
+
gamma = gds.FloatItem(
|
|
81
|
+
_("Gamma"),
|
|
82
|
+
default=1.0,
|
|
83
|
+
min=0.0,
|
|
84
|
+
help=_("Gamma correction factor (higher values give more contrast)."),
|
|
85
|
+
)
|
|
86
|
+
gain = gds.FloatItem(
|
|
87
|
+
_("Gain"),
|
|
88
|
+
default=1.0,
|
|
89
|
+
min=0.0,
|
|
90
|
+
help=_("Gain factor (higher values give more contrast)."),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@computation_function()
|
|
95
|
+
def adjust_gamma(src: ImageObj, p: AdjustGammaParam) -> ImageObj:
|
|
96
|
+
"""Gamma correction with :py:func:`skimage.exposure.adjust_gamma`
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
src: input image object
|
|
100
|
+
p: parameters
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Output image object
|
|
104
|
+
"""
|
|
105
|
+
dst = dst_1_to_1(src, "adjust_gamma", f"gamma={p.gamma}, gain={p.gain}")
|
|
106
|
+
dst.data = exposure.adjust_gamma(src.data, gamma=p.gamma, gain=p.gain)
|
|
107
|
+
restore_data_outside_roi(dst, src)
|
|
108
|
+
return dst
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class AdjustLogParam(gds.DataSet):
|
|
112
|
+
"""Logarithmic adjustment parameters"""
|
|
113
|
+
|
|
114
|
+
gain = gds.FloatItem(
|
|
115
|
+
_("Gain"),
|
|
116
|
+
default=1.0,
|
|
117
|
+
min=0.0,
|
|
118
|
+
help=_("Gain factor (higher values give more contrast)."),
|
|
119
|
+
)
|
|
120
|
+
inv = gds.BoolItem(
|
|
121
|
+
_("Inverse"),
|
|
122
|
+
default=False,
|
|
123
|
+
help=_("If True, apply inverse logarithmic transformation."),
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@computation_function()
|
|
128
|
+
def adjust_log(src: ImageObj, p: AdjustLogParam) -> ImageObj:
|
|
129
|
+
"""Compute log correction with :py:func:`skimage.exposure.adjust_log`
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
src: input image object
|
|
133
|
+
p: parameters
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Output image object
|
|
137
|
+
"""
|
|
138
|
+
dst = dst_1_to_1(src, "adjust_log", f"gain={p.gain}, inv={p.inv}")
|
|
139
|
+
dst.data = exposure.adjust_log(src.data, gain=p.gain, inv=p.inv)
|
|
140
|
+
restore_data_outside_roi(dst, src)
|
|
141
|
+
return dst
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class AdjustSigmoidParam(gds.DataSet):
|
|
145
|
+
"""Sigmoid adjustment parameters"""
|
|
146
|
+
|
|
147
|
+
cutoff = gds.FloatItem(
|
|
148
|
+
_("Cutoff"),
|
|
149
|
+
default=0.5,
|
|
150
|
+
min=0.0,
|
|
151
|
+
max=1.0,
|
|
152
|
+
help=_("Cutoff value (higher values give more contrast)."),
|
|
153
|
+
)
|
|
154
|
+
gain = gds.FloatItem(
|
|
155
|
+
_("Gain"),
|
|
156
|
+
default=10.0,
|
|
157
|
+
min=0.0,
|
|
158
|
+
help=_("Gain factor (higher values give more contrast)."),
|
|
159
|
+
)
|
|
160
|
+
inv = gds.BoolItem(
|
|
161
|
+
_("Inverse"),
|
|
162
|
+
default=False,
|
|
163
|
+
help=_("If True, apply inverse sigmoid transformation."),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@computation_function()
|
|
168
|
+
def adjust_sigmoid(src: ImageObj, p: AdjustSigmoidParam) -> ImageObj:
|
|
169
|
+
"""Compute sigmoid correction with :py:func:`skimage.exposure.adjust_sigmoid`
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
src: input image object
|
|
173
|
+
p: parameters
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
Output image object
|
|
177
|
+
"""
|
|
178
|
+
dst = dst_1_to_1(
|
|
179
|
+
src, "adjust_sigmoid", f"cutoff={p.cutoff}, gain={p.gain}, inv={p.inv}"
|
|
180
|
+
)
|
|
181
|
+
dst.data = exposure.adjust_sigmoid(
|
|
182
|
+
src.data, cutoff=p.cutoff, gain=p.gain, inv=p.inv
|
|
183
|
+
)
|
|
184
|
+
restore_data_outside_roi(dst, src)
|
|
185
|
+
return dst
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class RescaleIntensityParam(gds.DataSet):
|
|
189
|
+
"""Intensity rescaling parameters"""
|
|
190
|
+
|
|
191
|
+
_dtype_list = ["image", "dtype"] + ImageObj.get_valid_dtypenames()
|
|
192
|
+
in_range = gds.ChoiceItem(
|
|
193
|
+
_("Input range"),
|
|
194
|
+
list(zip(_dtype_list, _dtype_list)),
|
|
195
|
+
default="image",
|
|
196
|
+
help=_(
|
|
197
|
+
"Min and max intensity values of input image ('image' refers to input "
|
|
198
|
+
"image min/max levels, 'dtype' refers to input image data type range)."
|
|
199
|
+
),
|
|
200
|
+
)
|
|
201
|
+
out_range = gds.ChoiceItem(
|
|
202
|
+
_("Output range"),
|
|
203
|
+
list(zip(_dtype_list, _dtype_list)),
|
|
204
|
+
default="dtype",
|
|
205
|
+
help=_(
|
|
206
|
+
"Min and max intensity values of output image ('image' refers to input "
|
|
207
|
+
"image min/max levels, 'dtype' refers to input image data type range).."
|
|
208
|
+
),
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@computation_function()
|
|
213
|
+
def rescale_intensity(src: ImageObj, p: RescaleIntensityParam) -> ImageObj:
|
|
214
|
+
"""Rescale image intensity levels
|
|
215
|
+
with :py:func:`skimage.exposure.rescale_intensity`
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
src: input image object
|
|
219
|
+
p: parameters
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
Output image object
|
|
223
|
+
"""
|
|
224
|
+
dst = dst_1_to_1(
|
|
225
|
+
src,
|
|
226
|
+
"rescale_intensity",
|
|
227
|
+
f"in_range={p.in_range}, out_range={p.out_range}",
|
|
228
|
+
)
|
|
229
|
+
dst.data = exposure.rescale_intensity(
|
|
230
|
+
src.data, in_range=p.in_range, out_range=p.out_range
|
|
231
|
+
)
|
|
232
|
+
restore_data_outside_roi(dst, src)
|
|
233
|
+
return dst
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class EqualizeHistParam(gds.DataSet):
|
|
237
|
+
"""Histogram equalization parameters"""
|
|
238
|
+
|
|
239
|
+
nbins = gds.IntItem(
|
|
240
|
+
_("Number of bins"),
|
|
241
|
+
min=1,
|
|
242
|
+
default=256,
|
|
243
|
+
help=_("Number of bins for image histogram."),
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@computation_function()
|
|
248
|
+
def equalize_hist(src: ImageObj, p: EqualizeHistParam) -> ImageObj:
|
|
249
|
+
"""Histogram equalization with :py:func:`skimage.exposure.equalize_hist`
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
src: input image object
|
|
253
|
+
p: parameters
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
Output image object
|
|
257
|
+
"""
|
|
258
|
+
dst = dst_1_to_1(src, "equalize_hist", f"nbins={p.nbins}")
|
|
259
|
+
dst.data = exposure.equalize_hist(src.data, nbins=p.nbins)
|
|
260
|
+
restore_data_outside_roi(dst, src)
|
|
261
|
+
return dst
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class EqualizeAdaptHistParam(EqualizeHistParam):
|
|
265
|
+
"""Adaptive histogram equalization parameters"""
|
|
266
|
+
|
|
267
|
+
clip_limit = gds.FloatItem(
|
|
268
|
+
_("Clipping limit"),
|
|
269
|
+
default=0.01,
|
|
270
|
+
min=0.0,
|
|
271
|
+
max=1.0,
|
|
272
|
+
help=_("Clipping limit (higher values give more contrast)."),
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
@computation_function()
|
|
277
|
+
def equalize_adapthist(src: ImageObj, p: EqualizeAdaptHistParam) -> ImageObj:
|
|
278
|
+
"""Adaptive histogram equalization
|
|
279
|
+
with :py:func:`skimage.exposure.equalize_adapthist`
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
src: input image object
|
|
283
|
+
p: parameters
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
Output image object
|
|
287
|
+
"""
|
|
288
|
+
dst = dst_1_to_1(
|
|
289
|
+
src, "equalize_adapthist", f"nbins={p.nbins}, clip_limit={p.clip_limit}"
|
|
290
|
+
)
|
|
291
|
+
dst.data = exposure.equalize_adapthist(
|
|
292
|
+
src.data, clip_limit=p.clip_limit, nbins=p.nbins
|
|
293
|
+
)
|
|
294
|
+
restore_data_outside_roi(dst, src)
|
|
295
|
+
return dst
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class FlatFieldParam(BaseProcParam):
|
|
299
|
+
"""Flat-field parameters"""
|
|
300
|
+
|
|
301
|
+
threshold = gds.FloatItem(_("Threshold"), default=0.0)
|
|
302
|
+
|
|
303
|
+
def update_from_obj(self, obj: ImageObj) -> None:
|
|
304
|
+
"""Update parameters from image"""
|
|
305
|
+
self.set_from_datatype(obj.data.dtype)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@computation_function()
|
|
309
|
+
def flatfield(src1: ImageObj, src2: ImageObj, p: FlatFieldParam) -> ImageObj:
|
|
310
|
+
"""Compute flat field correction with :py:func:`sigima.tools.image.flatfield`
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
src1: raw data image object
|
|
314
|
+
src2: flat field image object
|
|
315
|
+
p: flat field parameters
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
Output image object
|
|
319
|
+
"""
|
|
320
|
+
dst = dst_2_to_1(src1, src2, "flatfield", f"threshold={p.threshold}")
|
|
321
|
+
dst.data = sigima.tools.image.flatfield(src1.data, src2.data, p.threshold)
|
|
322
|
+
restore_data_outside_roi(dst, src1)
|
|
323
|
+
return dst
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
# MARK: compute_1_to_1 functions -------------------------------------------------------
|
|
327
|
+
# Functions with 1 input image and 1 output image
|
|
328
|
+
# --------------------------------------------------------------------------------------
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
@computation_function()
|
|
332
|
+
def normalize(src: ImageObj, p: NormalizeParam) -> ImageObj:
|
|
333
|
+
"""
|
|
334
|
+
Normalize image data depending on its maximum,
|
|
335
|
+
with :py:func:`sigima.tools.image.normalize`
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
src: input image object
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
Output image object
|
|
342
|
+
"""
|
|
343
|
+
method: sigima.enums.NormalizationMethod = p.method
|
|
344
|
+
dst = dst_1_to_1(src, "normalize", suffix=f"ref={method.value}")
|
|
345
|
+
dst.data = sigima.tools.image.normalize(src.data, method)
|
|
346
|
+
restore_data_outside_roi(dst, src)
|
|
347
|
+
return dst
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
@computation_function()
|
|
351
|
+
def histogram(src: ImageObj, p: HistogramParam) -> SignalObj:
|
|
352
|
+
"""Compute histogram of the image data, with :py:func:`numpy.histogram`
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
src: input image object
|
|
356
|
+
p: parameters
|
|
357
|
+
|
|
358
|
+
Returns:
|
|
359
|
+
Signal object with the histogram
|
|
360
|
+
"""
|
|
361
|
+
data = src.get_masked_view().compressed()
|
|
362
|
+
suffix = p.get_suffix(data) # Also updates p.lower and p.upper
|
|
363
|
+
y, bin_edges = np.histogram(data, bins=p.bins, range=(p.lower, p.upper))
|
|
364
|
+
x = (bin_edges[:-1] + bin_edges[1:]) / 2
|
|
365
|
+
dst = new_signal_result(
|
|
366
|
+
src,
|
|
367
|
+
"histogram",
|
|
368
|
+
suffix=suffix,
|
|
369
|
+
units=(src.zunit, ""),
|
|
370
|
+
labels=(src.zlabel, _("Counts")),
|
|
371
|
+
)
|
|
372
|
+
dst.set_xydata(x, y)
|
|
373
|
+
dst.set_metadata_option("shade", 0.5)
|
|
374
|
+
dst.set_metadata_option("curvestyle", "Steps")
|
|
375
|
+
return dst
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
@computation_function()
|
|
379
|
+
def clip(src: ImageObj, p: ClipParam) -> ImageObj:
|
|
380
|
+
"""Apply clipping with :py:func:`numpy.clip`
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
src: input image object
|
|
384
|
+
p: parameters
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
Output image object
|
|
388
|
+
"""
|
|
389
|
+
return Wrap1to1Func(np.clip, a_min=p.lower, a_max=p.upper)(src)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@computation_function()
|
|
393
|
+
def offset_correction(src: ImageObj, p: ROI2DParam) -> ImageObj:
|
|
394
|
+
"""Apply offset correction
|
|
395
|
+
|
|
396
|
+
Args:
|
|
397
|
+
src: input image object
|
|
398
|
+
p: parameters
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
Output image object
|
|
402
|
+
"""
|
|
403
|
+
dst = dst_1_to_1(src, "offset_correction", p.get_suffix())
|
|
404
|
+
dst.data = src.data - np.nanmean(p.get_data(src))
|
|
405
|
+
restore_data_outside_roi(dst, src)
|
|
406
|
+
return dst
|