HOG特征描述子提取
- 灰度图像转换
- 梯度计算
- 分网格的梯度方向直方图
- 块描述子
- 块描述子归一化
- 特征数据与检测窗口
- 匹配方法
灰度图像转换
- cvtColor
- gray = R*0.3 + 0.59*G + 0.11*B
梯度计算
分网格的梯度方向直方图
分割为8*8=64像素的Cell网格
对每个Cell求取方向直方图 (Orientation Hist),分为9个Bin,角度取值范围为-180~180之间, 对-180~0之间的加上180取正数,对应的 值为梯度值。方向为Bin数组0~9的Index
块描述子
块描述子R-HOG
将2x2的网格单元组合成为一个大的块(Block)
对每个块之间有1/2部分是重叠区域
主要是将每个Cell的直方图合并为一个大的直方图(Bin索引不变[0~9]之间)
块描述子归一化
基于L2实现块描述子归一化,归一化因子计算:
特征数据与检测窗口
最终获得HOG描述算子(特征数据)
需要正向训练200个左右的特征样本
反向训练600~800个左右的特征样本
初步测试、开窗检测
举例:
对于64x128的像素块,可以分为8x16个Cell分为7x15个块(R-HOG) 总计的直方图向量数为: 7x15x2x2x9 = 3780个向量数组
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("D:/vcprojects/images/HOGV.png");
if (src.empty()) {
printf("could not load image...
");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
//HOG特征检测
/*Mat dst, dst_gray;
resize(src, dst, Size(64, 128));
cvtColor(dst, dst_gray, COLOR_BGR2GRAY);
HOGDescriptor detector(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);
vector<float> descriptors;
vector<Point> locations;
detector.compute(dst_gray, descriptors, Size(0, 0), Size(0, 0), locations);
printf("number of HOG descriptors : %d", descriptors.size());
*/
//行人检测
HOGDescriptor hog = HOGDescriptor();
hog.setSVMDetector(hog.getDefaultPeopleDetector());
vector<Rect> foundLocations;
hog.detectMultiScale(src, foundLocations, 0, Size(8, 8), Size(32, 32), 1.05, 2);
Mat result = src.clone();
for (size_t t = 0; t < foundLocations.size(); t++) {
rectangle(result, foundLocations[t], Scalar(0, 0, 255), 2, 8, 0);
}
namedWindow("HOG SVM Detector Demo", CV_WINDOW_AUTOSIZE);
imshow("HOG SVM Detector Demo", result);
waitKey(0);
return 0;
}