cellprofiler-library-nightly 5.0.0.dev340__tar.gz → 5.0.0.dev351__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.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/PKG-INFO +1 -1
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/_version.py +3 -3
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/functions/image_processing.py +217 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/functions/object_processing.py +47 -0
- cellprofiler_library_nightly-5.0.0.dev351/cellprofiler_library/modules/_dilateobjects.py +46 -0
- cellprofiler_library_nightly-5.0.0.dev351/cellprofiler_library/modules/_morph.py +128 -0
- cellprofiler_library_nightly-5.0.0.dev351/cellprofiler_library/opts/dilateobjects.py +15 -0
- cellprofiler_library_nightly-5.0.0.dev351/cellprofiler_library/opts/morph.py +44 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library_nightly.egg-info/PKG-INFO +1 -1
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library_nightly.egg-info/SOURCES.txt +4 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/LICENSE +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/README.md +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/functions/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/functions/file_processing.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/functions/measurement.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/functions/segmentation.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_closing.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_colortogray.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_combineobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_convertimagetoobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_convertobjectstoimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_correctilluminationapply.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_crop.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_dilateimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_enhanceedges.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_enhanceorsuppressfeatures.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_erodeimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_erodeobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_expandorshrinkobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_fillobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_gaussianfilter.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_measureimageoverlap.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_measureobjectsizeshape.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_medialaxis.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_medianfilter.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_morphologicalskeleton.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_opening.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_overlayobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_reducenoise.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_savecroppedobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_threshold.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/modules/_watershed.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/__init__.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/colortogray.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/convertimagetoobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/convertobjectstoimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/correctilluminationapply.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/crop.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/dilateimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/enhanceorsuppressfeatures.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/erodeimage.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/erodeobjects.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/measureimageoverlap.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/objectsizeshapefeatures.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/structuring_elements.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/opts/threshold.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/py.typed +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library/types.py +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library_nightly.egg-info/dependency_links.txt +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library_nightly.egg-info/requires.txt +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/cellprofiler_library_nightly.egg-info/top_level.txt +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/environment.yml +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/pyproject.toml +0 -0
- {cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/setup.cfg +0 -0
{cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/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.dev351
|
|
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.dev351'
|
|
32
|
+
__version_tuple__ = version_tuple = (5, 0, 0, 'dev351')
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gf1998bdae'
|
|
@@ -16,6 +16,7 @@ from cellprofiler_library.opts.crop import RemovalMethod
|
|
|
16
16
|
from cellprofiler_library.opts.structuring_elements import StructuringElementShape2D, StructuringElementShape3D
|
|
17
17
|
|
|
18
18
|
T = TypeVar("T", bound=ImageAny)
|
|
19
|
+
MorphImageT = TypeVar("Union[ImageGrayscale, ImageGrayscaleMask]", bound=Union[ImageGrayscale, ImageGrayscaleMask])
|
|
19
20
|
|
|
20
21
|
def rgb_to_greyscale(image):
|
|
21
22
|
if image.shape[-1] == 4:
|
|
@@ -1128,3 +1129,219 @@ def suppress(
|
|
|
1128
1129
|
footprint = __structuring_element(radius, im_volumetric)
|
|
1129
1130
|
result = skimage.morphology.opening(data, footprint)
|
|
1130
1131
|
return __unmask(result, im_pixel_data, im_mask)
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
################################################################################
|
|
1135
|
+
# Morphological Operations (from Morph module)
|
|
1136
|
+
################################################################################
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
def apply_branchpoints(
|
|
1140
|
+
pixel_data: MorphImageT,
|
|
1141
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1142
|
+
) -> MorphImageT:
|
|
1143
|
+
"""Apply branchpoints morphological operation.
|
|
1144
|
+
|
|
1145
|
+
Removes all pixels except those that are the branchpoints of a skeleton.
|
|
1146
|
+
This operation should be applied to an image after skeletonizing.
|
|
1147
|
+
"""
|
|
1148
|
+
return centrosome.cpmorphology.branchpoints(pixel_data, mask)
|
|
1149
|
+
|
|
1150
|
+
def apply_bridge(
|
|
1151
|
+
pixel_data: MorphImageT,
|
|
1152
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1153
|
+
count: int,
|
|
1154
|
+
) -> MorphImageT:
|
|
1155
|
+
"""Apply bridge morphological operation.
|
|
1156
|
+
|
|
1157
|
+
Sets a pixel to 1 if it has two non-zero neighbors that are on
|
|
1158
|
+
opposite sides of this pixel.
|
|
1159
|
+
"""
|
|
1160
|
+
return centrosome.cpmorphology.bridge(pixel_data, mask, count)
|
|
1161
|
+
|
|
1162
|
+
def apply_clean(
|
|
1163
|
+
pixel_data: MorphImageT,
|
|
1164
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1165
|
+
count: int,
|
|
1166
|
+
) -> ImageGrayscale:
|
|
1167
|
+
"""Apply clean morphological operation.
|
|
1168
|
+
|
|
1169
|
+
Removes isolated pixels.
|
|
1170
|
+
"""
|
|
1171
|
+
return centrosome.cpmorphology.clean(pixel_data, mask, count)
|
|
1172
|
+
|
|
1173
|
+
def apply_convex_hull(
|
|
1174
|
+
pixel_data: MorphImageT,
|
|
1175
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1176
|
+
) -> ImageGrayscale:
|
|
1177
|
+
"""Apply convex hull morphological operation.
|
|
1178
|
+
|
|
1179
|
+
Finds the convex hull of a binary image.
|
|
1180
|
+
"""
|
|
1181
|
+
if mask is None:
|
|
1182
|
+
return centrosome.cpmorphology.convex_hull_image(pixel_data)
|
|
1183
|
+
else:
|
|
1184
|
+
return centrosome.cpmorphology.convex_hull_image(pixel_data & mask)
|
|
1185
|
+
|
|
1186
|
+
def apply_diag(
|
|
1187
|
+
pixel_data: MorphImageT,
|
|
1188
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1189
|
+
count: int,
|
|
1190
|
+
) -> ImageGrayscale:
|
|
1191
|
+
"""Apply diag morphological operation.
|
|
1192
|
+
|
|
1193
|
+
Fills in pixels whose neighbors are diagonally connected to 4-connect
|
|
1194
|
+
pixels that are 8-connected.
|
|
1195
|
+
"""
|
|
1196
|
+
return centrosome.cpmorphology.diag(pixel_data, mask, count)
|
|
1197
|
+
|
|
1198
|
+
def apply_distance(
|
|
1199
|
+
pixel_data: MorphImageT,
|
|
1200
|
+
rescale_values: bool,
|
|
1201
|
+
) -> ImageGrayscale:
|
|
1202
|
+
"""Apply distance transform morphological operation.
|
|
1203
|
+
|
|
1204
|
+
Computes the distance transform of a binary image.
|
|
1205
|
+
"""
|
|
1206
|
+
image = scipy.ndimage.distance_transform_edt(pixel_data)
|
|
1207
|
+
if rescale_values:
|
|
1208
|
+
image = image / numpy.max(image)
|
|
1209
|
+
return image
|
|
1210
|
+
|
|
1211
|
+
def apply_endpoints(
|
|
1212
|
+
pixel_data: MorphImageT,
|
|
1213
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1214
|
+
) -> ImageGrayscale:
|
|
1215
|
+
"""Apply endpoints morphological operation.
|
|
1216
|
+
|
|
1217
|
+
Removes all pixels except the ones that are at the end of a skeleton.
|
|
1218
|
+
"""
|
|
1219
|
+
return centrosome.cpmorphology.endpoints(pixel_data, mask)
|
|
1220
|
+
|
|
1221
|
+
def apply_fill(
|
|
1222
|
+
pixel_data: MorphImageT,
|
|
1223
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1224
|
+
count: int,
|
|
1225
|
+
) -> ImageGrayscale:
|
|
1226
|
+
"""Apply fill morphological operation.
|
|
1227
|
+
|
|
1228
|
+
Sets a pixel to 1 if all of its neighbors are 1.
|
|
1229
|
+
"""
|
|
1230
|
+
return centrosome.cpmorphology.fill(pixel_data, mask, count)
|
|
1231
|
+
|
|
1232
|
+
def apply_hbreak(
|
|
1233
|
+
pixel_data: MorphImageT,
|
|
1234
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1235
|
+
count: int,
|
|
1236
|
+
) -> ImageGrayscale:
|
|
1237
|
+
"""Apply hbreak morphological operation.
|
|
1238
|
+
|
|
1239
|
+
Removes pixels that form vertical bridges between horizontal lines.
|
|
1240
|
+
"""
|
|
1241
|
+
return centrosome.cpmorphology.hbreak(pixel_data, mask, count)
|
|
1242
|
+
|
|
1243
|
+
def apply_majority(
|
|
1244
|
+
pixel_data: MorphImageT,
|
|
1245
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1246
|
+
count: int,
|
|
1247
|
+
) -> ImageGrayscale:
|
|
1248
|
+
"""Apply majority morphological operation.
|
|
1249
|
+
|
|
1250
|
+
Each pixel takes on the value of the majority that surround it.
|
|
1251
|
+
"""
|
|
1252
|
+
return centrosome.cpmorphology.majority(pixel_data, mask, count)
|
|
1253
|
+
|
|
1254
|
+
def apply_openlines(
|
|
1255
|
+
pixel_data: MorphImageT,
|
|
1256
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1257
|
+
linelength: int,
|
|
1258
|
+
) -> ImageGrayscale:
|
|
1259
|
+
"""Apply openlines morphological operation.
|
|
1260
|
+
|
|
1261
|
+
Performs an erosion followed by a dilation using rotating linear structural
|
|
1262
|
+
elements.
|
|
1263
|
+
"""
|
|
1264
|
+
return centrosome.cpmorphology.openlines(pixel_data, linelength=linelength, mask=mask)
|
|
1265
|
+
|
|
1266
|
+
def apply_remove(
|
|
1267
|
+
pixel_data: MorphImageT,
|
|
1268
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1269
|
+
count: int,
|
|
1270
|
+
) -> ImageGrayscale:
|
|
1271
|
+
"""Apply remove morphological operation.
|
|
1272
|
+
|
|
1273
|
+
Removes pixels that are otherwise surrounded by others (4 connected).
|
|
1274
|
+
"""
|
|
1275
|
+
return centrosome.cpmorphology.remove(pixel_data, mask, count)
|
|
1276
|
+
|
|
1277
|
+
def apply_shrink(
|
|
1278
|
+
pixel_data: MorphImageT,
|
|
1279
|
+
count: int,
|
|
1280
|
+
) -> ImageGrayscale:
|
|
1281
|
+
"""Apply shrink morphological operation.
|
|
1282
|
+
|
|
1283
|
+
Performs a thinning operation that erodes unless that operation would change
|
|
1284
|
+
the image's Euler number.
|
|
1285
|
+
"""
|
|
1286
|
+
return centrosome.cpmorphology.binary_shrink(pixel_data, count)
|
|
1287
|
+
|
|
1288
|
+
def apply_skelpe(
|
|
1289
|
+
pixel_data: MorphImageT,
|
|
1290
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1291
|
+
) -> ImageGrayscale:
|
|
1292
|
+
"""Apply skelpe morphological operation.
|
|
1293
|
+
|
|
1294
|
+
Performs a skeletonizing operation using the metric, PE * D to control the
|
|
1295
|
+
erosion order.
|
|
1296
|
+
"""
|
|
1297
|
+
return centrosome.cpmorphology.skeletonize(
|
|
1298
|
+
pixel_data,
|
|
1299
|
+
mask,
|
|
1300
|
+
scipy.ndimage.distance_transform_edt(pixel_data)
|
|
1301
|
+
* centrosome.filter.poisson_equation(pixel_data),
|
|
1302
|
+
)
|
|
1303
|
+
|
|
1304
|
+
def apply_spur(
|
|
1305
|
+
pixel_data: MorphImageT,
|
|
1306
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1307
|
+
count: int,
|
|
1308
|
+
) -> ImageGrayscale:
|
|
1309
|
+
"""Apply spur morphological operation.
|
|
1310
|
+
|
|
1311
|
+
Removes spur pixels, i.e., pixels that have exactly one 8-connected neighbor.
|
|
1312
|
+
"""
|
|
1313
|
+
return centrosome.cpmorphology.spur(pixel_data, mask, count)
|
|
1314
|
+
|
|
1315
|
+
def apply_thicken(
|
|
1316
|
+
pixel_data: MorphImageT,
|
|
1317
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1318
|
+
count: int,
|
|
1319
|
+
) -> ImageGrayscale:
|
|
1320
|
+
"""Apply thicken morphological operation.
|
|
1321
|
+
|
|
1322
|
+
Dilates the exteriors of objects where that dilation does not 8-connect the
|
|
1323
|
+
object with another.
|
|
1324
|
+
"""
|
|
1325
|
+
return centrosome.cpmorphology.thicken(pixel_data, mask, count)
|
|
1326
|
+
|
|
1327
|
+
def apply_thin(
|
|
1328
|
+
pixel_data: MorphImageT,
|
|
1329
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1330
|
+
count: int,
|
|
1331
|
+
) -> ImageGrayscale:
|
|
1332
|
+
"""Apply thin morphological operation.
|
|
1333
|
+
|
|
1334
|
+
Thin lines preserving the Euler number using the thinning algorithm.
|
|
1335
|
+
"""
|
|
1336
|
+
return centrosome.cpmorphology.thin(pixel_data, mask, count)
|
|
1337
|
+
|
|
1338
|
+
def apply_vbreak(
|
|
1339
|
+
pixel_data: MorphImageT,
|
|
1340
|
+
mask: Optional[ImageGrayscaleMask],
|
|
1341
|
+
) -> ImageGrayscale:
|
|
1342
|
+
"""Apply vbreak morphological operation.
|
|
1343
|
+
|
|
1344
|
+
Removes pixels that form horizontal bridges between vertical lines.
|
|
1345
|
+
"""
|
|
1346
|
+
return centrosome.cpmorphology.vbreak(pixel_data, mask)
|
|
1347
|
+
|
|
@@ -629,3 +629,50 @@ def erode_objects_with_structuring_element(
|
|
|
629
629
|
|
|
630
630
|
return y_data
|
|
631
631
|
|
|
632
|
+
################################################################################
|
|
633
|
+
# DilateObjects
|
|
634
|
+
################################################################################
|
|
635
|
+
|
|
636
|
+
def dilate_objects_with_structuring_element(
|
|
637
|
+
labels: ObjectSegmentation,
|
|
638
|
+
structuring_element: StructuringElement
|
|
639
|
+
) -> ObjectSegmentation:
|
|
640
|
+
"""Dilate objects based on the structuring element provided.
|
|
641
|
+
|
|
642
|
+
This function is similar to the "Expand" function of ExpandOrShrinkObjects,
|
|
643
|
+
with two major distinctions:
|
|
644
|
+
1. DilateObjects supports 3D objects, unlike ExpandOrShrinkObjects.
|
|
645
|
+
2. In ExpandOrShrinkObjects, two objects closer than the expansion distance
|
|
646
|
+
will expand until they meet and then stop there. In this module, the object with
|
|
647
|
+
the larger object number (the object that is lower in the image) will be expanded
|
|
648
|
+
on top of the object with the smaller object number.
|
|
649
|
+
|
|
650
|
+
Args:
|
|
651
|
+
labels: Input labeled objects array
|
|
652
|
+
structuring_element: Structuring element for dilation operation
|
|
653
|
+
|
|
654
|
+
Returns:
|
|
655
|
+
Dilated objects array with same dimensions as input
|
|
656
|
+
"""
|
|
657
|
+
is_strel_2d = structuring_element.ndim == 2
|
|
658
|
+
|
|
659
|
+
is_img_2d = labels.ndim == 2
|
|
660
|
+
|
|
661
|
+
if is_strel_2d and not is_img_2d:
|
|
662
|
+
y_data = numpy.zeros_like(labels)
|
|
663
|
+
|
|
664
|
+
for index, plane in enumerate(labels):
|
|
665
|
+
|
|
666
|
+
y_data[index] = skimage.morphology.dilation(plane, structuring_element)
|
|
667
|
+
|
|
668
|
+
return y_data
|
|
669
|
+
|
|
670
|
+
if not is_strel_2d and is_img_2d:
|
|
671
|
+
raise NotImplementedError(
|
|
672
|
+
"A 3D structuring element cannot be applied to a 2D image."
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
y_data = skimage.morphology.dilation(labels, structuring_element)
|
|
676
|
+
|
|
677
|
+
return y_data
|
|
678
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
DilateObjects module for the CellProfiler library.
|
|
5
|
+
|
|
6
|
+
This module contains the core algorithms for object dilation operations.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from pydantic import validate_call, ConfigDict, Field
|
|
10
|
+
from typing import Union, Tuple, Annotated
|
|
11
|
+
from cellprofiler_library.types import StructuringElement, ObjectSegmentation
|
|
12
|
+
from cellprofiler_library.functions.object_processing import dilate_objects_with_structuring_element
|
|
13
|
+
from cellprofiler_library.functions.image_processing import get_structuring_element
|
|
14
|
+
from cellprofiler_library.opts.structuring_elements import StructuringElementShape2D, StructuringElementShape3D
|
|
15
|
+
|
|
16
|
+
StructuringElementSize = Annotated[int, Field(description="Size of structuring element", gt=0)]
|
|
17
|
+
StructuringElementParameters = Tuple[Union[StructuringElementShape2D, StructuringElementShape3D], StructuringElementSize]
|
|
18
|
+
|
|
19
|
+
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
|
20
|
+
def dilate_objects(
|
|
21
|
+
labels: Annotated[ObjectSegmentation, Field(description="Input object segmentations")],
|
|
22
|
+
structuring_element: Annotated[Union[StructuringElement, StructuringElementParameters], Field(description="Structuring element for dilation operation as either an NDArray or a tuple of (StructuringElement[N]D, size)")],
|
|
23
|
+
) -> ObjectSegmentation:
|
|
24
|
+
"""Dilate objects based on the structuring element provided.
|
|
25
|
+
|
|
26
|
+
This function is similar to the "Expand" function of ExpandOrShrinkObjects,
|
|
27
|
+
with two major distinctions:
|
|
28
|
+
1. DilateObjects supports 3D objects, unlike ExpandOrShrinkObjects.
|
|
29
|
+
2. In ExpandOrShrinkObjects, two objects closer than the expansion distance
|
|
30
|
+
will expand until they meet and then stop there. In this module, the object with
|
|
31
|
+
the larger object number (the object that is lower in the image) will be expanded
|
|
32
|
+
on top of the object with the smaller object number.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
labels: Input labeled objects array
|
|
36
|
+
structuring_element: Structuring element for dilation operation
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Dilated objects array with same dimensions as input
|
|
40
|
+
"""
|
|
41
|
+
if isinstance(structuring_element, tuple):
|
|
42
|
+
structuring_element = get_structuring_element(structuring_element[0], structuring_element[1])
|
|
43
|
+
return dilate_objects_with_structuring_element(
|
|
44
|
+
labels=labels,
|
|
45
|
+
structuring_element=structuring_element
|
|
46
|
+
)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Annotated, Optional, List, Dict, Any
|
|
3
|
+
from pydantic import validate_call, Field, ConfigDict
|
|
4
|
+
|
|
5
|
+
from ..opts.morph import MorphFunction
|
|
6
|
+
from ..functions.image_processing import (
|
|
7
|
+
apply_branchpoints,
|
|
8
|
+
apply_bridge,
|
|
9
|
+
apply_clean,
|
|
10
|
+
apply_convex_hull,
|
|
11
|
+
apply_diag,
|
|
12
|
+
apply_distance,
|
|
13
|
+
apply_endpoints,
|
|
14
|
+
apply_fill,
|
|
15
|
+
apply_hbreak,
|
|
16
|
+
apply_majority,
|
|
17
|
+
apply_openlines,
|
|
18
|
+
apply_remove,
|
|
19
|
+
apply_shrink,
|
|
20
|
+
apply_skelpe,
|
|
21
|
+
apply_spur,
|
|
22
|
+
apply_thicken,
|
|
23
|
+
apply_thin,
|
|
24
|
+
apply_vbreak,
|
|
25
|
+
MorphImageT
|
|
26
|
+
)
|
|
27
|
+
from ..types import ImageGrayscaleMask
|
|
28
|
+
|
|
29
|
+
LOGGER = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
def morph_operation(
|
|
32
|
+
pixel_data: Annotated[MorphImageT, Field(description="Image array supporting binary, integer, or float types")],
|
|
33
|
+
mask: Annotated[Optional[ImageGrayscaleMask], Field(description="Optional boolean mask array")],
|
|
34
|
+
function_name: Annotated[MorphFunction, Field(description="Morphological operation to perform")],
|
|
35
|
+
repeat_count: Annotated[int, Field(description="Number of times to repeat the operation", ge=1)],
|
|
36
|
+
custom_repeats: Annotated[int, Field(description="Custom repeat value for specific operations", ge=1)],
|
|
37
|
+
rescale_values: Annotated[bool, Field(description="Whether to rescale distance values from 0 to 1")],
|
|
38
|
+
) -> MorphImageT:
|
|
39
|
+
"""Apply a morphological operation to the image, routing to appropriate function from functions layer."""
|
|
40
|
+
count = repeat_count
|
|
41
|
+
|
|
42
|
+
is_binary = pixel_data.dtype.kind == "b"
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
function_name != MorphFunction.OPENLINES and not is_binary
|
|
46
|
+
):
|
|
47
|
+
# Apply a very crude threshold to the image for binary algorithms
|
|
48
|
+
LOGGER.warning(
|
|
49
|
+
"Warning: converting image to binary for %s\n" % function_name
|
|
50
|
+
)
|
|
51
|
+
pixel_data = pixel_data != 0
|
|
52
|
+
|
|
53
|
+
# Route to appropriate function from functions layer
|
|
54
|
+
if function_name == MorphFunction.BRANCHPOINTS:
|
|
55
|
+
return apply_branchpoints(pixel_data, mask)
|
|
56
|
+
elif function_name == MorphFunction.BRIDGE:
|
|
57
|
+
return apply_bridge(pixel_data, mask, count)
|
|
58
|
+
elif function_name == MorphFunction.CLEAN:
|
|
59
|
+
return apply_clean(pixel_data, mask, count)
|
|
60
|
+
elif function_name == MorphFunction.CONVEX_HULL:
|
|
61
|
+
return apply_convex_hull(pixel_data, mask)
|
|
62
|
+
elif function_name == MorphFunction.DIAG:
|
|
63
|
+
return apply_diag(pixel_data, mask, count)
|
|
64
|
+
elif function_name == MorphFunction.DISTANCE:
|
|
65
|
+
return apply_distance(pixel_data, rescale_values)
|
|
66
|
+
elif function_name == MorphFunction.ENDPOINTS:
|
|
67
|
+
return apply_endpoints(pixel_data, mask)
|
|
68
|
+
elif function_name == MorphFunction.FILL:
|
|
69
|
+
return apply_fill(pixel_data, mask, count)
|
|
70
|
+
elif function_name == MorphFunction.HBREAK:
|
|
71
|
+
return apply_hbreak(pixel_data, mask, count)
|
|
72
|
+
elif function_name == MorphFunction.MAJORITY:
|
|
73
|
+
return apply_majority(pixel_data, mask, count)
|
|
74
|
+
elif function_name == MorphFunction.OPENLINES:
|
|
75
|
+
return apply_openlines(pixel_data, mask, custom_repeats)
|
|
76
|
+
elif function_name == MorphFunction.REMOVE:
|
|
77
|
+
return apply_remove(pixel_data, mask, count)
|
|
78
|
+
elif function_name == MorphFunction.SHRINK:
|
|
79
|
+
return apply_shrink(pixel_data, count)
|
|
80
|
+
elif function_name == MorphFunction.SKELPE:
|
|
81
|
+
return apply_skelpe(pixel_data, mask)
|
|
82
|
+
elif function_name == MorphFunction.SPUR:
|
|
83
|
+
return apply_spur(pixel_data, mask, count)
|
|
84
|
+
elif function_name == MorphFunction.THICKEN:
|
|
85
|
+
return apply_thicken(pixel_data, mask, count)
|
|
86
|
+
elif function_name == MorphFunction.THIN:
|
|
87
|
+
return apply_thin(pixel_data, mask, count)
|
|
88
|
+
elif function_name == MorphFunction.VBREAK:
|
|
89
|
+
return apply_vbreak(pixel_data, mask)
|
|
90
|
+
else:
|
|
91
|
+
raise NotImplementedError(
|
|
92
|
+
"Unimplemented morphological function: %s" % function_name
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
|
|
97
|
+
def apply_morphological_operations(
|
|
98
|
+
pixel_data: Annotated[MorphImageT, Field(description="Image array supporting binary, integer, or float types")],
|
|
99
|
+
mask: Annotated[Optional[ImageGrayscaleMask], Field(description="Optional boolean mask array")] = None,
|
|
100
|
+
operations_list: Annotated[List[Dict[str, Any]], Field(description="List of morphological operations to apply sequentially")] = [],
|
|
101
|
+
) -> MorphImageT:
|
|
102
|
+
"""Apply a sequence of morphological operations to the image.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
pixel_data: Input image pixel data to process
|
|
106
|
+
mask: Optional image mask to constrain operations
|
|
107
|
+
operations_list: List of operation dictionaries, each containing:
|
|
108
|
+
- function_name: Name of morphological operation (MorphFunction enum)
|
|
109
|
+
- repeat_count: Number of times to repeat the operation
|
|
110
|
+
- custom_repeats: Custom repeat value for specific operations
|
|
111
|
+
- rescale_values: Whether to rescale distance values from 0 to 1
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Processed pixel data array with applied morphological operations
|
|
115
|
+
"""
|
|
116
|
+
result_pixel_data = pixel_data
|
|
117
|
+
|
|
118
|
+
for operation in operations_list:
|
|
119
|
+
result_pixel_data = morph_operation(
|
|
120
|
+
result_pixel_data,
|
|
121
|
+
mask,
|
|
122
|
+
operation["function_name"],
|
|
123
|
+
operation["repeat_count"],
|
|
124
|
+
operation["custom_repeats"],
|
|
125
|
+
operation["rescale_values"]
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return result_pixel_data
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Options and enums for DilateObjects module
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Note: DilateObjects 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 DilateObjects as it uses standard
|
|
13
|
+
# StructuringElement configuration from cellprofiler_core. For structuring element shapes,
|
|
14
|
+
# see cellprofiler_library.opts.structuring_elements
|
|
15
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class MorphFunction(str, Enum):
|
|
5
|
+
"""Morphological operations available in the Morph module."""
|
|
6
|
+
BRANCHPOINTS = "branchpoints"
|
|
7
|
+
BRIDGE = "bridge"
|
|
8
|
+
CLEAN = "clean"
|
|
9
|
+
CONVEX_HULL = "convex hull"
|
|
10
|
+
DIAG = "diag"
|
|
11
|
+
DISTANCE = "distance"
|
|
12
|
+
ENDPOINTS = "endpoints"
|
|
13
|
+
FILL = "fill"
|
|
14
|
+
HBREAK = "hbreak"
|
|
15
|
+
MAJORITY = "majority"
|
|
16
|
+
OPENLINES = "openlines"
|
|
17
|
+
REMOVE = "remove"
|
|
18
|
+
SHRINK = "shrink"
|
|
19
|
+
SKELPE = "skelpe"
|
|
20
|
+
SPUR = "spur"
|
|
21
|
+
THICKEN = "thicken"
|
|
22
|
+
THIN = "thin"
|
|
23
|
+
VBREAK = "vbreak"
|
|
24
|
+
|
|
25
|
+
MorphFunctions_All = [
|
|
26
|
+
MorphFunction.BRANCHPOINTS.value,
|
|
27
|
+
MorphFunction.BRIDGE.value,
|
|
28
|
+
MorphFunction.CLEAN.value,
|
|
29
|
+
MorphFunction.CONVEX_HULL.value,
|
|
30
|
+
MorphFunction.DIAG.value,
|
|
31
|
+
MorphFunction.DISTANCE.value,
|
|
32
|
+
MorphFunction.ENDPOINTS.value,
|
|
33
|
+
MorphFunction.FILL.value,
|
|
34
|
+
MorphFunction.HBREAK.value,
|
|
35
|
+
MorphFunction.MAJORITY.value,
|
|
36
|
+
MorphFunction.OPENLINES.value,
|
|
37
|
+
MorphFunction.REMOVE.value,
|
|
38
|
+
MorphFunction.SHRINK.value,
|
|
39
|
+
MorphFunction.SKELPE.value,
|
|
40
|
+
MorphFunction.SPUR.value,
|
|
41
|
+
MorphFunction.THICKEN.value,
|
|
42
|
+
MorphFunction.THIN.value,
|
|
43
|
+
MorphFunction.VBREAK.value,
|
|
44
|
+
]
|
|
@@ -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.dev351
|
|
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>
|
|
@@ -21,6 +21,7 @@ cellprofiler_library/modules/_convertobjectstoimage.py
|
|
|
21
21
|
cellprofiler_library/modules/_correctilluminationapply.py
|
|
22
22
|
cellprofiler_library/modules/_crop.py
|
|
23
23
|
cellprofiler_library/modules/_dilateimage.py
|
|
24
|
+
cellprofiler_library/modules/_dilateobjects.py
|
|
24
25
|
cellprofiler_library/modules/_enhanceedges.py
|
|
25
26
|
cellprofiler_library/modules/_enhanceorsuppressfeatures.py
|
|
26
27
|
cellprofiler_library/modules/_erodeimage.py
|
|
@@ -32,6 +33,7 @@ cellprofiler_library/modules/_measureimageoverlap.py
|
|
|
32
33
|
cellprofiler_library/modules/_measureobjectsizeshape.py
|
|
33
34
|
cellprofiler_library/modules/_medialaxis.py
|
|
34
35
|
cellprofiler_library/modules/_medianfilter.py
|
|
36
|
+
cellprofiler_library/modules/_morph.py
|
|
35
37
|
cellprofiler_library/modules/_morphologicalskeleton.py
|
|
36
38
|
cellprofiler_library/modules/_opening.py
|
|
37
39
|
cellprofiler_library/modules/_overlayobjects.py
|
|
@@ -46,10 +48,12 @@ cellprofiler_library/opts/convertobjectstoimage.py
|
|
|
46
48
|
cellprofiler_library/opts/correctilluminationapply.py
|
|
47
49
|
cellprofiler_library/opts/crop.py
|
|
48
50
|
cellprofiler_library/opts/dilateimage.py
|
|
51
|
+
cellprofiler_library/opts/dilateobjects.py
|
|
49
52
|
cellprofiler_library/opts/enhanceorsuppressfeatures.py
|
|
50
53
|
cellprofiler_library/opts/erodeimage.py
|
|
51
54
|
cellprofiler_library/opts/erodeobjects.py
|
|
52
55
|
cellprofiler_library/opts/measureimageoverlap.py
|
|
56
|
+
cellprofiler_library/opts/morph.py
|
|
53
57
|
cellprofiler_library/opts/objectsizeshapefeatures.py
|
|
54
58
|
cellprofiler_library/opts/structuring_elements.py
|
|
55
59
|
cellprofiler_library/opts/threshold.py
|
{cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/LICENSE
RENAMED
|
File without changes
|
{cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/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
|
{cellprofiler_library_nightly-5.0.0.dev340 → cellprofiler_library_nightly-5.0.0.dev351}/setup.cfg
RENAMED
|
File without changes
|