OpenCV之图像特征提取与检测(十) HOG特征检测

用于人像的识别,动物识别。需要提前录入训练数据,才能进行对比识别,OpenCV中已经录入了行人的训练数据

HOG(Histogram of Oriented Gradient)特征描述子提取:

  • 灰度图像转换—gray = R*0.3 + 0.59*G + 0.11*B
  • 梯度计算—sobel算子计算梯度,像素点的两个特征:方向(角度)与梯度
  • 分网格的梯度方向直方图
    这里写图片描述
  • 块描述子—方块的:R-HOG 圆形的:C-HOG
    这里写图片描述
  • 块描述子归一化 —至此得到了 HOG特征的数据了
    这里写图片描述
  • 特征数据与检测窗口

        最终获得HOG描述算子(特征数据)
        需要正向训练200个左右的特征样本
        反向训练600~800个左右的特征样本
        初步测试、开窗检测
    
        举例:
            对于64x128的像素块,可以分为8x16个Cell分为7x15个块(R-HOG)
            总计的直方图向量数为:
            7x15x2x2x9 = 3780个向量数组
    
  • 匹配方法

    cv::HOGDescriptor HOGDescriptor( // HOG特征描述子提取
        Size _winSize, // 窗口大小,对应上面举例的 64x128
        Size _blockSize, // 2x2个_cellSize,也就是 16x16
        Size _blockStride, // 每次移动步长,也就是 _cellSize的尺寸 8x8
        Size _cellSize, // 8x8
        int _nbins, // 对梯度方向直方图中的bins 9
        int _derivAperture=1, // 求梯度的参数
        double _winSigma=-1, 
        int _histogramNormType=HOGDescriptor::L2Hys, // 求直方图的参数
        double _L2HysThreshold=0.2, // 归一化阈值参数
        bool _gammaCorrection=false, // 对于灰度的输入图像是否要做伽马校正
        int _nlevels=HOGDescriptor::DEFAULT_NLEVELS, 
        bool _signedGradient=false 
    

    )

代码

    #include "../common/common.hpp"

    void main(int argc, char** argv)
    {
        Mat src = imread(getCVImagesPath("images/hogman.png"));
        imshow("src-13", src);

        // HOG特征描述子
        Mat dst, dst_gray;
        resize(src, dst, Size(64, 128)); // 将原始图像变成 64x128 尺寸
        imshow("resize2-13", dst);
        cvtColor(dst, dst_gray, COLOR_BGR2GRAY);
        HOGDescriptor detector(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9); // HOG特征描述子提取类

        vector<float> descriptors; // 保存举例中的计算出来的3780个向量数组
        vector<Point> locations; // 作用?
        detector.compute(dst_gray, descriptors, Size(0, 0), Size(0, 0), locations); // 计算HOG特征描述子
        // descriptors.size=3780, locations.size=0
        cout << "descriptors.size=" << descriptors.size() << ", locations.size=" << locations.size() << endl;

        // HOG+SVM 实现行人检测
        Mat walkers = imread(getCVImagesPath("images/HOGV.png"));
        imshow("walkers", walkers);

        HOGDescriptor hog = HOGDescriptor();
        hog.setSVMDetector(hog.getDefaultPeopleDetector()); // opencv自带的封装好了行人数据的Detector
        vector<Rect> foundLocations; // 保存检测到的行人的 Rect
        hog.detectMultiScale(walkers, foundLocations, 0, Size(8, 8), Size(32, 32), 1.05, 2); // 在多个尺寸上寻找,detect 同一尺度
        cout << "foundLocations.size=" << foundLocations.size() << endl; // foundLocations.size=3
        Mat result = walkers.clone();
        for (size_t t = 0; t < foundLocations.size(); t++) {
            rectangle(result, foundLocations[t], Scalar(0, 0, 255), 2, 8, 0); // 绘制行人的方框
        }
        imshow("HOG SVM Detector", result);

        waitKey(0);
    }

效果图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/huanghuangjin/article/details/81273439