使用SVM训练CK +地标以进行表达识别

时间:2014-11-27 15:00:33

标签: c++ opencv image-processing machine-learning svm

我正在尝试在移动设备上开发一个实时的面部表情识别,以用于我在大学的最终论文。

我已经在OpenCV和STASM库中实现了一个使用第一个的面部检测器和一个使用第二个的地标检测器。

所以,现在我就在这一点上: output after ASM

现在,我的想法是使用SVM进行分类。 我已经下载了CK +数据集。 我无法理解的是:我如何利用CK +数据集中的标志信息进行培训? 我的意思是,最初,我想把每个人的每个地图的所有地标的所有X e Y坐标放在一个矩阵中。

所以我的标记矩阵包含N个子矩阵,其中N是我的数据集中的人数。

我不知道这是否是正确的工作方式。

但是,我不能继续,因为在数据集中并非所有人都有不同表达式的相同帧数,然后具有不同帧的数量,子矩阵不能合并在一起。

enter image description here

例如,在这种情况下,同一个表达式的两个人有18或11帧。

1 个答案:

答案 0 :(得分:1)

好吧,粗略的想法会是这样的:

    每个图像的
  • 从你的痉挛点x,y,x,y,x,y,x,y得到一个(平面,1d)特征向量...

    (你可能需要对它们进行标准化,比如获取边界并减去位置,除以大小)

    (将差异带到基础模型/中性可能是另一个要检查的想法)

  • 训练数据集将是每行1个此类特征的Mat,并且标签每行将具有1个表达式id。 (你想让这个独立于这个人,因为你以后的测试将与看不见的人合作)

  • 预测,以与培训相同的方式处理您的数据


Mat trainData, trainLabels;
// no idea about stasm, i'll just assume, you got a vector<float> of x,y points per image
for ( all images ) // not per person
{   
    trainData.push_back( Mat(points) );       // a single, flat float array
    trainLabels.push_back( expression_id );   // integer labels
}

trainData = trainData.reshape(1, numImages);  // numImg x numPoints*2 (x,y)

// for multi-class svm, kernelType = ml::SVM::POLY 
// and svmType = ml::SVM::NU_SVC with nu ~ 1/numExpressions maybe, 
// but parametering this is, where the *real* work starts ;(

svm->train(trainData, labels);

...

Mat test(points);

int expr_id = svm->predict(test);