mcpField
C
cellpose-cell-segmentation

cellpose-cell-segmentation

github.com/jaechang-hits数据与数据库38477 次安装6 天前更新
代码仓库

关于 cellpose-cell-segmentation

面向显微图像分析的 Cellpose 技能,使用预训练模型分割细胞或细胞核,适合需要处理多种细胞类型及批量图像的研究流程。它可生成带标签的掩膜,并支持 3D z-stack 分割。

主要功能

  1. 01预训练模型分割细胞与细胞核
  2. 02自动估算细胞直径
  3. 03支持 3D z-stack 分割
  4. 04批量处理图像
  5. 05输出整数标签掩膜
  6. 06可微调自定义模型

适用场景

  1. 01分割荧光显微图像中的细胞
  2. 02批量处理大型显微图像集
  3. 03测量掩膜中的细胞形态
  4. 04对 z-stack 数据进行 3D 分割

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill cellpose-cell-segmentation

安装后在 Claude Code 中输入/cellpose-cell-segmentation确认已加载。

详细介绍

Cellpose — 深度学习细胞分割

概述

Cellpose 使用基于流场的神经网络,无需手动调整参数即可分割荧光显微图像中的单个细胞或细胞核。预训练模型(cyto3、nuclei、tissuenet)可泛化到不同细胞类型、放大倍率和染色条件,无需手动选择阈值或优化分水岭参数。Cellpose 输出整数标签掩码(每个细胞对应一个唯一整数),可与 scikit-image regionprops 配合进行形态测量,也可与 TrackPy 配合进行跟踪。内置的直径估算器无需指定细胞大小,不过提供近似直径可提高准确性。

适用场景

  • 分割荧光显微图像中的细胞或细胞核,尤其适用于因强度变化或细胞接触而导致基于规则的阈值处理失效的情况
  • 批量处理大型显微图像数据集,无需为每张图像单独调整参数
  • 使用单个模型分割多种细胞类型(贴壁细胞、血细胞、细菌、类器官)
  • 生成标签掩码,以便使用 scikit-image 进行下游区域属性测量(面积、强度、形状)
  • 使用 do_3D=True 对 z-stack 显微数据进行 3D 体积分割
  • 当细胞彼此分离且基于规则的阈值处理足够时,使用 scikit-image watershed
  • 将 StarDist 用作替代深度学习分割器,它针对星凸形细胞(神经元、细胞核)进行了优化

前置条件

  • Python 包:cellpose、numpy、matplotlib
  • 可选:支持 CUDA 的 GPU,可实现 10–50× 加速(GUI 需运行 pip install cellpose[gui])
  • 输入:灰度或多通道 TIFF/PNG 图像(2D 或 3D 数组)
# Install Cellpose
pip install cellpose

# Install with GUI support
pip install cellpose[gui]

# Install with GPU (PyTorch CUDA)
pip install cellpose torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# Verify
python -c "from cellpose import models; print('Cellpose ready')"

快速开始

from cellpose import models
import numpy as np
from skimage import io

# Load image (grayscale or 2D array)
img = io.imread("cells.tif")  # shape: (H, W) or (H, W, C)

# Initialize model and segment
model = models.Cellpose(model_type="cyto3", gpu=False)
masks, flows, styles, diams = model.eval(img, diameter=0, channels=[0, 0])

print(f"Cells segmented: {masks.max()}")  # number of cells
print(f"Estimated diameter: {diams:.1f} px")
print(f"Mask shape: {masks.shape}")

工作流

步骤 1:加载并检查图像

加载显微图像,并在分割前检查通道布局。

import numpy as np
from skimage import io
import matplotlib.pyplot as plt

# Load single-channel fluorescence image
img_gray = io.imread("nucleus_dapi.tif")           # shape: (H, W)
img_rgb = io.imread("cells_multichannel.tif")      # shape: (H, W, C)

print(f"Grayscale shape: {img_gray.shape}, dtype: {img_gray.dtype}")
print(f"Multichannel shape: {img_rgb.shape}")

# Preview
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(img_gray, cmap="gray")
axes[0].set_title("DAPI (nuclei)")
axes[1].imshow(img_rgb[..., 0], cmap="green")
axes[1].set_title("GFP channel")
plt.tight_layout()
plt.savefig("image_preview.png", dpi=100)
print("Saved: image_preview.png")
步骤 2:使用预训练模型分割细胞

使用适当的预训练模型运行 Cellpose。

from cellpose import models
import numpy as np
from skimage import io

# Available models: 'cyto3' (cells), 'nuclei', 'tissuenet', 'cyto2', 'CP'
model = models.Cellpose(model_type="cyto3", gpu=False)

img = io.imread("cells.tif")

# channels=[cytoplasm_channel, nucleus_channel]
# Use [0, 0] for grayscale; [1, 3] for green cytoplasm + blue nucleus (1-indexed)
masks, flows, styles, diams = model.eval(
    img,
    diameter=0,          # 0 = auto-estimate; or provide px estimate
    channels=[0, 0],     # grayscale
    flow_threshold=0.4,  # lower = fewer false positives; range 0.1-1.0
    cellprob_threshold=0.0,  # lower = more cells detected; range -6 to 6
)

print(f"Cells found: {masks.max()}")
print(f"Estimated cell diameter: {diams:.1f} pixels")
np.save("masks.npy", masks)
步骤 3:从 DAPI 通道分割细胞核

对 DAPI 染色的细胞核使用 nuclei 模型。

from cellpose import models
from skimage import io
import numpy as np

model = models.Cellpose(model_type="nuclei", gpu=False)
dapi = io.imread("dapi.tif")

# Nucleus-only segmentation: channels=[0, 0] (single channel)
masks, flows, styles, diams = model.eval(
    dapi,
    diameter=30,         # approximate nucleus diameter in pixels
    channels=[0, 0],
    flow_threshold=0.4,
    cellprob_threshold=0.0,
)

print(f"Nuclei segmented: {masks.max()}")
# Save label mask as TIFF for ImageJ/FIJI compatibility
from skimage import io as skio
skio.imsave("nuclei_masks.tif", masks.astype(np.uint16))
print("Saved: nuclei_masks.tif")
步骤 4:可视化分割结果

将掩码叠加到原始图像上以进行质量控制。

from cellpose import plot as cpplot
import matplotlib.pyplot as plt
import numpy as np
from skimage import io

img = io.imread("cells.tif")
masks = np.load("masks.npy")
flows_data = None  # load if you saved them: flows = np.load("flows.npy", allow_pickle=True)

# Cellpose built-in visualization
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

# Original image
axes[0].imshow(img, cmap="gray")
axes[0].set_title(f"Original image")

# Label mask (each cell = unique color)
axes[1].imshow(masks, cmap="tab20")
axes[1].set_title(f"Segmentation masks ({masks.max()} cells)")

# Overlay: outline on original
from skimage.segmentation import find_boundaries
boundaries = find_boundaries(masks, mode="inner")
overlay = np.stack([img / img.max()] * 3, axis=-1)
overlay[boundaries] = [1, 0, 0]  # red outlines
axes[2].imshow(overlay)
axes[2].set_title("Outlines overlay")

plt.tight_layout()
plt.savefig("segmentation_result.png", dpi=150)
print("Saved: segmentation_result.png")
步骤 5:从掩码测量细胞属性

使用 scikit-image regionprops 提取形态和强度测量值。

import numpy as np
import pandas as pd
from skimage.measure import regionprops_table
from skimage import io

masks = np.load("masks.npy")
img = io.imread("cells.tif")

# Measure morphology and intensity per cell
props = regionprops_table(
    masks, intensity_image=img,
    properties=["label", "area", "centroid", "eccentricity",
                 "mean_intensity", "max_intensity", "perimeter",
                 "equivalent_diameter_area"]
)
df = pd.DataFrame(props)
df.columns = ["cell_id", "area_px", "centroid_y", "centroid_x",
              "eccentricity", "mean_intensity", "max_intensity",
              "perimeter", "diameter_px"]

print(f"Cells measured: {len(df)}")
print(f"Median area: {df['area_px'].median():.0f} px²")
print(f"Median diameter: {df['diameter_px'].median():.1f} px")
print(df.head())

df.to_csv("cell_measurements.csv", index=False)
步骤 6:批量分割多张图像

处理一个图像目录并汇总结果。

from cellpose import models
from skimage import io
from skimage.measure import regionprops_table
import pandas as pd
import numpy as np
from pathlib import Path

model = models.Cellpose(model_type="cyto3", gpu=False)
image_dir = Path("images/")
output_dir = Path("results/")
output_dir.mkdir(exist_ok=True)

all_stats = []
for img_path in sorted(image_dir.glob("*.tif")):
    img = io.imread(img_path)
    masks, _, _, diams = model.eval(img, diameter=0, channels=[0, 0])
    
    # Save mask
    np.save(output_dir / f"{img_path.stem}_masks.npy", masks)
    
    # Measure
    if masks.max() > 0:
        props = regionprops_table(masks, intensity_image=img,
                                  properties=["label", "area", "mean_intensity"])
        df = pd.DataFrame(props)
        df["image"] = img_path.name
        df["est_diameter"] = diams
        all_stats.append(df)
    
    print(f"{img_path.name}: {masks.max()} cells, diameter={diams:.0f}px")

summary = pd.concat(all_stats, ignore_index=True)
summary.to_csv(output_dir / "all_cells.csv", index=False)
print(f"\nTotal cells: {len(summary)} across {summary['image'].nunique()} images")

关键参数

参数默认值范围/选项效果
model_type"cyto3""cyto3"、"cyto2"、"nuclei"、"tissuenet"、"CP"、自定义路径预训练模型;cyto3 通用性最强;nuclei 适用于仅 DAPI 的情况
diameter300–500 px以像素为单位的细胞近似直径;0 = 根据图像自动估算
channels[0, 0][cyto, nucleus](0=灰度、1=R、2=G、3=B)细胞质和细胞核染色的通道索引
flow_threshold0.40.1–1.0流场中的细胞概率阈值;值越低,条件越严格
cellprob_threshold0.0−6 至 6细胞概率截断值;增大可找到更多细胞
gpuFalseTrue、False启用 GPU 推理(需要 CUDA PyTorch)
do_3DFalseTrue、False启用对 z-stack 的 3D 体积分割
min_size15整数 px²以像素²为单位的最小对象大小;会舍弃更小的对象
batch_size8整数每个 GPU 批次处理的图像切片数
normalizeTrueTrue、False分割前对图像强度进行归一化

常用方案

方案 1:分割多通道图像(GFP + DAPI)
from cellpose import models
from skimage import io
import numpy as np

model = models.Cellpose(model_type="cyto3", gpu=False)

# Multichannel image: channel 1 = GFP (cytoplasm), channel 3 = DAPI (nucleus)
img_multi = io.imread("cells_gfp_dapi.tif")  # shape: (H, W, 3)

# channels=[cytoplasm_channel, nucleus_channel] (1-indexed for multichannel)
masks, flows, styles, diams = model.eval(
    img_multi,
    diameter=0,
    channels=[2, 3],  # GFP=channel2, DAPI=channel3 (1-indexed)
    flow_threshold=0.4,
)
print(f"Cells segmented: {masks.max()}, diameter: {diams:.0f}px")
np.save("masks_multichannel.npy", masks)
方案 2:使用 Cellpose CLI 批量处理目录
# CLI batch segmentation of all TIFFs in a directory
cellpose \
    --image_path images/ \
    --pretrained_model cyto3 \
    --diameter 0 \
    --chan 0 \
    --save_tif \
    --no_npy

# With GPU
cellpose \
    --image_path images/ \
    --pretrained_model nuclei \
    --diameter 30 \
    --chan 0 \
    --use_gpu \
    --save_tif

# Results saved as: images/*_cp_masks.tif
echo "Done. Masks saved in images/ directory."
方案 3:针对自定义细胞类型微调 Cellpose
from cellpose import models, train
import numpy as np
from skimage import io

# Prepare training data: list of images and corresponding masks
train_images = [io.imread(f"train/img_{i}.tif") for i in range(10)]
train_masks = [np.load(f"train/mask_{i}.npy") for i in range(10)]

# Fine-tune starting from cyto3
model = models.CellposeModel(model_type="cyto3")

# Train: saves model to models/ directory
model_path = train.train_seg(
    model.net,
    train_data=train_images,
    train_labels=train_masks,
    channels=[0, 0],
    save_path="models/",
    n_epochs=100,
    learning_rate=0.2,
    weight_decay=1e-5,
)
print(f"Fine-tuned model saved: {model_path}")

预期输出

输出格式说明
masks arraynumpy int32标签掩膜:0=背景,1..N=唯一细胞 ID
flows listnumpy arrays流场分量:[XY 流、细胞概率、梯度]
styles arraynumpy float风格向量嵌入(用于模型相似度)
diams float标量估算的平均细胞直径,单位为像素
*_masks.npyNumPy保存的掩膜数组(由 np.save 生成)
*_cp_masks.tifTIFF uint16掩膜 TIFF(来自 CLI --save_tif);兼容 FIJI/ImageJ

故障排查

问题原因解决方案
所有细胞都合并成一个掩膜直径过大或细胞距离过近减小 diameter;将 flow_threshold 增至 0.6–0.8
检测到的细胞很少直径过小或 cellprob_threshold 过高将 cellprob_threshold 增至 −2;使用 diameter=0 自动检测
大量误报(背景被标记)flow_threshold 过低将 flow_threshold 增至 0.6–0.9;增大 min_size
GPU 显存不足图像对于 GPU 批处理来说过大分块处理;减小 batch_size;裁剪图像
对新细胞类型的泛化效果差模型未在相似细胞上训练尝试所有预训练模型;使用 10-20 张已标注图像微调
3D 分割速度很慢在 CPU 上处理大型 z-stack启用 GPU;减小 z-stack 深度;使用 anisotropy 参数
掩膜值超出 uint8 范围图像中细胞数超过 255使用 dtype=np.uint16 或 np.int32 保存
导入错误:No module named 'cellpose'未安装软件包pip install cellpose 或 conda install -c conda-forge cellpose

参考资料

评论

支持 Markdown