forked from CellProfiler/CellProfiler-plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
convertoutlinestoobjects.py
101 lines (70 loc) · 2.31 KB
/
convertoutlinestoobjects.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# coding=utf-8
"""
ConvertOutlinesToObjects
=====================
**ConvertOutlinesToObjects** converts a binary image of outlines to objects. Contiguous outlined regions are converted
to unique objects.
|
============ ============ ===============
Supports 2D? Supports 3D? Respects masks?
============ ============ ===============
YES YES NO
============ ============ ===============
"""
import numpy
import scipy.ndimage
import skimage
import skimage.measure
import cellprofiler.module
import cellprofiler.setting
class ConvertOutlinesToObjects(cellprofiler.module.ImageSegmentation):
category = "Advanced"
module_name = "ConvertOutlinesToObjects"
variable_revision_number = 1
def create_settings(self):
super(ConvertOutlinesToObjects, self).create_settings()
self.diameter = cellprofiler.setting.FloatRange(
text="Typical diameter of objects",
value=(0.0, numpy.inf),
doc="Typical diameter of objects, in pixels (min, max). Objects outside this range will be discarded."
)
def settings(self):
settings = super(ConvertOutlinesToObjects, self).settings()
settings += [
self.diameter
]
return settings
def visible_settings(self):
visible_settings = super(ConvertOutlinesToObjects, self).visible_settings()
visible_settings += [
self.diameter
]
return visible_settings
def run(self, workspace):
self.function = convert_outlines_to_objects
super(ConvertOutlinesToObjects, self).run(workspace)
def convert_outlines_to_objects(outlines, diameter):
labels = skimage.measure.label(
outlines > 0,
background=True,
connectivity=1
)
indexes = numpy.unique(labels)
radius = numpy.divide(diameter, 2.0)
if labels.ndim == 2:
factor = radius ** 2
else:
factor = (4.0 / 3.0) * (radius ** 3)
min_area, max_area = numpy.pi * factor
areas = scipy.ndimage.sum(
numpy.ones_like(labels),
labels,
index=indexes
)
is_background = numpy.logical_or(
areas < min_area,
areas > max_area
)
background_indexes = numpy.unique(labels)[is_background]
labels[numpy.isin(labels, background_indexes)] = 0
return labels