cellprofiler-library-nightly 5.0.0.dev416__tar.gz → 5.0.0.dev462__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 (82) hide show
  1. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/PKG-INFO +1 -1
  2. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/_version.py +3 -3
  3. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/functions/image_processing.py +156 -4
  4. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/functions/object_processing.py +520 -26
  5. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/__init__.py +3 -0
  6. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/modules/_identifyprimaryobjects.py +223 -0
  7. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/modules/_identifysecondaryobjects.py +264 -0
  8. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/modules/_identifytertiaryobjects.py +66 -0
  9. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/modules/_imagemath.py +64 -0
  10. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_threshold.py +1 -2
  11. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/opts/identifyprimaryobjects.py +22 -0
  12. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/opts/identifysecondaryobjects.py +8 -0
  13. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/opts/identifytertiaryobjects.py +5 -0
  14. cellprofiler_library_nightly-5.0.0.dev462/cellprofiler_library/opts/imagemath.py +30 -0
  15. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library_nightly.egg-info/PKG-INFO +1 -1
  16. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library_nightly.egg-info/SOURCES.txt +8 -0
  17. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/LICENSE +0 -0
  18. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/README.md +0 -0
  19. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/__init__.py +0 -0
  20. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/functions/__init__.py +0 -0
  21. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/functions/file_processing.py +0 -0
  22. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/functions/measurement.py +0 -0
  23. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/functions/segmentation.py +0 -0
  24. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_closing.py +0 -0
  25. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_colortogray.py +0 -0
  26. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_combineobjects.py +0 -0
  27. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_convertimagetoobjects.py +0 -0
  28. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_convertobjectstoimage.py +0 -0
  29. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_correctilluminationapply.py +0 -0
  30. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_crop.py +0 -0
  31. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_dilateimage.py +0 -0
  32. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_dilateobjects.py +0 -0
  33. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_enhanceedges.py +0 -0
  34. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_enhanceorsuppressfeatures.py +0 -0
  35. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_erodeimage.py +0 -0
  36. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_erodeobjects.py +0 -0
  37. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_expandorshrinkobjects.py +0 -0
  38. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_fillobjects.py +0 -0
  39. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_gaussianfilter.py +0 -0
  40. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_measureimageoverlap.py +0 -0
  41. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_measureobjectsizeshape.py +0 -0
  42. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_medialaxis.py +0 -0
  43. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_medianfilter.py +0 -0
  44. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_morph.py +0 -0
  45. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_morphologicalskeleton.py +0 -0
  46. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_opening.py +0 -0
  47. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_overlayobjects.py +0 -0
  48. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_overlayoutlines.py +0 -0
  49. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_reducenoise.py +0 -0
  50. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_removeholes.py +0 -0
  51. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_resize.py +0 -0
  52. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_savecroppedobjects.py +0 -0
  53. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_shrinktoobjectcenters.py +0 -0
  54. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/modules/_watershed.py +0 -0
  55. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/__init__.py +0 -0
  56. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/colortogray.py +0 -0
  57. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/convertimagetoobjects.py +0 -0
  58. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/convertobjectstoimage.py +0 -0
  59. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/correctilluminationapply.py +0 -0
  60. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/crop.py +0 -0
  61. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/dilateimage.py +0 -0
  62. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/dilateobjects.py +0 -0
  63. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/enhanceorsuppressfeatures.py +0 -0
  64. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/erodeimage.py +0 -0
  65. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/erodeobjects.py +0 -0
  66. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/measureimageoverlap.py +0 -0
  67. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/morph.py +0 -0
  68. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/objectsizeshapefeatures.py +0 -0
  69. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/overlayoutlines.py +0 -0
  70. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/removeholes.py +0 -0
  71. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/resize.py +0 -0
  72. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/shrinktoobjectcenters.py +0 -0
  73. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/structuring_elements.py +0 -0
  74. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/opts/threshold.py +0 -0
  75. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/py.typed +0 -0
  76. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library/types.py +0 -0
  77. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library_nightly.egg-info/dependency_links.txt +0 -0
  78. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library_nightly.egg-info/requires.txt +0 -0
  79. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/cellprofiler_library_nightly.egg-info/top_level.txt +0 -0
  80. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/environment.yml +0 -0
  81. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/pyproject.toml +0 -0
  82. {cellprofiler_library_nightly-5.0.0.dev416 → cellprofiler_library_nightly-5.0.0.dev462}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cellprofiler-library-nightly
3
- Version: 5.0.0.dev416
3
+ Version: 5.0.0.dev462
4
4
  Summary: cellprofiler-library implements CellProfiler's image processing and mathematical code, and is usable as a standalone library
5
5
  Author: Anne Carpenter, Thouis (Ray) Jones, Lee Kamentsky, Vebjorn Ljosa, David Logan, Mark Bray, Madison Swain-Bowden, Allen Goodman, Claire McQuinn, Alice Lucas, Callum Tromans-Coia
6
6
  Author-email: Beth Cimini <bcimini@broadinstitute.org>, David Stirling <dstirling@glencoesoftware.com>, Nodar Gogoberidze <ngogober@broadinstitute.org>
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '5.0.0.dev416'
32
- __version_tuple__ = version_tuple = (5, 0, 0, 'dev416')
31
+ __version__ = version = '5.0.0.dev462'
32
+ __version_tuple__ = version_tuple = (5, 0, 0, 'dev462')
33
33
 
34
- __commit_id__ = commit_id = 'g16aa642b5'
34
+ __commit_id__ = commit_id = 'g8dcb1b2d8'
@@ -1,8 +1,10 @@
1
1
  import numpy
2
+ from numpy import isscalar as _isscalar
2
3
  import skimage.color
3
4
  import skimage.morphology
4
5
  import skimage.segmentation
5
6
  import skimage.util
7
+ from skimage.util import invert as _invert
6
8
  import skimage.transform
7
9
  import skimage
8
10
  import skimage.restoration
@@ -13,16 +15,20 @@ import scipy
13
15
  import scipy.interpolate
14
16
  import matplotlib
15
17
  import math
18
+ from typing import Any, Optional, Tuple, Callable, Union, List, cast, Dict, TypeVar
16
19
  from numpy.typing import NDArray
17
- import centrosome.filter
18
- from typing import Any, Optional, Tuple, Callable, Union, List, TypeVar
19
20
  from cellprofiler_library.types import ImageGrayscale, ImageGrayscaleMask, Image2DColor, Image2DGrayscale, ImageAny, ImageAnyMask, ObjectSegmentation, Image2D, Image2DMask, StructuringElement, ObjectLabelSet, ImageColor, ImageBinaryMask
20
21
  from cellprofiler_library.opts import threshold as Threshold
21
22
  from cellprofiler_library.opts.enhanceorsuppressfeatures import SpeckleAccuracy, NeuriteMethod
22
23
  from cellprofiler_library.opts.overlayoutlines import BrightnessMode
23
24
  from cellprofiler_library.opts.crop import RemovalMethod
24
25
  from cellprofiler_library.opts.structuring_elements import StructuringElementShape2D, StructuringElementShape3D
25
- from ..opts.resize import ResizingMethod, DimensionMethod, InterpolationMethod
26
+ from cellprofiler_library.opts.resize import ResizingMethod, DimensionMethod, InterpolationMethod
27
+ from cellprofiler_library.opts.imagemath import Operator
28
+
29
+ # TODO: python_latest - remove this if later skimage versions update types
30
+ invert = cast(Callable[[ImageAny], ImageAny], _invert)
31
+ isscalar = cast(Callable[[Optional[ImageAny]], bool], _isscalar)
26
32
 
27
33
  T = TypeVar("T", bound=ImageAny)
28
34
  MorphImageT = TypeVar("Union[ImageGrayscale, ImageGrayscaleMask]", bound=Union[ImageGrayscale, ImageGrayscaleMask])
@@ -382,7 +388,7 @@ def get_threshold_robust_background(
382
388
  upper_outlier_fraction: float = 0.05,
383
389
  averaging_method: Threshold.AveragingMethod = Threshold.AveragingMethod.MEAN,
384
390
  variance_method: Threshold.VarianceMethod = Threshold.VarianceMethod.STANDARD_DEVIATION,
385
- number_of_deviations: int = 2,
391
+ number_of_deviations: float = 2.0,
386
392
  ) -> float:
387
393
  """Calculate threshold based on mean & standard deviation.
388
394
  The threshold is calculated by trimming the top and bottom 5% of
@@ -1702,3 +1708,149 @@ def fill_holes(image: ImageAny, diameter: float) -> ImageAny:
1702
1708
  size = numpy.pi * factor
1703
1709
 
1704
1710
  return skimage.morphology.remove_small_holes(image, size)
1711
+
1712
+ ################################################################################
1713
+ # ImageMath
1714
+ ################################################################################
1715
+
1716
+ def imagemath_apply_on_image(
1717
+ output_pixel_data: ImageAny,
1718
+ pd: ImageAny,
1719
+ comparitor: ImageAny,
1720
+ op: Callable[[ImageAny, ImageAny], ImageAny],
1721
+ opval: Operator,
1722
+ ) -> ImageAny:
1723
+ assert isinstance(output_pixel_data, numpy.ndarray), "output_pixel_data must be a numpy array" # Pylance needs to understand this is a numpy array
1724
+ if not isscalar(pd) and output_pixel_data.ndim != pd.ndim:
1725
+ if output_pixel_data.ndim == 2:
1726
+ output_pixel_data = output_pixel_data[:, :, numpy.newaxis]
1727
+ if opval == Operator.EQUALS and not isscalar(comparitor):
1728
+ comparitor = comparitor[:, :, numpy.newaxis]
1729
+ if pd.ndim == 2:
1730
+ pd = pd[:, :, numpy.newaxis]
1731
+ if opval == Operator.EQUALS:
1732
+ output_pixel_data = output_pixel_data & (comparitor == pd)
1733
+ else:
1734
+ output_pixel_data = op(output_pixel_data, pd)
1735
+ return output_pixel_data
1736
+
1737
+
1738
+
1739
+ def imagemath_apply_binary_operation(
1740
+ opval: Operator,
1741
+ operands: List[Union[ImageAny, float]],
1742
+ masks: Optional[List[Optional[Union[ImageAnyMask, bool]]]],
1743
+ output_pixel_data: ImageAny,
1744
+ output_mask: Optional[ImageAnyMask],
1745
+ image_factors: Optional[List[float]], # TODO: can this be removed?
1746
+ ignore_mask: bool, # TODO: can this be removed?
1747
+ ) -> Tuple[
1748
+ ImageAny,
1749
+ Optional[ImageAnyMask],
1750
+ ]:
1751
+ #
1752
+ # Helper function to determine if logical operations should be used
1753
+ #
1754
+ def use_logical_operation(pixel_data: List[ImageAny]) -> bool:
1755
+ return all(
1756
+ [pd.dtype == bool for pd in pixel_data if not isscalar(pd)]
1757
+ )
1758
+
1759
+ #
1760
+ # Helper function for logical subtraction
1761
+ #
1762
+
1763
+ def logical_subtract(output_pixel_data: ImageAny, pd: ImageAny) -> ImageAny:
1764
+ output_pixel_data[pd] = False
1765
+ return output_pixel_data
1766
+
1767
+ comparitor = operands[0] # fix pylance error
1768
+ use_logical = use_logical_operation(operands)
1769
+ op_fn_dispatch: Dict[Operator, Callable[[ImageAny, ImageAny], ImageAny]] = {
1770
+ Operator.ADD: numpy.add,
1771
+ Operator.SUBTRACT: logical_subtract if use_logical else numpy.subtract,
1772
+ Operator.DIFFERENCE: numpy.logical_xor if use_logical else lambda x, y: numpy.abs(numpy.subtract(x, y)),
1773
+ Operator.MULTIPLY: numpy.logical_and if use_logical else numpy.multiply,
1774
+ Operator.MINIMUM: numpy.minimum,
1775
+ Operator.MAXIMUM: numpy.maximum,
1776
+ Operator.AVERAGE: numpy.add,
1777
+ Operator.MAXIMUM: numpy.maximum,
1778
+ Operator.AND: numpy.logical_and,
1779
+ Operator.OR: numpy.logical_or,
1780
+ Operator.EQUALS: numpy.equal,
1781
+ Operator.NONE: lambda x, y: x,
1782
+ Operator.DIVIDE: numpy.divide,
1783
+ }
1784
+ if opval not in op_fn_dispatch:
1785
+ raise NotImplementedError(f"Unimplemented operation: {opval}")
1786
+ #
1787
+ # Binary operations
1788
+ #
1789
+ op = op_fn_dispatch[opval]
1790
+
1791
+ #
1792
+ # Equals and Subtract operations need additional handling
1793
+ #
1794
+ if opval == Operator.EQUALS:
1795
+ output_pixel_data = numpy.ones(operands[0].shape, bool)
1796
+ comparitor = operands[0]
1797
+ elif opval == Operator.SUBTRACT and use_logical:
1798
+ output_pixel_data = operands[0].copy()
1799
+
1800
+
1801
+ # _masks is a list of Nones if masks is None. Fixes type warnings.
1802
+ if masks is None:
1803
+ masks = [None for _ in operands]
1804
+
1805
+ #
1806
+ # Apply the operation to each image in the list
1807
+ #
1808
+ for pd, mask in zip(operands[1:], masks[1:]):
1809
+ output_pixel_data = imagemath_apply_on_image(output_pixel_data, pd, comparitor, op, opval)
1810
+ if not ignore_mask:
1811
+ if output_mask is None:
1812
+ output_mask = mask
1813
+ elif mask is not None:
1814
+ output_mask = output_mask & mask
1815
+ #
1816
+ # Average operation needs additional handling
1817
+ #
1818
+ if opval == Operator.AVERAGE:
1819
+ if not use_logical:
1820
+ assert image_factors is not None, "image_factors must be provided for average operation"
1821
+ output_pixel_data /= sum(image_factors)
1822
+ return output_pixel_data, output_mask
1823
+
1824
+
1825
+ def imagemath_apply_unary_operation(
1826
+ opval: Operator,
1827
+ operands: List[Union[ImageAny, float]],
1828
+ masks: Optional[List[Optional[Union[ImageAnyMask, bool]]]],
1829
+ output_pixel_data: ImageAny,
1830
+ output_mask: Optional[ImageAnyMask],
1831
+ ignore_mask: bool,
1832
+ ) -> Tuple[
1833
+ ImageAny,
1834
+ Optional[ImageAnyMask],
1835
+ ]:
1836
+ if opval == Operator.STDEV:
1837
+ pixel_array = numpy.array(operands)
1838
+ output_pixel_data = numpy.std(pixel_array,axis=0)
1839
+ if not ignore_mask:
1840
+ mask_array = numpy.array(masks)
1841
+ output_mask = mask_array.all(axis=0)
1842
+ elif opval == Operator.INVERT:
1843
+ output_pixel_data = invert(output_pixel_data)
1844
+ elif opval == Operator.NOT:
1845
+ output_pixel_data = numpy.logical_not(output_pixel_data)
1846
+ elif opval == Operator.LOG_TRANSFORM:
1847
+ output_pixel_data = numpy.log2(output_pixel_data + 1)
1848
+ elif opval == Operator.LOG_TRANSFORM_LEGACY:
1849
+ output_pixel_data = numpy.log2(output_pixel_data)
1850
+ elif opval == Operator.NONE:
1851
+ output_pixel_data = output_pixel_data.copy()
1852
+ else:
1853
+ raise NotImplementedError(
1854
+ "The operation %s has not been implemented" % opval
1855
+ )
1856
+ return output_pixel_data, output_mask