我想使用svm分类器进行面部表情检测。我知道opencv有一个svm api,但我不知道应该用什么来训练分类器。到目前为止,我已经阅读了很多论文,所有这些都是在面部特征检测后训练分类器时说的。
到目前为止,我做了什么,
注意:我知道如何仅使用正面和负面图像训练SVM,我看到了这段代码here,但我不知道如何将面部特征信息与它结合起来。
有人可以帮我用svm开始分类。
一个。什么应该是训练分类器的样本输入?
湾如何使用此面部特征点训练分类器?
此致
答案 0 :(得分:16)
opencv中的机器学习算法都带有类似的界面。为了训练它,你传递一个NxM Mat offeatures(N行,每个特征一行长度为M)和一个带有类标签的Nx1 Mat。像这样:
//traindata //trainlabels
f e a t u r e 1
f e a t u r e -1
f e a t u r e 1
f e a t u r e 1
f e a t u r e -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<Point> points;
Mat testData = Mat(points).reshape(1,32); // flattened to 1 row
testData.convertTo(testData ,CV_32F);
float p = svm.predict( testData );
答案 1 :(得分:3)
面部姿势识别是一个广泛研究的问题,您需要使用的适当功能可以通过对现有文献的深入研究找到。一旦你拥有了你认为很好的特征描述符,你就可以继续训练SVM。一旦您使用最佳参数(通过交叉验证找到)训练SVM,就可以开始在看不见的数据上测试SVM模型,并报告准确性。一般来说,这就是管道。
现在关于SVM的部分:
SVM是一个二元分类器 - 它可以区分两个类(尽管它也可以扩展到多个类)。 OpenCV在ML库中有SVM的内置模块。 SVM类有两个函数:train(..)
和predict(..)
。要训练分类器,您可以在输入中输入大量的样本特征描述符及其类标签(通常为-1和+1)。请记住OpenCV支持的格式:每个训练样本都必须是行向量。并且每行在标签向量中将具有一个对应的类标签。因此,如果您有一个长度为n
的描述符,并且您有m
个样本描述符,那么您的训练矩阵将为m x n
(m
行,每行长度为{{1} }}),标签向量的长度为n
。还有一个m
对象,其中包含SVM类型等属性以及您必须指定的SVMParams
等参数值。
训练后,您从图像中提取特征,将其转换为单行格式,并提供给C
,它将告诉您它属于哪个类(+1或-1)。
还有一个predict()
具有相似的参数,格式相似,可以为您提供SVM参数的最佳值。
另请查看此detailed SO answer以查看示例。
编辑: 假设您有一个返回特征向量的特征描述符,算法将类似于:
train_auto()
我不认为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()
是现有函数,您可能需要自己编写它们。