SVM,即支持向量机,在结合相关特征描述子之后,在目标识别,如行人识别、汽车识别、人脸识别等领域中有着重要应用。opencv中提供了HOG特征描述子,这种特征提供支持SVM的接口。这不再进行原理性的介绍,直接介绍如何使用opencv进行SVM+HOG训练和检测。
1、svm+hog训练
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <string>
#define PosSamNO 3000 //正样本个数
#define NegSamNO 3000 //负样本个数
#define HardExampleNO 1000 //难例个数
void train_svm_hog()
{
//HOG检测器,用来计算HOG描述子的
//检测窗口(48,48),块尺寸(16,16),块步长(8,8),cell尺寸(8,8),直方图bin个数9
cv::HOGDescriptor hog(cv::Size(48, 48), cv::Size(16, 16), cv::Size(8, 8), cv::Size(8, 8), 9);
int DescriptorDim;//HOG描述子的维数,由图片大小、检测窗口大小、块大小、细胞单元中直方图bin个数决定
//设置SVM参数
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
svm->setType(cv::ml::SVM::Types::C_SVC);
svm->setKernel(cv::ml::SVM::KernelTypes::LINEAR);
svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));
std::string ImgName;
//正样本图片的文件列表
std::ifstream finPos("positive_samples.txt");
//负样本图片的文件列表
std::ifstream finNeg("negative_samples.txt");
//所有训练样本的特征向量组成的矩阵,行数等于所有样本的个数,列数等于HOG描述子维数
cv::Mat sampleFeatureMat;
//训练样本的类别向量,行数等于所有样本的个数,列数等于1;1表示有目标,-1表示无目标
cv::Mat sampleLabelMat;
//依次读取正样本图片,生成HOG描述子
for (int num = 0; num < PosSamNO && getline(finPos, ImgName); num++)
{
std::cout << "Processing:" << ImgName << std::endl;
cv::Mat image = cv::imread(ImgName);
//HOG描述子向量
std::vector<float> descriptors;
//计算HOG描述子,检测窗口移动步长(8,8)
hog.compute(image, descriptors, cv::Size(8, 8));
//处理第一个样本时初始化特征向量矩阵和类别矩阵,因为只有知道了特征向量的维数才能初始化特征向量