如何利用openCV和人脸特征训练支持向量机(svm)分类器?
我想使用svm分类器进行面部表情检测。我知道opencv有一个SVMAPI,但我不知道应该输入什么来训练分类器。到目前为止,我读了很多论文,都说在人脸特征检测后训练分类器 到目前为止我所做的如何利用openCV和人脸特征训练支持向量机(svm)分类器?,c,opencv,svm,face-detection,feature-detection,C,Opencv,Svm,Face Detection,Feature Detection,我想使用svm分类器进行面部表情检测。我知道opencv有一个SVMAPI,但我不知道应该输入什么来训练分类器。到目前为止,我读了很多论文,都说在人脸特征检测后训练分类器 到目前为止我所做的 人脸检测 每帧计算16个面部点。下面是面部特征检测的输出![输入图像描述] 保存特征点像素地址的向量 注意:我知道如何仅使用正面和负面图像来训练SVM,我看到了这段代码,但我不知道如何将面部特征信息与之结合 谁能帮我用svm开始分类 a、 训练分类器的样本输入应该是什么 b、 如何使用此面部特征点训练分类器
在这方面,人脸手势识别是一个广泛研究的问题,通过对现有文献的深入研究,可以找到您需要使用的适当特征。一旦您拥有了您认为良好的特征描述符,您就可以继续使用这些特征训练支持向量机。一旦您使用最佳参数训练支持向量机(通过交叉验证发现),您开始在看不见的数据上测试SVM模型,并报告准确性。通常,这就是管道 现在是关于支持向量机的部分: SVM是一个二元分类器-它可以区分两个类(尽管它也可以扩展到多个类)。OpenCV在ML库中有一个内置模块。SVM类有两个函数开始:
train(…)
和predict(…)
。要训练分类器,您需要输入大量的样本特征描述符及其类标签(通常为-1和+1)。请记住OpenCV支持的格式:每个训练样本都必须是一个行向量。每行在标签向量中都有一个对应的类标签。因此,如果您有一个长度为n
的描述符,并且您有m
这样的样本描述符,那么您的训练矩阵将是mxn
(m
行,每个行的长度n
),标签向量的长度m
。还有一个SVMParams
对象,其中包含SVM类型等属性以及必须指定的C
等参数的值
经过训练后,您可以从图像中提取特征,将其转换为单行格式,然后将其交给predict()
,它将告诉您它属于哪一类(+1或-1)
还有一个train_auto()
,具有类似的参数和类似的格式,可以为您提供SVM参数的最佳值
还可以检查此项以查看示例
编辑:
假设您有一个返回特征向量的特征描述符,该算法类似于:
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()
是现有的函数,您可能需要自己编写它们。opencv中的机器学习算法都有一个类似的接口。要训练它,您需要传递一个NxM Mat属性(N行,每个属性一行,长度为M)和一个带有类标签的Nx1垫。如下所示:
//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
对于预测,以相同的方式将一行填充到垫子中,它将返回预测的标签
比如说,你的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 );
Mat trainData;//开始时为空
垫子标签;
对于所有面部_点_向量:
{
对于(size_t i=0;ihey,把脸上的点带回来;)(你使用的是哪个opencv版本?)谢谢你的回答..正如我在问题中提到的,我从理论上知道我需要做什么。我知道在特征提取之后,我必须训练SVM分类器。而且我知道训练之后,我可以使用predict()预测面部表情。所以我的主要问题是如何使用这些特征点来训练svm分类器??如果你能给出一些代码片段也会有帮助。再次感谢,但我是否只提供特征?不提供相关图像?那么它将如何关联哪些特征属于哪个图像?不,不提供图像(除非原始图像本身是一个特征,这是很少见的)。你必须从图像中提取特征进行训练,在测试时,你再次提取图像特征。训练和测试的不是图像,而是相应的特征。如何保存训练过的svm“mySvmObject”,我做了SvmObject.save(“abc.xml”);,这不起作用:'(它是否给了您一些错误消息?它是mySvmObject.save(…)
.Hi Break谢谢你的回答,但我有一个问题--我如何提供图像和特征点?意思是,假设我有50张正片图像和20张负片图像,每张图像有16个特征点,那么我如何插入哪个图像下的哪些特征的信息?我应该在该图像中向后推u什么案例?-为什么我的“重塑”行中有2个16个?嗯,当我开始在这里输入时,它看起来像是你想要做情绪检测,像快乐/悲伤。现在你编辑了几次,似乎更多,你想要人脸识别/人物识别,这是一双不同的鞋。你能澄清一下吗?哦!!我想做表情识别只检测离子。现在只有高兴和悲伤。啊,好的。注意,与图像没有联系。(它不知道图像,它只知道你的地标点)它最后说的是高兴还是不高兴。好的,我理解,但我不是很清楚。假设image1在(xi,yi)上有特征,image2在(Xi2,yi2)上有特征,那么要做SVM,我们只需要插入(Xi,Yi)和(Xi2,Yi2)?