使用机器学习合并对象#

ObjectMergerapoc库中的一个随机森林分类器,它可以学习哪些标签需要合并,哪些不需要。它允许在对象被(有意或无意地)过度分割后对标签图像进行后处理。

import apoc
from skimage.io import imread, imshow
import pyclesperanto_prototype as cle
import numpy as np

一个常见的例子可以从显示细胞膜强度的图像中得到。

image = imread('../../data/membrane2d.tif')
cle.asarray(image)
cle._ image
shape(256, 256)
dtypefloat32
size256.0 kB
min277.0
max44092.0

由于膜在图像的不同区域具有不同的强度,我们首先需要对此进行校正。

background_subtracted = cle.divide_by_gaussian_background(image, sigma_x=10, sigma_y=10)
background_subtracted
cle._ image
shape(256, 256)
dtypefloat32
size256.0 kB
min0.15839748
max11.448771

出于技术原因,还建议将强度图像转换为整数类型的图像。因此,可能需要进行归一化。重要的是,用于训练和用于预测的图像应具有相同范围的强度。

oversegmented = imread("../../data/membrane2d_oversegmented.tif")
cle.asarray(oversegmented).astype(np.uint32)
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min1.0
max54.0

注释用于告诉算法哪些分割对象应该合并,哪些不应该。

annotation = imread("../../data/membrane2d_merge_annotation.tif")
cle.asarray(annotation).astype(np.uint32)
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min0.0
max2.0

为了可视化,我们可以将注释与膜图像叠加。

cle.imshow(background_subtracted, max_display_intensity=4, continue_drawing=True)
cle.imshow(annotation, alpha=0.6, labels=True)
../_images/ed4124ba7532565c50e80bc09e8a750e648ef841fefa532d76468f463025b4fb.png

为了更清楚地显示需要注释的内容,我们还叠加了标签边缘图像和注释。请注意,不应合并的边缘是小点,始终仔细地只注释两个对象(不应合并的对象)。

cle.imshow(cle.detect_label_edges(oversegmented), continue_drawing=True)
cle.imshow(annotation, alpha=0.6, labels=True)
../_images/3e3e7c26276223990a47c1d3fa12c738cead94714793ea0d4cfdfc692f647b4b.png

训练合并器#

LabelMerger可以使用三个特征进行训练:

  • touch_portion:一个对象接触另一个对象的相对数量。例如,在对称的蜂窝状组织中,相邻细胞之间的接触比例为1/6

  • touch_count:对象接触的像素数。使用此参数时,确保用于训练和预测的图像具有相同的体素大小。

  • mean_touch_intensity:接触对象之间的平均强度。如果一个细胞被过度分割,在该细胞内会发现多个对象。这些对象接触的区域比两个细胞接触的区域具有较低的强度。因此,它们可以被区分。如上所示的图像归一化是关键。

  • centroid_distance:标记对象的质心之间的距离(以像素或体素为单位)。

注意:大多数特征建议仅在各向同性图像中使用。

feature_definition = "touch_portion mean_touch_intensity"

classifier_filename = "label_merger.cl"

apoc.erase_classifier(classifier_filename)
classifier = apoc.ObjectMerger(opencl_filename=classifier_filename)

classifier.train(features=feature_definition,
                 labels=oversegmented,
                 sparse_annotation=annotation,
                 image=background_subtracted) 
merged_labels = classifier.predict(labels=oversegmented, image=background_subtracted)
merged_labels
cle._ image
shape(256, 256)
dtypeuint32
size256.0 kB
min1.0
max31.0