Comment former un classificateur SVM (Support Vector Machine) avec OpenCV avec fonctions faciales?

Je souhaite utiliser le classifieur svm pour la détection de l’expression faciale. Je sais qu’opencv a une API svm, mais je n’ai aucune idée de ce qui devrait être l’entrée pour former le classifieur. J’ai lu de nombreux articles jusqu’à présent, disent tous après que le classifieur ait été entraîné à la détection des traits du visage.

jusqu’ici ce que j’ai fait,

  1. Détection facial,
  2. Calcul de 16 points du visage dans chaque image. Vous trouverez ci-dessous une sortie de la détection des caractéristiques faciales! [entrer image description
  3. Un vecteur qui contient l’adresse de pixel des points caractéristiques ici

Remarque: je sais comment je peux former le SVM uniquement avec des images positives et négatives. J’ai vu ce code ici . Mais je ne sais pas comment je combine les informations relatives aux traits du visage.

Quelqu’un peut-il m’aider s’il vous plaît à commencer le classement avec svm.

une. Quel devrait être l’exemple de saisie pour former le classificateur?

b. Comment entraîner le classificateur avec ces points de fonction du visage?

Cordialement,

les algorithmes d’apprentissage automatique à l’openv ont tous une interface similaire. pour le former, vous passez à un NxM Mat en fonctionnalités (N lignes, chacune comportant une ligne de longueur M) et un Nx1 Mat avec les libellés de classe. comme ça:

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

pour la prédiction, vous remplissez un tapis avec 1 ligne de la même manière, et il renverra l’étiquette prévue

alors, disons, vos 16 points du visage sont stockés dans un vecteur, vous feriez comme:

 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 ); 

La reconnaissance des gestes du visage est un problème largement documenté, et les caractéristiques appropriées que vous devez utiliser peuvent être trouvées par une étude très approfondie de la littérature existante. Une fois que vous avez trouvé le descripteur de fonctionnalité que vous estimez bon, vous continuez à former le SVM à ces éléments. Une fois que vous avez formé le SVM avec les parameters optimaux (obtenus grâce à la validation croisée), vous commencez à tester le modèle SVM sur des données invisibles et vous en signalez la précision. C’est en général le pipeline.

Maintenant la partie sur les SVM:

SVM est un classificateur binary – il peut différencier deux classes (bien qu’il puisse également être étendu à plusieurs classes). OpenCV a un module intégré pour SVM dans la bibliothèque ML. La classe SVM a deux fonctions pour commencer: train(..) et predict(..) . Pour former le classifieur, vous devez entrer en entrée une très grande quantité de descripteurs d’échantillons d’échantillon, ainsi que leurs étiquettes de classe (généralement -1 et +1). Rappelez-vous le format pris en charge par OpenCV: chaque échantillon d’apprentissage doit être un vecteur ligne. Et chaque ligne aura une étiquette de classe correspondante dans le vecteur étiquettes. Donc, si vous avez un descripteur de longueur n et que vous en avez, la masortingce de votre entraînement serait mxn ( m lignes, chacune de longueur n ) et le vecteur d’étiquettes serait de longueur m . Il existe également un object SVMParams contenant des propriétés telles que le type SVM et des valeurs pour des parameters tels que C que vous devrez spécifier.

Une fois formé, vous extrayez les caractéristiques d’une image, la convertissez dans un format à une seule ligne, puis vous transmettez predict() et vous indiquerez à quelle classe elle appartient (+1 ou -1).

Il y a aussi train_auto() avec des arguments similaires avec un format similaire qui vous donne les valeurs optimales des parameters SVM.

Vérifiez également cette réponse détaillée SO pour voir un exemple.

EDIT: En supposant que vous ayez un descripteur d’entités qui renvoie un vecteur d’entités, l’algorithme serait quelque chose comme:

 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 ); 

Je ne présume pas que extractFeatures() et alignAsRow() sont des fonctions existantes, vous devrez peut-être les écrire vous-même.