diy:projets:approximationvitesse
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
diy:projets:approximationvitesse [2018/07/18 19:07] – [Idée générale] sdurand | diy:projets:approximationvitesse [2018/07/19 12:41] (Version actuelle) – [Bilan et sources du projet] sdurand | ||
---|---|---|---|
Ligne 3: | Ligne 3: | ||
==== Idée générale ==== | ==== Idée générale ==== | ||
- | Avec ce nouveau projet, nous allons **estimer la vitesse** d'un objet se déplaçant **perpendiculairement à la caméra** de notre Raspberry à une **distance donnée**, comme illustré par le schéma ci-dessous. | + | //**Je ne garantis en aucun cas la qualité de la méthode présentée ci-dessous ou de la précision qu' |
+ | |||
+ | Avec ce nouveau projet, nous allons **estimer la vitesse** d'un objet se déplaçant **perpendiculairement à la caméra** de notre Raspberry à une **distance donnée** | ||
{{: | {{: | ||
Pour estimer cette vitesse, nous aurons besoin de: | Pour estimer cette vitesse, nous aurons besoin de: | ||
- | - * **mesurer le déplacement d'un objet** en pixels | + | * **mesurer le déplacement d'un objet** en pixel entre deux images capturées par la caméra. |
- | | + | * **calculer** à partir de ce déplacement et de la distance " |
==== Mesure du déplacement ==== | ==== Mesure du déplacement ==== | ||
+ | |||
+ | Pour mesurer le déplacement, | ||
+ | |||
+ | Pour cette partie du projet, je vous recommande de consulter [[https:// | ||
+ | |||
+ | On va simplement prendre une image de référence et à partir des différences qu'on observera avec les nouvelles images, on déduira **la nouvelle position de notre objet**. | ||
+ | |||
+ | <code Python> | ||
+ | # Notre image de référence | ||
+ | firstFrame = cv2.cvtColor(firstFrame, | ||
+ | firstFrame = cv2.GaussianBlur(firstFrame, | ||
+ | firstFrame = firstFrame.astype(" | ||
+ | |||
+ | # ... | ||
+ | |||
+ | while frame_count < 400: | ||
+ | # On capture l' | ||
+ | grabbedAFrame, | ||
+ | |||
+ | if not grabbedAFrame: | ||
+ | continue | ||
+ | |||
+ | frame_count = frame_count + 1 | ||
+ | | ||
+ | # On passe en niveau de gris et on floute pour limiter les différences ponctuelles | ||
+ | grayFrame = cv2.cvtColor(frame, | ||
+ | greyFrame = cv2.GaussianBlur(grayFrame, | ||
+ | |||
+ | # On fait une moyenne pondérée des images précédentes et de l' | ||
+ | cv2.accumulateWeighted(greyFrame, | ||
+ | diff = cv2.absdiff(cv2.convertScaleAbs(firstFrame), | ||
+ | # On seuille la différence entre notre image moyenne et l' | ||
+ | thresh = cv2.threshold(diff, | ||
+ | |||
+ | # On dilate un peu le résultat et on récupère les contours, parmis ces contours, on aura notre objet en mouvement (si le seuillage qu'on a choisi est adapté) | ||
+ | thresh = cv2.dilate(thresh, | ||
+ | _, contours, _ = cv2.findContours(thresh.copy(), | ||
+ | </ | ||
+ | |||
+ | On récupèrera ensuite les coordonnées de notre objet en mouvement en passant par une boîte enveloppante, | ||
+ | <code Python> | ||
+ | x, y, w, h = cv2.boundingRect(cnt_m) | ||
+ | </ | ||
+ | |||
+ | Si vous vous amusez à afficher cette boîte, vous obtiendrez quelque chose de ce genre: | ||
+ | {{: | ||
+ | |||
+ | En **mesurant le temps écoulé entre chaque mesure** du déplacement, | ||
==== Calcul de la vitesse ==== | ==== Calcul de la vitesse ==== | ||
+ | |||
+ | On a désormais la vitesse de notre objet en pixels par seconde, il nous reste simplement à **appliquer la formule** du schéma précédent pour obtenir notre vitesse en m/s. | ||
+ | |||
+ | <code Python> | ||
+ | import math | ||
+ | |||
+ | # On calcule au préalable la distance en mètre que va représenter un pixel de l' | ||
+ | fov = math.radians(53.5) | ||
+ | meters_per_pixel = 2 * math.sin(fov/ | ||
+ | </ | ||
+ | |||
+ | Il ne vous reste plus qu'à multiplier ce nombre par le déplacement en pixel par seconde, et voilà, **vous avez la vitesse de votre objet !** | ||
==== Bilan et sources du projet ==== | ==== Bilan et sources du projet ==== | ||
+ | Malheureusement, | ||
+ | |||
+ | Il semblerai quand même que les résultats qu'on obtient soient cohérents à vitesse de marche/ | ||
+ | |||
+ | <code Python> | ||
+ | import cv2 | ||
+ | import sys | ||
+ | import math | ||
+ | |||
+ | if len(sys.argv) != 2: | ||
+ | print(" | ||
+ | exit(-1) | ||
+ | |||
+ | cam = cv2.VideoCapture(0) | ||
+ | width = 640 | ||
+ | height = 480 | ||
+ | |||
+ | cam.set(cv2.CAP_PROP_FRAME_WIDTH, | ||
+ | cam.set(cv2.CAP_PROP_FRAME_HEIGHT, | ||
+ | |||
+ | fov = math.radians(53.5) | ||
+ | meters_per_pixel = 2 * math.sin(fov/ | ||
+ | |||
+ | frame_count = 0 | ||
+ | |||
+ | grabbedAFrame, | ||
+ | |||
+ | if not grabbedAFrame: | ||
+ | print(" | ||
+ | exit(-2) | ||
+ | |||
+ | firstFrame = cv2.cvtColor(firstFrame, | ||
+ | firstFrame = cv2.GaussianBlur(firstFrame, | ||
+ | firstFrame = firstFrame.astype(" | ||
+ | |||
+ | boxMid = 0 | ||
+ | t0 = cv2.getTickCount() | ||
+ | t1 = t0 | ||
+ | x, y, w, h = 0, 0, 0, 0 | ||
+ | |||
+ | # Nombre d' | ||
+ | frames_before_refresh = 10 | ||
+ | |||
+ | while frame_count < 400: | ||
+ | grabbedAFrame, | ||
+ | |||
+ | if not grabbedAFrame: | ||
+ | continue | ||
+ | |||
+ | frame_count = frame_count + 1 | ||
+ | | ||
+ | grayFrame = cv2.cvtColor(frame, | ||
+ | greyFrame = cv2.GaussianBlur(grayFrame, | ||
+ | |||
+ | cv2.accumulateWeighted(greyFrame, | ||
+ | diff = cv2.absdiff(cv2.convertScaleAbs(firstFrame), | ||
+ | thresh = cv2.threshold(diff, | ||
+ | |||
+ | thresh = cv2.dilate(thresh, | ||
+ | _, contours, _ = cv2.findContours(thresh.copy(), | ||
+ | |||
+ | if len(contours) != 0: | ||
+ | cnt_m = contours[0] | ||
+ | area_m = cv2.contourArea(cnt_m) | ||
+ | |||
+ | |||
+ | for cnt in contours[1: | ||
+ | area = cv2.contourArea(cnt) | ||
+ | if area > area_m: | ||
+ | area_m = area | ||
+ | cnt_m = cnt | ||
+ | |||
+ | if frame_count % frames_before_refresh == 0: | ||
+ | t2 = cv2.getTickCount() | ||
+ | x, y, w, h = cv2.boundingRect(cnt_m) | ||
+ | newMid = x + w/2 | ||
+ | elapsed = (t2 - t1)/ | ||
+ | pixels_per_sec = abs(newMid - boxMid)/ | ||
+ | print(' | ||
+ | print(' | ||
+ | print(' | ||
+ | t1 = t2 | ||
+ | boxMid = newMid | ||
+ | # A dé-commenter si vous voulez un retour vidéo | ||
+ | # cv2.rectangle(greyFrame, | ||
+ | |||
+ | # cv2.imshow(' | ||
+ | # cv2.waitKey(1) | ||
+ | | ||
+ | # cv2.destroyAllWindows() | ||
+ | </ | ||
---- | ---- | ||
//Auteur: S. Durand// | //Auteur: S. Durand// |
diy/projets/approximationvitesse.1531940829.txt.gz · Dernière modification : 2018/07/18 19:07 de sdurand