-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathbrightfieldprojectchannels.py
More file actions
122 lines (101 loc) · 4.92 KB
/
brightfieldprojectchannels.py
File metadata and controls
122 lines (101 loc) · 4.92 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import numpy
from cellprofiler_core.image import Image
from cellprofiler_core.module import Module
from cellprofiler_core.setting import SettingsGroup, HiddenCount
from cellprofiler_core.setting.do_something import DoSomething, RemoveSettingButton
from cellprofiler_core.setting.subscriber import ImageSubscriber
from cellprofiler_core.setting.text import ImageName
class BrightfieldProjectChannels(Module):
module_name = "BrightfieldProjectChannels"
variable_revision_number = 1
category = "Image Processing"
def create_settings(self):
self.output_image_name = ImageName(
"Name the output image",
"ProjectionBlue",
doc="Enter the name for the projected image."
)
self.stack_channels = []
self.stack_channel_count = HiddenCount(self.stack_channels)
self.add_stack_channel_cb(can_remove=False)
self.add_stack_channel = DoSomething(
"Add another image",
"Add another image",
self.add_stack_channel_cb
)
def add_stack_channel_cb(self, can_remove=True):
group = SettingsGroup()
group.append("image_name", ImageSubscriber("Select image", "None"))
if can_remove:
group.append("remover", RemoveSettingButton("", "Remove", self.stack_channels, group))
self.stack_channels.append(group)
def settings(self):
result = [self.output_image_name, self.stack_channel_count]
for stack_channel in self.stack_channels:
result += [stack_channel.image_name]
return result
def visible_settings(self):
result = [self.output_image_name]
for sc_group in self.stack_channels:
result.append(sc_group.image_name)
if hasattr(sc_group, "remover"):
result.append(sc_group.remover)
result.append(self.add_stack_channel)
return result
def prepare_settings(self, setting_values):
try:
num_stack_images = int(setting_values[1])
except (ValueError, IndexError):
num_stack_images = 1
del self.stack_channels[num_stack_images:]
while len(self.stack_channels) < num_stack_images:
self.add_stack_channel_cb()
def run(self, workspace):
bright_max = None
bright_min = None
norm0 = None
reference_image = None
final_mask = None
for i, group in enumerate(self.stack_channels):
img_name = group.image_name.value
if img_name == "None":
continue
image_obj = workspace.image_set.get_image(img_name)
pixels = image_obj.pixel_data.copy()
mask = image_obj.mask if image_obj.has_mask else numpy.ones(pixels.shape[:2], bool)
if bright_max is None:
# Initialization (replicates set_image)
reference_image = image_obj
bright_max = pixels.copy()
bright_min = pixels.copy()
norm0 = numpy.mean(pixels)
final_mask = mask.copy()
else:
# Accumulation (replicates accumulate_image for P_BRIGHTFIELD)
norm = numpy.mean(pixels)
# Normalize pixels relative to the first image
rescaled_pixels = pixels * (norm0 / norm) if norm != 0 else pixels
# Identify where new pixels are higher/lower
max_mask = (bright_max < rescaled_pixels) & mask
min_mask = (bright_min > rescaled_pixels) & mask
bright_min[min_mask] = rescaled_pixels[min_mask]
bright_max[max_mask] = rescaled_pixels[max_mask]
# This specific line from your source ensures min follows max if max is updated
bright_min[max_mask] = bright_max[max_mask]
# Combine masks (replicates P_MASK or standard mask handling)
final_mask = final_mask & mask
if bright_max is not None:
# Replicates provide_image: result = max - min
output_pixels = bright_max - bright_min
# CRITICAL: Setting parent_image ensures SaveImages/FlagImages works
new_image = Image(output_pixels, mask=final_mask, parent_image=reference_image)
workspace.image_set.add(self.output_image_name.value, new_image)
if self.show_window:
workspace.display_data.output_pixels = output_pixels
def display(self, workspace, figure):
if hasattr(workspace.display_data, 'output_pixels'):
pixels = workspace.display_data.output_pixels
figure.set_subplots((1, 1))
figure.subplot_imshow(0, 0, pixels, title=self.output_image_name.value, colormap="gray")
def upgrade_settings(self, setting_values, variable_revision_number, module_name):
return setting_values, variable_revision_number