向 skimage 中的 regionprops 添加额外的属性

Add extra properties to regionprops in skimage

我正在使用 scikit-image(或 skimage)包中的 regionprops 函数,使用同一包中的 SLIC 超像素算法计算分割图像的区域特征.

除了函数中计算的那些之外,我还需要额外的特征,主要是:标准差、偏度、峰度。

我使用其他功能作为模板修改了 _regionprops.py 的源代码以包含这些属性:

    @property
    def sd_intensity(self):
        return np.std(self.intensity_image[self.image])

    @property
    def skew_intensity(self):
        return skew(self.intensity_image[self.image])

我知道这是不好的做法,不是长期解决方案,因为我的代码将无法 运行 在另一台机器上或者如果我更新 skimage。

我发现函数 skimage.measure.regionprops() 有一个 extra_properties=None 参数,根据文档:

Add extra property computation functions that are not included with skimage.

我的问题是:我可以得到一个 np.std 的工作示例吗?我真的不知道如何使用这个参数。

谢谢

我在 skimage 的开发分支的文档中找到了一个参考。它包含在 0.18.dev0 版本

代码来源:https://github.com/scikit-image/scikit-image/blob/master/skimage/measure/_regionprops.py#L1028

Link 到文档:https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.regionprops

# Add custom measurements by passing functions as ``extra_properties``
from skimage import data, util
from skimage.measure import label, regionprops
import numpy as np

img = util.img_as_ubyte(data.coins()) > 110
label_img = label(img, connectivity=img.ndim)

def pixelcount(regionmask):
    return np.sum(regionmask)

props = regionprops(label_img, extra_properties=(pixelcount,))
props[0].pixelcount
    7741
props[1]['pixelcount']
    42

extra_properties 只接受一个以区域掩码和强度图像作为参数的函数列表。这是一个简单的例子:

from skimage import data, util
from skimage.measure import label, regionprops
import numpy as np
img = util.img_as_ubyte(data.coins()) > 110
label_img = label(img, connectivity=img.ndim)

def sd_intensity(regionmask, intensity_image):
        return np.std(intensity_image[regionmask])

def skew_intensity(regionmask, intensity_image):
        return skew(intensity_image[regionmask])
    
props = regionprops(label_img, intensity_image=img,
                    extra_properties=(sd_intensity, skew_intensity))

您现在可以使用您的函数名称访问您的额外属性

props[0].sd_intensity
>>> 0.4847985617008998

编辑 08/28/2021,更新示例以实际计算区域局部统计数据,正如@CrisLuengo 和@JDWarner 所指出的(谢谢你们)

上面 filippo 接受的答案(编辑:已更正;原 post 如下)以危险的方式微妙地不正确。该答案返回的统计数据应用于 整个边界框 的强度,而不是掩蔽和标记的子区域!传递的扩展函数需要使用regionmask对强度图进行切片。完整更正示例:

import numpy as np
from scipy.stats import skew
from skimage import data, util
from skimage.measure import label, regionprops

img = util.img_as_ubyte(data.coins()) > 110
label_img = label(img, connectivity=img.ndim)

def sd_intensity(regionmask, intensity_image):
        return np.std(intensity_image[regionmask])  # Note slicing

def skew_intensity(regionmask, intensity_image):
        return skew(intensity_image[regionmask])   # Note slicing
    
props = regionprops(label_img, intensity_image=img,
                    extra_properties=(sd_intensity, skew_intensity))

这将为强度图像的标记区域正确生成局部统计信息。

我还没有足够的“声誉”来评论该答案,因此作为一个单独的答案提交,因为这是一个重要的区别。