最近在尝试运用opencv的svm训练器来实现图片分类,选用的是hog特征和sift特征两种,过程大致相同的,都是要把每一个样品提取出来的特征化成同样维度的一维向量,因为opencv的svm是以一个行向量作为一个训练数据。
sift特征每一幅图提取的特征向量的个数是不同的,在网上搜索后选择使用pca降维的方式来归一化特征向量的维度。参考文章
hog特征在统一图像尺寸以及hog特征提取的检测窗口大小,得出的特征向量的维度是一定的。
使用svm检测时要按照训练的方式来对待检测样品进行处理,即将图像提取成与训练模型同样的维度的特征向量。
例如hog特征向量是1*588维,sift特征经过pca方式降维后是1*128维的。
#include <iostream>
#include <opencv2/opencv.hpp> //头文件
#include <opencv2/xfeatures2d.hpp>
#include <stdio.h>
#include <time.h>
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include <io.h> //查找文件相关函数
using namespace cv::ml;
using namespace cv; //包含cv命名空间
using namespace std;
void getFiles(string path, vector<string>& files);
void getBubble(Mat& trainingImages, vector<int>& trainingLabels);
void getNoBubble(Mat& trainingImages, vector<int>& trainingLabels);
Mat detector_HOG(Mat image) {
HOGDescriptor hog(Size(128, 128), Size(16, 16), Size(8, 8), Size(8, 8), 3);
Mat featureMat;
vector<float> descriptors;
hog.compute(image, descriptors);
featureMat = Mat::zeros(1, descriptors.size(), CV_32FC1);
for (int j = 0; j<descriptors.size(); j++)
{
featureMat.at<float>(0, j) = descriptors[j];
}
return featureMat;
}
int main() {
Mat classes;
Mat tra