本文共 4055 字,大约阅读时间需要 13 分钟。
HOG(Histogram of Oriented Gradients)特征描述子是一种基于图像局部区域的密集型描述符,通过计算局部区域的梯度方向直方图来构成特征。本文将详细介绍HOG的理论基础及其在OpenCV中的实现。
HOG特征描述子是局部归一化的梯度方向直方图。具体来说,是对图像局部区域的密集型描述,通过计算局部区域的梯度方向直方图来构成特征。这种方法能够有效地捕捉图像中局部形状信息。
HOG描述子通过统计图像局部区域的梯度方向信息,作为该局部图像区域的表征。它能够提供图像局部区域的密集描述,同时具有一定的鲁棒性,能够弱化光照变化的影响。
HOG算法的实现源自2005年CVPR会议的一篇论文。本文将重点介绍其在OpenCV中的实现方法。
OpenCV中一个HOG描述子是针对一个检测窗口而言的。一个检测窗口包含105个Block,每个Block包含4个Cell。每个Cell的HOG描述子向量长度为9维,因此一个检测窗口的HOG描述子向量总长度为:[105 \times 4 \times 9 = 3780 \text{维}]
计算图像中每个像素的梯度,包括梯度方向和模长。梯度计算使用水平和垂直边缘算子:[\text{水平边缘算子} = [-1, 0, 1]][\text{垂直边缘算子} = [-1, 0, 1]^T]每个像素的梯度方向由这两个算子计算得出。
将图像划分为8×8像素的单元格(Cell)。每个单元格内计算梯度方向直方图。
每个单元格统计9个方向的梯度直方图。每个像素的梯度方向对应到直方图中的特定bin,并根据梯度模长进行加权投票。
采用三线性插值方法,将像素的梯度模长作为权值投入对应的bin中。这种插值方法能够有效减少混叠效应,避免边界和量化带来的突变。
将多个单元格组合成一个块,计算块内的梯度直方图并进行归一化。OpenCV支持四种归一化方法:
通过归一化,可以有效压缩梯度强度的变化范围,减少光照和阴影对特征的影响。
gpu::HOGDescriptor::HOGDescriptor(Size win_size, Size block_size, Size block_stride, Size cell_size, int nbins, double win_sigma, double threshold_L2hys, bool gamma_correction, int nlevels)
参数说明:
win_size
:检测窗口大小,默认为128×64。block_size
:块大小,默认为16×16。block_stride
:块滑动步长,默认为8×8。cell_size
:单元格大小,默认为8×8。nbins
:直方图bin数量,默认为9。win_sigma
:高斯滤波窗口参数,默认值由函数定义。threshold_L2hys
:L2-Hys归一化收缩率,默认为0.2。gamma_correction
:是否进行Gamma校正,默认为true。nlevels
:检测窗口的最大数量,默认值由函数定义。获取检测窗口的HOG特征向量维数:
size_t gpu::HOGDescriptor::getDescriptorSize() const
获取块的直方图大小:
size_t gpu::HOGDescriptor::getBlockHistogramSize() const
void gpu::HOGDescriptor::setSVMDetector(const vector& detector)
static vectorgpu::HOGDescriptor::getDefaultPeopleDetector()
void gpu::HOGDescriptor::detectMultiScale(const GpuMat& img, vector& found_locations, double hit_threshold, Size win_stride, Size padding, double scale0, int group_threshold)
void gpu::HOGDescriptor::compute(const Mat& img, vector& descriptors, Size win_stride, Size padding, const vector & locations) const
void HOGDescriptor::computeGradient(const Mat& img, Mat& grad, Mat& qangle, Size paddingTL, Size paddingBR) const
#include#include #include #include using namespace cv;int main(int argc, char** argv) { Mat img = imread(argv[1]); if (argc != 2 || !img.data) { printf("没有图片\n"); return -1; } HOGDescriptor defaultHog; defaultHog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); vector found; defaultHog.detectMultiScale(img, found); for (int i = 0; i < found.size(); i++) { Rect r = found[i]; rectangle(img, r.tl(), r.br(), Scalar(0, 0, 255), 3); } namedWindow("检测行人", CV_WINDOW_AUTOSIZE); imshow("检测行人", img); waitKey(0); return 0;}
#include#include #include using namespace cv;int main(int argc, char** argv) { Mat img = imread(argv[1]); if (argc != 2 || !img.data) { printf("没有图片\n"); return -1; } HOGDescriptor defaultHog; vector descriptors; defaultHog.compute(img, descriptors, Size(8,8), Size(0,0)); printf("特征向量大小:%zu\n", descriptors.size()); for (int j=0; j<3780; j++) { printf("%f,", descriptors[j]); } printf("\n"); return 0;}
通过以上内容,可以看出HOG是一种高效的特征提取方法,广泛应用于行人检测等任务中。
转载地址:http://jorfk.baihongyu.com/