Refresh

This website github.com/herophilus/cellpose/commit/d5c9d7931c4d22bf72a7243bcf5f290fa1931b39 is currently offline. Cloudflare's Always Online™ shows a snapshot of this web page from the Internet Archive's Wayback Machine. To check for the live version, click Refresh.

Skip to content

Commit

Permalink
adding more documentation in gui
Browse files Browse the repository at this point in the history
  • Loading branch information
carsen-stringer committed Apr 3, 2022
1 parent 06df602 commit d5c9d79
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 33 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ If you want to improve Cellpose for yourself and for everyone else, please consi

Cellpose 2.0 now allows human-in-the-loop training of models! Check out the twitter [thread](twitter) and [preprint](biorxiv) for details.

Read how to use it yourself in the [docs](docs), and check out the full human-in-the-loop
Read how to use it yourself in the [docs](https://cellpose.readthedocs.io/en/latest/gui.html#training-your-own-cellpose-model), and check out the full human-in-the-loop video:

[![video](https://img.youtube.com/vi/3Y1VKcxjNy4/default.jpg)](https://youtu.be/3Y1VKcxjNy4)

![gui screenshot](https://www.cellpose.org/static/images/cellpose_gui.png)

### UPDATE v1.0 (Jan 2022)

Cellpose has been relatively stable for a while now. Small bugs will continue to be fixed, but we are now releasing a reference 1.0 version. Larger updates to Cellpose will go towards a new 2.0 candidate version to be released soon.
Expand Down
22 changes: 14 additions & 8 deletions cellpose/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import numpy as np
import cv2
from scipy.ndimage import gaussian_filter

from . import guiparts, menus, io
from .. import models, core, dynamics
Expand Down Expand Up @@ -132,7 +131,7 @@ def run():
print('downloading logo')
download_url_to_file('https://www.cellpose.org/static/images/cellpose_transparent.png', icon_path, progress=True)
if not guip_path.is_file():
download_url_to_file('https://github.com/MouseLand/cellpose/raw/master/docs/_static/cellpose_gui.png', guip_path, progress=True)
download_url_to_file('https://www.cellpose.org/static/images/cellpose_gui.png', guip_path, progress=True)
icon_path = str(icon_path.resolve())
app_icon = QtGui.QIcon()
app_icon.addFile(icon_path, QtCore.QSize(16, 16))
Expand Down Expand Up @@ -255,6 +254,10 @@ def help_window(self):
HW = guiparts.HelpWindow(self)
HW.show()

def train_help_window(self):
THW = guiparts.TrainHelpWindow(self)
THW.show()

def gui_window(self):
EG = guiparts.ExampleGUI(self)
EG.show()
Expand Down Expand Up @@ -303,8 +306,14 @@ def make_buttons(self):
self.RGBDropDown.currentIndexChanged.connect(self.color_choose)
#self.RGBDropDown.setFixedWidth(60)
self.RGBDropDown.setStyleSheet(self.dropdowns)


self.l0.addWidget(self.RGBDropDown, b,0,1,4)
label = QLabel('[press R / G / B to \n toggle RGB and color ]')
label.setStyleSheet(label_style)
label.setFont(self.smallfont)
self.l0.addWidget(label, b+1,0,1,4)

b+=3

self.resize = -1
Expand Down Expand Up @@ -451,7 +460,7 @@ def make_buttons(self):
# post-hoc paramater tuning

b+=1
label = QLabel('flow threshold:')
label = QLabel('flow_threshold:')
label.setToolTip('threshold on flow error to accept a mask (set higher to get more cells, e.g. in range from (0.1, 3.0), OR set to 0.0 to turn off so no cells discarded);\n press enter to recompute if model already run')
label.setStyleSheet(label_style)
label.setFont(self.medfont)
Expand All @@ -463,7 +472,7 @@ def make_buttons(self):
self.l0.addWidget(self.flow_threshold, b,5,1,4)

b+=1
label = QLabel('cellprob threshold:')
label = QLabel('cellprob_threshold:')
label.setToolTip('threshold on cellprob output to seed cell masks (set lower to include more pixels or higher to include fewer, e.g. in range from (-6, 6)); \n press enter to recompute if model already run')
label.setStyleSheet(label_style)
label.setFont(self.medfont)
Expand Down Expand Up @@ -782,7 +791,7 @@ def model_choose(self, index):

def calibrate_size(self):
self.initialize_model(model_name='cyto')
diams, _ = self.model.sz.eval(self.stack[self.currentZ].copy(), invert=self.invert.isChecked(),
diams, _ = self.model.sz.eval(self.stack[self.currentZ].copy(),
channels=self.get_channels(), progress=self.progress)
diams = np.maximum(5.0, diams)
logger.info('estimated diameter of cells using %s model = %0.1f pixels'%
Expand Down Expand Up @@ -1624,9 +1633,6 @@ def train_model(self):
self.diameter = diam_labels
self.Diameter.setText('%0.2f'%self.diameter)
logger.info(f'>>>> diameter set to diam_labels ( = {diam_labels: 0.3f} )')
if self.train_files[0] == self.filename:
print(f'GUI_INFO: trained on all images + masks in folder --> auto-end training')
return
self.compute_model()
logger.info(f'!!! computed masks for {os.path.split(self.filename)[1]} from new model !!!')

Expand Down
53 changes: 42 additions & 11 deletions cellpose/gui/guiparts.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def __init__(self, parent=None):
class HelpWindow(QDialog):
def __init__(self, parent=None):
super(HelpWindow, self).__init__(parent)
self.setGeometry(100,100,700,800)
self.setGeometry(100,50,700,850)
self.setWindowTitle('cellpose help')
self.win = QWidget(self)
layout = QGridLayout()
Expand All @@ -278,6 +278,8 @@ def __init__(self, parent=None):
<p class="has-line-data" data-line-start="17" data-line-end="18">!NOTE!: The GUI automatically saves after you draw a mask in 2D but NOT after 3D mask drawing and NOT after segmentation. Save in the file menu or with Ctrl+S. The output file is in the same folder as the loaded image with <code>_seg.npy</code> appended.</p>
<table class="table table-striped table-bordered">
<br><br>
FYI there are tooltips throughout the GUI (hover over text to see)
<br>
<thead>
<tr>
<th>Keyboard shortcuts</th>
Expand Down Expand Up @@ -310,6 +312,10 @@ def __init__(self, parent=None):
<td>SAVE MASKS IN IMAGE to <code>_seg.npy</code> file</td>
</tr>
<tr>
<td>CTRL+T</td>
<td>train model using _seg.npy files in folder
</tr>
<tr>
<td>CTRL+P</td>
<td>load <code>_seg.npy</code> file (note: it will load automatically with image if it exists)</td>
</tr>
Expand All @@ -318,10 +324,6 @@ def __init__(self, parent=None):
<td>load masks file (must be same size as image with 0 for NO mask, and 1,2,3… for masks)</td>
</tr>
<tr>
<td>CTRL+N</td>
<td>load numpy stack (NOT WORKING ATM)</td>
</tr>
<tr>
<td>A/D or LEFT/RIGHT</td>
<td>cycle through images in current directory</td>
</tr>
Expand All @@ -330,12 +332,12 @@ def __init__(self, parent=None):
<td>change color (RGB/gray/red/green/blue)</td>
</tr>
<tr>
<td>PAGE-UP / PAGE-DOWN</td>
<td>change to flows and cell prob views (if segmentation computed)</td>
<td>R / G / B </td>
<td>toggle between RGB and Red or Green or Blue</td>
</tr>
<tr>
<td>, / .</td>
<td>increase / decrease brush size for drawing masks</td>
<td>PAGE-UP / PAGE-DOWN</td>
<td>change to flows and cell prob views (if segmentation computed)</td>
</tr>
<tr>
<td>X</td>
Expand All @@ -346,8 +348,8 @@ def __init__(self, parent=None):
<td>toggle outlines ON or OFF</td>
</tr>
<tr>
<td>C</td>
<td>cycle through labels for image type (saved to <code>_seg.npy</code>)</td>
<td>, / .</td>
<td>increase / decrease brush size for drawing masks</td>
</tr>
</tbody>
</table>
Expand All @@ -364,6 +366,35 @@ def __init__(self, parent=None):
layout.addWidget(label, 0, 0, 1, 1)
self.show()


class TrainHelpWindow(QDialog):
def __init__(self, parent=None):
super(TrainHelpWindow, self).__init__(parent)
self.setGeometry(100,50,700,300)
self.setWindowTitle('training instructions')
self.win = QWidget(self)
layout = QGridLayout()
self.win.setLayout(layout)

text = ('''
Check out this <a href="https://youtu.be/3Y1VKcxjNy4">video</a> to learn the process.
<ol>
<li>Drag and drop an image from a folder of images with a similar style (like similar cell types).</li>
<li>Run the built-in models on one of the images using the "model zoo" and find the one that works best for your data. Make sure that if you have a nuclear channel you have selected it for CHAN2.</li>
<li>Fix the labelling by drawing new ROIs (right-click) and deleting incorrect ones (CTRL+click). The GUI autosaves any manual changes (but does not autosave after running the model, for that click CTRL+S). The segmentation is saved in a "_seg.npy" file.</li>
<li> Go to the "Models" menu in the File bar at the top and click "Train new model..." or use shortcut CTRL+T. </li>
<li> Choose the pretrained model to start the training from (the model you used in #2), and type in the model name that you want to use. The other parameters should work well in general for most data types. Then click OK. </li>
<li> The model will train (much faster if you have a GPU) and then auto-run on the next image in the folder. Next you can repeat #3-#5 as many times as is necessary. </li>
<li> The trained model is available to use in the future in the GUI in the "custom model" section and is saved in your image folder. </li>
</ol>
''')
label = QLabel(text)
label.setFont(QtGui.QFont("Arial", 8))
label.setWordWrap(True)
layout.addWidget(label, 0, 0, 1, 1)
self.show()


class TypeRadioButtons(QButtonGroup):
def __init__(self, parent=None, row=0, col=0):
super(TypeRadioButtons, self).__init__()
Expand Down
18 changes: 11 additions & 7 deletions cellpose/gui/menus.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,24 @@ def modelmenu(parent):
parent.newmodel.setEnabled(False)
model_menu.addAction(parent.newmodel)

openTrainHelp = QAction("Training instructions", parent)
openTrainHelp.triggered.connect(parent.train_help_window)
model_menu.addAction(openTrainHelp)

def helpmenu(parent):
main_menu = parent.menuBar()
help_menu = main_menu.addMenu("&Help")

checkMKL = QAction("Check CPU MKL -- see terminal", parent)
checkMKL.triggered.connect(lambda: models.check_mkl(istorch=parent.torch))
help_menu.addAction(checkMKL)

openHelp = QAction("&Help window", parent)
openHelp = QAction("&Help with GUI", parent)
openHelp.setShortcut("Ctrl+H")
openHelp.triggered.connect(parent.help_window)
help_menu.addAction(openHelp)

openGUI = QAction("&GUI layout", parent)
openGUI.setShortcut("Ctrl+G")
openGUI.triggered.connect(parent.gui_window)
help_menu.addAction(openGUI)
help_menu.addAction(openGUI)

openTrainHelp = QAction("Training instructions", parent)
openTrainHelp.triggered.connect(parent.train_help_window)
help_menu.addAction(openTrainHelp)
Binary file removed docs/_static/cellpose_gui.png
Binary file not shown.
13 changes: 7 additions & 6 deletions docs/gui.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ CHAN2 (OPT): if *cytoplasm* model is chosen, then choose the nuclear channel for
Training your own cellpose model
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Check out this `video <https://youtu.be/3Y1VKcxjNy4>`_ to watch Marius going through the process.
Check out this `video <https://youtu.be/3Y1VKcxjNy4>`_ to learn the process.

1. Drag and drop an image from a folder of images with a similar style (like similar cell types).
2. Run the built-in models on the data in the "model zoo" and find the one that works best for your data. Make sure that if you have a nuclear channel you have selected it for CHAN2.
2. Run the built-in models on one of the images using the "model zoo" and find the one that works best for your data. Make sure that if you have a nuclear channel you have selected it for CHAN2.
3. Fix the labelling by drawing new ROIs (right-click) and deleting incorrect ones (CTRL+click). The GUI autosaves any manual changes (but does not autosave after running the model, for that click CTRL+S). The segmentation is saved in a ``_seg.npy`` file.
4. Go to the "Models" menu in the File bar at the top and click "Train new model..." or use shortcut CTRL+T.
5. Choose the pretrained model to start the training from (the model you used in #2), and type in the model name that you want to use. The other parameters should work well in general for most data types. Then click OK.
Expand Down Expand Up @@ -114,6 +114,8 @@ Keyboard shortcuts
+---------------------+-----------------------------------------------+
| CTRL+S | SAVE MASKS IN IMAGE to ``_seg.npy`` file |
+---------------------+-----------------------------------------------+
| CTRL+T | start model training using ``_seg.npy`` files |
+---------------------+-----------------------------------------------+
| CTRL+P | load ``_seg.npy`` file (note: it will load |
| | automatically with image if it exists) |
+---------------------+-----------------------------------------------+
Expand All @@ -124,17 +126,16 @@ Keyboard shortcuts
+---------------------+-----------------------------------------------+
| W/S or UP/DOWN | change color (RGB/gray/red/green/blue) |
+---------------------+-----------------------------------------------+
| R / G / B | press to toggle RGB and Red or Green or Blue |
+---------------------+-----------------------------------------------+
| PAGE-UP / PAGE-DOWN | change to flows and cell prob views (if |
| | segmentation computed) |
+---------------------+-----------------------------------------------+
| , / . | increase / decrease brush size for drawing |
+---------------------+-----------------------------------------------+
| X | turn masks ON or OFF |
+---------------------+-----------------------------------------------+
| Z | toggle outlines ON or OFF |
+---------------------+-----------------------------------------------+
| C | cycle through labels for image type (saved to |
| | ``_seg.npy``) |
| , / . | increase / decrease brush size for drawing |
+---------------------+-----------------------------------------------+


Expand Down

0 comments on commit d5c9d79

Please sign in to comment.