Search code examples
pythonimage-segmentationfeature-extractionscikit-imageglcm

Cropping Image to Object Region's Area


I'm going to apply texture recognition to different flower pictures and I'm considering GLCM for feature extraction. Before applying GLCM I should convert RGB images to gray images. I also want to subtract background information from gray images to apply GLCM only flower object's pixels to remove noise. I'm considering using skimage. How can I subtract the background pixels from a gray image to ensure that majority of the pixels belong to flower object?


Solution

  • If background pixels have a constant intensity value, let's say 0, you can use any of the methods proposed in Using skimage for non-rectangular image areas or Python: taking the GLCM of a non-rectangular region. Notice that those methods yield an approximated GLCM as image pixels with the same intensity level than background pixels are discarded from the co-occurrence analysis.

    If you want to compute all the co-occurrences over a region of interest without discarding any pixels inside the ROI, the following snippet might put you on the right track:

    import numpy as np 
    from skimage import io, color, util
    from skimage.feature.texture import greycoprops
    import matplotlib.pyplot as plt
    
    def glcm_roi(img, mask, dh=1, dv =0, levels=256):
        glcm = np.zeros(shape=(levels, levels), dtype=np.int_)
        for i in range(img.shape[0] - dv):
            for j in range(img.shape[1] - dh):
                if mask[i, j] and mask[i + dv, j + dh]:
                    glcm[img[i, j], img[i + dv, j + dv]] += 1
        return glcm/glcm.sum()
    
    arr = io.imread('https://i.sstatic.net/q6cpu.png')
    mask = arr[:, :, -1] > 0
    img = util.img_as_ubyte(color.rgb2gray(arr[:, :, :-1]))
    
    glcm = glcm_roi(img, mask)
    energy = greycoprops(glcm[:, :, None, None], 'energy')
    print('Energy = {}'.format(energy))
    
    fig, ax = plt.subplots(1, 3)
    ax[0].imshow(arr)
    ax[0].set_title('RGB')
    ax[1].imshow(img, cmap='gray')
    ax[1].set_title('Gray')
    ax[2].imshow(mask, cmap='gray')
    ax[2].set(title='Mask')
    for axi in ax: axi.set_axis_off()
    plt.show(fig)
    

    Output:

    [[0.15203625]]
    

    Results