【问题标题】:Image texture with skimage带有 skimage 的图像纹理
【发布时间】:2018-11-22 20:31:15
【问题描述】:

我正在尝试从使用 greycomatrix 创建的 GLCM 中获取 texture properties,来自 skimage.feature。我的输入数据是具有多个波段的图像,我想要每个像素的纹理属性(生成尺寸为cols x rows x (properties *bands) 的图像),因为它可以使用 ENVI 来实现。但我对这个太陌生了,无法掌握greycomatrixgreycoprops。这是我尝试过的:

import numpy as np
from skimage import io
from skimage.feature import greycomatrix, greycoprops

array = io.imread('MYFILE.tif')
array = array.astype(np.int64)
props = ['contrast', 'dissimilarity', 'homogeneity', 'energy', 'correlation', 'ASM']
textures = np.zeros((array.shape[0], array.shape[1], array.shape[2] * len(props)), np.float32)
angles = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4]
bands = array.shape[2]
for b in range(bands):
    glcm = greycomatrix(array[:, :, b], [1], angles, np.nanmax(array) + 1,
                        symmetric=True, normed=True)
    for p, prop in enumerate(props):
        textures[:, :, b] = greycoprops(glcm, prop)

不幸的是,这给了我每个prop1 x 4 矩阵,我猜这是整个图像的每个角度的一个值,但这不是我想要的。我需要每个像素,例如每个像素的contrast,从其各自的环境计算。我错过了什么?

【问题讨论】:

    标签: python image-processing feature-extraction scikit-image glcm


    【解决方案1】:

    这个 sn-p 应该可以完成工作:

    import numpy as np
    from skimage import io, util
    from skimage.feature.texture import greycomatrix, greycoprops
    
    img = io.imread('fourbandimg.tif')
    
    rows, cols, bands = img.shape
    
    radius = 5
    side = 2*radius + 1
    
    distances = [1]
    angles = [0, np.pi/2]
    props = ['contrast', 'dissimilarity', 'homogeneity']
    dim = len(distances)*len(angles)*len(props)*bands
    
    padded = np.pad(img, radius, mode='reflect')
    windows = [util.view_as_windows(padded[:, :, band].copy(), (side, side))
               for band in range(bands)]
    feats = np.zeros(shape=(rows, cols, dim))
    
    for row in range(rows):
        for col in range(cols):
            pixel_feats = []
            for band in range(bands):
                glcm = greycomatrix(windows[band][row, col, :, :],
                                    distances=distances,
                                    angles=angles)
                pixel_feats.extend([greycoprops(glcm, prop).ravel()
                                    for prop in props])
            feats[row, col, :] = np.concatenate(pixel_feats)
    

    示例图片有 128 行、128 列和 4 个波段(点击here 下载)。在每个图像像素处,使用大小为 11 的正方形局部邻域来计算与每个波段的右侧像素和上方像素相对应的灰度矩阵。然后,计算这些矩阵的对比度相异性同质性。因此,我们有 4 个波段、1 个距离、2 个角度和 3 个属性。因此对于每个像素,特征向量有 4 × 1 × 2 × 3 = 24 个分量。

    请注意,为了保留行数和列数,已使用沿阵列边缘镜像的图像本身对图像进行了填充。如果这种方法不符合您的需求,您可以简单地忽略图像的外框。

    作为最后的警告,代码可能需要一段时间才能运行。

    演示

    In [193]: img.shape
    Out[193]: (128, 128, 4)
    
    In [194]: feats.shape
    Out[194]: (128, 128, 24)
    
    In [195]: feats[64, 64, :]
    Out[195]: 
    array([  1.51690000e+04,   9.50100000e+03,   1.02300000e+03,
             8.53000000e+02,   1.25203577e+01,   9.38930575e+00,
             2.54300000e+03,   1.47800000e+03,   3.89000000e+02,
             3.10000000e+02,   2.95064854e+01,   3.38267222e+01,
             2.18970000e+04,   1.71690000e+04,   1.21900000e+03,
             1.06700000e+03,   1.09729371e+01,   1.11741654e+01,
             2.54300000e+03,   1.47800000e+03,   3.89000000e+02,
             3.10000000e+02,   2.95064854e+01,   3.38267222e+01])
    
    In [196]: io.imshow(img)
    Out[196]: <matplotlib.image.AxesImage at 0x2a74bc728d0>
    

    编辑

    您可以通过 NumPy 的 uint8 或 scikit-images 的 img_as_ubyte 将数据转换为 greycomatrix 所需的类型。

    【讨论】:

    • 看起来是个不错的解决方案,但我的图像是 float32 卫星图像,而 greycomatrix 需要无符号整数。您是否还有一种解决方法可以将其包含在此处?
    • 好东西,非常感谢。我是否正确理解:distance = 1 表示在angles 方向上偏移 1 个像素?那么angles = [0] 会向上 1 个像素,而angles = [np.pi/2] 会向下 1 个像素?要像在 ENVI 中那样做,然后我可以使用angles = [np.pi/4] 与右上角的像素(1 个像素和 1 个像素)进行比较?此外,是否有可能加快速度,例如通过使用并行化?
    • distances=[1]angles=[0, np.pi/2] 实际上对应向右偏移 1 像素,向上偏移 1 像素。
    • 我认为有。一种可能的方法是通过scikit-image.org/docs/dev/api/…
    • 很好的提示,我会试一试!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2022-07-19
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2012-11-24
    相关资源
    最近更新 更多