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 20:24] – [Mesure du déplacement] 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 " | * **calculer** à partir de ce déplacement et de la distance " | ||
| + | |||
| ==== Mesure du déplacement ==== | ==== Mesure du déplacement ==== | ||
| Pour mesurer le déplacement, | Pour mesurer le déplacement, | ||
| - | Pour cette partie du projet, je vous recommande de consulter [[https:// | + | 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**. | 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**. | ||
| Ligne 35: | Ligne 38: | ||
| frame_count = frame_count + 1 | frame_count = frame_count + 1 | ||
| | | ||
| - | # On passe en niveau de gris et on floute pour éviter | + | # On passe en niveau de gris et on floute pour limiter |
| grayFrame = cv2.cvtColor(frame, | grayFrame = cv2.cvtColor(frame, | ||
| greyFrame = cv2.GaussianBlur(grayFrame, | greyFrame = cv2.GaussianBlur(grayFrame, | ||
| Ligne 45: | Ligne 48: | ||
| thresh = cv2.threshold(diff, | thresh = cv2.threshold(diff, | ||
| - | # On dilate un peu le résultat et on récupère les contours, parmis ces contours, on aura notre objets | + | # 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, | thresh = cv2.dilate(thresh, | ||
| _, contours, _ = cv2.findContours(thresh.copy(), | _, contours, _ = cv2.findContours(thresh.copy(), | ||
| </ | </ | ||
| - | On récupèrera ensuite les coordonnées de notre objets | + | On récupèrera ensuite les coordonnées de notre objet en mouvement en passant par une boîte enveloppante, |
| <code Python> | <code Python> | ||
| x, y, w, h = cv2.boundingRect(cnt_m) | x, y, w, h = cv2.boundingRect(cnt_m) | ||
| </ | </ | ||
| - | En **mesurant le temps écoulé entre chaque mesure** du déplacement, | + | 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.1531945496.txt.gz · Dernière modification : de sdurand
