繁体   English   中英

Python:采用非矩形区域的GLCM

[英]Python: taking the GLCM of a non-rectangular region

我一直在使用skiIC的SLIC实现来分割超像素中的图像。 我想使用GLCM从这些超像素中提取额外的特征以解决分类问题。 这些超像素不是矩形。 在MATLAB中,您可以将像素设置为NaN,算法将忽略它们( 链接 )。 我可以使用它来围绕超像素制作边界框,然后将未使用的像素设置为NaN。

但是, skimage中的greycomatrix函数与MATLAB实现完全不同。 将像素设置为NaN时,函数会在断言上失败,以检查是否所有值都大于0。

是否有可用于非矩形ROI的Python实现?

问题是您必须将整数数组传递给greycomatrix ,但是np.nan类型为float (有关详细信息,请查看此线程 )。 因此,您无法将ROI外部的像素编码为NaN

一种近似的解决方法来处理非矩形的投资回报率将在ROI之外的像素被设置为0 ,并使用功能haralickmahotas库。 此函数返回从四个不同GLCM中提取的13个Haralick特征,对应于四个2-D方向和距离参数的特定值。

从文档:

ignore_zeros可用于使函数忽略任何零值像素(作为背景)。

总之,您需要屏蔽那些落在ROI之外的像素,并在调用haralickignore_zeros设置为True


DEMO

首先,让我们生成一些模拟数据:

In [213]: import numpy as np

In [214]: shape = (3, 4)

In [215]: levels = 8

In [216]: np.random.seed(2017)

In [217]: x = np.random.randint(0, levels, size=shape)

In [218]: x
Out[218]: 
array([[3, 1, 6, 5],
       [2, 0, 2, 2],
       [3, 7, 7, 7]])

然后我们必须从图像中移除所有零,因为在这种方法中,零强度级别被保留用于ROI之外的像素。 值得指出的是,将强度01合并为单个强度1在结果中引入不准确性。

In [219]: x[x == 0] = 1

In [220]: x
Out[220]: 
array([[3, 1, 6, 5],
       [2, 1, 2, 2],
       [3, 7, 7, 7]])

下一步包括为ROI外部的像素定义遮罩(在此玩具示例中,图像的四个角)并将这些像素设置为0

In [221]: non_roi = np.zeros(shape=shape, dtype=np.bool)

In [222]: non_roi[np.ix_([0, -1], [0, -1])] = True

In [223]: non_roi
Out[223]: 
array([[ True, False, False,  True],
       [False, False, False, False],
       [ True, False, False,  True]], dtype=bool)

In [224]: x[non_roi] = 0

In [225]: x
Out[225]: 
array([[0, 1, 6, 0],
       [2, 1, 2, 2],
       [0, 7, 7, 0]])

我们现在可以从GLCM的非矩形ROI中执行特征提取:

In [226]: import mahotas.features.texture as mht

In [227]: features = mht.haralick(x, ignore_zeros=True)

In [228]: features.size
Out[228]: 52

In [229]: features.ravel()
Out[229]: array([ 0.18      ,  5.4       ,  0.5254833 , ...,  0.81127812,
       -0.68810414,  0.96300727])

检查共生矩阵的外观可能很有用。 例如,“像素到右边”GLCM将是:

In [230]: mht.cooccurence(x, 0)
Out[230]: 
array([[0, 1, 0, ..., 0, 1, 2],
       [1, 0, 2, ..., 0, 1, 0],
       [0, 2, 2, ..., 0, 0, 0],
       ..., 
       [0, 0, 0, ..., 0, 0, 0],
       [1, 1, 0, ..., 0, 0, 0],
       [2, 0, 0, ..., 0, 0, 2]])

虽然mahotas也是一个优秀的计算机视觉库,但没有必要停止使用skimage来做到这一点。

什么必要的,因为@Tonechas已经指出的那样,是那些NaN值设定为一个整数,因为np.nan具有类型floatgreycomatrix函数需要一个整数数组。

最简单的选择是将NaN设置为零,但是,如果像素中的值已经为零并且不想混合它们,则可以选择任何其他常量。 之后,您所要做的就是从GLCM中筛选出所选择的值(再次,通常为零)。

要理解这意味着什么,让我们看看skimage告诉我们有关greycomatrix函数输出的greycomatrix

4-D ndarray

[...]值P [i,j,d,theta]是灰度级j出现在距离d处并且与灰度级i成角度θ的次数。 如果normed为False,则输出为uint32类型,否则为float64。 尺寸为:水平x水平x距离数x角度数。

换句话说,数组的前两个维度定义了一个矩阵,告诉我们两个不同的值有多少次相隔一定距离。 需要注意的是GLCM 保留输入数组的形状。 那些行和列告诉我们值是如何相关的。

知道了这一点,很容易过滤出ROI之外的值(想象我们将NaN设置为零):

glcm = greycomatrix(img, [1], [0])  # Calculate the GLCM "one pixel to the right"
filt_glcm = glcm[1:, 1:, :, :]           # Filter out the first row and column

现在,您可以轻松计算过滤后的GLCM的Haralick属性。 例如:

greycoprops(filt_glcm, prop='contrast')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM