如何使用具有面部特征的openCV训练支持向量机(svm)分类器?

我想使用svm分类器进行面部表情检测。 我知道opencv有一个svm api,但我不知道应该用什么来训练分类器。 到目前为止,我已经阅读了很多论文,所有这些都是在面部特征检测后训练分类器时说的。

到目前为止我做了什么,

  1. 人脸检测,
  2. 每帧中16个面部点计算。 下面是面部特征检测的输出![输入图像说明
  3. 保持特征的向量指向像素地址 这里

注意:我知道如何只用正片和负片训练SVM,我在这里看到了这段代码,但我不知道如何将面部特征信息与它结合起来。

有人可以帮我开始用svm进行分类。

一个。 什么应该是训练分类器的样本输入?

湾 如何使用此面部特征点训练分类器?

问候,

opencv中的机器学习算法都带有类似的界面。 为了训练它,你传递一个NxM Mat offeatures(N行,每个特征一行长度为M)和一个带有类标签的Nx1 Mat。 像这样:

//traindata //trainlabels feature 1 feature -1 feature 1 feature 1 feature -1 

对于预测,您以相同的方式填充1行的Mat,它将返回预测的标签

所以,比方说,你的16个面部点存储在一个矢量中,你会这样做:

 Mat trainData; // start empty Mat labels; for all facial_point_vecs: { for( size_t i=0; i<16; i++ ) { trainData.push_back(point[i]); } labels.push_back(label); // 1 or -1 } // now here comes the magic: // reshape it, so it has N rows, each being a flat float, x,y,x,y,x,y,x,y... 32 element array trainData = trainData.reshape(1, 16*2); // numpoints*2 for x,y // we have to convert to float: trainData.convertTo(trainData,CV_32F); SVM svm; // params omitted for simplicity (but that's where the *real* work starts..) svm.train( trainData, labels ); //later predict: vector points; Mat testData = Mat(points).reshape(1,32); // flattened to 1 row testData.convertTo(testData ,CV_32F); float p = svm.predict( testData ); 

面部姿势识别是一个广泛研究的问题,通过对现有文献的深入研究可以找到您需要使用的适当特征。 一旦你拥有了你认为很好的特征描述符,你就可以继续训练SVM。 一旦您使用最佳参数(通过交叉validation找到)训练SVM,就可以开始在看不见的数据上测试SVM模型,并报告准确性。 总的来说,这就是管道。

现在关于SVM的部分:

SVM是一个二元分类器 – 它可以区分两个类(尽管它也可以扩展到多个类)。 OpenCV在ML库中有一个用于SVM的内置模块。 SVM类有两个函数开始: train(..)predict(..) 。 要训​​练分类器,您可以在输入中输入大量的样本特征描述符及其类标签(通常为-1和+1)。 请记住OpenCV支持的格式:每个训练样本都必须是行向量。 并且每行在标签向量中将具有一个对应的类标签。 因此,如果您有一个长度为n的描述符,并且您有m这样的样本描述符,那么您的训练矩阵将是mxnm行,每个长度为n ),标签向量的长度为m 。 还有一个SVMParams对象,它包含SVM类型的属性和C类参数的值,您必须指定这些属性。

一旦经过训练,您可以从图像中提取特征,将其转换为单行格式,并提供predict() ,它将告诉您它属于哪个类(+1或-1)。

还有一个具有类似参数的train_auto() ,其格式类似,可以为您提供SVM参数的最佳值。

另请查看详细的SO答案以查看示例。

编辑:假设您有一个返回特征向量的特征描述符,算法将类似于:

 Mat trainingMat, labelsMat; for each image in training database: feature = extractFeatures( image[i] ); Mat feature_row = alignAsRow( feature ); trainingMat.push_back( feature_row ); labelsMat.push_back( -1 or 1 ); //depending upon class. mySvmObject.train( trainingMat, labelsMat, Mat(), Mat(), mySvmParams ); 

我不认为extractFeatures()alignAsRow()是现有函数,您可能需要自己编写它们。