cellprofiler-library-nightly 5.0.0.dev462__tar.gz → 5.0.0.dev475__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.
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/PKG-INFO +1 -1
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/_version.py +3 -3
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/functions/image_processing.py +235 -21
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_enhanceedges.py +22 -20
- cellprofiler_library_nightly-5.0.0.dev475/cellprofiler_library/modules/_flipandrotate.py +89 -0
- cellprofiler_library_nightly-5.0.0.dev475/cellprofiler_library/modules/_graytocolor.py +58 -0
- cellprofiler_library_nightly-5.0.0.dev475/cellprofiler_library/opts/enhanceedges.py +14 -0
- cellprofiler_library_nightly-5.0.0.dev475/cellprofiler_library/opts/flipandrotate.py +29 -0
- cellprofiler_library_nightly-5.0.0.dev475/cellprofiler_library/opts/graytocolor.py +20 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library_nightly.egg-info/PKG-INFO +1 -1
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library_nightly.egg-info/SOURCES.txt +5 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/LICENSE +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/README.md +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/functions/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/functions/file_processing.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/functions/measurement.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/functions/object_processing.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/functions/segmentation.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_closing.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_colortogray.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_combineobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_convertimagetoobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_convertobjectstoimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_correctilluminationapply.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_crop.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_dilateimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_dilateobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_enhanceorsuppressfeatures.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_erodeimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_erodeobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_expandorshrinkobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_fillobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_gaussianfilter.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_identifyprimaryobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_identifysecondaryobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_identifytertiaryobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_imagemath.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_measureimageoverlap.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_measureobjectsizeshape.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_medialaxis.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_medianfilter.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_morph.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_morphologicalskeleton.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_opening.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_overlayobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_overlayoutlines.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_reducenoise.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_removeholes.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_resize.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_savecroppedobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_shrinktoobjectcenters.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_threshold.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/modules/_watershed.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/colortogray.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/convertimagetoobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/convertobjectstoimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/correctilluminationapply.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/crop.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/dilateimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/dilateobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/enhanceorsuppressfeatures.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/erodeimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/erodeobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/identifyprimaryobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/identifysecondaryobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/identifytertiaryobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/imagemath.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/measureimageoverlap.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/morph.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/objectsizeshapefeatures.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/overlayoutlines.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/removeholes.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/resize.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/shrinktoobjectcenters.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/structuring_elements.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/opts/threshold.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/py.typed +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library/types.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library_nightly.egg-info/dependency_links.txt +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library_nightly.egg-info/requires.txt +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/cellprofiler_library_nightly.egg-info/top_level.txt +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/environment.yml +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/pyproject.toml +0 -0
- {cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/setup.cfg +0 -0
{cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cellprofiler-library-nightly
|
|
3
|
-
Version: 5.0.0.
|
|
3
|
+
Version: 5.0.0.dev475
|
|
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.
|
|
32
|
-
__version_tuple__ = version_tuple = (5, 0, 0, '
|
|
31
|
+
__version__ = version = '5.0.0.dev475'
|
|
32
|
+
__version_tuple__ = version_tuple = (5, 0, 0, 'dev475')
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gc4686c345'
|
|
@@ -17,7 +17,7 @@ import matplotlib
|
|
|
17
17
|
import math
|
|
18
18
|
from typing import Any, Optional, Tuple, Callable, Union, List, cast, Dict, TypeVar
|
|
19
19
|
from numpy.typing import NDArray
|
|
20
|
-
from cellprofiler_library.types import ImageGrayscale, ImageGrayscaleMask, Image2DColor, Image2DGrayscale, ImageAny, ImageAnyMask, ObjectSegmentation, Image2D, Image2DMask, StructuringElement, ObjectLabelSet, ImageColor, ImageBinaryMask
|
|
20
|
+
from cellprofiler_library.types import ImageGrayscale, ImageGrayscaleMask, Image2DColor, Image2DGrayscale, Image2DGrayscaleMask, ImageAny, ImageAnyMask, ObjectSegmentation, Image2D, Image2DMask, StructuringElement, ObjectLabelSet, ImageColor, ImageBinaryMask
|
|
21
21
|
from cellprofiler_library.opts import threshold as Threshold
|
|
22
22
|
from cellprofiler_library.opts.enhanceorsuppressfeatures import SpeckleAccuracy, NeuriteMethod
|
|
23
23
|
from cellprofiler_library.opts.overlayoutlines import BrightnessMode
|
|
@@ -25,8 +25,8 @@ from cellprofiler_library.opts.crop import RemovalMethod
|
|
|
25
25
|
from cellprofiler_library.opts.structuring_elements import StructuringElementShape2D, StructuringElementShape3D
|
|
26
26
|
from cellprofiler_library.opts.resize import ResizingMethod, DimensionMethod, InterpolationMethod
|
|
27
27
|
from cellprofiler_library.opts.imagemath import Operator
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
from cellprofiler_library.opts.flipandrotate import RotationCoordinateAlignmnet
|
|
29
|
+
from cellprofiler_library.opts.enhanceedges import EdgeDirection
|
|
30
30
|
invert = cast(Callable[[ImageAny], ImageAny], _invert)
|
|
31
31
|
isscalar = cast(Callable[[Optional[ImageAny]], bool], _isscalar)
|
|
32
32
|
|
|
@@ -49,30 +49,46 @@ def medial_axis(image):
|
|
|
49
49
|
return skimage.morphology.medial_axis(image)
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
###############################################################################
|
|
53
|
+
# EnhanceEdges
|
|
54
|
+
###############################################################################
|
|
55
|
+
|
|
56
|
+
def enhance_edges_sobel(
|
|
57
|
+
image: Image2DGrayscale,
|
|
58
|
+
mask: Optional[Image2DGrayscaleMask]=None,
|
|
59
|
+
direction: EdgeDirection=EdgeDirection.ALL
|
|
60
|
+
):
|
|
61
|
+
if direction == EdgeDirection.ALL:
|
|
54
62
|
output_pixels = centrosome.filter.sobel(image, mask)
|
|
55
|
-
elif direction
|
|
63
|
+
elif direction == EdgeDirection.HORIZONTAL:
|
|
56
64
|
output_pixels = centrosome.filter.hsobel(image, mask)
|
|
57
|
-
elif direction
|
|
65
|
+
elif direction == EdgeDirection.VERTICAL:
|
|
58
66
|
output_pixels = centrosome.filter.vsobel(image, mask)
|
|
59
67
|
else:
|
|
60
68
|
raise NotImplementedError(f"Unimplemented direction for Sobel: {direction}")
|
|
61
69
|
return output_pixels
|
|
62
70
|
|
|
63
71
|
|
|
64
|
-
def enhance_edges_log(
|
|
72
|
+
def enhance_edges_log(
|
|
73
|
+
image: Image2DGrayscale,
|
|
74
|
+
mask: Optional[Image2DGrayscaleMask]=None,
|
|
75
|
+
sigma: float=2.0
|
|
76
|
+
) -> Image2DGrayscale:
|
|
65
77
|
size = int(sigma * 4) + 1
|
|
66
78
|
output_pixels = centrosome.filter.laplacian_of_gaussian(image, mask, size, sigma)
|
|
67
79
|
return output_pixels
|
|
68
80
|
|
|
69
81
|
|
|
70
|
-
def enhance_edges_prewitt(
|
|
71
|
-
|
|
82
|
+
def enhance_edges_prewitt(
|
|
83
|
+
image: Image2DGrayscale,
|
|
84
|
+
mask: Optional[Image2DGrayscaleMask]=None,
|
|
85
|
+
direction: EdgeDirection=EdgeDirection.ALL
|
|
86
|
+
) -> Image2DGrayscale:
|
|
87
|
+
if direction == EdgeDirection.ALL:
|
|
72
88
|
output_pixels = centrosome.filter.prewitt(image, mask)
|
|
73
|
-
elif direction
|
|
89
|
+
elif direction == EdgeDirection.HORIZONTAL:
|
|
74
90
|
output_pixels = centrosome.filter.hprewitt(image, mask)
|
|
75
|
-
elif direction
|
|
91
|
+
elif direction == EdgeDirection.VERTICAL:
|
|
76
92
|
output_pixels = centrosome.filter.vprewitt(image, mask)
|
|
77
93
|
else:
|
|
78
94
|
raise NotImplementedError(f"Unimplemented direction for Prewitt: {direction}")
|
|
@@ -80,15 +96,15 @@ def enhance_edges_prewitt(image, mask=None, direction="all"):
|
|
|
80
96
|
|
|
81
97
|
|
|
82
98
|
def enhance_edges_canny(
|
|
83
|
-
image,
|
|
84
|
-
mask=None,
|
|
85
|
-
auto_threshold=True,
|
|
86
|
-
auto_low_threshold=True,
|
|
87
|
-
sigma=1.0,
|
|
88
|
-
low_threshold=0.1,
|
|
89
|
-
manual_threshold=0.2,
|
|
90
|
-
threshold_adjustment_factor=1.0,
|
|
91
|
-
):
|
|
99
|
+
image: Image2DGrayscale,
|
|
100
|
+
mask: Optional[Image2DGrayscaleMask] = None,
|
|
101
|
+
auto_threshold: bool = True,
|
|
102
|
+
auto_low_threshold: bool = True,
|
|
103
|
+
sigma: float = 1.0,
|
|
104
|
+
low_threshold: float = 0.1,
|
|
105
|
+
manual_threshold: float = 0.2,
|
|
106
|
+
threshold_adjustment_factor: float = 1.0,
|
|
107
|
+
) -> Image2DGrayscale:
|
|
92
108
|
|
|
93
109
|
if auto_threshold or auto_low_threshold:
|
|
94
110
|
sobel_image = centrosome.filter.sobel(image)
|
|
@@ -104,6 +120,26 @@ def enhance_edges_canny(
|
|
|
104
120
|
output_pixels = centrosome.filter.canny(image, mask, sigma, low_th, high_th)
|
|
105
121
|
return output_pixels
|
|
106
122
|
|
|
123
|
+
def stretched_rgb_from_components(
|
|
124
|
+
r: Image2DGrayscale,
|
|
125
|
+
g: Optional[Image2DGrayscale]=None,
|
|
126
|
+
b: Optional[Image2DGrayscale]=None
|
|
127
|
+
):
|
|
128
|
+
if g:
|
|
129
|
+
assert r.shape == g.shape
|
|
130
|
+
if b:
|
|
131
|
+
assert r.shape == b.shape
|
|
132
|
+
|
|
133
|
+
color_image = numpy.zeros((r.shape[0], r.shape[1], 3))
|
|
134
|
+
color_image[:, :, 0] = centrosome.filter.stretch(r)
|
|
135
|
+
|
|
136
|
+
if g:
|
|
137
|
+
color_image[:, :, 1] = centrosome.filter.stretch(g)
|
|
138
|
+
if b:
|
|
139
|
+
color_image[:, :, 2] = centrosome.filter.stretch(b)
|
|
140
|
+
|
|
141
|
+
return color_image
|
|
142
|
+
|
|
107
143
|
|
|
108
144
|
def morphology_closing(image, structuring_element=skimage.morphology.disk(1)):
|
|
109
145
|
if structuring_element.ndim == 3 and image.ndim == 2:
|
|
@@ -1854,3 +1890,181 @@ def imagemath_apply_unary_operation(
|
|
|
1854
1890
|
"The operation %s has not been implemented" % opval
|
|
1855
1891
|
)
|
|
1856
1892
|
return output_pixel_data, output_mask
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
###############################################################################
|
|
1896
|
+
# GrayToColor
|
|
1897
|
+
###############################################################################
|
|
1898
|
+
|
|
1899
|
+
def gray_to_rgb(
|
|
1900
|
+
pixel_data_arr: List[Optional[Image2DGrayscale]],
|
|
1901
|
+
adjustment_factor_array: List[float],
|
|
1902
|
+
intensities: List[Tuple[float, ...]]=[(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)],
|
|
1903
|
+
wants_rescale: bool=True,
|
|
1904
|
+
) -> Image2DColor:
|
|
1905
|
+
assert(len(pixel_data_arr) == len(adjustment_factor_array)), f"pixel_data_arr and adjustment_factor_array must be the same length. pixel_data_arr has {len(pixel_data_arr)} elements, adjustment_factor_array has {len(adjustment_factor_array)} elements."
|
|
1906
|
+
assert(len(pixel_data_arr) == len(intensities)), f"pixel_data_arr and intensities must be the same length. pixel_data_arr has {len(pixel_data_arr)} elements, intensities has {len(intensities)} elements."
|
|
1907
|
+
|
|
1908
|
+
parent_image = None
|
|
1909
|
+
rgb_pixel_data = None
|
|
1910
|
+
for pixel_data, adjustment_factor, intensity_triplet in zip(pixel_data_arr, adjustment_factor_array, intensities):
|
|
1911
|
+
if pixel_data is None:
|
|
1912
|
+
continue
|
|
1913
|
+
multiplier = numpy.array(intensity_triplet) * adjustment_factor
|
|
1914
|
+
if wants_rescale:
|
|
1915
|
+
pixel_data = pixel_data /numpy.max(pixel_data)
|
|
1916
|
+
if parent_image is not None:
|
|
1917
|
+
if parent_image.shape != pixel_data.shape:
|
|
1918
|
+
raise ValueError(
|
|
1919
|
+
"The input images have different sizes (%s vs %s)"
|
|
1920
|
+
% (
|
|
1921
|
+
parent_image.shape,
|
|
1922
|
+
pixel_data.shape,
|
|
1923
|
+
)
|
|
1924
|
+
)
|
|
1925
|
+
rgb_pixel_data += numpy.dstack([pixel_data] * 3) * multiplier
|
|
1926
|
+
else:
|
|
1927
|
+
parent_image = pixel_data
|
|
1928
|
+
rgb_pixel_data = numpy.dstack([pixel_data] * 3) * multiplier
|
|
1929
|
+
return rgb_pixel_data
|
|
1930
|
+
|
|
1931
|
+
def gray_to_cmyk(*args, **kwargs):
|
|
1932
|
+
# gray to cmyk has the same implementation as gray to rgb but with different intensities
|
|
1933
|
+
return gray_to_rgb(*args, **kwargs)
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
def gray_to_composite_color(
|
|
1937
|
+
pixel_data_arr: List[Optional[Image2DGrayscale]],
|
|
1938
|
+
color_array: List[Tuple[int, int, int]],
|
|
1939
|
+
weight_array: List[float],
|
|
1940
|
+
wants_rescale: bool,
|
|
1941
|
+
) -> Image2DColor:
|
|
1942
|
+
source_channels = pixel_data_arr
|
|
1943
|
+
parent_image = pixel_data_arr[0]
|
|
1944
|
+
for idx, pd in enumerate(source_channels):
|
|
1945
|
+
if pd is None:
|
|
1946
|
+
continue
|
|
1947
|
+
if pd.shape != source_channels[0].shape:
|
|
1948
|
+
raise ValueError(
|
|
1949
|
+
"The input images have different sizes (%s vs %s)"
|
|
1950
|
+
% (
|
|
1951
|
+
source_channels[0].shape,
|
|
1952
|
+
pd.shape,
|
|
1953
|
+
)
|
|
1954
|
+
)
|
|
1955
|
+
|
|
1956
|
+
colors: List[NDArray[numpy.float32]] = []
|
|
1957
|
+
pixel_data = parent_image
|
|
1958
|
+
if wants_rescale:
|
|
1959
|
+
pixel_data = pixel_data / numpy.max(pixel_data)
|
|
1960
|
+
for color_tuple, weight in zip(color_array, weight_array):
|
|
1961
|
+
color = (weight * numpy.array(color_tuple).astype(pixel_data.dtype) / 255)
|
|
1962
|
+
colors += [color[numpy.newaxis, numpy.newaxis, :]]
|
|
1963
|
+
rgb_pixel_data = pixel_data[:, :, numpy.newaxis] * colors[0]
|
|
1964
|
+
for image, color in zip(source_channels[1:], colors[1:]):
|
|
1965
|
+
if wants_rescale:
|
|
1966
|
+
image = image / numpy.max(image)
|
|
1967
|
+
rgb_pixel_data = rgb_pixel_data + image[:, :, numpy.newaxis] * color
|
|
1968
|
+
|
|
1969
|
+
return rgb_pixel_data
|
|
1970
|
+
|
|
1971
|
+
|
|
1972
|
+
def gray_to_stacked_color(
|
|
1973
|
+
pixel_data_arr: List[Optional[Image2DGrayscale]]
|
|
1974
|
+
) -> Image2DColor:
|
|
1975
|
+
source_channels = pixel_data_arr
|
|
1976
|
+
rgb_pixel_data = numpy.dstack(source_channels)
|
|
1977
|
+
return rgb_pixel_data
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
################################################################################
|
|
1981
|
+
# FlipAndRotate
|
|
1982
|
+
################################################################################
|
|
1983
|
+
|
|
1984
|
+
def flip_image_left_to_right(pixel_data: Image2D) -> NDArray[numpy.int_]:
|
|
1985
|
+
i, j = numpy.mgrid[
|
|
1986
|
+
0 : pixel_data.shape[0], pixel_data.shape[1] - 1 : -1 : -1
|
|
1987
|
+
]
|
|
1988
|
+
return i, j
|
|
1989
|
+
|
|
1990
|
+
def flip_image_top_to_bottom(pixel_data: Image2D) -> NDArray[numpy.int_]:
|
|
1991
|
+
i, j = numpy.mgrid[
|
|
1992
|
+
pixel_data.shape[0] - 1 : -1 : -1, 0 : pixel_data.shape[1]
|
|
1993
|
+
]
|
|
1994
|
+
return i, j
|
|
1995
|
+
|
|
1996
|
+
def flip_image_both(pixel_data: Image2D) -> NDArray[numpy.int_]:
|
|
1997
|
+
i, j = numpy.mgrid[
|
|
1998
|
+
pixel_data.shape[0] - 1 : -1 : -1, pixel_data.shape[1] - 1 : -1 : -1
|
|
1999
|
+
]
|
|
2000
|
+
return i, j
|
|
2001
|
+
|
|
2002
|
+
|
|
2003
|
+
def rotate_image_angle(pixel_data: Image2D, mask: Image2DMask, rotate_angle: float, wants_crop: bool) -> Tuple[Image2D, Image2DMask, Optional[Image2DMask]]:
|
|
2004
|
+
angle = rotate_angle
|
|
2005
|
+
mask = scipy.ndimage.rotate(mask.astype(float), angle, reshape=True) > 0.50
|
|
2006
|
+
crop = (
|
|
2007
|
+
scipy.ndimage.rotate(
|
|
2008
|
+
numpy.ones(pixel_data.shape[:2]), angle, reshape=True
|
|
2009
|
+
)
|
|
2010
|
+
> 0.50
|
|
2011
|
+
)
|
|
2012
|
+
mask = mask & crop
|
|
2013
|
+
pixel_data = scipy.ndimage.rotate(pixel_data, angle, reshape=True)
|
|
2014
|
+
if wants_crop:
|
|
2015
|
+
#
|
|
2016
|
+
# We want to find the largest rectangle that fits inside
|
|
2017
|
+
# the crop. The cumulative sum in the i and j direction gives
|
|
2018
|
+
# the length of the rectangle in each direction and
|
|
2019
|
+
# multiplying them gives you the area.
|
|
2020
|
+
#
|
|
2021
|
+
# The left and right halves are symmetric, so we compute
|
|
2022
|
+
# on just two of the quadrants.
|
|
2023
|
+
#
|
|
2024
|
+
half = (numpy.array(crop.shape) / 2).astype(int)
|
|
2025
|
+
#
|
|
2026
|
+
# Operate on the lower right
|
|
2027
|
+
#
|
|
2028
|
+
quartercrop = crop[half[0] :, half[1] :]
|
|
2029
|
+
ci = numpy.cumsum(quartercrop, 0)
|
|
2030
|
+
cj = numpy.cumsum(quartercrop, 1)
|
|
2031
|
+
carea_d = ci * cj
|
|
2032
|
+
carea_d[quartercrop == 0] = 0
|
|
2033
|
+
#
|
|
2034
|
+
# Operate on the upper right by flipping I
|
|
2035
|
+
#
|
|
2036
|
+
quartercrop = crop[crop.shape[0] - half[0] - 1 :: -1, half[1] :]
|
|
2037
|
+
ci = numpy.cumsum(quartercrop, 0)
|
|
2038
|
+
cj = numpy.cumsum(quartercrop, 1)
|
|
2039
|
+
carea_u = ci * cj
|
|
2040
|
+
carea_u[quartercrop == 0] = 0
|
|
2041
|
+
carea = carea_d + carea_u
|
|
2042
|
+
max_carea = numpy.max(carea)
|
|
2043
|
+
max_area = numpy.argwhere(carea == max_carea)[0] + half
|
|
2044
|
+
min_i = max(crop.shape[0] - max_area[0] - 1, 0)
|
|
2045
|
+
max_i = max_area[0] + 1
|
|
2046
|
+
min_j = max(crop.shape[1] - max_area[1] - 1, 0)
|
|
2047
|
+
max_j = max_area[1] + 1
|
|
2048
|
+
ii = numpy.index_exp[min_i:max_i, min_j:max_j]
|
|
2049
|
+
crop = numpy.zeros(pixel_data.shape, bool)
|
|
2050
|
+
crop[ii] = True
|
|
2051
|
+
mask = mask[ii]
|
|
2052
|
+
pixel_data = pixel_data[ii]
|
|
2053
|
+
else:
|
|
2054
|
+
crop = None
|
|
2055
|
+
return pixel_data, mask, crop
|
|
2056
|
+
|
|
2057
|
+
|
|
2058
|
+
def rotate_image_coordinates(pixel_data: Image2D, mask: Image2DMask, rotate_point_1: Tuple[float, float], rotate_point_2: Tuple[float, float], rotate_coordinate_alignment: RotationCoordinateAlignmnet) -> float:
|
|
2059
|
+
xdiff = rotate_point_2[0] - rotate_point_1[0]
|
|
2060
|
+
ydiff = rotate_point_2[1] - rotate_point_1[1]
|
|
2061
|
+
|
|
2062
|
+
if rotate_coordinate_alignment == RotationCoordinateAlignmnet.VERTICALLY:
|
|
2063
|
+
angle = -numpy.arctan2(ydiff, xdiff) * 180.0 / numpy.pi
|
|
2064
|
+
elif rotate_coordinate_alignment == RotationCoordinateAlignmnet.HORIZONTALLY:
|
|
2065
|
+
angle = numpy.arctan2(xdiff, ydiff) * 180.0 / numpy.pi
|
|
2066
|
+
else:
|
|
2067
|
+
raise NotImplementedError(
|
|
2068
|
+
"Unknown axis: %s" % rotate_coordinate_alignment.value
|
|
2069
|
+
)
|
|
2070
|
+
return angle
|
|
@@ -2,28 +2,30 @@ import warnings
|
|
|
2
2
|
|
|
3
3
|
import numpy
|
|
4
4
|
import centrosome
|
|
5
|
-
|
|
5
|
+
from pydantic import Field, validate_call, ConfigDict
|
|
6
|
+
from typing import Annotated, Optional
|
|
6
7
|
from ..functions.image_processing import (
|
|
7
8
|
enhance_edges_sobel,
|
|
8
9
|
enhance_edges_log,
|
|
9
10
|
enhance_edges_prewitt,
|
|
10
11
|
enhance_edges_canny,
|
|
11
12
|
)
|
|
13
|
+
from ..opts.enhanceedges import EdgeFindingMethod, EdgeDirection
|
|
14
|
+
from ..types import Image2DGrayscale, Image2DGrayscaleMask
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
|
14
17
|
def enhanceedges(
|
|
15
|
-
image,
|
|
16
|
-
mask=None,
|
|
17
|
-
method="
|
|
18
|
-
automatic_threshold=True,
|
|
19
|
-
direction="
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
):
|
|
18
|
+
image: Annotated[Image2DGrayscale, Field(description="Input image")],
|
|
19
|
+
mask: Annotated[Optional[Image2DGrayscaleMask], Field(description="Mask of the input image")] = None,
|
|
20
|
+
method: Annotated[EdgeFindingMethod, Field(description="Edge finding method")] = EdgeFindingMethod.SOBEL,
|
|
21
|
+
automatic_threshold: Annotated[bool, Field(description="Automatically calculate the threshold?")] = True,
|
|
22
|
+
direction: Annotated[EdgeDirection, Field(description="Select edge direction to enhance")] = EdgeDirection.ALL,
|
|
23
|
+
sigma: Annotated[int, Field(description="Gaussian's sigma value")] = 10,
|
|
24
|
+
manual_threshold: Annotated[float, Field(description="Absolute threshold")] = 0.2,
|
|
25
|
+
threshold_adjustment_factor: Annotated[float, Field(description="Threshold adjustment factor")] = 1.0,
|
|
26
|
+
automatic_low_threshold: Annotated[bool, Field(description="Automatically calculate the low / soft threshold cutoff for the Canny method?")] = True,
|
|
27
|
+
low_threshold: Annotated[float, Field(description="Low threshold value")] = 0.1,
|
|
28
|
+
) -> Image2DGrayscale:
|
|
27
29
|
"""EnhanceEdges module
|
|
28
30
|
|
|
29
31
|
Parameters
|
|
@@ -64,13 +66,13 @@ def enhanceedges(
|
|
|
64
66
|
if mask is None:
|
|
65
67
|
mask = numpy.ones(image.shape, bool)
|
|
66
68
|
|
|
67
|
-
if method
|
|
69
|
+
if method == EdgeFindingMethod.SOBEL:
|
|
68
70
|
output_pixels = enhance_edges_sobel(image, mask, direction)
|
|
69
|
-
elif method
|
|
71
|
+
elif method == EdgeFindingMethod.LOG:
|
|
70
72
|
output_pixels = enhance_edges_log(image, mask, sigma)
|
|
71
|
-
elif method
|
|
73
|
+
elif method == EdgeFindingMethod.PREWITT:
|
|
72
74
|
output_pixels = enhance_edges_prewitt(image, mask, direction)
|
|
73
|
-
elif method
|
|
75
|
+
elif method == EdgeFindingMethod.CANNY:
|
|
74
76
|
output_pixels = enhance_edges_canny(
|
|
75
77
|
image,
|
|
76
78
|
mask,
|
|
@@ -81,9 +83,9 @@ def enhanceedges(
|
|
|
81
83
|
manual_threshold=manual_threshold,
|
|
82
84
|
threshold_adjustment_factor=threshold_adjustment_factor,
|
|
83
85
|
)
|
|
84
|
-
elif method
|
|
86
|
+
elif method == EdgeFindingMethod.ROBERTS:
|
|
85
87
|
output_pixels = centrosome.filter.roberts(image, mask)
|
|
86
|
-
elif method
|
|
88
|
+
elif method == EdgeFindingMethod.KIRSCH:
|
|
87
89
|
output_pixels = centrosome.kirsch.kirsch(image)
|
|
88
90
|
else:
|
|
89
91
|
raise NotImplementedError(f"{method} edge detection method is not implemented.")
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
from pydantic import Field, validate_call, ConfigDict
|
|
3
|
+
from typing import Annotated, Optional, Tuple, Dict, Callable
|
|
4
|
+
from numpy.typing import NDArray
|
|
5
|
+
from cellprofiler_library.functions.image_processing import flip_image_both, flip_image_left_to_right, flip_image_top_to_bottom, rotate_image_angle, rotate_image_coordinates
|
|
6
|
+
from cellprofiler_library.types import Image2D, Image2DMask
|
|
7
|
+
from cellprofiler_library.opts.flipandrotate import FlipDirection, RotateMethod, RotationCoordinateAlignmnet
|
|
8
|
+
|
|
9
|
+
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
|
10
|
+
def flip_and_rotate(
|
|
11
|
+
pixel_data: Annotated[Image2D, Field(description="Pixel data of image to be flipped and/or rotated")],
|
|
12
|
+
mask: Annotated[Image2DMask, Field(description="Mask of the image to be flipped and/or rotated")],
|
|
13
|
+
flip_choice: Annotated[FlipDirection, Field(description="Direction to flip the image")],
|
|
14
|
+
rotate_choice: Annotated[RotateMethod, Field(description="Rotation method")],
|
|
15
|
+
rotate_angle: Annotated[Optional[float], Field(description="Angle to rotate the image")],
|
|
16
|
+
rotate_point_1: Annotated[Optional[Tuple[float, float]], Field(description="Point to rotate the image around")],
|
|
17
|
+
rotate_point_2: Annotated[Optional[Tuple[float, float]], Field(description="Second point to rotate the image around")],
|
|
18
|
+
rotate_coordinate_alignment: Annotated[Optional[RotationCoordinateAlignmnet], Field(description="Alignment of the rotated points. The points you select will be aligned horizontally or vertically after the rotation is complete.")],
|
|
19
|
+
wants_crop: Annotated[bool, Field(description="Whether to crop the image")],
|
|
20
|
+
) -> Tuple[Image2D, Image2DMask, Optional[Image2DMask], float]:
|
|
21
|
+
#
|
|
22
|
+
# Perform flip
|
|
23
|
+
#
|
|
24
|
+
pixel_data, mask = flip_image(pixel_data, mask, flip_choice)
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Perform rotation
|
|
28
|
+
#
|
|
29
|
+
pixel_data, mask, crop, angle = rotate_image(pixel_data, mask, rotate_choice, rotate_angle, rotate_point_1, rotate_point_2, rotate_coordinate_alignment, wants_crop)
|
|
30
|
+
|
|
31
|
+
return pixel_data, mask, crop, angle
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def flip_image(
|
|
35
|
+
pixel_data: Image2D,
|
|
36
|
+
mask: Image2DMask,
|
|
37
|
+
flip_choice: FlipDirection
|
|
38
|
+
) -> Tuple[Image2D, Image2DMask]:
|
|
39
|
+
flip_dispatch: Dict[FlipDirection, Callable[[Image2D], NDArray[numpy.int_]]] = {
|
|
40
|
+
FlipDirection.LEFT_TO_RIGHT: flip_image_left_to_right,
|
|
41
|
+
FlipDirection.TOP_TO_BOTTOM: flip_image_top_to_bottom,
|
|
42
|
+
FlipDirection.BOTH: flip_image_both,
|
|
43
|
+
}
|
|
44
|
+
if flip_choice != FlipDirection.NONE:
|
|
45
|
+
if flip_choice in flip_dispatch.keys():
|
|
46
|
+
i, j = flip_dispatch[flip_choice](pixel_data)
|
|
47
|
+
else:
|
|
48
|
+
raise NotImplementedError(
|
|
49
|
+
"Unknown flipping operation: %s" % flip_choice.value
|
|
50
|
+
)
|
|
51
|
+
mask = mask[i, j]
|
|
52
|
+
if pixel_data.ndim == 2:
|
|
53
|
+
pixel_data = pixel_data[i, j]
|
|
54
|
+
else:
|
|
55
|
+
pixel_data = pixel_data[i, j, :]
|
|
56
|
+
return pixel_data, mask
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def rotate_image(
|
|
60
|
+
pixel_data: Image2D,
|
|
61
|
+
mask: Image2DMask,
|
|
62
|
+
rotate_choice: RotateMethod,
|
|
63
|
+
rotate_angle: Optional[float],
|
|
64
|
+
rotate_point_1: Optional[Tuple[float, float]],
|
|
65
|
+
rotate_point_2: Optional[Tuple[float, float]],
|
|
66
|
+
rotate_coordinate_alignment: Optional[RotationCoordinateAlignmnet],
|
|
67
|
+
wants_crop: bool,
|
|
68
|
+
) -> Tuple[Image2D, Image2DMask, Optional[Image2DMask], float]:
|
|
69
|
+
if rotate_choice != RotateMethod.NONE:
|
|
70
|
+
if rotate_choice == RotateMethod.ANGLE:
|
|
71
|
+
assert rotate_angle is not None, "rotate_angle must be provided for rotate_choice == RotateMethod.ANGLE"
|
|
72
|
+
angle = rotate_angle
|
|
73
|
+
elif rotate_choice == RotateMethod.COORDINATES:
|
|
74
|
+
assert rotate_point_1 is not None, "rotate_point_1 must be provided for rotate_choice == RotateMethod.COORDINATES"
|
|
75
|
+
assert rotate_point_2 is not None, "rotate_point_2 must be provided for rotate_choice == RotateMethod.COORDINATES"
|
|
76
|
+
assert rotate_coordinate_alignment is not None, "rotate_coordinate_alignment must be provided for rotate_choice == RotateMethod.COORDINATES"
|
|
77
|
+
angle = rotate_image_coordinates(pixel_data, mask, rotate_point_1, rotate_point_2, rotate_coordinate_alignment)
|
|
78
|
+
|
|
79
|
+
else:
|
|
80
|
+
raise NotImplementedError(
|
|
81
|
+
"Unknown rotation method: %s" % rotate_choice.value
|
|
82
|
+
)
|
|
83
|
+
# rangle = angle * numpy.pi / 180.0
|
|
84
|
+
pixel_data, mask, crop = rotate_image_angle(pixel_data, mask, angle, wants_crop)
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
crop = None
|
|
88
|
+
angle = 0.0
|
|
89
|
+
return pixel_data, mask, crop, angle
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
from numpy.typing import NDArray
|
|
3
|
+
from typing import List, Tuple, Optional
|
|
4
|
+
from pydantic import validate_call, ConfigDict
|
|
5
|
+
from cellprofiler_library.opts.graytocolor import Scheme
|
|
6
|
+
from cellprofiler_library.types import Image2DGrayscale, Image2DColor
|
|
7
|
+
from cellprofiler_library.functions.image_processing import gray_to_rgb, gray_to_cmyk, gray_to_composite_color, gray_to_stacked_color
|
|
8
|
+
|
|
9
|
+
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
|
10
|
+
def gray_to_color(
|
|
11
|
+
pixel_data_arr: List[Optional[Image2DGrayscale]],
|
|
12
|
+
scheme: Scheme,
|
|
13
|
+
color_array: Optional[List[Tuple[int, int, int]]] = None,
|
|
14
|
+
weight_array: Optional[List[float]] = None,
|
|
15
|
+
adjustment_factor_array: Optional[List[float]] = None,
|
|
16
|
+
intensities: List[Tuple[float, ...]]=[(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)],
|
|
17
|
+
wants_rescale: bool=True,
|
|
18
|
+
) -> Image2DColor:
|
|
19
|
+
rgb_pixel_data = None
|
|
20
|
+
if scheme == Scheme.RGB:
|
|
21
|
+
assert adjustment_factor_array is not None, "adjustment_factor_array must be provided for RGB mode"
|
|
22
|
+
assert intensities is not None, "intensities must be provided for RGB mode"
|
|
23
|
+
rgb_pixel_data = gray_to_rgb(
|
|
24
|
+
pixel_data_arr = pixel_data_arr,
|
|
25
|
+
adjustment_factor_array = adjustment_factor_array,
|
|
26
|
+
intensities = intensities,
|
|
27
|
+
wants_rescale = wants_rescale,
|
|
28
|
+
)
|
|
29
|
+
elif scheme == Scheme.CMYK:
|
|
30
|
+
assert adjustment_factor_array is not None, "adjustment_factor_array must be provided for CMYK mode"
|
|
31
|
+
assert intensities is not None, "intensities must be provided for CMYK mode"
|
|
32
|
+
rgb_pixel_data = gray_to_cmyk(
|
|
33
|
+
pixel_data_arr = pixel_data_arr,
|
|
34
|
+
adjustment_factor_array = adjustment_factor_array,
|
|
35
|
+
intensities = intensities,
|
|
36
|
+
wants_rescale = wants_rescale,
|
|
37
|
+
)
|
|
38
|
+
elif scheme == Scheme.COMPOSITE:
|
|
39
|
+
assert color_array is not None, "color_array must be provided for composite mode"
|
|
40
|
+
assert weight_array is not None, "weight_array must be provided for composite mode"
|
|
41
|
+
rgb_pixel_data = gray_to_composite_color(
|
|
42
|
+
pixel_data_arr = pixel_data_arr,
|
|
43
|
+
color_array = color_array,
|
|
44
|
+
weight_array = weight_array,
|
|
45
|
+
wants_rescale = wants_rescale,
|
|
46
|
+
)
|
|
47
|
+
elif scheme == Scheme.STACK:
|
|
48
|
+
assert pixel_data_arr is not None, "pixel_data_arr must be provided for stack mode"
|
|
49
|
+
rgb_pixel_data = gray_to_stacked_color(
|
|
50
|
+
pixel_data_arr = pixel_data_arr,
|
|
51
|
+
)
|
|
52
|
+
else:
|
|
53
|
+
raise ValueError(f"Unimplemented scheme: {scheme}")
|
|
54
|
+
if scheme.value != Scheme.STACK and wants_rescale:
|
|
55
|
+
# If we rescaled, clip values that went out of range after multiplication
|
|
56
|
+
rgb_pixel_data[rgb_pixel_data > 1] = 1
|
|
57
|
+
return rgb_pixel_data
|
|
58
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class EdgeFindingMethod(str, Enum):
|
|
4
|
+
SOBEL = "Sobel"
|
|
5
|
+
PREWITT = "Prewitt"
|
|
6
|
+
ROBERTS = "Roberts"
|
|
7
|
+
LOG = "Log"
|
|
8
|
+
CANNY = "Canny"
|
|
9
|
+
KIRSCH = "Kirsch"
|
|
10
|
+
|
|
11
|
+
class EdgeDirection(str, Enum):
|
|
12
|
+
ALL = "All"
|
|
13
|
+
HORIZONTAL = "Horizontal"
|
|
14
|
+
VERTICAL = "Vertical"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class FlipDirection(str, Enum):
|
|
4
|
+
NONE = "Do not flip"
|
|
5
|
+
LEFT_TO_RIGHT = "Left to right"
|
|
6
|
+
TOP_TO_BOTTOM = "Top to bottom"
|
|
7
|
+
BOTH = "Left to right and top to bottom"
|
|
8
|
+
|
|
9
|
+
class RotateMethod(str, Enum):
|
|
10
|
+
NONE = "Do not rotate"
|
|
11
|
+
ANGLE = "Enter angle"
|
|
12
|
+
COORDINATES = "Enter coordinates"
|
|
13
|
+
|
|
14
|
+
class RotationCoordinateAlignmnet(str, Enum):
|
|
15
|
+
HORIZONTALLY = "Horizontally"
|
|
16
|
+
VERTICALLY = "Vertically"
|
|
17
|
+
|
|
18
|
+
D_ANGLE = "angle"
|
|
19
|
+
|
|
20
|
+
"""Rotation measurement category"""
|
|
21
|
+
M_ROTATION_CATEGORY = "Rotation"
|
|
22
|
+
"""Rotation measurement format (+ image name)"""
|
|
23
|
+
M_ROTATION_F = "%s_%%s" % M_ROTATION_CATEGORY
|
|
24
|
+
|
|
25
|
+
FLIP_ALL = [FlipDirection.NONE, FlipDirection.LEFT_TO_RIGHT, FlipDirection.TOP_TO_BOTTOM, FlipDirection.BOTH]
|
|
26
|
+
|
|
27
|
+
ROTATE_ALL = [RotateMethod.NONE, RotateMethod.ANGLE, RotateMethod.COORDINATES]
|
|
28
|
+
|
|
29
|
+
C_ALL = [RotationCoordinateAlignmnet.HORIZONTALLY, RotationCoordinateAlignmnet.VERTICALLY]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class Scheme(str, Enum):
|
|
4
|
+
RGB = "RGB"
|
|
5
|
+
CMYK = "CMYK"
|
|
6
|
+
STACK = "Stack"
|
|
7
|
+
COMPOSITE = "Composite"
|
|
8
|
+
LEAVE_THIS_BLACK = "Leave this black"
|
|
9
|
+
|
|
10
|
+
DEFAULT_COLORS = [
|
|
11
|
+
"#%02x%02x%02x" % color
|
|
12
|
+
for color in (
|
|
13
|
+
(255, 0, 0),
|
|
14
|
+
(0, 255, 0),
|
|
15
|
+
(0, 0, 255),
|
|
16
|
+
(128, 128, 0),
|
|
17
|
+
(128, 0, 128),
|
|
18
|
+
(0, 128, 128),
|
|
19
|
+
)
|
|
20
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cellprofiler-library-nightly
|
|
3
|
-
Version: 5.0.0.
|
|
3
|
+
Version: 5.0.0.dev475
|
|
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,9 @@ cellprofiler_library/modules/_erodeimage.py
|
|
|
28
28
|
cellprofiler_library/modules/_erodeobjects.py
|
|
29
29
|
cellprofiler_library/modules/_expandorshrinkobjects.py
|
|
30
30
|
cellprofiler_library/modules/_fillobjects.py
|
|
31
|
+
cellprofiler_library/modules/_flipandrotate.py
|
|
31
32
|
cellprofiler_library/modules/_gaussianfilter.py
|
|
33
|
+
cellprofiler_library/modules/_graytocolor.py
|
|
32
34
|
cellprofiler_library/modules/_identifyprimaryobjects.py
|
|
33
35
|
cellprofiler_library/modules/_identifysecondaryobjects.py
|
|
34
36
|
cellprofiler_library/modules/_identifytertiaryobjects.py
|
|
@@ -57,9 +59,12 @@ cellprofiler_library/opts/correctilluminationapply.py
|
|
|
57
59
|
cellprofiler_library/opts/crop.py
|
|
58
60
|
cellprofiler_library/opts/dilateimage.py
|
|
59
61
|
cellprofiler_library/opts/dilateobjects.py
|
|
62
|
+
cellprofiler_library/opts/enhanceedges.py
|
|
60
63
|
cellprofiler_library/opts/enhanceorsuppressfeatures.py
|
|
61
64
|
cellprofiler_library/opts/erodeimage.py
|
|
62
65
|
cellprofiler_library/opts/erodeobjects.py
|
|
66
|
+
cellprofiler_library/opts/flipandrotate.py
|
|
67
|
+
cellprofiler_library/opts/graytocolor.py
|
|
63
68
|
cellprofiler_library/opts/identifyprimaryobjects.py
|
|
64
69
|
cellprofiler_library/opts/identifysecondaryobjects.py
|
|
65
70
|
cellprofiler_library/opts/identifytertiaryobjects.py
|
{cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/LICENSE
RENAMED
|
File without changes
|
{cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cellprofiler_library_nightly-5.0.0.dev462 → cellprofiler_library_nightly-5.0.0.dev475}/setup.cfg
RENAMED
|
File without changes
|