implémenter un flot optique (traitement d'image) - Algo - Programmation
Marsh Posté le 28-01-2018 à 18:04:35
Bonjour,
Je ne connais pas le flot optique et je suis une "quiche" en maths, je pose dans mon message mon avis sans la moindre certitude. De ce que je t'interprète il y a 3 cas.
Le premier, qui ne semble pas être le tien mais qui me paraît important pour bien comprendre le problème : disons que nous avons une image noire sur laquelle se trouve un point lumineux fixe d'intensité I aux coordonnées (x ; y). Capturons cette image avec un capteur de lumière, ce dernier reste ouvert pendant un certain temps Δt, l'intensité lumineuse mesurée sur l'image est alors I.Δt, elle correspond à l'intensité mesurée au point lumineux.
Maintenant mettons en mouvement ce point lumineux avec une vitesse horizontale Vx et verticale Vy et tentons de nouveau de le capturer. Le capteur restant toujours ouvert un certain temps, le point va se déplacer le temps de l'acquisition, passant des coordonnées (x0 ; y0) aux coordonnées (x1 ; y1). Soit Δx et Δy la distance parcourue respectivement sur l'axe horizontal et vertical. Nous pouvons poser que :
Δx = x1 - x0 = Vx.Δt
Δy = y1 - y0 = Vy.Δt
L'intensité lumineuse mesurée sur l'image est toujours de I.Δt mais cette fois-ci elle correspond à la trajectoire suivie par le déplacement du point lumineux. Dans le cas d'un déplacement rectiligne uniforme, et on supposera que sur un Δt très faible le déplacement est tel quel, la trajectoire est alors une droite allant de (x0 ; y0) à (x1 ; y1) et donc de norme :
L = Sqrt[ (x1 - x0)² + (y1 - y0)² ] = Sqrt[ Δt².(Vx² + Vy²) ] = Δt.Sqrt(Vx² + Vy²)
L'intensité lumineuse en un point est alors de :
I(x;y) = I.Δt / L = I.Δt / [ Δt.Sqrt(Vx² + Vy²) ] = I / Sqrt(Vx² + Vy²)
On peut donc déduire que la norme de la vitesse vaut :
V = Sqrt(Vx² + Vy²) = I² / I(x;y)
Cela est pour le cas où nous avons une seule image prise pendant une durée de temps Δt.
Le second cas, qui semble être le tien, tu as deux images prises séparément d'un court instant Δt, le temps de capture de chaque image est alors infinitésimal (attention, en général, ce terme appelle l'expression dt mais pas ici) et nous ne le considèrerons pas.
Toujours un point lumineux fixe de coordonnées (x ; y) et d'intensité I sur un fond noir. On prend une image de cette situation, l'intensité lumineuse mesurée sur l'image est alors I et correspond à celle de notre point lumineux. Si on prend une autre image, quelques instants plus tard, on obtient la même chose.
Maintenant mettons notre point en mouvement supposé rectiligne uniforme (car on travaille sur un Δt faible), prenons une image à l'instant t0 puis un court instant plus tard t1 nous avons alors notre point lumineux qui passe des coordonnées (x0; y0) aux coordonnées (x1 ; y1) pendant un laps de temps Δt = t1 - t0. On peut poser :
Δx = x1 - x0
Δy = y1 - y0
L = Sqrt(Δx² + Δy²)
L'intensité lumineuse mesurée sur la première image est alors la même que celle mesurée sur la seconde. Seulement sur chaque image tu n'as plus un seul point lumineux mais deux, un point P0 aux coordonnées (x0 ; y0) et un point P1 aux coordonnées (x1 ; y1) où :
I = I(P0) + I(P1)
Une petite pause s'impose, il faut s'imaginer sur un système à deux points que le premier point (point de départ) baisse progressivement en intensité pendant que le second point (point d'arrivée) augmente progressivement en intensité. Je n'ai pas trouvé d'animation mais voilà une image (de wikipedia) représentant cet effet sur une prise non plus en deux temps mais en 5 :
Il faut comprendre qu'à l'instant t-1, cette image était la même sauf que le point #5 n'existait pas, le point #4 avait l'intensité du #5, le #3 l'intensité du #4, etc. et il y avait en plus un point #0 avec l'intensité du point #1.
Plus le mouvement est rapide, plus l'intensité d'un point va diminuer rapidement entre deux images.
Reprenons, la vitesse est donc directement liée à la variation d'intensité d'un point entre deux prises. Reprenons le cas du point fixe, entre deux prises, son intensité lumineuse sera la même, la variation d'intensité sera nulle et donc sa vitesse aussi. Quelque soit le cas nous pouvons alors poser :
ΔI = I1(P0) - I0(P0) { se lit "intensité du point P1 à l'instant t1 moins l'intensité du point P1 à l'instant t0" }
I = I(P0) + I(P1)
V = (ΔI / I) * (L / Δt) { la vitesse est donc la distance L parcourue pendant un temps Δt fois la variation relative d'intensité lumineuse ΔI / I }
Donc, ce n'est toujours pas clair chez moi, en données d'entrée tu as normalement deux images espacées d'un laps de temps Δt. Sur la première image tu as deux points P-1 et P0 avec pour intensité lumineuse respectivement I0(P-1) et I0(P0) et une seconde image avec deux points P0 et P1 ayant pour intensité lumineuse respectivement I1(P0) et I1(P1).
Normalement, dans le cas d'un mouvement rectiligne uniforme tu as :
I0(P-1) = I1(P0)
I0(P0) = I1(P1)
I = I0(P-1) + I0(P0) = I1(P0) + I1(P1)
ΔI = I1(P0) - I0(P0) = I0(P0) - I0(P-1) = I1(P1) - I1(P0)
Δx = x(P0) - x(P-1) = x(P1) - x(P0)
Δy = y(P0) - y(P-1) = y(P1) - y(P0)
L = Sqrt(Δx² + Δy²)
Δt = [t0] - [t-1] = [t1] - [t0]
Le troisième cas c'est celui où tu n'as qu'une tâche lumineuse dont tu suis son intensité au cours du temps sans connaître les autres tâches formées. La solution est alors de regarder en quelque sorte la diffusion du champ d'intensité lumineuse. Mais cela demande d'analyser une zone de pixels (variation de l'intensité sur la distance) minimale de 2^n (où n est le nombre de dimensions) et sur au moins 3 images (variation de l'intensité au cours du temps). Bref je ne vais pas aller plus loin, il faudrait en savoir plus sur le problème.
Marsh Posté le 27-01-2018 à 17:44:51
Bonjour,
je cherche a obtenir la vitesse absolue (norme) des pixels d'une image, et pour cela je veux utiliser la méthode du flot optique. Le probleme c'est que j'ai du mal à implémenter le code car les explication du flot optique sont à base de math et j'ai un peu de mal avec ca.
D'apres ce que j'ai compris on peut estimer la vitesse absolue via la formule :
v_abs = (di/dt)/(di/dx + di/dy) avec i qui représente l'intensité de l'image et x,y les coordonnées du pixel.
di/dt peut se noter : image2.I(x,y,t + 1) - image1.I(x,y,t) // je prend deux images espacées de 1 seconde avec (x,y) le pixel que je veux étudier
en c++ ca donne :
mais je ne sais pas comment faire pour implémenter di/dx et di/dy
avez vous une idée?
Merci d'avance