我正在使用scikit-image中可用的measure.regionprops方法来测量所连接组件的属性。它计算出一堆属性(Python-regionprops)。但是,我只需要每个连接组件的面积。有没有一种方法可以只计算单个属性并保存计算?
最佳答案
使用regionprops
和cache=False
似乎有一种更直接的方法来执行相同的操作。我使用skimage.segmentation.slic
和n_segments=10000
生成标签。然后:
rps = regionprops(labels, cache=False)
[r.area for r in rps]
我对regionprops documentation的理解是,设置
cache=False
意味着在调用属性之前不会计算属性。根据Jupyter笔记本中的%%time
,使用cache=False
运行上面的代码需要166毫秒,而使用cache=True
运行247ms则可以正常工作。我尝试了与其他答案相同的方法,发现它的速度要慢得多。
%%time
ard = np.empty(10000, dtype=int)
for i in range(10000):
ard[i] = size(np.where(labels==0)[1])
那花了34.3秒。
这是一个完整的工作示例,比较了使用
skimage
宇航员样本图像和由slic分段生成的标签的两种方法:import numpy as np
import skimage
from skimage.segmentation import slic
from skimage.data import astronaut
img = astronaut()
# `+ 1` is added to avoid a region with the label of `0`
# zero is considered unlabeled so isn't counted by regionprops
# but would be counted by the other method.
segments = slic(img, n_segments=1000, compactness=10) + 1
# This is just to make it more like the original poster's
# question.
labels, num = skimage.measure.label(segments, return_num=True)
使用OP的建议方法计算面积,并调整索引值以避免使用零标签:
%%time
area = {}
for i in range(1,num + 1):
area[i + 1] = np.size(np.where(labels==i)[1])
CPU times: user 512 ms, sys: 0 ns, total: 512 msWall time: 506 ms
使用regionprops进行相同的计算:
%%time
rps = skimage.measure.regionprops(labels, cache=False)
area2 = [r.area for r in rps]
CPU times: user 16.6 ms, sys: 0 ns, total: 16.6 msWall time: 16.2 ms
验证结果在元素方面均相等:
np.equal(area.values(), area2).all()
True
因此,只要考虑了零标签和索引差异,两种方法都可以得到相同的结果,但是没有缓存的regionprops更快。