Search code examples
pythonimage-processingscikit-imagefeature-extractionhistogram-of-oriented-gradients

skimage hog returns no feature vector with length 0


I am trying to extract hog descriptors for some ROI on a given image (2D) using the implementation in skimage.feature. I have attached some samples of the ROI that I have extracted. I am just using the hog descriptor with all the default values.

Configuration: python:3.9.13; scikit-image: 0.19.2; Windows 10

The feature vector that is returned has nothing i.e. it is a null array ([]).

NOTE: I want to use the HOG descriptors from positive and negative sample to train and Linear SVM model.

Sample ROI positive sample negative sample

Code to reproduce problem

from skimage.feature import hog
import cv2 as cv
img = cv.imread(<path to image>, cv.IMREAD_GRAYSCALE)
desc = hog(img)
print(desc)

#output: array([], dtype=float64)

The feature descriptor should not be null. Even if I am giving a completely blank white image there should be a descriptor. But again I am not getting a descriptor for the positive samples as well.

Can someone please help with what is going wrong or is it an issue with the implementation?


Solution

  • I referenced the source code

    It looks like it produces output for n_blocks_rowxn_blocks_col elements, with:

    s_row, s_col = image.shape[:2]
    c_row, c_col = pixels_per_cell  # input parameter, 8x8 by default
    b_row, b_col = cells_per_block  # input parameter, 3x3 by default
    
    n_cells_row = int(s_row // c_row)  # number of cells along row-axis
    n_cells_col = int(s_col // c_col)  # number of cells along col-axis
    
    n_blocks_row = (n_cells_row - b_row) + 1
    n_blocks_col = (n_cells_col - b_col) + 1
    

    With the image having only 16 rows, you get two cells vertically, which is not enough to fill a single block of 3x3 cells. So, n_blocks_row is 0, and you get as output a 0x22 array of blocks.

    For such small images, you must change the pixels_per_cell and/or the cells_per_block parameters so that pixels_per_cell[0] * cells_per_block[0] is not larger than your image height (and similarly for the image width).

    For example, this worked for me:

    skimage.feature.hog(img, cells_per_block=(2,2))
    

    though I don't know if this produces a useful output or not. Having fewer cells per block might not give you as good a result. Maybe you could make the blocks wider as you make them less tall, so their size remains the same? Something like cells_per_block=(2,5)? I don't have enough experience with HOG to advice on this.