Skip to content

Commit

Permalink
Merge pull request #40 from fmi-faim/cellpose
Browse files Browse the repository at this point in the history
  • Loading branch information
imagejan authored Nov 27, 2023
2 parents 9a08b3b + 38bbd07 commit dd717cb
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11.0-beta.5 - 3.11']
python-version: ['3.8', '3.9', '3.10', '3.11']

steps:
- uses: actions/checkout@v3
Expand Down
18 changes: 18 additions & 0 deletions config_cellpose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2023 Friedrich Miescher Institute for Biomedical Research (FMI), Basel (Switzerland)
#
# SPDX-License-Identifier: MIT

# Required
file_selection: # criteria for file selection in case of multiple channels/slices per position
channel: C01
process: # choose method how to segment, filter, and sample the objects
segment: cellpose
filter: []
sample: centers

# Each subsequent section provides arguments to one of the methods defined in 'process'
cellpose:
diameter: 10.0
pretrained_model: cyto2
cellprob_threshold: 0.0
flow_threshold: 0.4
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ build-backend = "hatchling.build"
name = "faim-wako-searchfirst"
description = ''
readme = "README.md"
requires-python = ">=3.7"
requires-python = ">=3.8"
license = "MIT"
keywords = []
authors = [
Expand All @@ -19,7 +19,6 @@ authors = [
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand All @@ -28,6 +27,7 @@ classifiers = [
"Programming Language :: Python :: Implementation :: PyPy",
]
dependencies = [
"cellpose",
"confuse",
"rich",
"scikit-image",
Expand Down Expand Up @@ -55,7 +55,7 @@ cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=faim_w
no-cov = "cov --no-cov {args}"

[[tool.hatch.envs.test.matrix]]
python = ["37", "38", "39", "310", "311"]
python = ["38", "39", "310", "311"]

[tool.coverage.run]
branch = true
Expand Down
36 changes: 32 additions & 4 deletions src/faim_wako_searchfirst/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
"""

import logging
from pathlib import Path
from typing import Union

import numpy as np
from cellpose import models
from scipy.ndimage import binary_fill_holes
from skimage.measure import label, regionprops

Expand All @@ -26,10 +29,6 @@ def threshold(
:param img: input image
:param threshold: global threshold
:param include_holes: if true, holes will be filled
:param min_size: minimum object size
:param max_size: maximum object size
:param min_eccentricity: minimum eccentricity of object
:param max_eccentricity: maximum eccentricity of object
:param logger:
:return: a label image representing the detected objects
Expand All @@ -41,3 +40,32 @@ def threshold(
regions = regionprops(labeled_image)
logger.info(f"Found {len(regions)} connected components.")
return labeled_image


def cellpose(
img,
diameter: float,
pretrained_model: Union[str, Path] = "cyto2",
logger=logging,
**kwargs,
):
"""Segment a given image by global thresholding.
:param img: input image
:param diameter: expected object diameter
:param pretrained_model: name of cellpose model, or path to pretrained model
:param logger:
:return: a label image representing the detected objects
"""
logger.info(f"Load cellpose model: {pretrained_model}")
model: models.CellposeModel = models.CellposeModel(
pretrained_model=pretrained_model,
)
mask, _, _ = model.eval(
img,
channels=[0, 0],
diameter=diameter,
**kwargs,
)
return mask
36 changes: 36 additions & 0 deletions tests/test_cellpose.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: 2023 Friedrich Miescher Institute for Biomedical Research (FMI), Basel (Switzerland)
#
# SPDX-License-Identifier: MIT

"""Test faim_wako_searchfirst module."""
import csv
import shutil
from pathlib import Path

import pytest
from faim_wako_searchfirst.main import run


@pytest.fixture
def _data_path(tmp_path):
# copy test set into tmp_path, return resulting Path
testset_path = Path("tests/resources/TestSet")
assert testset_path.exists()
return shutil.copytree(testset_path, tmp_path / "TestSet")


def test_cellpose(_data_path):
"""Test run with parameters defined in the sample config_cellpose.yml file."""
run(_data_path, configfile="config_cellpose.yml")
csv_path = _data_path / "TestSet_D07_T0001F002L01A02Z01C01.csv"
assert csv_path.exists()
with open(csv_path, "r") as csv_file:
reader = csv.reader(csv_file, quoting=csv.QUOTE_NONNUMERIC)
entries = list(reader)
assert len(entries) == 3, "Incorrect number of objects detected."
assert entries[0] == pytest.approx([1, 40.5, 30.5])
assert entries[1] == pytest.approx([2, 158.5, 58.5])
assert entries[2] == pytest.approx([3, 79.5287, 146.4483])

segmentation_folder = _data_path.parent / (_data_path.name + "_segmentation")
assert sum(1 for _ in segmentation_folder.glob("*")) == 1

0 comments on commit dd717cb

Please sign in to comment.