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;
}

 

posted @ 2019-10-10 11:25  osbreak  阅读(709)  评论(0编辑  收藏  举报