瓦片中的连通分量标记#

在瓦片中标记对象是一项具有挑战性的任务。如果无法避免这一步骤,dask-image提供了合适的功能来获取跨多个瓦片的标记图像。

import numpy as np
import dask
import dask.array as da
from skimage.data import cells3d
from skimage.io import imread
from skimage.measure import label as skimage_label
import pyclesperanto_prototype as cle
from pyclesperanto_prototype import imshow
from dask_image.ndmeasure import label as daskimage_label
image = imread("../../data/blobs.tif") > 128
imshow(image)
../_images/bc8b964563969e824e1e452e9ee92af0a0b36f9e58fefa5725be34bf21a7f04b.png
tiles = da.from_array(image, chunks=(128, 128))
tiles
Array Chunk
Bytes 63.50 kiB 16.00 kiB
Shape (254, 256) (128, 128)
Count 4 Tasks 4 Chunks
Type bool numpy.ndarray
256 254

我们将使用scikit-image的label()函数来处理我们的图像。

procedure = skimage_label

tile_map = da.map_blocks(procedure, tiles)

result = tile_map.compute()
imshow(result, labels=True)
../_images/85f5dc7fe2faef30a7c0698b3ac33dd3c8f3c7351c3eabf940aa698f5020eab0.png

在这张图像中,我们已经可以看到结果在图像水平和垂直中心的瓦片边界处有伪影。为了进一步检查结果,我们将计算不分瓦片的图像连通分量标记。

reference = skimage_label(image)

imshow(reference, labels=True)
../_images/cdc69e90459a3a8cba2befb95af73d5516bbe4e985521e69b09df76db2dc5308.png

接下来,我们可以比较标记图像中的最大强度,看看这两个图像中的标记总数是否相等。它们不相等:

result.max(), reference.max()
(20, 63)

通过计算结果图像中像素强度的标准差(按参考标记分组),我们可以可视化哪些对象没有被正确分割。

stddev_map = cle.standard_deviation_intensity_map(result, reference) > 0

imshow(stddev_map)
../_images/eb860aef8140012781f0c648b5db2f14c66501acef97671110743f440349f90c.png

使用dask-image进行瓦片连通分量标记#

图像处理库dask-image提供了一个分布式版本的连通分量标记功能dask_image.ndmeasure.label

result_di, num_labels = daskimage_label(image)

imshow(result_di, labels=True)
../_images/cdc69e90459a3a8cba2befb95af73d5516bbe4e985521e69b09df76db2dc5308.png

注意,这个操作的结果是一个dask数组,计算最大值等操作并不直观:

result_di.max(), reference.max()
(dask.array<amax-aggregate, shape=(), dtype=int32, chunksize=(), chunktype=numpy.ndarray>,
 63)
np.asarray(result_di).max(), reference.max()
(63, 63)