Skip to content

Commit

Permalink
adding instructions for M1 mac (#523), more info for cp2 (#522), and …
Browse files Browse the repository at this point in the history
…forcing tiff saving for masks > 2**16 (#524), and new suggestion mode
  • Loading branch information
carsen-stringer committed Jul 3, 2022
1 parent e6d7d2e commit be94059
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 16 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

A generalist algorithm for cell and nucleus segmentation.

Cellpose was written by Carsen Stringer and Marius Pachitariu. To learn about Cellpose 1.0, read the [paper](https://t.co/kBMXmPp3Yn?amp=1) or watch the [talk](https://t.co/JChCsTD0SK?amp=1). For support, please open an [issue](https://github.com/MouseLand/cellpose/issues). If you use Cellpose in your work please cite the paper. Please find the detailed documentation at <span style="font-size:larger;">[cellpose.readthedocs.io](https://cellpose.readthedocs.io/en/latest/)</span>.
Cellpose was written by Carsen Stringer and Marius Pachitariu. To learn about Cellpose 2.0 (human-in-the-loop), read the [paper](https://www.biorxiv.org/content/10.1101/2022.04.01.486764v1) or watch the [talk](https://www.youtube.com/watch?v=3ydtAhfq6H0). To learn about Cellpose 1.0, read the [paper](https://t.co/kBMXmPp3Yn?amp=1) or watch the [talk](https://t.co/JChCsTD0SK?amp=1). For support, please open an [issue](https://github.com/MouseLand/cellpose/issues). Please find the detailed documentation at <span style="font-size:larger;">[cellpose.readthedocs.io](https://cellpose.readthedocs.io/en/latest/)</span>.

If you want to improve Cellpose for yourself and for everyone else, please consider contributing manual segmentations for a few of your images via the built-in GUI interface (see instructions below).
**CITATION**: If you use the new human-in-the-loop training or the new models, please cite the Cellpose 2.0 [paper](https://www.biorxiv.org/content/10.1101/2022.04.01.486764v1). If you use the original built-in models (`cyto` or `nuclei`), please cite the Cellpose 1.0 [paper](https://t.co/kBMXmPp3Yn?amp=1).

If you want to improve Cellpose for yourself and for everyone else, please consider contributing manual segmentations for a few of your images via the built-in GUI interface (see instructions below).

### :star2: UPDATE v2.0 (April 2022) :star2:

Expand Down
56 changes: 49 additions & 7 deletions cellpose/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from pyqtgraph import GraphicsScene

import numpy as np
from scipy.stats import mode
import cv2

from . import guiparts, menus, io
Expand Down Expand Up @@ -125,13 +126,18 @@ def run():
app = QApplication(sys.argv)
icon_path = pathlib.Path.home().joinpath('.cellpose', 'logo.png')
guip_path = pathlib.Path.home().joinpath('.cellpose', 'cellpose_gui.png')
style_path = pathlib.Path.home().joinpath('.cellpose', 'style_choice.npy')
if not icon_path.is_file():
cp_dir = pathlib.Path.home().joinpath('.cellpose')
cp_dir.mkdir(exist_ok=True)
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():
print('downloading help window image')
download_url_to_file('https://www.cellpose.org/static/images/cellpose_gui.png', guip_path, progress=True)
if not style_path.is_file():
print('downloading style classifier')
download_url_to_file('https://www.cellpose.org/static/models/style_choice.npy', style_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 @@ -503,15 +509,15 @@ def make_buttons(self):
self.GB.setLayout(self.GBg)

# compute segmentation with general models
net_text = ['cyto','nuclei','tissuenet','livecell', 'cyto2']
self.net_text = ['cyto','nuclei','tissuenet','livecell', 'cyto2']
nett = ['cellpose cyto model',
'cellpose nuclei model',
'tissuenet cell model',
'livecell model',
'cellpose cyto2 model']
self.StyleButtons = []
for j in range(len(net_text)):
self.StyleButtons.append(guiparts.ModelButton(self, net_text[j], net_text[j]))
for j in range(len(self.net_text)):
self.StyleButtons.append(guiparts.ModelButton(self, self.net_text[j], self.net_text[j]))
self.GBg.addWidget(self.StyleButtons[-1], 0,2*j,1,2)
if j < 4:
self.StyleButtons[-1].setFixedWidth(45)
Expand All @@ -520,17 +526,24 @@ def make_buttons(self):
self.StyleButtons[-1].setToolTip(nett[j])

# compute segmentation with style model
net_text = ['CP', 'CPx', 'TN1', 'TN2', 'TN3', #'TN-p','TN-gi','TN-i',
'LC1', 'LC2', 'LC3', 'LC4', #'LC-g','LC-e','LC-r','LC-n',
]
self.net_text.extend(['CP', 'CPx', 'TN1', 'TN2', 'TN3', #'TN-p','TN-gi','TN-i',
'LC1', 'LC2', 'LC3', 'LC4', #'LC-g','LC-e','LC-r','LC-n',
])
nett = ['cellpose cyto fluorescent', 'cellpose other', 'tissuenet 1', 'tissuenet 2', 'tissuenet 3',
'livecell A172 + SKOV3', 'livecell various', 'livecell BV2 + SkBr3', 'livecell SHSY5Y']
for j in range(9):
self.StyleButtons.append(guiparts.ModelButton(self, net_text[j], net_text[j]))
self.StyleButtons.append(guiparts.ModelButton(self, self.net_text[j+5], self.net_text[j+5]))
self.GBg.addWidget(self.StyleButtons[-1], 1,j,1,1)
self.StyleButtons[-1].setFixedWidth(22)
self.StyleButtons[-1].setToolTip(nett[j])

self.StyleToModel = QPushButton(' compute style and run suggested model')
self.StyleToModel.setStyleSheet(self.styleInactive)
self.StyleToModel.clicked.connect(self.suggest_model)
self.StyleToModel.setToolTip(' uses general cp2 model to compute style and runs suggested model based on style')
self.StyleToModel.setFont(self.smallfont)
self.GBg.addWidget(self.StyleToModel, 2,0,1,10)

self.l0.addWidget(self.GB, b, 0, 2, 9)

b+=2
Expand Down Expand Up @@ -1705,6 +1718,33 @@ def compute_cprob(self):
io._masks_to_gui(self, maski, outlines=None)
self.show()

def suggest_model(self, model_name=None):
logger.info('computing styles with 2D image...')
data = self.stack[self.NZ//2].copy()
styles_gt = np.load(os.fspath(pathlib.Path.home().joinpath('.cellpose', 'style_choice.npy')),
allow_pickle=True).item()
train_styles, train_labels, label_models = styles_gt['train_styles'], styles_gt['leiden_labels'], styles_gt['label_models']
self.diameter = float(self.Diameter.text())
self.current_model = 'general'
channels = self.get_channels()
model = models.CellposeModel(model_type='general', gpu=self.useGPU.isChecked())
styles = model.eval(data,
channels=channels,
diameter=self.diameter,
compute_masks=False)[-1]

n_neighbors = 5
dists = ((train_styles - styles)**2).sum(axis=1)**0.5
neighbor_labels = train_labels[dists.argsort()[:n_neighbors]]
label = mode(neighbor_labels)[0][0]
model_type = label_models[label]
logger.info(f'style suggests model {model_type}')
ind = self.net_text.index(model_type)
for i in range(len(self.net_text)):
self.StyleButtons[i].setStyleSheet(self.styleUnpressed)
self.StyleButtons[ind].setStyleSheet(self.stylePressed)
self.compute_model(model_name=model_type)

def compute_model(self, model_name=None):
self.progress.setValue(0)
try:
Expand Down Expand Up @@ -1781,6 +1821,8 @@ def enable_buttons(self):
if len(self.model_strings) > 0:
self.ModelButton.setStyleSheet(self.styleUnpressed)
self.ModelButton.setEnabled(True)
self.StyleToModel.setStyleSheet(self.styleUnpressed)
self.StyleToModel.setEnabled(True)
for i in range(len(self.StyleButtons)):
self.StyleButtons[i].setEnabled(True)
self.StyleButtons[i].setStyleSheet(self.styleUnpressed)
Expand Down
9 changes: 5 additions & 4 deletions cellpose/gui/guiparts.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def press(self, parent):
class TrainWindow(QDialog):
def __init__(self, parent, model_strings):
super().__init__(parent)
self.setGeometry(100,100,600,300)
self.setGeometry(100,100,900,350)
self.setWindowTitle('train settings')
self.win = QWidget(self)
self.l0 = QGridLayout()
Expand Down Expand Up @@ -88,16 +88,17 @@ def __init__(self, parent, model_strings):
self.l0.addWidget(qlabel, i+yoff,0,1,1)
self.edits.append(QLineEdit())
self.edits[-1].setText(str(parent.training_params[label]))
self.edits[-1].setFixedWidth(200)
self.l0.addWidget(self.edits[-1], i+yoff, 1,1,1)

yoff+=len(labels)

yoff+=1
qlabel = QLabel('(to remove files, click cancel then remove from folder and reopen train window)')
self.l0.addWidget(qlabel, yoff,0,1,4)
qlabel = QLabel('(to remove files, click cancel then remove \nfrom folder and reopen train window)')
self.l0.addWidget(qlabel, yoff,0,2,4)

# click button
yoff+=1
yoff+=2
QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
self.buttonBox = QDialogButtonBox(QBtn)
self.buttonBox.accepted.connect(lambda: self.accept(parent))
Expand Down
8 changes: 6 additions & 2 deletions cellpose/gui/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,12 @@ def _save_png(parent):
filename = parent.filename
base = os.path.splitext(filename)[0]
if parent.NZ==1:
print('GUI_INFO: saving 2D masks to png')
imsave(base + '_cp_masks.png', parent.cellpix[0])
if parent.cellpix[0].max() > 65534:
print('GUI_INFO: saving 2D masks to tif (too many masks for PNG)')
imsave(base + '_cp_masks.tif', parent.cellpix[0])
else:
print('GUI_INFO: saving 2D masks to png')
imsave(base + '_cp_masks.png', parent.cellpix[0].astype(np.uint16))
else:
print('GUI_INFO: saving 3D masks to tiff')
imsave(base + '_cp_masks.tif', parent.cellpix)
Expand Down
2 changes: 1 addition & 1 deletion cellpose/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
_MODEL_DIR_DEFAULT = pathlib.Path.home().joinpath('.cellpose', 'models')
MODEL_DIR = pathlib.Path(_MODEL_DIR_ENV) if _MODEL_DIR_ENV else _MODEL_DIR_DEFAULT

MODEL_NAMES = ['cyto','nuclei','tissuenet','livecell', 'cyto2',
MODEL_NAMES = ['cyto','nuclei','tissuenet','livecell', 'cyto2', 'general',
'CP', 'CPx', 'TN1', 'TN2', 'TN3', 'LC1', 'LC2', 'LC3', 'LC4']

def model_path(model_type, model_index, use_torch=True):
Expand Down
17 changes: 17 additions & 0 deletions docs/gui.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ Check out this `video <https://youtu.be/3Y1VKcxjNy4>`_ to learn the process.
6. 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.
7. 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.

If you have **3D** data, please save random XY, YZ and XZ slices through your 3D data,
ideally sufficiently spaced from each other so the information each slice has is
distinct. Then put these slices into a folder and start the human-in-the-loop training.
You can then use the new custom model on new 3D data.

.. note::
You can only start training with one of the built-in Cellpose models or from scratch.
When you start training from a built-in model or from scratch each time, then you are training
the network on all the previously labelled images in the folder and weighting them equally in
your training set.

If you restart from a previous retraining, you are biasing the network towards the earlier
images it has already been trained on. Conversely, if you have created a custom model
with different images, and you retrain that model, then you are downweighting the images
that you have already trained on and excluded from your new training set. Therefore, we recommend having all images
that you want to be trained for the same model in the same folder so they are all used.

Contributing training data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
4 changes: 4 additions & 0 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ this code at the beginning of your notebook before you import cellpose:
import os
os.environ["CELLPOSE_LOCAL_MODELS_PATH"] = "/PATH_FOR_MODELS/"

M1 Mac installation
~~~~~~~~~~~~~~~~~~~~~~~

Please use the instructions provided on `image.sc <https://forum.image.sc/t/cellpose-on-macos-m1-pro-apple-silicon-arm64/68018/4>`
by Peter Sobolewski.

Common issues
~~~~~~~~~~~~~~~~~~~~~~~
Expand Down

0 comments on commit be94059

Please sign in to comment.