在OpenCL兼容GPU上进行对象分类#

APOC基于pyclesperantoscikit-learn。它允许根据测量的属性/特征(如强度、形状和相邻细胞数量)对对象进行分类。

import apoc

from skimage.io import imread, imsave
import pyclesperanto_prototype as cle
import numpy as np
import matplotlib.pyplot as plt

对于对象分类,我们需要一个强度图像和一个标签图像作为输入。

# load intensity image
image = imread('../../data/blobs.tif')

# segment the image
labels = cle.label(cle.threshold_otsu(image))

fig, axs = plt.subplots(1, 2)

cle.imshow(image, color_map="Greys_r", plot=axs[0])
cle.imshow(labels, labels=True, plot=axs[1])
../_images/fa297a6ff94d7e67daf1bf1ec0ab5638bddf284678939e68cfd3b433292d0378.png

训练#

我们还需要一个地面真实标注图像。这个图像也是一个具有稀疏标注的标签图像。通过所有应该属于类别1的对象画了一条值为1的线。通过所有应该被分类为类别2的对象画了一条值为2的线。如果线穿过背景,这将被忽略。在这个例子中,对象被标注为三个类别:

  • 细长的对象

  • 圆形对象

  • 小对象

annotation = cle.push(imread('../../data/label_annotation.tif'))

fig, axs = plt.subplots(1, 2)

cle.imshow(labels, labels=True, plot=axs[0])
cle.imshow(annotation, labels=True, plot=axs[1])
../_images/146b524bd41585fb8be17f58fbde072c865befc7981ca2a0a1efd152448fd340.png

接下来,我们需要定义我们想要用于分类对象的特征。我们将使用面积、形状和强度的标准差。

features = 'area mean_max_distance_to_centroid_ratio standard_deviation_intensity'
# Create an object classifier
filename = "../../data/blobs_object_classifier.cl"
classifier = apoc.ObjectClassifier(filename)

# train it; after training, it will be saved to the file specified above
classifier.train(features, labels, annotation, image)

在分类器训练完成后,我们可以立即使用它来预测图像中对象的分类。

# determine object classification
classification_result = classifier.predict(labels, image)

cle.imshow(classification_result, labels=True)
../_images/f39c851ff0b77b66b8cc4045185abf5ddb35f8fb60dcadc3704c6b6ae598d23a.png

预测#

你也可以从磁盘重新加载分类器并将其应用于其他图像。我们将通过旋转原始图像来模拟这一过程。顺便说一下,这是一个很好的健全性检查,可以看看分类是否依赖于图像的方向。

image2 = cle.rotate(image, angle_around_z_in_degrees=90)
labels2 = cle.rotate(labels, angle_around_z_in_degrees=90)
classifier2 = apoc.ObjectClassifier("../../data/blobs_object_classifier.cl")

classification_result2 = classifier2.predict(labels2, image2)

cle.imshow(classification_result2, labels=True)
../_images/01f6b12bedc4242bef52b89fea7595aefd441139067670817bdbc8b49344b559.png

可用于对象分类的特征#

我们可以打印出所有可用的特征。带有?的参数在该位置期望一个数字,并且可以多次指定多个值。

apoc.list_available_object_classification_features()
['label',
 'original_label',
 'bbox_min_x',
 'bbox_min_y',
 'bbox_min_z',
 'bbox_max_x',
 'bbox_max_y',
 'bbox_max_z',
 'bbox_width',
 'bbox_height',
 'bbox_depth',
 'min_intensity',
 'max_intensity',
 'sum_intensity',
 'area',
 'mean_intensity',
 'sum_intensity_times_x',
 'mass_center_x',
 'sum_intensity_times_y',
 'mass_center_y',
 'sum_intensity_times_z',
 'mass_center_z',
 'sum_x',
 'centroid_x',
 'sum_y',
 'centroid_y',
 'sum_z',
 'centroid_z',
 'sum_distance_to_centroid',
 'mean_distance_to_centroid',
 'sum_distance_to_mass_center',
 'mean_distance_to_mass_center',
 'standard_deviation_intensity',
 'max_distance_to_centroid',
 'max_distance_to_mass_center',
 'mean_max_distance_to_centroid_ratio',
 'mean_max_distance_to_mass_center_ratio',
 'touching_neighbor_count',
 'average_distance_of_touching_neighbors',
 'average_distance_of_n_nearest_neighbors=?',
 'average_distance_of_n_nearest_neighbors=?']