DPM中使用的HOG特征提取方法,和原始的HOG不太一样,比原来的要快一些,检测效果也好一些。下边的代码是从作者的目标检测中抽出的,详情见这里。虽然已经比原始HOG快了不少,但仍有一些优化空间,比如代码中存在一些不必要的乘法,多余的计算等。
//fast hog 源码注释,求出的特征和原始的特征不太一样
//参考论文“Object detection with discriminatively train part based models”
//zhangyaocold@gmail.com
#include <math.h>
#include "mex.h"
// small value, used to avoid division by zero
#define eps 0.0001
// unit vectors used to compute gradient orientation
//把cos(a)和sin(a)按[0, pi]分为9个bin,快速近似计算梯度方向使用
double uu[9] = {1.0000,
0.9397,
0.7660,
0.500,
0.1736,
-0.1736,
-0.5000,
-0.7660,
-0.9397};
double vv[9] = {0.0000,
0.3420,
0.6428,
0.8660,
0.9848,
0.9848,
0.8660,
0.6428,
0.3420};
static inline float min(float x, float y) { return (x <= y ? x : y); }
static inline float max(float x, float y) { return (x <= y ? y : x); }
static inline int min(int x, int y) { return (x <= y ? x : y); }
static inline int max(int x, int y) { return (x <= y ? y : x); }
// main function:
// takes a double color image and a bin size
// returns HOG features
//输入:三通道图像,每个cell的大小8x8
mxArray *process(const mxArray *mximage, const mxArray *mxsbin) {
double *im = (double *)mxGetPr(mximage);
const int *dims = mxGetDimensions(mximage);//图像维度三个值分别是{H, W, C};
if (mxGetNumberOfDimensions(mximage) != 3 ||
dims[2] != 3 ||
mxGetClassID(mximage) != mxDOUBLE_CLASS)
mexErrMsgTxt("Invalid input");
int sbin = (int)mxGetScalar(mxsbin);
// memory for caching orientation histograms & their norms
int blocks[2];//这里用block来表示一个8x8的小块,paper里是用cell来表示,表搞混了,这个数组存的是H和W各可以划分多少cell
blocks[0] = (int)round((double)dims[0]/(double)sbin);//H方向多少个cell
blocks[1] &