pythonopencvfeature-extractionscikit-imageglcm

How to pass the HH subband of an image to greycomatrix function?


I'm using scikit-images's function greycomatrix, to which I want to give as input one of the components obtained from wavelet transform after haar filtering.

import pywt
import cv2
from skimage.feature import greycomatrix

original = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)
coeffs2 = pywt.dwt2(original, 'haar')
LL, (LH, HL, HH) = coeffs2
cv2.imshow('image', HH)
gCoMat = greycomatrix(HH, [2], [0], 256, symmetric=True, normed=True)

If I pass HH to greycomatrix I get this error:

ValueError: Float images are not supported by greycomatrix. Convert the image to an unsigned integer type.

I tried to convert the image using this code:

from skimage import util

im = util.img_as_ubyte(HH)
im /= 32
gCoMat = greycomatrix(im, [2], [0], 256, symmetric=True, normed=True)

But I got this error:

raise ValueError("Images of type float must be between -1 and 1.") ValueError: Images of type float must be between -1 and 1.


Solution

  • You need to rescale the intensity to the range [0, 1] before converting the image to 8-bit unsigned integer:

    from skimage import util, exposure, data
    import pywt
    from skimage.feature import greycomatrix
    
    original = data.camera()
    LL, (LH, HL, HH) = pywt.dwt2(original, 'haar')
    HH_scaled = exposure.rescale_intensity(HH, out_range=(0, 1))
    
    bin_width = 32
    im = util.img_as_ubyte(HH_scaled)
    im_binned = im//bin_width
    
    gCoMat = greycomatrix(im_binned, distances=[2], angles=[0], 
                          levels=256//bin_width, symmetric=True, normed=True)
    

    Notice that if the image passed to graycomatrix is binned, then the levels parameter should not be 256, you have to divide this value by the same factor (32 in your code). It is also important to point out that intensity binning has to be carried out through integer division (//), otherwise the dtype of im_binned would be float. As a final caveat, you have to pass as_gray=True to the function io.imread, otherwise you'll get the following error when trying to compute the grey level co-occurrence matrix:

    ValueError: The parameter image must be a 2-dimensional array