Skip to content

Commit 4b97a21

Browse files
committed
WIP csv+docs + make_label + lint
1 parent 6bf0dd1 commit 4b97a21

File tree

12 files changed

+153
-51
lines changed

12 files changed

+153
-51
lines changed

docs/res/code/utils.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ get_time
1313
**************************************
1414
.. autofunction:: napari_cellseg3d.utils::get_time
1515

16+
time_difference
17+
**************************************
18+
.. autofunction:: napari_cellseg3d.utils::time_difference
19+
1620
get_time_filepath
1721
**************************************
1822
.. autofunction:: napari_cellseg3d.utils::get_time_filepath

docs/res/guides/inference_module_guide.rst

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,38 +31,44 @@ Interface and functionalities
3131

3232
* **Loading data** :
3333

34-
| When launching the module, you will be asked to provide an image folder containing all the volumes you'd like to be labeled.
35-
| All images with the chosen (**.tif** or **.tiff** currently supported) extension in this folder will be labeled.
36-
| You can then choose an output folder, where all the results will be saved.
34+
| When launching the module, you will be asked to provide an **image folder** containing all the volumes you'd like to be labeled.
35+
| All images with the chosen extension (**.tif** or **.tiff** currently supported) in this folder will be labeled.
36+
| You can then choose an **output folder**, where all the results will be saved.
3737
3838

3939
* **Model choice** :
4040

41-
| You can then choose one of the provided models above, which will be used for inference.
42-
| You may also choose to load custom weights rather than the pre-trained ones, simply ensure they are compatible (e.g. produced from the training module for the same model)
41+
| You can then choose one of the provided **models** above, which will be used for inference.
42+
| You may also choose to **load custom weights** rather than the pre-trained ones, simply ensure they are **compatible** (e.g. produced from the training module for the same model)
4343
4444

4545
* **Anisotropy** :
4646

47-
| If you want to see your results without anisotropy when you have anisotropic images, you can specify that you have anisotropic data
48-
| and set the resolution of your image in micron, this wil save and show the results without anisotropy.
47+
| If you want to see your results without **anisotropy** when you have anisotropic images, you can specify that you have anisotropic data
48+
| and set the **resolution of your imaging method in micron**, this wil save and show the results without anisotropy.
4949
5050

5151
* **Thresholding** :
5252

53-
| You can perform thresholding to binarize your labels, all values beneath the confidence threshold will be set to 0 using this.
54-
| If you wish to use instance segmentation it is recommended to use thresholding.
53+
| You can perform thresholding to **binarize your labels**,
54+
| all values beneath the **confidence threshold** will be set to 0 using this.
5555
5656
* **Instance segmentation** :
5757

58-
| You can convert the semantic segmentation into instance labels by using either the watershed or connected components method.
58+
| You can convert the semantic segmentation into instance labels by using either the `watershed`_ or `connected components`_ method.
5959
| You can set the probability threshold from which a pixel is considered as a valid instance, as well as the minimum size in pixels for objects. All smaller objects will be removed.
6060
| Instance labels will be saved (and shown if applicable) separately from other results.
6161
62+
63+
.. _watershed: https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html
64+
.. _connected components: https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.label
65+
66+
6267
* **Viewing results** :
6368

64-
| You can also select whether you'd like to see the results in napari afterwards.
65-
| By default the first image processed will be displayed, but you can choose to display up to ten at once. You can also request to see the originals.
69+
| You can also select whether you'd like to **see the results** in napari afterwards.
70+
| By default the first image processed will be displayed, but you can choose to display up to **ten at once**.
71+
| You can also request to see the originals.
6672
6773

6874
When you are done choosing your parameters, you can press the **Start** button to begin the inference process.

docs/res/guides/training_module_guide.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ The training module is comprised of several tabs.
3939
* The path to the labels folder
4040
* The path to the results folder
4141

42+
* Whether to copy results to a zip file (for easier transferability)
43+
44+
* Whether to use pre-trained weights that are provided; if you choose to do so, the model will be initialized with the specified weights, possibly improving performance (transfer learning).
45+
You can also load custom weights; simply ensure they are compatible with the model.
46+
4247
2) The second tab, **Augmentation**, lets you define dataset and augmentation parameters such as :
4348

4449
* Whether to use images "as is" (**requires all images to be of the same size and cubic**) or extract patches.
@@ -77,6 +82,8 @@ Generalized Dice loss `Generalized dice Loss from MONAI`_ with ``sigmoid=tru
7782
Dice-CE loss `Dice-CE Loss from MONAI`_ with ``sigmoid=true``
7883
Tversky loss `Tversky Loss from MONAI`_ with ``sigmoid=true``
7984
======================== ================================================================================================
85+
86+
8087
.. _Dice Loss from MONAI: https://docs.monai.io/en/stable/losses.html#diceloss
8188
.. _Focal Loss from MONAI: https://docs.monai.io/en/stable/losses.html#focalloss
8289
.. _Dice-focal Loss from MONAI: https://docs.monai.io/en/stable/losses.html#dicefocalloss

napari_cellseg3d/_tests/test_utils.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,33 @@
88
from napari_cellseg3d import utils
99

1010

11+
def test_fill_list_in_between():
12+
13+
list = [1, 2, 3, 4, 5, 6]
14+
res = [
15+
1,
16+
"",
17+
"",
18+
2,
19+
"",
20+
"",
21+
3,
22+
"",
23+
"",
24+
4,
25+
"",
26+
"",
27+
5,
28+
"",
29+
"",
30+
6,
31+
"",
32+
"",
33+
]
34+
35+
assert utils.fill_list_in_between(list, 2, "") == res
36+
37+
1138
def test_align_array_sizes():
1239

1340
im = np.zeros((128, 512, 256))

napari_cellseg3d/interface.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def open_file_dialog(
9191
return filenames
9292

9393

94-
def make_label(name, parent):
94+
def make_label(name, parent=None):
9595
"""Creates a QLabel
9696
9797
Args:
@@ -101,7 +101,10 @@ def make_label(name, parent):
101101
Returns: created label
102102
103103
"""
104-
return QLabel(name, parent)
104+
if parent is not None:
105+
return QLabel(name, parent)
106+
else:
107+
return QLabel(name)
105108

106109

107110
def make_scrollable(
@@ -302,7 +305,7 @@ def make_combobox(
302305
Args:
303306
entries array(str): Entries to add to the dropdown menu. Defaults to None, no entries if None
304307
parent (QWidget): parent QWidget to add dropdown menu to. Defaults to None, no parent is set if None
305-
label (str) : if not None, creates a Qlabel with the contents of 'label', and returns the label as well
308+
label (str) : if not None, creates a QLabel with the contents of 'label', and returns the label as well
306309
fixed (bool): if True, will set the size policy of the dropdown menu to Fixed in h and w. Defaults to True.
307310
308311
Returns:

napari_cellseg3d/launch_review.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import os
21
from pathlib import Path
32

43
import matplotlib.pyplot as plt

napari_cellseg3d/model_workers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def inference(self):
201201
pad = utils.get_padding_dim(check)
202202
# print(pad)
203203
dims = 128
204-
dims = 64
204+
# dims = 64 # TODO
205205

206206
model = self.model_dict["class"].get_net()
207207
if self.model_dict["name"] == "SegResNet":

napari_cellseg3d/plugin_crop.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from magicgui.widgets import Slider
99

1010
# Qt
11-
from qtpy.QtWidgets import QLabel
1211
from qtpy.QtWidgets import QSizePolicy
1312
from tifffile import imwrite
1413

@@ -51,7 +50,7 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent):
5150

5251
self.box_widgets = ui.make_n_spinboxes(3, 1, 1000, DEFAULT_CROP_SIZE)
5352
self.box_lbl = [
54-
QLabel("Size in " + axis + " of cropped volume :")
53+
ui.make_label("Size in " + axis + " of cropped volume :", self)
5554
for axis in "xyz"
5655
]
5756

napari_cellseg3d/plugin_model_inference.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
import numpy as np
66

77
# Qt
8-
from qtpy.QtWidgets import QLabel
98
from qtpy.QtWidgets import QSizePolicy
10-
from qtpy.QtWidgets import QWidget
119

1210
# local
1311
from napari_cellseg3d import interface as ui
@@ -28,30 +26,32 @@ def __init__(self, viewer: "napari.viewer.Viewer"):
2826
* Data :
2927
* A file extension choice for the images to load from selected folders
3028
31-
* Two buttons to choose the images folder to run segmentation and save results in, respectively
29+
* Two fields to choose the images folder to run segmentation and save results in, respectively
30+
31+
* Inference options :
32+
* A dropdown menu to select which model should be used for inference
33+
34+
* An option to load custom weights for the selected model (e.g. from training module)
35+
3236
3337
* Post-processing :
3438
* A box to select if data is anisotropic, if checked, asks for resolution in micron for each axis
3539
3640
* A box to choose whether to threshold, if checked asks for a threshold between 0 and 1
3741
38-
* Display options :
39-
* A dropdown menu to select which model should be used for inference
42+
* A box to enable instance segmentation. If enabled, displays :
43+
* The choice of method to use for instance segmentation
44+
45+
* The probability threshold below which to remove objects
46+
47+
* The size in pixels of small objects to remove
4048
41-
* A checkbox to choose whether to display results in napari afterwards. Will ask for how many results to display, capped at 10
49+
* A checkbox to choose whether to display results in napari afterwards. Will ask for how many results to display, capped at 10
4250
4351
* A button to launch the inference process
4452
4553
* A button to close the widget
4654
47-
TODO:
48-
49-
* Verify if way of loading model is OK
50-
51-
* Padding OK ?
52-
53-
* Save toggle ?
54-
5555
Args:
5656
viewer (napari.viewer.Viewer): napari viewer to display the widget in
5757
"""
@@ -100,7 +100,7 @@ def __init__(self, viewer: "napari.viewer.Viewer"):
100100
)
101101

102102
self.display_number_choice = ui.make_n_spinboxes(1, 1, 10, 1)
103-
self.lbl_display_number = QLabel("How many ? (max. 10)", self)
103+
self.lbl_display_number = ui.make_label("How many ? (max. 10)", self)
104104

105105
self.aniso_checkbox = ui.make_checkbox(
106106
"Anisotropic data", self.toggle_display_aniso
@@ -110,7 +110,8 @@ def __init__(self, viewer: "napari.viewer.Viewer"):
110110
n=3, min=1.0, max=1000, default=1.5, step=0.5, double=True
111111
)
112112
self.aniso_box_lbl = [
113-
QLabel("Resolution in " + axis + " (microns) :") for axis in "xyz"
113+
ui.make_label("Resolution in " + axis + " (microns) :", self)
114+
for axis in "xyz"
114115
]
115116

116117
self.aniso_box_widgets[-1].setValue(5.0) # TODO change default
@@ -147,7 +148,9 @@ def __init__(self, viewer: "napari.viewer.Viewer"):
147148
self.instance_prob_thresh = ui.make_n_spinboxes(
148149
n=1, max=0.99, default=0.7, step=0.05, double=True
149150
)
150-
self.instance_prob_thresh_lbl = QLabel("Probability threshold :")
151+
self.instance_prob_thresh_lbl = ui.make_label(
152+
"Probability threshold :", self
153+
)
151154
self.instance_prob_t_container = ui.combine_blocks(
152155
second=self.instance_prob_thresh,
153156
first=self.instance_prob_thresh_lbl,
@@ -157,8 +160,8 @@ def __init__(self, viewer: "napari.viewer.Viewer"):
157160
self.instance_small_object_thresh = ui.make_n_spinboxes(
158161
n=1, max=100, default=10, step=5
159162
)
160-
self.instance_small_object_thresh_lbl = QLabel(
161-
"Small object removal threshold :"
163+
self.instance_small_object_thresh_lbl = ui.make_label(
164+
"Small object removal threshold :", self
162165
)
163166
self.instance_small_object_t_container = ui.combine_blocks(
164167
second=self.instance_small_object_thresh,

0 commit comments

Comments
 (0)