opencv::HOG特征检测
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...\n"); 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; }