Skip to content

Commit 251f309

Browse files
authored
Merge pull request #55 from computational-cell-analytics/update_labeling_components
Update for labeling components The labeling of components works well and is ready for a merge.
2 parents 5967230 + 6ff74a3 commit 251f309

File tree

11 files changed

+223
-99
lines changed

11 files changed

+223
-99
lines changed

flamingo_tools/segmentation/postprocessing.py

Lines changed: 11 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def erode_subset(
249249
Returns:
250250
The dataframe containing elements left after the erosion.
251251
"""
252-
print("initial length", len(table))
252+
print(f"Initial length: {len(table)}")
253253
n_neighbors = 100
254254
for i in range(iterations):
255255
table = table[table[keyword] < threshold]
@@ -406,10 +406,12 @@ def components_sgn(
406406
min_cells = 20000
407407
threshold = threshold_erode if threshold_erode is not None else 40
408408

409-
print(f"Using threshold of {threshold} micrometer for eroding segmentation with keyword {keyword}.")
410-
411-
new_subset = erode_subset(table.copy(), iterations=iterations,
412-
threshold=threshold, min_cells=min_cells, keyword=keyword)
409+
if iterations != 0:
410+
print(f"Using threshold of {threshold} micrometer for eroding segmentation with keyword {keyword}.")
411+
new_subset = erode_subset(table.copy(), iterations=iterations,
412+
threshold=threshold, min_cells=min_cells, keyword=keyword)
413+
else:
414+
new_subset = table.copy()
413415

414416
# create graph from coordinates of eroded subset
415417
centroids_subset = list(zip(new_subset["anchor_x"], new_subset["anchor_y"], new_subset["anchor_z"]))
@@ -486,41 +488,10 @@ def label_components_sgn(
486488
table.sort_values("label_id")
487489

488490
component_labels = [0 for _ in range(len(table))]
491+
table.loc[:, "component_labels"] = component_labels
489492
# be aware of 'label_id' of dataframe starting at 1
490493
for lab, comp in enumerate(components):
491-
for comp_index in comp:
492-
component_labels[comp_index - 1] = lab + 1
493-
494-
return component_labels
495-
496-
497-
def postprocess_sgn_seg(
498-
table: pd.DataFrame,
499-
min_size: int = 1000,
500-
threshold_erode: Optional[float] = None,
501-
min_component_length: int = 50,
502-
max_edge_distance: float = 30,
503-
iterations_erode: Optional[int] = None,
504-
) -> pd.DataFrame:
505-
"""Postprocessing SGN segmentation of cochlea.
506-
507-
Args:
508-
table: Dataframe of segmentation table.
509-
min_size: Minimal number of pixels for filtering small instances.
510-
threshold_erode: Threshold of column value after erosion step with spatial statistics.
511-
min_component_length: Minimal length for filtering out connected components.
512-
max_edge_distance: Maximal distance in micrometer between points to create edges for connected components.
513-
iterations_erode: Number of iterations for erosion, normally determined automatically.
514-
515-
Returns:
516-
Dataframe with component labels.
517-
"""
518-
519-
comp_labels = label_components_sgn(table, min_size=min_size, threshold_erode=threshold_erode,
520-
min_component_length=min_component_length,
521-
max_edge_distance=max_edge_distance, iterations_erode=iterations_erode)
522-
523-
table.loc[:, "component_labels"] = comp_labels
494+
table.loc[table["label_id"].isin(comp), "component_labels"] = lab + 1
524495

525496
return table
526497

@@ -583,37 +554,10 @@ def label_components_ihc(
583554
length_components, components = zip(*sorted(zip(length_components, components), reverse=True))
584555

585556
component_labels = [0 for _ in range(len(table))]
557+
table.loc[:, "component_labels"] = component_labels
586558
# be aware of 'label_id' of dataframe starting at 1
587559
for lab, comp in enumerate(components):
588-
for comp_index in comp:
589-
component_labels[comp_index - 1] = lab + 1
590-
591-
return component_labels
592-
593-
594-
def postprocess_ihc_seg(
595-
table: pd.DataFrame,
596-
min_size: int = 1000,
597-
min_component_length: int = 50,
598-
max_edge_distance: float = 30,
599-
) -> pd.DataFrame:
600-
"""Postprocessing IHC segmentation of cochlea.
601-
602-
Args:
603-
table: Dataframe of segmentation table.
604-
min_size: Minimal number of pixels for filtering small instances.
605-
min_component_length: Minimal length for filtering out connected components.
606-
max_edge_distance: Maximal distance in micrometer between points to create edges for connected components.
607-
608-
Returns:
609-
Dataframe with component labels.
610-
"""
611-
612-
comp_labels = label_components_ihc(table, min_size=min_size,
613-
min_component_length=min_component_length,
614-
max_edge_distance=max_edge_distance)
615-
616-
table.loc[:, "component_labels"] = comp_labels
560+
table.loc[table["label_id"].isin(comp), "component_labels"] = lab + 1
617561

618562
return table
619563

reproducibility/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ The extraction of blocks from a 3D volume is required for the creation of annota
1010
Usage:
1111
```
1212
python repro_block_extraction.py --input <JSON-file> --output <out-dir>
13-
```
13+
```
1414

15-
## Post-processing of SGN segmentation
15+
## Labeling components in the segmentation
1616

17-
The post-processing of the SGN segmentation may involve the erosion of the segmentation to exclude artifacts, the variation of the minimal number of nodes within a component, or the minimal distance between nodes to consider them the same component.
17+
The labeling of the SGN segmentation may involve the erosion of the segmentation to exclude artifacts, the variation of the minimal number of nodes within a component, or the minimal distance between nodes to consider them the same component.
1818

1919
Usage:
2020
```
21-
python repro_postprocess_sgn_v1.py --input <JSON-file> --output <out-dir>
22-
```
21+
python repro_label_components.py --input <JSON-file> --output <out-dir>
22+
```
2323

reproducibility/block_extraction/ChReef_MLR144R.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"GFP",
77
"SGN_v2"
88
],
9+
"segmentation_channel": "SGN_v2",
10+
"type": "sgn",
11+
"n_blocks": 6,
912
"crop_centers": [
1013
[
1114
1329,

reproducibility/block_extraction/ChReef_MLR145R.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"GFP",
77
"SGN_v2"
88
],
9+
"segmentation_channel": "SGN_v2",
10+
"type": "sgn",
11+
"n_blocks": 6,
912
"crop_centers": [
1013
[
1114
789,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
[
2+
{
3+
"cochlea": "M_LR_000155_L",
4+
"image_channel": [
5+
"PV",
6+
"GFP",
7+
"SGN_v2"
8+
],
9+
"segmentation_channel": "SGN_v2",
10+
"type": "sgn",
11+
"n_blocks": 6,
12+
"crop_centers": [
13+
[
14+
1725,
15+
713,
16+
482
17+
],
18+
[
19+
1395,
20+
810,
21+
389
22+
],
23+
[
24+
1070,
25+
681,
26+
454
27+
],
28+
[
29+
1057,
30+
677,
31+
785
32+
],
33+
[
34+
1121,
35+
1002,
36+
769
37+
],
38+
[
39+
803,
40+
1057,
41+
690
42+
]
43+
],
44+
"halo_size": [
45+
256,
46+
256,
47+
50
48+
],
49+
"component_list": [
50+
1
51+
]
52+
}
53+
]

reproducibility/block_extraction/ChReef_MLR155R.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"GFP",
77
"SGN_v2"
88
],
9+
"segmentation_channel": "SGN_v2",
10+
"type": "sgn",
11+
"n_blocks": 6,
912
"crop_centers": [
1013
[
1114
1634,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[
2+
{
3+
"cochlea": "M_LR_000226_L",
4+
"image_channel": "VGlut3",
5+
"cell_type": "ihc",
6+
"unet_version": "v4c"
7+
},
8+
{
9+
"cochlea": "M_LR_000226_R",
10+
"image_channel": "VGlut3",
11+
"cell_type": "ihc",
12+
"unet_version": "v4c"
13+
},
14+
{
15+
"cochlea": "M_LR_000227_L",
16+
"image_channel": "VGlut3",
17+
"cell_type": "ihc",
18+
"unet_version": "v4c"
19+
},
20+
{
21+
"cochlea": "M_LR_000227_R",
22+
"image_channel": "VGlut3",
23+
"cell_type": "ihc",
24+
"unet_version": "v4c"
25+
}
26+
]
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
[
2+
{
3+
"cochlea": "M_LR_000143_L",
4+
"image_channel": "PV",
5+
"cell_type": "sgn",
6+
"max_edge_distance": 70,
7+
"unet_version": "v2"
8+
},
9+
{
10+
"cochlea": "M_LR_000144_L",
11+
"image_channel": "PV",
12+
"cell_type": "sgn",
13+
"max_edge_distance": 50,
14+
"unet_version": "v2"
15+
},
16+
{
17+
"cochlea": "M_LR_000145_L",
18+
"image_channel": "PV",
19+
"cell_type": "sgn",
20+
"unet_version": "v2"
21+
},
22+
{
23+
"cochlea": "M_LR_000153_L",
24+
"image_channel": "PV",
25+
"cell_type": "sgn",
26+
"unet_version": "v2"
27+
},
28+
{
29+
"cochlea": "M_LR_000155_L",
30+
"image_channel": "PV",
31+
"cell_type": "sgn",
32+
"unet_version": "v2"
33+
},
34+
{
35+
"cochlea": "M_LR_000189_L",
36+
"image_channel": "PV",
37+
"cell_type": "sgn",
38+
"unet_version": "v2"
39+
},
40+
{
41+
"cochlea": "M_LR_000143_R",
42+
"image_channel": "PV",
43+
"cell_type": "sgn",
44+
"max_edge_distance": 50,
45+
"unet_version": "v2"
46+
},
47+
{
48+
"cochlea": "M_LR_000144_R",
49+
"image_channel": "PV",
50+
"cell_type": "sgn",
51+
"unet_version": "v2"
52+
},
53+
{
54+
"cochlea": "M_LR_000145_R",
55+
"image_channel": "PV",
56+
"cell_type": "sgn",
57+
"unet_version": "v2"
58+
},
59+
{
60+
"cochlea": "M_LR_000153_R",
61+
"image_channel": "PV",
62+
"cell_type": "sgn",
63+
"unet_version": "v2"
64+
},
65+
{
66+
"cochlea": "M_LR_000155_R",
67+
"image_channel": "PV",
68+
"cell_type": "sgn",
69+
"unet_version": "v2"
70+
},
71+
{
72+
"cochlea": "M_LR_000189_R",
73+
"image_channel": "PV",
74+
"cell_type": "sgn",
75+
"unet_version": "v2"
76+
}
77+
]

0 commit comments

Comments
 (0)