cellprofiler-library-nightly 5.0.0.dev318__py3-none-any.whl → 5.0.0.dev324__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.
@@ -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.dev318'
32
- __version_tuple__ = version_tuple = (5, 0, 0, 'dev318')
31
+ __version__ = version = '5.0.0.dev324'
32
+ __version_tuple__ = version_tuple = (5, 0, 0, 'dev324')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -5,9 +5,12 @@ import centrosome
5
5
  import centrosome.threshold
6
6
  import scipy
7
7
  import matplotlib
8
+ import math
8
9
  from typing import Any, Optional, Tuple, Callable, Union, List
9
- from ..types import ImageGrayscale, ImageGrayscaleMask, Image2DColor, Image2DGrayscale, ImageAny, ObjectSegmentation, Image2D
10
- from ..opts import threshold as Threshold
10
+ from cellprofiler_library.types import ImageGrayscale, ImageGrayscaleMask, Image2DColor, Image2DGrayscale, ImageAny, ObjectSegmentation, Image2D, Image2DMask, StructuringElement
11
+ from cellprofiler_library.opts import threshold as Threshold
12
+ from cellprofiler_library.opts.crop import RemovalMethod
13
+ from cellprofiler_library.opts.structuring_elements import StructuringElementShape2D, StructuringElementShape3D
11
14
 
12
15
  def rgb_to_greyscale(image):
13
16
  if image.shape[-1] == 4:
@@ -117,6 +120,47 @@ def morphological_skeleton_3d(image):
117
120
  return skimage.morphology.skeletonize_3d(image)
118
121
 
119
122
 
123
+ ################################################################################
124
+ # Morphological Operations Helpers
125
+ ################################################################################
126
+
127
+ def get_structuring_element(shape: Union[StructuringElementShape2D, StructuringElementShape3D], size: int) -> StructuringElement:
128
+ return getattr(skimage.morphology, shape.value.lower())(size)
129
+
130
+ ################################################################################
131
+ # ErodeImage
132
+ ################################################################################
133
+
134
+ def morphology_erosion(image: ImageAny, structuring_element: StructuringElement) -> ImageAny:
135
+ """Apply morphological erosion to an image.
136
+
137
+ Args:
138
+ image: Input image (2D or 3D)
139
+ structuring_element: Structuring element for erosion
140
+
141
+ Returns:
142
+ Eroded image with same dimensions as input
143
+ """
144
+ is_strel_2d = structuring_element.ndim == 2
145
+ is_img_2d = image.ndim == 2
146
+
147
+ if is_strel_2d and not is_img_2d:
148
+ # Apply 2D structuring element to 3D image planewise
149
+ y_data = numpy.zeros_like(image)
150
+ for index, plane in enumerate(image):
151
+ y_data[index] = skimage.morphology.erosion(plane, structuring_element)
152
+ return y_data
153
+
154
+ if not is_strel_2d and is_img_2d:
155
+ raise NotImplementedError(
156
+ "A 3D structuring element cannot be applied to a 2D image."
157
+ )
158
+
159
+ # Apply erosion directly for matching dimensions
160
+ y_data = skimage.morphology.erosion(image, structuring_element)
161
+ return y_data
162
+
163
+
120
164
  def median_filter(image, window_size, mode):
121
165
  return scipy.ndimage.median_filter(image, size=window_size, mode=mode)
122
166
 
@@ -634,3 +678,215 @@ def clip_low(output_pixels: Image2D) -> Image2D:
634
678
 
635
679
  def clip_high(output_pixels: Image2D) -> Image2D:
636
680
  return numpy.where(output_pixels > 1, 1, output_pixels)
681
+
682
+ ################################################################################
683
+ # Crop
684
+ ################################################################################
685
+
686
+ def get_ellipse_cropping(
687
+ orig_image_pixels: Image2D,
688
+ ellipse_center: Tuple[float, float],
689
+ ellipse_radius: Tuple[float, float]
690
+ ) -> Image2DMask:
691
+ x_center, y_center = ellipse_center
692
+ x_radius, y_radius = ellipse_radius
693
+ x_max = orig_image_pixels.shape[1]
694
+ y_max = orig_image_pixels.shape[0]
695
+ if x_radius > y_radius:
696
+ dist_x = math.sqrt(x_radius ** 2 - y_radius ** 2)
697
+ dist_y = 0
698
+ major_radius = x_radius
699
+ else:
700
+ dist_x = 0
701
+ dist_y = math.sqrt(y_radius ** 2 - x_radius ** 2)
702
+ major_radius = y_radius
703
+
704
+ focus_1_x, focus_1_y = (x_center - dist_x, y_center - dist_y)
705
+ focus_2_x, focus_2_y = (x_center + dist_x, y_center + dist_y)
706
+ y, x = numpy.mgrid[0:y_max, 0:x_max]
707
+ d1 = numpy.sqrt((x - focus_1_x) ** 2 + (y - focus_1_y) ** 2)
708
+ d2 = numpy.sqrt((x - focus_2_x) ** 2 + (y - focus_2_y) ** 2)
709
+ cropping = d1 + d2 <= major_radius * 2
710
+ return cropping
711
+
712
+
713
+ def get_rectangle_cropping(
714
+ orig_image_pixels: Image2D,
715
+ bounding_box: Tuple[Optional[int], Optional[int], Optional[int], Optional[int]],
716
+ validate_boundaries: bool = True
717
+ ) -> Image2DMask:
718
+ cropping = numpy.ones(orig_image_pixels.shape[:2], bool)
719
+ left, right, top, bottom = bounding_box
720
+ if validate_boundaries:
721
+ if left and left > 0:
722
+ cropping[:, :left] = False
723
+ if right and right < cropping.shape[1]:
724
+ cropping[:, right:] = False
725
+ if top and top > 0:
726
+ cropping[:top, :] = False
727
+ if bottom and bottom < cropping.shape[0]:
728
+ cropping[bottom:, :] = False
729
+ else:
730
+ cropping[:, :left] = False
731
+ cropping[:, right:] = False
732
+ cropping[:top, :] = False
733
+ cropping[bottom:, :] = False
734
+ return cropping
735
+
736
+
737
+ def crop_image(
738
+ image: Union[Image2D, Image2DMask],
739
+ crop_mask: Image2DMask,
740
+ crop_internal: Optional[bool]=False
741
+ ) -> Union[Image2D, Image2DMask]:
742
+ """Crop an image to the size of the nonzero portion of a crop mask"""
743
+ i_histogram = crop_mask.sum(axis=1)
744
+ i_cumsum = numpy.cumsum(i_histogram != 0)
745
+ j_histogram = crop_mask.sum(axis=0)
746
+ j_cumsum = numpy.cumsum(j_histogram != 0)
747
+ if i_cumsum[-1] == 0:
748
+ # The whole image is cropped away
749
+ return numpy.zeros((0, 0), dtype=image.dtype)
750
+ if crop_internal:
751
+ #
752
+ # Make up sequences of rows and columns to keep
753
+ #
754
+ i_keep = numpy.argwhere(i_histogram > 0)
755
+ j_keep = numpy.argwhere(j_histogram > 0)
756
+ #
757
+ # Then slice the array by I, then by J to get what's not blank
758
+ #
759
+ return image[i_keep.flatten(), :][:, j_keep.flatten()].copy()
760
+ else:
761
+ #
762
+ # The first non-blank row and column are where the cumsum is 1
763
+ # The last are at the first where the cumsum is it's max (meaning
764
+ # what came after was all zeros and added nothing)
765
+ #
766
+ i_first = numpy.argwhere(i_cumsum == 1)[0]
767
+ i_last = numpy.argwhere(i_cumsum == i_cumsum.max())[0]
768
+ i_end = i_last + 1
769
+ j_first = numpy.argwhere(j_cumsum == 1)[0]
770
+ j_last = numpy.argwhere(j_cumsum == j_cumsum.max())[0]
771
+ j_end = j_last + 1
772
+
773
+ if image.ndim == 3:
774
+ return image[i_first[0] : i_end[0], j_first[0] : j_end[0], :].copy()
775
+
776
+ return image[i_first[0] : i_end[0], j_first[0] : j_end[0]].copy()
777
+
778
+
779
+ def get_cropped_mask(
780
+ cropping: Image2DMask,
781
+ mask: Optional[Image2DMask],
782
+ removal_method: RemovalMethod = RemovalMethod.NO,
783
+ ) -> Image2DMask:
784
+ if removal_method == RemovalMethod.NO:
785
+ #
786
+ # Check for previous cropping's mask. If it doesn't exist, set it to the current cropping
787
+ #
788
+ if mask is None:
789
+ mask = cropping
790
+ elif removal_method in (RemovalMethod.EDGES, RemovalMethod.ALL):
791
+ crop_internal = removal_method == RemovalMethod.ALL
792
+ #
793
+ # Check for previous cropping's mask. If it doesn't exist, set it to the region of interest specified
794
+ # by the cropping. The final mask output size could be smaller as the crop_image function removes
795
+ # edges by default.
796
+ #
797
+ if mask is None:
798
+ mask = crop_image(cropping, cropping, crop_internal)
799
+ else:
800
+ raise NotImplementedError(f"Unimplemented removal method: {removal_method}")
801
+ assert mask is not None
802
+ return mask
803
+
804
+
805
+ def get_cropped_image_mask(
806
+ cropping: Image2DMask,
807
+ mask: Optional[Image2DMask],
808
+ orig_image_mask: Optional[Image2DMask] = None,
809
+ removal_method: RemovalMethod = RemovalMethod.NO,
810
+ ) -> Image2DMask:
811
+ if mask is None:
812
+ mask = get_cropped_mask(cropping, mask, removal_method)
813
+ if removal_method == RemovalMethod.NO:
814
+ #
815
+ # Check if a mask has been set on the original image. If not, set it to the current mask
816
+ # This is a mask that could have been set by another module and this module "respects masks".
817
+ #
818
+ if orig_image_mask is not None:
819
+ # Image mask is the region of interest indicator for the final image object.
820
+ image_mask = orig_image_mask & mask
821
+ else:
822
+ image_mask = mask
823
+
824
+ return image_mask
825
+ elif removal_method in (RemovalMethod.EDGES, RemovalMethod.ALL):
826
+ crop_internal = removal_method == RemovalMethod.ALL
827
+ #
828
+ # Check if a mask has been set on the original image. If not, set it to the current mask
829
+ # This is a mask that could have been set by another module and this module "respects masks".
830
+ # The final mask output size could be smaller as the crop_image function removes edges by default.
831
+ #
832
+ if orig_image_mask is not None:
833
+ # Image mask is the region of interest indicator for the final image object.
834
+ image_mask = crop_image(orig_image_mask, cropping, crop_internal) & mask
835
+ else:
836
+ image_mask = mask
837
+ else:
838
+ raise NotImplementedError(f"Unimplemented removal method: {removal_method}")
839
+
840
+ return image_mask
841
+
842
+
843
+ def get_cropped_image_pixels(
844
+ orig_image_pixels: Image2D,
845
+ cropping: Image2DMask,
846
+ mask: Optional[Image2DMask],
847
+ removal_method: RemovalMethod = RemovalMethod.NO,
848
+ ) -> Image2D:
849
+ if removal_method == RemovalMethod.NO:
850
+ cropped_pixel_data = apply_crop_keep_rows_and_columns(orig_image_pixels, cropping)
851
+ elif removal_method in (RemovalMethod.EDGES, RemovalMethod.ALL):
852
+ cropped_pixel_data = apply_crop_remove_rows_and_columns(orig_image_pixels, cropping, mask, removal_method)
853
+ else:
854
+ raise NotImplementedError(f"Unimplemented removal method: {removal_method}")
855
+ return cropped_pixel_data
856
+
857
+
858
+ def apply_crop_keep_rows_and_columns(
859
+ orig_image_pixels: Image2D,
860
+ final_cropping: Image2DMask,
861
+ ) -> Image2D:
862
+ cropped_pixel_data = orig_image_pixels.copy()
863
+ cropped_pixel_data = erase_pixels(cropped_pixel_data, final_cropping)
864
+ return cropped_pixel_data
865
+
866
+
867
+ def apply_crop_remove_rows_and_columns(
868
+ orig_image_pixels: Image2D,
869
+ final_cropping: Image2DMask,
870
+ mask: Optional[Image2DMask],
871
+ removal_method: RemovalMethod = RemovalMethod.EDGES,
872
+ ) -> Image2D:
873
+ if mask is None:
874
+ mask = get_cropped_mask(final_cropping, mask, removal_method)
875
+ # Apply first level of cropping to get the region of interest that matches the original image
876
+ cropped_pixel_data = crop_image(orig_image_pixels, final_cropping, removal_method==RemovalMethod.ALL)
877
+ cropped_pixel_data = erase_pixels(cropped_pixel_data, mask)
878
+ return cropped_pixel_data
879
+
880
+
881
+ def erase_pixels(
882
+ cropped_pixel_data: Image2D,
883
+ crop: Image2DMask
884
+ ) -> Image2D:
885
+ #
886
+ # Apply crop to all channels automatically for color images
887
+ #
888
+ if cropped_pixel_data.ndim == 3:
889
+ cropped_pixel_data[~crop, :] = 0
890
+ else:
891
+ cropped_pixel_data[~crop] = 0
892
+ return cropped_pixel_data
@@ -0,0 +1,45 @@
1
+ from typing import Annotated, Optional, Tuple, List
2
+ from pydantic import Field, validate_call, ConfigDict
3
+ import numpy
4
+ from cellprofiler_library.types import Image2D, Image2DMask
5
+ from cellprofiler_library.functions.image_processing import get_cropped_mask, get_cropped_image_mask, get_cropped_image_pixels
6
+ from cellprofiler_library.opts.crop import RemovalMethod, Measurement
7
+
8
+ @validate_call(config=ConfigDict(arbitrary_types_allowed=True))
9
+ def crop(
10
+ orig_image_pixels: Annotated[Image2D, Field(description="Pixel values of the original image")],
11
+ cropping: Annotated[Image2DMask, Field(description="The region of interest to be kept. 1 for pixels to keep, 0 for pixels to remove")],
12
+ mask: Annotated[Optional[Image2DMask], Field(description="Previous cropping's mask")],
13
+ orig_image_mask: Annotated[Optional[Image2DMask], Field(description="Mask that may have been set on the original image")],
14
+ removal_method: Annotated[RemovalMethod, Field(description="Removal method")],
15
+ ) -> Tuple[Image2D, Image2DMask, Image2DMask]:
16
+ #
17
+ # Crop the mask
18
+ #
19
+ mask = get_cropped_mask(cropping, mask, removal_method)
20
+
21
+ #
22
+ # Crop the image_mask
23
+ image_mask = get_cropped_image_mask(cropping, mask, orig_image_mask, removal_method)
24
+
25
+ #
26
+ # Crop the image
27
+ #
28
+ cropped_pixel_data = get_cropped_image_pixels(orig_image_pixels, cropping, mask, removal_method)
29
+
30
+ return cropped_pixel_data, mask, image_mask
31
+
32
+ @validate_call(config=ConfigDict(arbitrary_types_allowed=True))
33
+ def measure_area_retained_after_cropping(cropping: Image2DMask) -> int:
34
+ return numpy.sum(cropping.astype(float))
35
+
36
+ @validate_call(config=ConfigDict(arbitrary_types_allowed=True))
37
+ def measure_original_image_area(orig_image_pixels: Image2D) -> int:
38
+ return numpy.product(orig_image_pixels.shape)
39
+
40
+ @validate_call(config=ConfigDict(arbitrary_types_allowed=True))
41
+ def get_measurements(cropping: Image2DMask, orig_image_pixels:Image2D, cropped_image_name: str = "CroppedImage") -> List[Tuple[str, str, int]]:
42
+ orig_image_area = measure_original_image_area(orig_image_pixels)
43
+ area_retained_after_cropping = measure_area_retained_after_cropping(cropping)
44
+ return [("Image", str(Measurement.ORIGINAL_AREA % cropped_image_name), orig_image_area),
45
+ ("Image", str(Measurement.AREA_RETAINED % cropped_image_name), area_retained_after_cropping)]
@@ -0,0 +1,36 @@
1
+ # coding=utf-8
2
+
3
+ """
4
+ ErodeImage module for the CellProfiler library.
5
+
6
+ This module contains the core algorithms for morphological erosion operations.
7
+ """
8
+
9
+ from pydantic import validate_call, ConfigDict, Field
10
+ from typing import Union, Tuple, Annotated
11
+ from cellprofiler_library.types import ImageAny, StructuringElement
12
+ from cellprofiler_library.functions.image_processing import morphology_erosion, get_structuring_element
13
+ from cellprofiler_library.opts.structuring_elements import StructuringElementShape2D, StructuringElementShape3D
14
+
15
+ StructuringElementSize = Annotated[int, Field(description="Size of structuring element", gt=0)]
16
+ StructuringElementParameters = Tuple[Union[StructuringElementShape2D, StructuringElementShape3D], StructuringElementSize]
17
+ @validate_call(config=ConfigDict(arbitrary_types_allowed=True))
18
+ def erode_image(
19
+ image: Annotated[ImageAny, Field(description="Input image to perform erosion on")],
20
+ structuring_element: Annotated[Union[StructuringElement, StructuringElementParameters], Field(description="Structuring element for erosion operation as either an NDArray or a tuple of (StructuringElement[N]D, size)")]
21
+ ) -> ImageAny:
22
+ """Apply morphological erosion to an image.
23
+
24
+ Args:
25
+ image: Input image (2D or 3D grayscale)
26
+ structuring_element: Structuring element for erosion operation as an NDArray or a tuple of (StructuringElement[N]D, size)
27
+
28
+ Returns:
29
+ Eroded image with same dimensions and type as input
30
+
31
+ Raises:
32
+ NotImplementedError: If trying to apply 3D structuring element to 2D image
33
+ """
34
+ if isinstance(structuring_element, tuple):
35
+ structuring_element = get_structuring_element(structuring_element[0], structuring_element[1])
36
+ return morphology_erosion(image, structuring_element)
@@ -0,0 +1,41 @@
1
+ from enum import Enum
2
+
3
+ class Shape(str, Enum):
4
+ RECTANGLE = "Rectangle"
5
+ ELLIPSE = "Ellipse"
6
+ IMAGE = "Image"
7
+ OBJECTS = "Objects"
8
+ CROPPING = "Previous cropping"
9
+
10
+ class RemovalMethod(str, Enum):
11
+ NO = "No"
12
+ EDGES = "Edges"
13
+ ALL = "All"
14
+
15
+ class Measurement(str, Enum):
16
+ AREA_RETAINED = "Crop_AreaRetainedAfterCropping_%s"
17
+ ORIGINAL_AREA = "Crop_OriginalImageArea_%s"
18
+
19
+ class CroppingMethod(str, Enum):
20
+ COORDINATES = "Coordinates"
21
+ MOUSE = "Mouse"
22
+
23
+ class CroppingPattern(str, Enum):
24
+ FIRST = "First"
25
+ INDIVIDUALLY = "Individually"
26
+
27
+ class Limits(str, Enum):
28
+ ABSOLUTE = "Absolute"
29
+ FROM_EDGE = "From edge"
30
+
31
+ class Ellipse(str, Enum):
32
+ XCENTER = "xcenter"
33
+ YCENTER = "ycenter"
34
+ XRADIUS = "xradius"
35
+ YRADIUS = "yradius"
36
+
37
+ class Rectangle(str, Enum):
38
+ LEFT = "left"
39
+ TOP = "top"
40
+ RIGHT = "right"
41
+ BOTTOM = "bottom"
@@ -0,0 +1,14 @@
1
+ # coding=utf-8
2
+
3
+ """
4
+ Options and enums for ErodeImage module
5
+ """
6
+
7
+ # Note: ErodeImage is a simple morphological operation module that doesn't require
8
+ # complex enums. The main configuration is handled through the StructuringElement
9
+ # setting which is managed by the core framework. This file is created for
10
+ # consistency with the refactoring pattern but may be minimal.
11
+
12
+ # Currently no custom enums needed for ErodeImage as it uses standard
13
+ # StructuringElement configuration from cellprofiler_core. For structuring element shapes,
14
+ # see cellprofiler_library.opts.structuring_elements
@@ -0,0 +1,12 @@
1
+ from enum import Enum
2
+
3
+ class StructuringElementShape2D(str, Enum):
4
+ DIAMOND = "Diamond"
5
+ DISK = "Disk"
6
+ SQUARE = "Square"
7
+ STAR = "Star"
8
+
9
+ class StructuringElementShape3D(str, Enum):
10
+ BALL = "Ball"
11
+ CUBE = "Cube"
12
+ OCTAHEDRON = "Octahedron"
@@ -117,3 +117,5 @@ Image3D = Union[Image3DColor, Image3DGrayscale, Image3DBinary]
117
117
  Image3DMask = Union[Image3DColorMask, Image3DGrayscaleMask]
118
118
 
119
119
  ImageInt = Union[Image2DInt, Image3DInt]
120
+
121
+ StructuringElement = NDArray[np.uint8]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cellprofiler-library-nightly
3
- Version: 5.0.0.dev318
3
+ Version: 5.0.0.dev324
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>
@@ -1,10 +1,10 @@
1
1
  cellprofiler_library/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- cellprofiler_library/_version.py,sha256=VKwI68zHVxr7qKLpGyfYE5ws8C3HO1sHftyVZcFWLQk,721
2
+ cellprofiler_library/_version.py,sha256=X_dsIS438JBC3vSFB9YEnaGPIPrvCqTB7mibbwXlkv0,721
3
3
  cellprofiler_library/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- cellprofiler_library/types.py,sha256=5cCxXOO_TE-uSF4ZB6sDG3eTZ1VWDSXUFifg0N4JYs8,8516
4
+ cellprofiler_library/types.py,sha256=cU38AwLLsMiI3XCwfrmWmDNpGWgLfpCpsuwnijaT8vU,8559
5
5
  cellprofiler_library/functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  cellprofiler_library/functions/file_processing.py,sha256=jumpdgxReyV5xzF4YXZWhkei9CQ9GtWD-VUCuFh-FZM,5168
7
- cellprofiler_library/functions/image_processing.py,sha256=3mGdRhWaVUqCxIh1hjde6Ffnq_wJfJAWxZZU3MNfQkM,24780
7
+ cellprofiler_library/functions/image_processing.py,sha256=SMt7vykb0nvEEFoo0VGNRDORSjLAZuxW2AQZOND-jjw,34874
8
8
  cellprofiler_library/functions/measurement.py,sha256=8pXcEb1fLgwOEDiTJho1_O-fFGTtIp-Qn1lStjQBjbo,29221
9
9
  cellprofiler_library/functions/object_processing.py,sha256=3cKNq5ewBf_HWz6rdX3XR4WUbd6SklbHZ_H40xt9ODM,19443
10
10
  cellprofiler_library/functions/segmentation.py,sha256=LNE22ByY0X7GepQaHqLdxkzlmIXjD3EglAYJjtT2dGo,25257
@@ -15,7 +15,9 @@ cellprofiler_library/modules/_combineobjects.py,sha256=dZz0RXjvVukem3e46wPfQWOQC
15
15
  cellprofiler_library/modules/_convertimagetoobjects.py,sha256=_X2YWEHK4hFaP13LEBD-vIwwUUhgJEJLcTkhyMe4JBA,1075
16
16
  cellprofiler_library/modules/_convertobjectstoimage.py,sha256=PMYjH_prBKma4LNgUxmA5GzF7fQ6ko09XszKatTulB4,2274
17
17
  cellprofiler_library/modules/_correctilluminationapply.py,sha256=8bZC3AnQv3vpUrNSnLvcc_s0E-P63XbrfwMv7OZNjt4,2084
18
+ cellprofiler_library/modules/_crop.py,sha256=0T0sQsK7o5dHVXMZ4OqvAJkskkyez1MXcnPlU5yqsV4,2422
18
19
  cellprofiler_library/modules/_enhanceedges.py,sha256=PaXZck8fPcxRf-IXCstu-OWmsvM_rDDPMMQ3cZFfVZc,2951
20
+ cellprofiler_library/modules/_erodeimage.py,sha256=nFHn4hdpjXJaPvnpSyfPAxWgd7UXi0fUUgPqEl26CCY,1802
19
21
  cellprofiler_library/modules/_expandorshrinkobjects.py,sha256=A1oeW_O8C5NLJr-xU1R9pSulDau8XUeWaKiilpr-85g,856
20
22
  cellprofiler_library/modules/_fillobjects.py,sha256=1zvlZNJhG8kEzAnVyiSLGPNE338EB5wopD2eK0BVWrc,469
21
23
  cellprofiler_library/modules/_gaussianfilter.py,sha256=zVt562oviuoyy6l85Tgg_rjyQdOFCEnYLuykHYnYni8,174
@@ -35,11 +37,14 @@ cellprofiler_library/opts/colortogray.py,sha256=ptAanLQW9iMgQHgC7xvYlbIbshBd5d7u
35
37
  cellprofiler_library/opts/convertimagetoobjects.py,sha256=9e3VOdpjd4084ATZyFtSQg_VpxbyXrYVFmEFJkrHakg,67
36
38
  cellprofiler_library/opts/convertobjectstoimage.py,sha256=U3jeVtKYFgfxbO7NYndanAyZFoEvbyScOq4T8cpjfX8,188
37
39
  cellprofiler_library/opts/correctilluminationapply.py,sha256=IkAqjMjaRdsoY2aXw5_dLI1iRYqCwvcNwCWEpWNZrN4,96
40
+ cellprofiler_library/opts/crop.py,sha256=GaArWq3WZd_Ykunj1SSbFOYkqDQ6TXy2MDKxG4fA6ZE,879
41
+ cellprofiler_library/opts/erodeimage.py,sha256=T3LCqu83rTqTDlc_7ebuPBKnr-FKomRHA8WD0uA9Y1g,584
38
42
  cellprofiler_library/opts/measureimageoverlap.py,sha256=uopQCJTX1Uk-NNDAISsdYEOuOtiEBYOyCwu57ZT7X84,134
39
43
  cellprofiler_library/opts/objectsizeshapefeatures.py,sha256=3GIntOH3qXs7F16Tpjmtg7opHYAmmOjEdEwW6q3ht_Y,6306
44
+ cellprofiler_library/opts/structuring_elements.py,sha256=Q4pBdCgDmjPx05t61Zqi40Iof8Nj3UR5k-F7brImLZY,263
40
45
  cellprofiler_library/opts/threshold.py,sha256=yg_i5to22Nd9hTakaRxo9UIQZRYWFpavJimjl5JONx4,938
41
- cellprofiler_library_nightly-5.0.0.dev318.dist-info/licenses/LICENSE,sha256=QLWaBS7kAioYx7PmJNXAMJaY8NODcFAag60YlUWuyz0,2276
42
- cellprofiler_library_nightly-5.0.0.dev318.dist-info/METADATA,sha256=knZAToPornredt8suy093xlyBp6eTYhKl4A_wEElejs,5534
43
- cellprofiler_library_nightly-5.0.0.dev318.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
- cellprofiler_library_nightly-5.0.0.dev318.dist-info/top_level.txt,sha256=LXq0ApDeDD4gotb6YFTySzdyScvHfS_pqoTg1QsNLBs,21
45
- cellprofiler_library_nightly-5.0.0.dev318.dist-info/RECORD,,
46
+ cellprofiler_library_nightly-5.0.0.dev324.dist-info/licenses/LICENSE,sha256=QLWaBS7kAioYx7PmJNXAMJaY8NODcFAag60YlUWuyz0,2276
47
+ cellprofiler_library_nightly-5.0.0.dev324.dist-info/METADATA,sha256=v47gHLjhRnydgeEgCJO2nxodQTAvyIRGVILWkhb2CXs,5534
48
+ cellprofiler_library_nightly-5.0.0.dev324.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ cellprofiler_library_nightly-5.0.0.dev324.dist-info/top_level.txt,sha256=LXq0ApDeDD4gotb6YFTySzdyScvHfS_pqoTg1QsNLBs,21
50
+ cellprofiler_library_nightly-5.0.0.dev324.dist-info/RECORD,,