我在匹配人脸方面是新手,正在尝试学习如何使用带有HOG描述子的SVM。我编写了一个简单的基于SVM的人脸识别器,但在激活它时,代码总是返回1
float *getHOG(const cv::Mat &image, int* count)//计算HOG{
cv::HOGDescriptor hog;
std::vector<float> res;
cv::Mat img2;
cv::resize(image, img2, cv::Size(64, 128));
hog.compute(img2, res, cv::Size(8, 8), cv::Size(0, 0));
*count = res.size();
float* result = new float[*count];
for(int i = 0; i < res.size(); i++)
{
result[i] = res[i];
}
return result;
}
const int dataSetLength = 10;
float **getTraininigData(int* setlen, int* veclen)//加载一些数据样本
{
char *names[dataSetLength] = {
"../faces/s1/1.pgm",
"../faces/s1/2.pgm",
"../faces/s1/3.pgm",
"../faces/s1/4.pgm",
"../faces/s1/5.pgm",
"../faces/cars/1.jpg",
"../faces/cars/2.jpg",
"../faces/cars/3.jpg",
"../faces/cars/4.jpg",
"../faces/cars/5.jpg",
};
float **res = new float* [dataSetLength];
for(int i = 0; i < dataSetLength; i++)
{
std::cout<<names[i]<<"\n";
cv::Mat img = cv::imread(names[i], 0);
res[i] = getHOG(img, veclen);
}
*setlen = dataSetLength;
return res;
}
void test()//训练和激活SVM
{
int setlen, veclen;
float **trainingData = getTraininigData(&setlen, &veclen);
float *labels = new float[dataSetLength];
for(int i = 0; i < dataSetLength; i++)
{
labels[i] = (i < dataSetLength/2)? 0.0 : 1.0;
}
cv::Mat labelsMat(setlen, 1, CV_32FC1, labels);
cv::Mat trainingDataMat(setlen, veclen, CV_32FC1, trainingData);
cv::SVMParams params;
params.svm_type = cv::SVM::C_SVC;
params.kernel_type = cv::SVM::LINEAR;
params.term_crit = cv::TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
std::cout<<labelsMat<<"\n";
cv::SVM SVM;
SVM.train(trainingDataMat, labelsMat, cv::Mat(), cv::Mat(), params);
cv::Mat img = cv::imread("../faces/s1/2.pgm", 0);//来自训练数据的样本,但每个样本的答案都是1
auto desc = getHOG(img, &veclen);
cv::Mat sampleMat(1, veclen, CV_32FC1, desc);
float response = SVM.predict(sampleMat);
std::cout<<"resp "<< response<<"\n";
}
我的代码有什么问题?
PS 抱歉我的写作中有错误。英语不是我的母语
回答:
- 你的训练数据不多。请注意,Dalal和Triggs在他们关于HOG的原始论文中(http://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf)使用了数千个例子来训练SVM,而你只有5个负样本和5个正样本。
- 你没有设置C参数(你需要通过交叉验证找到一个好的值) – 你需要更多的数据。
- 可能人脸和汽车的HOG描述子无法用线性核分离,尝试使用RBF。但这不太可能是一个问题,因为D&L在他们的论文中使用了线性SVM。
- 阅读这个:http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf
- 如果你还没有这样做,让SVM在更简单的情况下工作(例如,只使用图像块而不是HOG)。