Cellpose | 3D细胞分割

文摘   科学   2024-09-29 21:57   上海  

科 / 研 / 图 / 像 / 处 / 理


Cellpose 是强大的细胞分割工具,不仅仅可以处理 2D 的细胞分割,也可以无需训练推广到 3D 细胞分割。


传统上,3D 分割需要可用的 3D 训练数据,这比二维训练数据要复杂得多。


这是因为创建三维训练数据需要独立地对每个二维切片进行分割,这非常耗时。例如,如果一个细胞在 Z 上跨越了 30 层,那就需要对这 30 层都进行手动二维分割。


Cellpose 采用对图像 XY,YZ,XZ 方向分别计算梯度,然后把得到的3个方向的梯度进行平均,最终无需训练一个 3D 模型,就可以实现 3D 的细胞分割。




这篇文章会介绍怎样利用 Cellpose 的 GUI 以及脚本进行 3D 细胞分割。





一、安装 Cellpose 以及 GPU dependency


参考之前的文章:

点击跳转《细胞分割神器 Cellpose(GPU加速)



二、利用 Cellpose GUI 进行 3D 细胞分割


1、打开 Cellpose GUI


安装好 cellpose 后,激活安装了 cellpose 的 conda 环境,,打开 cellpose 的 GUI:

python -m cellpose




2、导入 3D image stack


打开 Cellpose GUI 后,加载图像,图像应该是一个 tif 格式的 3D stack:



勾选 orthoviews 可以从三个角度观察图像




3、设置参数


cellpose 有几个关键的参数需要设置:

1、细胞大概的直径(单位为 pixel);

2、分割哪一个通道(这里的例子是单通道的图像,选择 gray);

3、选择哪个图像进行分割(这里选中 nuclei)。


细胞直径可以通过 Calibrate 功能进行预测,预测细胞直径有 17.4 个pixel,符合预期:




点击 model zoo 中的 model 之后,会自动下载该 model,并生成分割结果。可以多测试一些模型,选效果最好的模型:





4、导出结果


点击 File,选择 Save masks as PNG/tif,即可在图片所在文件夹得到 3D Mask 图像:


分割结果:





三、调用 cellpose API


因为要导入 Image stack,在 cellpose 对应的 conda 环境中 tifffile 这个包:

pip install tifffile -i https://pypi.tuna.tsinghua.edu.cn/simple/


代码示例:


from cellpose import modelsimport tifffile
img = tifffile.imread('test_stack.tif')
# define basic parameterscellDiameter = 17.4 # cell diameterchan = [0,0] # CHANNELS to segementminVol = 15 # filter small noisezScaleFactor = 1 # z step / xy pixel size
# set model, use GPU to calculatemodel = models.Cellpose(gpu=True, model_type='nuclei')
# segment imagemasks, flows, styles, diams = model.eval(img, diameter = cellDiameter, channels = chan, do_3D = True, anisotropy = zScaleFactor, min_size = minVol)


通过把 masks 和原图 plot 在一起,可以检查分割效果,plot 代码:


# DISPLAY RESULTSfrom stardist import random_label_cmapimport matplotlib.pyplot as pltimport matplotlib as mplimport numpy as np%matplotlib inline
np.random.seed(6)lbl_cmap = random_label_cmap()
plt.figure(figsize=(13,10))plt.subplot(121)plt.imshow(img[img.shape[0] // 2 - 5,:,:],cmap='gray')plt.title('Raw image (XY slice)')plt.axis('off')
plt.subplot(122)plt.imshow(img[img.shape[0] // 2 - 5,:,:],cmap='gray')plt.imshow(masks[img.shape[0] // 2 - 5,:,:], cmap=lbl_cmap, alpha=0.5)plt.title('Segmented image (XY slice)')plt.axis('off')


分割效果:



四、代码分析


1、导入 Image stack


import tifffileimg = tifffile.imread('test_stack.tif')


导入 Image stack 的方法有很多,tifffile 是导入 tiff 格式图像比较方便的一种方法。


导入后的图像直接是一个 numpy array。array 的维度,相对于原始的图像是 [Z,Y,X]。



2、进行3D细胞分割


# segment imagemasks, flows, styles, diams = model.eval(img, diameter = cellDiameter,                                          channels = chan,                                          do_3D = True,                                          anisotropy = zScaleFactor,                                          min_size = minVol)


跟进行 2D 细胞分割不同,进行 3D 细胞分割时,do_3D 需要定义为 True,不定义的情况下默认是 False。


anisotropy,即各向异性也需要进行定义。每一个 Voxel,三个维度 XYZ 的比例不一定是 1:1:1。


例如,如果成像时 Z step 是 2μm,而 XY 的 pixel size 是1μm,anisotropy需要定义为 2。


如果 3D分割效果比较差,可以采用先每层进行2D分割,再把不同层stitch 起来的方法


# segment imagemasks, flows, styles, diams = model.eval(img, diameter = cellDiameter,                                          channels = chan,                                          stitch_threshold = 0.2,                                          anisotropy = zScaleFactor,                                          min_size = minVol)


do_3D 默认是 False,定义 stitch_threshold,单层的结果:



3D 的效果:




2D stitch 的方法,在 2D 单层分割的效果是优于 3D 分割的。


但因为 2D stitch 只是通过 overlap 来判断层与层之间是否属于同一个物体,所以可能无法很好地把粘连的物体分开。





创作不易,点个关注再走吧
如果有任何问题,欢迎在文章下方留言
 

作者 | Treasure琛
排版 | 小乐喵喵   

往期回顾

◆ ImageJ | 荧光共标细胞计数

◆ ImageJ | 图像标注

◆ ImageJ | 图像去卷积

◆ ImageJ | 自动图片拼接

◆ ImageJ | 3D可视化及测量

◆ ImageJ | 图像自动配准

◆ ImageJ | 重新认识你的图像

◆ ImageJ | 荧光比率图




科研图像处理
科研图像处理一站式解决方案,原知乎《ImageJ实用教程》
 最新文章