一.基本函数介绍:
1.HOG特征提取:cv::HOGDescriptor类
CV_WRAP HOGDescriptor() :
winSize(64,128), // detect window
blockSize(16,16), // block 大小
blockStride(8,8), // overlap block的滑动步长
cellSize(8,8), // cell 大小
nbins(9), // 直方图的bin个数
derivAperture(1), // 微分算子核
winSigma(-1), // 在window上进行高斯加权
histogramNormType(HOGDescriptor::L2Hys), // 直方图归一化类型
L2HysThreshold(0.2), // L2 norm followed by clipping(limiting maximum values of v to 0. 2) and renormalising
gammaCorrection(true), // Gamma校正,去除光照影响
nlevels(HOGDescriptor::DEFAULT_NLEVELS) // 分层数
2.一个window内HOG特征的维数计算:
(1) block的个数:
blockNum=[(winSize.x-blockStride.x)/blockStride.x+1]*[(winSize.y - blockStride.y)/blockStride.y+1]
(2) 一个block中特征维数:
featuresPerBlock = ( blockSize.x/cellSize.x)*( blockSize.y/cellSize.y)*nbins
(3) window内HOG特征维数:
blockNum*featuresPerBlock
则按上面默认参数计算,一个window内维数应该为3780维。
3.HOG特征提取源代码:
#include
#include
#include
#include "opencv2\opencv.hpp"
#define IMG_PATH "D:\\1.jpg"//图片路径
using namespace std;
int main(void) {
cout << "hi!" << endl;
cv::Mat mat = cv::imread(IMG_PATH);
cout<<"width:"<<mat.cols<<" height:"<<mat.rows<<endl; //显示图片大小
// 显示原图像
cv::namedWindow("Image", CV_WINDOW_AUTOSIZE);
cv::moveWindow("Image", 0, 0);
cv::imshow("Image", mat);
cv::HOGDescriptor hog;
vector descriptors;
hog.compute(mat, descriptors);
cout<<"size of HOG:"<<descriptors.size()<<endl; //显示图片提取的总的HOG特征维数
cout << "finished." << endl;
cv::waitKey(0);
cout << "bye." << endl;
return EXIT_SUCCESS;
}
二.HOG和SVM结合进行检测
1.HOG和SVM结合:
HOGDescriptor::setSVMDetector(const vector& detector)
其中 const vector& detector 在 opencv 中有已经训练好的行人检测分类器,直接用:
HOGDescriptor::getDefaultPeopleDetector
HOGDescriptor::getPeopleDetector48x96
HOGDescriptor::getPeopleDetector64x128
2.对输入图像进行检测:
(1) 方法一:只在一个尺度上(即原图像上进行检测)
原型:
HOGDescriptor::detect(const Mat& img, vector& found_locations, double hit_threshold=0, Size win_stride=Size(), Size padding=Size())
参数解释:
- img – Source image. CV_8UC1 and CV_8UC4 types are supported for now.
- found_locations – Left-top corner points of detected objects boundaries.
- hit_threshold – Threshold for the distance between features and SVM classifying plane. Usually it is 0 and should be specfied 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.
- win_stride – Window stride. It must be a multiple of block stride.
- padding – Mock parameter to keep the CPU interface compatibility. It must be (0,0).
(2) 方法二:(在多个尺度上进行检测)
原型:
HOGDescriptor::detectMultiScale(const Mat& img, vector& found_locations, doublehit_threshold=0, Size win_stride=Size(), Size padding=Size(), double scale0=1.05, int group_threshold=2)
参数解释:
- found_locations – Detected objects boundaries.
- hit_threshold – Threshold for the distance between features and SVM classifying plane. SeeHOGDescriptor::detect() for details.
- win_stride – Window stride. It must be a multiple of block stride.
- padding – Mock parameter to keep the CPU interface compatibility. It must be (0,0).
- scale0 – Coefficient of the detection window increase.
- group_threshold – Coefficient to regulate the similarity threshold. When detected, some objects can be covered by many rectangles. 0 means not to perform grouping. See groupRectangles(),说白了就是一个目标上覆盖有多个框的时候,通过设置该参数能去重(overlap)。
3.在图像上进行检测源代码
(参考了http://blog.youkuaiyun.com/icvpr/article/details/8454439的代码)
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/objdetect/objdetect.hpp"
int main()
{
cv::Mat image = cv::imread("test.bmp");
if (image.empty())
{
std::cout<<"read image failed"<<std::endl;
}
// 定义HOG对象
cv::HOGDescriptor hog; // 采用默认参数
// 设置SVM分类器 采用已经训练好的行人检测分类器
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
// 3. 在测试图像上检测行人区域
std::vector regions; //存储返回的矩形框结果
// 在对尺度上对Image进行检测
hog.detectMultiScale(image, regions, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 1);
// 显示检测后的结果
for (size_t i = 0; i < regions.size(); i++)
{
cv::rectangle(image, regions[i], cv::Scalar(0,0,255), 2);
}
cv::imshow("hog", image);
cv::waitKey(0);
return 0;
}
4.可能出错的地方:
(1) hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
改为:
static vector detector = HOGDescriptor::getDefaultPeopleDetector();
if (!detector.size())
{
fprintf(stderr, "ERROR: getDefaultPeopleDetector returned NULL\n");
return -1;
}
hog.setSVMDetector(detector);
最后一个相关内容的比较好的英文网址:
http://docs.opencv.org/modules/gpu/doc/object_detection.html