Python: taking the GLCM of a non-rectangular region

后端 未结 2 672
面向向阳花
面向向阳花 2020-12-21 21:09

I have been using the SLIC implementation of skimage to segment images in superpixels. I would like to use GLCMs to extract additional features from these superpixels for a

2条回答
  •  抹茶落季
    2020-12-21 21:33

    The issue is you have to pass an integer array to greycomatrix, but np.nan has type float (take a look at this thread for details). As a result you cannot encode the pixels outside the ROI as NaN.

    An approximate workaround for dealing with non-rectangular ROI's would be setting the pixels outside the ROI to 0 and using the function haralick from mahotas library. This function returns 13 Haralick features extracted from four different GLCM's, corresponding to the four 2-D orientations and the particular value of the distance parameter.

    From the documentation:

    ignore_zeros can be used to have the function ignore any zero-valued pixels (as background).

    In summary, you need to mask those pixels that fall outside the ROI, and set ignore_zeros to True in the call to haralick.


    DEMO

    To begin with, let us generate some mock data:

    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]])
    

    Then we have to remove all the zeros from the image as in this approach the zero intensity level is reserved for the pixels outside the ROI. It is worth to point out that merging intensities 0 and 1 into a single intensity 1 introduces inaccuracies in the results.

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

    Next step consists in defining a mask for the pixels outside the ROI (in this toy example, the four corners of the image) and setting those pixels to 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]])
    

    We can now perform feature extraction from the GLCM's of a non-rectangular 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])
    

    It may be useful to check how the co-occurrence matrices look. For example, the "pixel to the right" GLCM would be:

    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]])
    

提交回复
热议问题