一.基本函数介绍:
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) 参数解释:
- img – Source image. See HOGDescriptor::detect() for type limitations.
- 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.csdn.net/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