Suivi d'objet dans une vidéo - Algo - Programmation
Marsh Posté le 03-05-2005 à 15:47:04
Salut,
A premiere vu c est pas mal ce que tu fais. Je ne suis pas sure a quoi ressemble un copepodes, mais bon voici une ou 2 idees comme ca:
Je ne sais pas comment tu definis ta taille minimum de ton objet, mais si c est une taille fixe tu risque d avoir des problemes dans certains cas. Par exemple si tes bebetes n ont pas la meme taille suivant l angle sous lequel tu les regarde tu risque de les perdre lors de certains de leur deplacement.
En plus de filer un numero a chaque copepode tu pourrais peut etre stocker une ou 2 proprietes genre la taille ou autre histoire de pouvoir les differentiers plus facilement lorsqu elle se croise.
Sinon pour les croisement tu dois pouvoir utiliser la direction de deplacement un peu mieux que ce que tu fais pour l instant en utilisant plus d image precedente. ce que je veux dire c est qu au lieu d utiliser la direction de deplacement pour seulement prevoir ou chercher le copepode dans l image suivante tu peux peut etre aussi calculer le vecteur de deplacement et la vitesse a laquel il change pour chaque individu ainsi que l amplitude de ces changement. Ca te permettrait par exemple de retrouver 2 individus differents si tu as un excite qui croise un calme grace au probabilite de deplacement de chaque individu.
Ext ce que tu pourrais pas aussi utiliser des info sur la forme, la couleur, la taille...?
Bonne chance
Marsh Posté le 03-05-2005 à 16:14:39
Merci pour tes suggestions, elles sont intéressantes
Je vais essayer de poster une des images que j'utilise pour mon traitment, ca sera plus explicite.
Concernant la taille, en effet elle est fixe (16px), il faut que j'étudie ma vidéo pour voir si dans certains cas, c'est insufisant. (mais je ne pense pas en fait ^^). La couleur c'est toujours la même par contre (la vidéo est en 8 niveaux de gris, qqch comme ca).
Concernant ton idée d'amélioration de l'utilisation des vecteurs, c'est interessant en effet, puisque la vitesse est plus ou moins constante sur un intervalle court, ca serait une bonne information de l'individualité de chaque copépode.
Concernant le calcul de celui-ci, c'est juste la norme du vecteur p(i-1)p / to ? (to c'est 1/framerate)
Je vais étudier ca
Marsh Posté le 03-05-2005 à 17:35:57
Tu peux effectivement calculer la vitesse en utilisant la norme du vecteur diviser par le frame rate, mais si tu utilise cette info seulement a titre de comparaison tu n as pas besoin d avoir vraiment une valeur en pixel/seconde ou cm/seconde et donc pas besoin de d embeter avec le frame rate. Si tu compare seulement le deplacement en pixel de chaque individu tu auras une inforamtions sur leur vitesse sans avoir a calculer la vitesse reele de facon precise.
Marsh Posté le 03-05-2005 à 18:02:50
De la vidéo dis-tu?
Elle est en quel format? Car suivant le format, tu peux retrouver les informations de justement ce qui est en mouvement entre 2 frames (cf. normes mpeg etc.).
Sinon à coup de transformée de Hough (/!\GOURMAND/!\) tu peux calculer des points d'appariement entre 2 images et regarder les points qui se déplacent.
Bref, cf. "motion tracking" sur ton moteur de recherche préféré
Marsh Posté le 03-05-2005 à 18:26:32
niemad => exact, merci de cette précision
moktar1er => heu, il faut pas que ce soit trop complexe =D Comme j'ai dis dans le premier post, j'suis qu'en DUT, donc les doc trouvée sur google (j'ai déja mater ^^) c'est clairement pas de mon niveau (ce qui revenait majoritairement c'était Kalman, algorithme monte carlo etc... j'y comprends rien =/ )
La vidéo est en avi (non compréssé), mais je récupère les images individuellement.
je vous poste une image bientot
edit :
Voila une image telle que je l'utilise dans mon programme (après que le fond est été supprimé).
http://hellien.free.fr/bazar/instant_00100.png
Marsh Posté le 03-05-2005 à 19:52:12
Kalmann ca reste incontournable et pas si compliqué que ça.
Ca peut valoir le coup d'y jeter un oeil
Marsh Posté le 06-05-2005 à 13:27:44
Joel F a écrit : Kalmann ca reste incontournable et pas si compliqué que ça. |
J'ai beau lire plein de document différent, je ne comprends pas le principe =/
Peut-être que ce n'est pas compliqué ... une fois qu'on a les connaissances mathématiques requisent pour, ce n'est pas mon cas :\
J'essaye d'utiliser les vitesses en ce moment, mais sans grands résultats :x
Marsh Posté le 06-05-2005 à 16:40:19
D apres la photo que tu as poste tes betes ont des tetes bien differentes les une des autres. Ca doit donc etre possible de les distinguer par la forme/taille.
Sinon petite question a 2 sous: Tu fais comment pour regrouper tes pixels restant en individu (connection par 4, par 8 ...?) Si ta detection d individu ne connecte pas assez de pixel ensemble tu risque de detecter plusieur betes alors qu il y en a qu une seule en realite. Un moyen facile de verifier comment ton programme se comporte est de colorer chaque zone detectee comme un individu avec une couleur differente. Ca te permettrait peut etre de detecter pourquoi tu "perd" des individus parfois.
Si j etais toi j essayerais de comprendre un peu plus a cause de quoi je perds mes individus avant d essayer d implementer une autre methode.
Si c est parce que leur taille est trop petite regarde du cote de la connectivite des pixels ou de la valeur de ton seuil pour les pixels isoles.
Si c est parce que tu confonds un individu avec un autre lorsqu ils se croisent essayes de regarder comment characteriser chaque individu (vitesse, direction de deplacement, forme, taille, gradient de couleur ...)
Sinon pour ton probleme pour utiliser le resultat de vitesse tu n as pas de resultat a cause de quoi? Parce que les vitesse ne sont pas assez differenciees? ...
Derniere idee: Au lieu d utiliser un seuil pour tes pixels isoles tu pourrais considerer tout groupe de pixels comme un individu et ensuite eliminer les "faux" individu correspondant a des pixels isoles en regardant leur comportement dans le temps. je suppose que tes pixels isole doivent soit reste statique dans le temps si ils correspondent a une impurete dans le milieu, soit apparaite et disparaitre de facon aleatoire et a des endroits differents si ils sont du a des erreurs de soustraction du fond d image. En tout cas ca m etonnerais que tes pixels isoles ce deplace dans le temps de la meme facon que tes betes. Ca te permettrait de n eliminer aucun pixel, et donc de ne pas risquer d eliminer un "vrai" individu tout en eliminant les faux individu au fur et a mesure que tu progresse dans ta video.
Marsh Posté le 07-05-2005 à 01:22:01
Merci pour tes remarques, encore une fois, je vais tâcher de prendre tout en compte.
L'image que j'ai posté ne représente qu'une seule image de la video (logique ^^" ) donc en fait, on voit les copépodes différents, car certains d'entre eux sont "de face" (mais comme c'est en 2D...) mais pendant la vidéo, ils leur arrive de pivoter, et donc leur forme revient "a la normale" (avec les antenes ^^).
Le regroupement se fait de manière moche et vraiment moche. Je pars du premier pixel detecté (qui sera de toute facon toujours en haut a gauche du copépode puisque je parcours l'image dans le sens de la lecture), ensuite, je regarde dans un carré de 50*50 (parametrable) afin de detecté tout les pixels coloré (le carré englobe mon copépode). J'applique ensuite la méthode de la masse pondérée afin de determiner le centre de gravité du copépode (somme(cooronnée*intensité pixel) / somme(intensite pixel)).
C'est moche, mais ca marche, niveau detection des copépodes, je n'ai pas réellement de probleme (peut etre un peu de lenteur, ca met environ 80ms-100ms). Néamoins, je vais qd meme étudier l'interet d'une fonction récursive en connectivité 4 ou 8, ca pourrait etre plus rapide / plus propre.
Concernant l'idée de prendre tout groupe de pixel comme individu, et supprimer après, oui c'set une idée. Mais au niveau de la mise en place, elle est un peu plus complexe. Encore une fois, je conserve l'idée car je dois faire des tests croisés avec d'autres especes de copépode. (Est ce qu'en ajustant mes paramètres, mon programmes sera efficace pour des espèces plus petites ? Si ce n'est pas le cas, je devrais utiliser les methodes que vous proposez)
Pour la vitesse, c'est surtout un probleme de precision. Certains deplacement sont nul (vecteur {0,0}) du coup, qd je calcule le rapport v1/v2 ca donne un Infinite ou un NaN. Mais ca peut facilement se contourner... en ne faisant pas de quotient. Pour l'instant la vitesse amener une imprecision supplémentaire, donc j'y travaille encore car en théorie c'est utile, je fais face a un problme d'implementation de la théorie :x
Marsh Posté le 07-05-2005 à 01:24:44
En fait, l'un des soucis majeur de ma video, c'est que parfois mes objets (copepode) réalisent des "bonds" assez grand en une seule frame (pour fuir un prédateur par exemple).
Dans ce cas, la réassociation ne se fait pas correctement (puisqu'il peut parcourir parfois 1/3 de l'écran).
Dans ces cas la ,tout ce que j'essaye de faire, c'est de voir si apres avoir traiter toute les coordonées, il y a des anciens copépodes qui n'ont pas été réassocier dans la nouvelle frame. Si un copépode n'a pas été retrouvé, j'essaye de voir si on peut pas l'associer avec une nouvelle coordonnées (motion tracking plus large).
Marsh Posté le 09-05-2005 à 13:55:29
A oui effectivement j avais pas realiser que tes copepodes pouvaient avoir des changements de vitesse si soudain et si large d une image sur l autre. Dans ce cas la effectivement l information sur la vitesse risque de ne pas etre tres utile...et pour etre honnete je ne vois pas vriament d autre solution que celle que tu utilise pour l instant pour reassocier un copepode avec son numero d identite. C est surement une solution qui marche tres bien quand tu n as qu un seul copepode qui fait un "bond" mais des que tu en as 2 je vois un peux la galere
Desole mais la je suis un peu a court d idee
Marsh Posté le 09-05-2005 à 17:16:42
J ai discute avec un copain qui fait du suivit d'objet en utilisant le principe de filtre a particule ( c est assez proche des filtre de Kalmann) et il m a dit que ca ne t aiderais pas tant que ca pour retrouver qui est qui dans le cas de "bond" de tes copepodes.
Par contre il a fait une remarque qui n est pas conne c est que si tes copepodes ont un minimum d inertie, il devrait continuer a avancer un peu apres le bond et, normalement, avec l inetie se deplacement devrait continuer dans la meme direction que le "bond". Ca te permettrait alors de connaitre dans quelle direstion le bond a ete fait et d eliminer certain copepode qui n aurait pas pu arriver la en faisant un bond dans cette direction. Par contre ca n elimine pas le probleme qui peut se poser dans le cas de 2 copepodes assez proches qui font un bond dans des directions opposees et au meme moment!
Marsh Posté le 10-05-2005 à 10:11:46
Hélas, après un bon la plupart du temps leur direction change, a vrai dire, ces sales bestioles ( ) arrivent a se diriger pendant le bon (ca fait une trace blanche dans la vidéo). Pour l'inertie, ca serait possible pour des objets plus lourd, la c'est trop faible (un copépode mesure pour les plus grand 10mm je crois) donc dans certains cas, oui, apres le bon la direction est toujours la même, mais souvent non il a changé de direction :\
Perso, moi aussi j'suis à court d'idée la ^^". Au pire je ferais un mode semi-automatique pour qu'apres analyse on puisse corriger à la main les trajectoires qui ont mal été réassocier. Je vais voir un de mes profs cet apres midi, je verrais s'il a d'autres idées.
En tout cas merci beaucoup pour ton aide, c'est très appreciable
(j'essayerai d'upper ce soir qq images pour montrer la trajectoire d'un bon )
En fait j'ai pu upper depuis mon stage (merci a l'interface http de free pour les FTP ^^)
voila le lien pour une dizaine d'image avec un saut (copépode du bas)
http://hellien.free.fr/bond.zip
Marsh Posté le 10-05-2005 à 13:15:42
C est marrant a voire le saut.
Y a surement moyen d utiliser la trainer blanche que ca laisse sur la video pour connaitre la direction et qui s etait.
Tu peux utiliser un gradient de couleur pour connaitre la direction de la trainee blanche et en deduire la directin de mouvement.
Marsh Posté le 06-06-2005 à 00:37:44
Joel F a écrit : Kalmann ca reste incontournable et pas si compliqué que ça. |
, kalman c'est complexe (du moins par rapport aux cours que j'ai eu) !
Marsh Posté le 06-06-2005 à 14:05:09
Euh les mecs, en même temps, si vous voulez vous taper de l'analyse d'image, faut pas vous attendre à quelque chose de super simple non plus hein. Une grande partie de la théorie du traitement du signal étant trés liée à l'automatisme, moi je ne peux que vous inviter à vous y plonger. Ensuite, dés qu'on a 2,3 principes de bases (fonction de transfert, transformée en Z) Kalman c'est largement abordable.
Marsh Posté le 03-05-2005 à 14:13:49
Bonjour
J'ouvre ce topic afin de récolter des idées sur ce sujet. C'est évidement totallement intéressé puisque je suis en stage, je dois développer un logiciel de suivi de copépodes (petits organismes aquatique (zooplancton) dans une video).
Ce n'est pas un topic de type "résolution d'exercice". J'ai déja bien avancer, j'ai quelque chose qui fonctionne, mais je souhaite l'améliorer.
Je commence par vous expliquer la methode utilisé, avec un bon gros copier coller de ce que j'ai écrit pour mon rapport de stage (c'est pour dans 6 semaines, j'ai encore du temps).
5.1 Explication de la méthode utilisée
La méthode utilisée dans ce programme afin de suivre et de visualise la trajectoire des copépodes dans la vidéo se découpe en cinq étapes.
1. Calcul dune image moyenne de la séquence
La première étape consiste à générer une image ne contenant que le fond fixe de la séquence vidéo à traiter. Cette image moyenne va servir à générer des « images instantanées » de la vidéo. Le principe utilisé est le suivant :
ImageMoyenne(i,j) = 1/N * ∑Imagep(i,j)
Pseudo Code :
Pour chaque image de la séquence{
Matrice[i][j] += image.valeurPixel(i,j) //On somme les pixels dans une matrice
}
Création dune BufferedImage im
Pour chaque variable de la matrice (i = {0..x} ; j = {0 ..y}){
Im.pixel(i,j) = Matrice[i][j] / Nombre_de_Fichiers_utilisés
}
2. Création des images instantanées
Une image instantanée est une image de la séquence à laquelle on a supprimé (par soustraction dimage) le fond fixe, afin de ne conserver que les objets mobiles (les copépodes). Le principe de lalgorithme :
ImageInstantanée(i,j) = ImageCourante(i,j) ImageMoyenne(i,j)
Peuso code :
Pour chaque image de la séquence{
Im.pixel(i,j) = ImageCourante.valeurPixel(i,j) ImageMoyenne.valeurPixel(i,j)
}
3. Construire la liste des coordonnées des objets contenus dans limage
Une fois limage instantanée créée, on peut lanalyser afin dy trouver les coordonnées des objets (les copépodes). On construit une liste de Coordonnées 2D (x,y). Le fond de limage étant noir du à la soustraction, on recherche les pixels colorés. Si on en trouve un, on regarde aux alentours afin de vérifier que ce nest pas un pixel isolé. On regarde également si cet objet na pas déjà été ajouté à la liste.
Pseudo code :
Pour j allant de 0 à y{
Pour i allant de 0 à x{
Si(im.valeurPixel(i,j) > 0){ //le pixel nest pas noir
Si(lobjet est de taille mini ET lobjet nest pas présent)
Ajouter les coordonnées à la liste.
}
}
}
4. Identifier les objets contenus dans la liste de coordonnées
Une fois les coordonnées récupérées, on essaye de leur associer un identifiant (un entier unique par objet) afin de suivre la trace de ces objets dans la séquence. Deux méthodes sont utilisées pour cela. Si lobjet apparaît pour la première ou la deuxième fois, on ne peut connaître la direction de celui-ci (on ne la connaît quaprès la deuxième analyse, les données pourront donc être utilisée la troisième fois). Dans ce cas, on pratique une analyse autour des coordonnées pour vérifier si un objet était dans cette zone précédemment. Si cest le cas, on peut réassocier lidentifiant. Si on ne trouve rien, cest un nouvel objet. La deuxième méthode se veut plus précise. Elle utilise le dernier vecteur directeur connu de la trajectoire de lobjet et prédit la position suivante de lobjet grâce à ce vecteur (on translate la position précédente par ce vecteur). Si on trouve un objet sur cette nouvelle position, on associe lidentifiant correspondant.
Pseudo code :
---
5. Construire la liste dobjets
La méthode didentification retourne lidentifiant associer à chaque coordonnée, ou une valeur spéciale en cas dobjet non trouvé (début de la création de la liste par exemple, il nexiste alors pas encore dobjet à associer).
Pseudo code :
Si(identifiant == -1){
Ajouter lobjet à la liste car cest une nouvelle entité
}Sinon{
Mettre à jour lobjet identifié avec ses nouvelles coordonnées
}
Les résultats sont assez correct, mais j'ai encore des erreurs lors de croisements des copépodes, lorsque celui-ci fait un brusque changement de direction, ou quand la caméra ne parvient pas a suivre un déplacement trop rapide.
Tout ces problèmes sont partiellement géré par mon programme, mais quand la "perturbation" devient trop importante, ou groupées avec d'autre perturbation, la on perd le suivi.
Que pensez vous de tout cela ? Comment l'améliorerez vous ?
Merci de votre aide
PS : j'ai fait plusieurs recherche sur le net, je sais que l'une des méthodes les plus utilisée se base sur le 'Kalman Filter' mais je n'ai pas les connaissances nécéssaire en maths pour en apprehender le concept, je ne suis qu'en 2eme année de DUT. Par conséquent, je recherche des méthodes assez simple à mettre en place.