Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
poppy-kine:gmmriemannian [2018/04/10 08:51]
m16devan [Code]
poppy-kine:gmmriemannian [2020/07/03 17:25] (current)
mai ↷ Page moved from gmmriemannian to poppy-kine:gmmriemannian
Line 41: Line 41:
 </​code>​ </​code>​
 Les données de squelettes ont été capturées à l'aide de la [[sensors:​kinect_library|bibliothèque Kinect]]. Le format est une matrice où chaque ligne est une trame, les colonnes correspondent aux positions 3D et orientations (quaternion) de chaque articulation dans l'​ordre de la hiérarchie du squelette. Dans notre cas uniquement les données du haut du corps sont considérées. Si le paramètre //​registration=1//,​ l'​alignement temporel entre les séquences d'​apprentissage est effectué, ce qui est utile pour apprendre un modèle idéal. Les données de squelettes ont été capturées à l'aide de la [[sensors:​kinect_library|bibliothèque Kinect]]. Le format est une matrice où chaque ligne est une trame, les colonnes correspondent aux positions 3D et orientations (quaternion) de chaque articulation dans l'​ordre de la hiérarchie du squelette. Dans notre cas uniquement les données du haut du corps sont considérées. Si le paramètre //​registration=1//,​ l'​alignement temporel entre les séquences d'​apprentissage est effectué, ce qui est utile pour apprendre un modèle idéal.
 +
 +De plus, pour segmenter la séquence en différent segments temporels correspondant à différents mouvements unitaires, et ainsi utiliser ces segments lors de l'​évaluation,​ les fonctions '​segmentSequence'​ et '​segmentSequenceKeyPose'​ sont utilisées. La première fonction segmente le mouvement en considérant les points de coupure comme les points de transitions entre deux mouvements unitaires. La seconde fonction permet d'en plus considérer les phases de pose de maintient comme des segments temporels. Plus de détail sur la méthode de segmentation peuvent être trouvé dans le 2ème article cité plus haut.
  
 Une fois les données chargées, //xIn// et //uIn// correspondent aux données de temps (trames), //xOut// est l'​ensemble des données pour chaque articulation séparément dans l'​espace des poses et //uOut// est l'​ensemble des données pour chaque articulation séparément projeté dans les espaces tangent correspondant. Ces données temporelles et spatiales sont ensuite concaténées pour passer en entrée de l'​apprentissage. Une fois les données chargées, //xIn// et //uIn// correspondent aux données de temps (trames), //xOut// est l'​ensemble des données pour chaque articulation séparément dans l'​espace des poses et //uOut// est l'​ensemble des données pour chaque articulation séparément projeté dans les espaces tangent correspondant. Ces données temporelles et spatiales sont ensuite concaténées pour passer en entrée de l'​apprentissage.
Line 49: Line 51:
 save('​modelExo3','​model'​);​ save('​modelExo3','​model'​);​
 </​code>​ </​code>​
-Le modèle GMM est appris à partir des données d'​apprentissage. Le nombre de gaussiennes du modèle est décidé par l'​intermédiaire du paramètre //​model.nbStates//​ au début du code. Le paramètre //nbIter// détermine le nombre d'​itérations maximum pour l'​apprentissage. Le modèle appris est ensuite sauvegardé.+Le modèle GMM est appris à partir des données d'​apprentissage. Le nombre de gaussiennes du modèle est décidé par l'​intermédiaire du paramètre //​model.nbStates//​ au début du code. Le paramètre //nbIter// détermine le nombre d'​itérations maximum pour l'​apprentissage. ​ 
 +Le modèle appris est ensuite sauvegardé.
  
     * 2. Evaluation ​     * 2. Evaluation ​
Line 71: Line 74:
 dataTest{1}=dataTest_;​oriMatTestLong{1}=oriMatTest_;​posMatTestLong{1}=posMatTest_;​ dataTest{1}=dataTest_;​oriMatTestLong{1}=oriMatTest_;​posMatTestLong{1}=posMatTest_;​
 </​code>​ </​code>​
 +
 +Ensuite la séquence peut être évaluée:
 +<code matlab>
 +%% Evaluate sequence
 +for rep=1:​length(dataTest)
 +    % temporal alignment
 +    if registration==1
 +        [dataTestAligned,​r,​allPoses,​poses,​motion,​distFI] = temporalAlignmentEval(model,​ dataTrain,​dataTest{rep},​fastDP);​
 +        posMatTest=posMatTestLong{rep}(:,​r);​
 +    else
 +        dataTestAligned=dataTest{rep};​
 +    end
 +
 +    % compute likelihoods
 +    [Lglobal,​Lbodypart,​Ljoints] = computeLikelihoods(model,​dataTestAligned);​
 +
 +    % get scores
 +    seuils=[seuil seuil seuil seuil seuil seuil];​minseuils=[-500 -500 -500 -500 -500 -500]; %default values
 +    [Sglobal,​Sbodypart,​Sjoints] = computeScores(model,​Lglobal,​Lbodypart,​Ljoints,​seuils,​minseuils);​
 +    scoreLA=[Sbodypart{1}.global.global Sbodypart{1}.global.perSegment];​
 +    scoreRA=[Sbodypart{2}.global.global Sbodypart{2}.global.perSegment];​
 +    scoreCol=[Sbodypart{3}.global.global Sbodypart{3}.global.perSegment];​
 +    % For each score, the first value corresponds to global score for the
 +    % whole sequence, and then for each temporal segment
 +end
 +</​code>​
 +Le score pour chaque partie du corps se trouve dans //​scoreLA//,​ //scoreRA// et //​scoreCol//​ pour le bras gauche, le bras droit et la colonne respectivement. Chaque vecteur contient d'​abord le score calculé pour toute la séquence puis pour chaque segment temporel. ​
 +
 +    * 3. Apprentissage des erreurs
 +Le script '​learnErrorFeatures.m'​ permet d'​apprendre les erreurs possibles pour un exercice. L'​idée est d'​apprendre à partir d'​erreurs simulées la différence entre ces erreurs et le mouvement idéal. Ces différences sont apprise par un modèle SVM (Support Vector Machine) qui permet lors de l'​analyse du mouvement de classifier l'​erreur détectée comme une erreur déjà apprise.
 +
 +La première partie du code concerne les paramètres qui sont similaires aux parties décrites plus haut.
 +
 +Ensuite, la seconde partie permet de charger le modèle d'​exercice idéal ainsi qu'un exercice de référence:​
 +<code matlab>
 +% model
 +load modelExo3
 +exo=3;
 +
 +% data correct train 
 +dirTrain='​data/​Assis3Maxime/';​
 +fnameTrain='​SkeletonSequence1.txt';​
 +[oriMatTrain,​posMatTrain,​dataTrain] = loadData(dirTrain,​fnameTrain,​filt,​est,​rem,​ws,​nbData);​
 +cuts=[0 model.cuts 300];
 +</​code>​
 +
 +La troisième partie du code génère les caractéristiques d'​erreurs pour chaque fichier d'​erreur correspondant à la différence entre le mouvement d'​erreur et le mouvement idéal appris. Ces différences sont calculées séparément par partie du corps et par segment temporel de l'​exercice. ​
 +<code matlab>
 +% data Erreur train
 +cptErr=0;
 +for err=[1 2 3]
 +    cptErr=cptErr+1;​
 +    dirTrain=sprintf('​data/​ErreursAssis3Maxime/​erreur%i/',​err);​
 +    for nf=1:nspp
 +        fnameTrain=sprintf('​SkeletonSequence%i.txt',​nf-1);​
 +        [oriMatTrainErr{nf},​posMatTrainErr{nf},​dataTrainErr{nf}] = loadData(dirTrain,​fnameTrain,​filt,​est,​rem,​ws,​nbData);​
 +        [dataTrainErr{nf},​r,​allPoses,​poses,​motion,​distFI] = temporalAlignmentEval(model,​ dataTrain,​dataTrainErr{nf},​fastDP);​
 +    end
 +    Mtr=[];​Mte=[];​
 +    for c=1:​length(cuts)-1
 +        for bp=1:3
 +            diff1=[];​diff2=[];​
 +            for nf=1:nspp
 +                diff{nf}=[];​
 +            end
 +            for t=cuts(c)+1:​cuts(c+1)
 +                for i=(bp-1)*3+1:​(bp-1)*3+3
 +                    for nf=1:nspp
 +                        diff{nf}=[diff{nf} logmap(dataTrainErr{nf}{i}.data(:,​t),​dataTrain{i}.data(:,​t))'​];​
 +                    end
 +                end
 +                if bp<3
 +                    for i=(bp-1)*3+10:​(bp-1)*3+12
 +                        for nf=1:nspp
 +                            diff{nf}=[diff{nf} (dataTrain{i}.data(:,​t)-dataTrainErr{nf}{i}.data(:,​t))'​];​
 +                        end
 +                    end
 +                end
 +            end
 +            Mtr{c}.bodypart{bp}=[];​
 +            for nf=1:nspp
 +                Mtr{c}.bodypart{bp}=[Mtr{c}.bodypart{bp};​ diff{nf}];
 +            end
 +        end
 +    end
 +    Train{cptErr}=Mtr;​
 +end
 +</​code>​
 +Il y a principalement deux choses à modifier dans cette partie. La première et le nombre de type d'​erreurs. Dans l'​exemple il y a 3 types d'​erreurs //[1 2 3]//. La seconde variable à modifier est le chemin vers le dossier où sont stockés les exemples d'​erreur //​dirTrain//​. A l'​intérieur de ce dossier, il doit y avoir //n// dossiers appelés //​erreur#​n//​ où //#n// est remplacé par le numéro d'​erreur.
 +
 +La quatrième partie concerne l'​apprentissage du modèle SVM à partir des erreurs:
 +<code matlab>
 +% Learning SVM Modèle
 +for c=1:​length(Train{1})
 +    for bp=1:​length(Train{1}{c}.bodypart)
 +        X=[];Y=[];
 +        for err=1:​cptErr
 +            X=[X;​Train{err}{c}.bodypart{bp}];​
 +            Y=[Y;​err;​err];​
 +        end
 +        u=unique(Y);​
 +        numClasses=length(u);​
 +        for k=1:​numClasses
 +            G1vAll=(Y==u(k));​
 +            svmModelsSegmented{c}.bodypart{bp}.models{k} = fitcsvm(X,​G1vAll,'​KernelScale','​auto','​Standardize',​true);​
 +            svmModelsSegmented{c}.exercise=exo;​
 +        end
 +        G1vAll=ones(size(G1vAll));​
 +        svmModelsSegmented{c}.bodypart{bp}.errorModel = fitcsvm(X,​G1vAll,'​KernelScale','​auto','​Standardize',​true);​
 +    end
 +end
 +</​code>​
 +
 +Enfin, la dernière partie permet de sauvegarder le modèle SVM (le nom //fname// peut être modifié) :
 +<code matlab>
 +% Save
 +fname=sprintf('​errorFeatures/​errorFeaturesModelAssis3Maxime'​);​
 +save(fname,'​svmModelsSegmented'​);​
 +</​code>​
 +
  • poppy-kine/gmmriemannian.1523350291.txt.gz
  • Last modified: 2019/04/25 14:08
  • (external edit)