11

I'm trying to use OpenCV's HOG descriptor, but the feature vector computed from it seems far too long. Here is a snippet that demonstrates the problem:

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <stdlib.h>
#include <vector>

int main()
{
    cv::Mat image = cv::imread("1.jpg");
    std::vector<float> features;
    cv::HOGDescriptor hogdis;
    hogdis.compute(image, features);
    printf("HOG feature's length is %zu %zu\n", hogdis.getDescriptorSize(), features.size());
    return 0;
}

The output is

HOG feature's length is 3780 1606500

The latter value seems absurd. The image 1.jpg has dimension 256x256x3, which has much less pixels than the feature vector. Why does OpenCV fills the feature vector with so many values? How do I obtain the 3780 long vector to feed to my SVM trainer?

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
Siyuan Ren
  • 7,573
  • 6
  • 47
  • 61

1 Answers1

18

Why does OpenCV fills the feature vector with so many values?

The size of hog features is determined by the following equation (not solely determined on the image dimensions):

size_hog_features = (size_t)nbins * ( blockSize.width/cellSize.width) 
                         * (blockSize.height/cellSize.height) * ((winSize.width 
                         - blockSize.width)/blockStride.width + 1) 
                         * ((winSize.height - blockSize.height)
                         / blockStride.height + 1);

So it's quite normal you got such a long HOG feature vector.

How do I obtain the 3780 long vector to feed to my SVM trainer?

You can setup the parameters (i.e. nbins, blockSize, cellSize, winSize) of HOG feature before computing it, in order to get a HOG feature with the size you want.

But why are hogdis.getDescriptorSize() and features.size() inconsistent?

They are different. getDescriptorSize() returns the number of coefficients required for the classification. And it can be computed as follows (refer to here):

HOG descriptor length = #Blocks * #CellsPerBlock * #BinsPerCell

On the other hand, features.size() returns all the HOG feature size of the whole image.

To train, you need to pass in features.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
  • But why are `hogdis.getDescriptorSize()` and `features.size()` inconsistent? – Siyuan Ren Mar 13 '14 at 09:34
  • The formula you provide is completely independent from the image size. However, when I try a image with dimension 690x622, the feature vector has 18514440 elements, different from the 1606500 above. Besides, it doesn't make sense that the feature vector has more elements than the total number of pixels, let alone more than 40 times. – Siyuan Ren Mar 13 '14 at 10:07
  • @C.R. No, you misunderstand the formula. It does depend on the image dimensions, e.g. you will have more `#Blocks` for larger images given same `blockSize`. – herohuyongtao Mar 13 '14 at 10:31
  • `#BLOCKS` appear nowhere in your formula for `size_hog_features`. – Siyuan Ren Mar 13 '14 at 10:38
  • @herohuyongtao Are OpenCV HoG descriptors invariant to the image size? If they are then I would like to switch from scikit-image to opencv. But if not, then what about the problem of detecting objects fro images that are a different size from the training samples that the HoG classifier was trained on? As here: http://stackoverflow.com/questions/23824147/choosing-normalizing-hog-parameters-for-object-detection – user961627 May 23 '14 at 08:36