Scikit 图像:计算图像对象中细胞的正确方法

Scikit image: proper way of counting cells in the objects of an image

假设您有一张 numpy.array:

形式的图像
vals=numpy.array([[3,24,25,6,2],[8,7,6,3,2],[1,4,23,23,1],[45,4,6,7,8],[17,11,2,86,84]])

您想要计算每个对象内有多少个细胞,给定阈值 17(示例):

from scipy import ndimage
from skimage.measure import regionprops

blobs = numpy.where(vals>17, 1, 0)
labels, no_objects = ndimage.label(blobs)
props = regionprops(blobs)

如果您检查,这会给出一个图像,其中有 4 个不同的对象超过阈值:

In[1]: blobs
Out[1]: 
array([[0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0],
       [1, 0, 0, 0, 0],
       [0, 0, 0, 1, 1]])

事实上:

In[2]: no_objects
Out[2]: 4

我想计算每个对象的单元格(或面积)数。预期结果是 object ID: number of cells 格式的字典:

size={0:2,1:2,2:1,3:2}

我的尝试:

size={}
for label in props:
    size[label]=props[label].area

Returns一个错误:

Traceback (most recent call last):

  File "<ipython-input-76-e7744547aa17>", line 3, in <module>
    size[label]=props[label].area

TypeError: list indices must be integers, not _RegionProperties

我知道我使用 label 不正确,但目的是迭代对象。 如何操作?

一些测试和研究有时会有很长的路要走。

问题出在 blobs 上,因为它没有携带不同的标签,而只携带 0,1 个值,而 label 需要用迭代器循环替换range(0,no_objects).

此解决方案似乎有效:

import skimage.measure as measure
import numpy
from scipy import ndimage
from skimage.measure import regionprops

vals=numpy.array([[3,24,25,6,2],[8,7,6,3,2],[1,4,23,23,1],[45,4,6,7,8],[17,11,2,86,84]])

blobs = numpy.where(vals>17, 1, 0) 
labels, no_objects = ndimage.label(blobs)

#blobs is not in an amicable type to be processed right now, so:
labelled=ndimage.label(blobs)
resh_labelled=labelled[0].reshape((vals.shape[0],vals.shape[1])) #labelled is a tuple: only the first element matters

#here come the props
props=measure.regionprops(resh_labelled) 

#here come the sought-after areas
size={i:props[i].area for i in range (0, no_objects)}

结果:

In[1]: size
Out[1]: {0: 2, 1: 2, 2: 1, 3: 2}

如果有人想检查 labels:

In[2]: labels
Out[2]: 
array([[0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 2, 2, 0],
       [3, 0, 0, 0, 0],
       [0, 0, 0, 4, 4]])

如果有人想绘制找到的 4 个对象:

import matplotlib.pyplot as plt
plt.set_cmap('OrRd')
plt.imshow(labels,origin='upper')

regionprops will generate a lot more information than just the area of each blob. So, if you are just looking to get the count of pixels for the blobs, as an alternative and with focus on performance, we can use np.bincountlabels 上用 ndimage.label 获得,像这样 -

np.bincount(labels.ravel())[1:]

因此,对于给定的样本 -

In [53]: labeled_areas = np.bincount(labels.ravel())[1:]

In [54]: labeled_areas
Out[54]: array([2, 2, 1, 2])

要将这些结果放入字典中,还需要一个步骤 -

In [55]: dict(zip(range(no_objects), labeled_areas))
Out[55]: {0: 2, 1: 2, 2: 1, 3: 2}

回答原问题:

  • 您必须将 regionprops 应用于标记图像:props = regionprops(labels)

  • 然后您可以使用以下方法构建字典:

    size = {r.label: r.area for r in props}

    产生

    {1: 2, 2: 2, 3: 1, 4: 2}