HOG特征检测介绍
属于块检测范畴,对于行人、动物、物体检测比较理想
HOG特征描述子提取
- 灰度图像转换
- 梯度计算
- 索贝尔算子计算
- 分网格的梯度方向直方图
- 分割为8*8=64像素的Cell网格
- 对每个Cell求取方向直方图(Orientation Hist)
- 区间分布上分为9个Bin,角度取值范围为-180180之间,对-1800之间的加上180取正数,对应的值为梯度值。方向为Bin数组的Index
- 块描述子
- 块描述子R-HoG,将2*2的网格单元组合成一个大的块(Block)
- 随着块推移每个块之间有1/2的部分是重叠区域
- 主要将每个Cell的直方图合并为一个大的直方图(Bin索引不变[0~9]之间)
- 块描述子归一化
- 基于L2实现块描述子归一化,可大大滤除光照因素的影响
- 特征数据与检测窗口
- 最终获得HoG描述算子(特征数据)
- 需要正向训练200个左右的特征样本
- 反向训练600~800个左右的特征样本
- 初步测试、开窗检测
- 举例:
- 对于64128的像素块,可以分为816个Cell分为715个块(R-HOG)总计的直方图向量数为71522*9=3780个向量数组
- 匹配方法
函数API
函数api
cv::HOGDescriptor::HOGDescriptor (
Size _winSize,
Size _blockSize,
Size _blockStride,
Size _cellSize,
int _nbins,
int _derivAperture = 1,
double _winSigma = -1,
HOGDescriptor::HistogramNormType _histogramNormType = HOGDescriptor::L2Hys,
double _L2HysThreshold = 0.2,
bool _gammaCorrection = false,
int _nlevels = HOGDescriptor::DEFAULT_NLEVELS,
bool _signedGradient = false
)
参数介绍
- _winSize 检测样本的尺寸大小
- _blockSize 块大小一般是2*2个Cell大小,Cell大小为8*8的话,这里是16*16
- _blockStride 块移动的步长,每个步长为1个Cell这里就是一个Cell的大小,如果Cell为8*8,这里就填写8*8
- _cellSize cell尺寸一般8*8
- _nbins 直方图计算区间数为9个(20度一个区间,负角度(-180~0)转化到正角度)
下面参数都是数学层面计算直方图所用到,一般采用默认值即可 - _derivAperture sets derivAperture with given value.
- _winSigma sets winSigma with given value.
- _histogramNormType sets histogramNormType with given value.
- _L2HysThreshold sets L2HysThreshold with given value.
- _gammaCorrection sets gammaCorrection with given value.
- _nlevels sets nlevels with given value.
- _signedGradient sets signedGradient with given value.
HOG计算描述子函数api
virtual void cv::HOGDescriptor::compute (
InputArray img,
std::vector< float > & descriptors,
Size winStride = Size(),
Size padding = Size(),
const std::vector< Point > & locations = std::vector< Point >()
)
参数列表
- img 要计算的图片
- descriptors 描述
- winStride 窗口步进,必须是步进的倍数
- padding 填充
- locations 点
api
virtual void cv::HOGDescriptor::detectMultiScale (
InputArray img,
std::vector< Rect > & foundLocations,
double hitThreshold = 0,
Size winStride = Size(),
Size padding = Size(),
double scale = 1.05,
double finalThreshold = 2.0,
bool useMeanshiftGrouping = false
)
参数列表
- img 待检测的图像单通道或者rgb3通道图片
- foundLocations 检测出来的轮廓方框集合
- hitThreshold Threshold for the distance between features and SVM classifying plane. Usually it is 0 and should be specified in the detector coefficients (as the last free coefficient). But if the free coefficient is omitted (which is allowed), you can specify it manually here.要素与SVM分类平面之间距离的阈值。通常为0,应在检测器系数中指定(作为最后一个自由系数)。但是,如果省略了自由系数(允许),则可以在此处手动指定它。
- winStride 窗口平移步进尺寸,一个Cell尺寸
- padding 填充
- scale 检测窗口的增加系数
- finalThreshold Final threshold
- useMeanshiftGrouping 使用分组算法
函数api
static std::vector<float> cv::HOGDescriptor::getDefaultPeopleDetector()
static std::vector<float> cv::HOGDescriptor::getDaimlerPeopleDetector()
功能描述
getDaimlerPeopleDetector:Returns coefficients of the classifier trained for people detection (for 48x96 windows). 返回经过训练以进行人检测的分类器的系数(对于48x96窗口)。
getDefaultPeopleDetector:Returns coefficients of the classifier trained for people detection (for 64x128 windows). 返回经过训练以进行人检测的分类器的系数(对于64x128窗口)
函数api
virtual void cv::HOGDescriptor::setSVMDetector (InputArray svmdetector)
功能描述
Sets coefficients for the linear SVM classifier. 设置线性SVM分类器的系数。
代码演示
int hog_hvm(void)
{
#if 0 //行人图片检测
Mat src, dst, gray_src;
string pic = string(Pic_Path) + string(Pic_Name);
cout << "打开图片路径:" << pic << endl;
src = imread(pic);
if (src.empty())
{
cout << "图片不存在或打开失败" << endl;
return -1;
}
//resize(src, dst, Size(64, 128));
//图片转换为灰度图像
cvtColor(src, gray_src, COLOR_BGR2GRAY);
namedWindow("原始图片", WINDOW_AUTOSIZE);
imshow("原始图片", src);
/*
//定义一个HOG对象
HOGDescriptor detector(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);
//计算HOG算子
vector<float> descriptors;
vector<Point> locations;
//这里是单窗口计算 窗口步进填写为不步进
detector.compute(gray_src, descriptors, Size(0, 0), Size(0, 0), locations);
printf("HOG descriptors is %d\n", descriptors.size());
*/
// 1. 定义HOG对象
cv::HOGDescriptor hog; // 采用默认参数
// 2. 设置SVM分类器
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); // 采用已经训练好的行人检测分类器
// 3. 在测试图像上检测行人区域
vector<cv::Rect> regions;
hog.detectMultiScale(gray_src, regions, 0, cv::Size(8, 8), cv::Size(32, 32), 1.05, 2);
dst=src.clone();
// 显示
for (size_t i = 0; i < regions.size(); i++)
{
cv::rectangle(dst, regions[i], cv::Scalar(0, 0, 255), 2);
}
namedWindow("行人检测图片", WINDOW_AUTOSIZE);
imshow("行人检测图片", dst);
#endif
#if 1 //行人视频检测
Mat src,gray_src,dst;
VideoCapture cap;
vector<Rect> regions;
// 1. 定义HOG对象
HOGDescriptor hog; // 采用默认参数
// 2. 设置SVM分类器
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); // 采用已经训练好的行人检测分类器
cap.open("test.mp4");
if (!cap.isOpened())
{
return -1;
}
while (1)
{
cap >> src;
imshow("srcVideo", src);
if (src.empty())
break;
src.copyTo(dst);
cvtColor(src, gray_src, COLOR_BGR2GRAY);
// 3. 在测试图像上检测行人区域
hog.detectMultiScale(gray_src, regions, 0, cv::Size(8, 8), cv::Size(32, 32), 1.05, 2);
// 显示,框出行人
for (size_t i = 0; i < regions.size(); i++)
{
cv::rectangle(dst, regions[i], cv::Scalar(0, 0, 255), 2);
}
imshow("VideoTest", dst);
waitKey(30); //延时30ms
}
waitKey(0);
destroyAllWindows();
return 0;
#endif