How to get hog features at a keypoint using python?

Hi,
I’m trying to get the hog features at specific keypoints of an image.
I’m resizing the images to size 256x256x3
then, I initialize
hog = cv2.HOGDescriptor(winSize=(256, 256), blockSize=(16,16), blockStride=(8,8), cellSize=(8,8), nbins=9)
hog.compute(image) → this returns a vector of length 34596

if I’m using ‘locations’

hog.compute(image, locations=[points]) it returns a vector of length 34596xnum_points. but for some reason this vector is all 0’s.

What am I doing wrong?

appreciate any help

Hi,
Can you give a full minimal example?

Hope it’s clearer

I’m a little lazy. Can you post your code as text (it’s better for google too) and use an opencv image

using lena

import numpy as np
import cv2
import matplotlib.pyplot as plt

lena = cv2.imread('lena.jpg')
lena = cv2.resize(lena, (256, 256)) # BGR image normalized to size of 256x256, no other preprocessing
points = [(155, 160), (135, 175), (160, 175), (165, 135), (135, 135)] # 5 keypoints of intrest

lena_p = lena # just for drawing points
for (x, y) in points:
    cv2.circle(lena_p, (x, y), 2, (255, 0, 0), 2)	

plt.figure(figsize=(7, 7))
plt.imshow(lena_p[..., ::-1])
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()

# HOG params
winSize = (256, 256)
blockSize = (16,16)
blockStride = (8,8)
cellSize = (8,8)
nbins = 9

# initialize hog descriptor
hog = cv2.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nbins)
# compute hog features
fv = hog.compute(lena)  # computing the feature vector fv
print(fv, np.all(fv==0)) # the fv values
print(f'fv dimensions {fv.shape}, {fv.shape[0]} == 31*31*2*2*9 :', fv.shape[0] == 31*31*2*2*9)
print()

fv_lm = hog.compute(lena, locations=points)  # computing the feature vector for the 5 points
print(fv_lm, np.all(fv_lm==0)) # the fv values
print(f'fv_lm dimensions {fv_lm.shape}, {fv_lm.shape[0]} / {len(points)} == {fv.shape[0]} :', 
      fv.shape[0] == fv_lm.shape[0] / len(points))

hint: cv.samples.findFile("lena.jpg") is a neat utility function that gives you the path to a resource file that comes with OpenCV.

1 Like

I must say that I don’t know how to use hog.
I run same program in C++.

Mat img = imread("g:/lib/opencv/samples/data/lena.jpg", IMREAD_GRAYSCALE);
Mat lena;
resize(img, lena, Size(256, 256));
Size winSize(256, 256);
Size blockSize(16, 16);
Size blockStride(8, 8);
Size cellSize(8, 8);
int nbins = 9;
vector <Point> pt = { Point(10,10), Point(100,20), Point(150,30), Point(150,30) };
vector< float> descriptors;
HOGDescriptor hog(winSize, blockSize, blockStride, cellSize, nbins);

hog.compute(lena, descriptors);
hog.compute(lena, descriptors,Size(), Size(), pt);

call hog.compute(lena, descriptors); 34596 desciptors for [0] is 0.226208031, [10] is 0.163035244 [34595] is 0.0669640526
hog.compute(lena, descriptors,Size(), Size(), pt); 138384 descriptors [0], [10] and [34595] are same and after all values are 0

I think that my program is wrong example…

I dig into the code and this condition must be false to get non zero descriptors

if( pt0.x < -padding.width || pt0.x > img.cols + padding.width - winSize.width ||
    pt0.y < -padding.height || pt0.y > img.rows + padding.height - winSize.height )

Hence you must set padding and winSize in compute args

I appreciate the help, thanks.
My mistake was setting winSize = (256, 256). hence for each keypoint it tried to calculate 31x31x2x2x9 histograms (and returned 0’s because the stride and padding issue).
Once I set winSize = (16, 16), for each keypoint it calculated the correct number of histograms 1x1x2x2x9 in the surrounding of the keypoint.

Thanks