Utiliser sa caméra embarquée de vélo pour envoyer des photos sur Mapillary

Posted on 22 August 2018 in DIY • 8 min read

Mapillary est un service permettant de prendre et partager des photos prises directement au niveau de la rue. Les photos partagées sont traitées par Mapillary (qui vend des traitements de photos prises dans la rue pour notamment en extraire de l’information) et disponibles pour tous sous une licence Creative Commons. Les photos (et une partie des résultats de traitement, dont les panneaux par exemple) sont également utilisables directement pour éditer OpenStreetMap. Plus d’informations sur le service sont disponibles dans cet article de linuxfr.

Quitte à avoir une caméra embarquée sur son vélo, pourquoi ne pas s’en servir pour contribuer des images à ce service ?

Montage de ma caméra sur mon vélo, vue de face Montage de ma caméra sur mon vélo, vue de dos

Utilisation en caméra embarquée pour le vélo

J’ai récemment décidé de monter une caméra embarquée sur mon vélo, pour filmer la route devant moi. Mon montage est très basique et consiste en une Xiaomi Yi Action 2K (d’un excellent rapport qualité/prix et suffisante pour cette fonction, trouvée autour de 50€ avec son boîtier étanche à l’occasion d’une promotion, il y en a très souvent sur le site dealabs.com). La caméra est régulièrement mise à jour par le constructeur (pour l’instant), il y a une certaine communauté autour, ce qui est plutôt encourageant pour l’instant. Il existe aussi un modèle 4K, beaucoup plus cher.

Pour la fixation sur guidon, j’utilise un adaptateur de ce genre, trouvé à 5€ sur Ebay, monté sur mon guidon avec un bout de chambre à air pour une meilleure adhérence. Attention en achetant, il y a deux types de modèles, ceux qui auront la caméra dans l’axe du guidon (pas très utile) et ceux qui auront la caméra perpendiculaire avec le guidon (comme sur la photo) !

Finalement, pour une cinquantaine d’euros, on peut obtenir ce genre de vidéos (non retouchée, qualité identique à celle fournie par la caméra), ce qui est suffisant dans la plupart des cas (de jour) pour avoir une trace et un numéro de plaque. La caméra filme en 2k à 30fps (vidéo ci-dessus) ou en Full HD à 60fps (mais j’ai l’impression qu’une meilleure résolution est plus utile qu’un haut débit d’images). Avec la batterie d’origine, je peux filmer environ 1h dans cette qualité ce qui est suffisant pour moi. Sinon, des batteries de rechange se trouvent facilement pour quelques euros en ligne.

Seul bémol, il faut une application (non-libre) pour mettre à jour le firmware et modifier les réglages de la caméra.

Note : Mapillary propose de prendre des photos directement avec votre téléphone, monté sur votre vélo, et vous fournit même un support gratuitement. Le support envoyé est de très mauvaise qualité, et il y a de grandes chances que votre téléphone s’explose par terre au premier dos d’âne (heureusement, le Fairphone 1 est résistant, il n’a rien eu !). Utiliser un autre support pour filmer est éventuellement envisageable, mais l’orienter correctement pour filmer impose quasiment de ne pas pouvoir s’en servir en guidage :/

Prendre des photos pour Mapillary

Le cas d’usage le plus simple (et le meilleur en termes de qualité de prise de vue !) est lorsque vous n’utilisez pas votre caméra pour filmer. Typiquement, lorsque vous faites du cyclotourisme sur voie verte, il y a peu de chances que vous ayiez besoin d’avoir votre caméra embarquée allumée. Dans ce cas, le plus simple est de passer la caméra en mode “timelapse” en prenant une photo toutes les quelques secondes (2 ou 5 secondes par exemple).

En parallèle, au moment de démarrer l’enregistrement, commencez l’enregistrement d’une trace GPX sur votre téléphone. Cela peut se faire facilement sur votre téléphone sur Android avec OsmAnd~ (disponible sur F-Droid). Choisissez une fréquence d’enregistrement au moins égale à la fréquence de capture des images idéalement.

Prenez également une photo de l’horloge de votre téléphone avec votre caméra à un moment du trajet, pour pouvoir faire facilement correspondre l’heure de votre caméra à l’heure de votre téléphone pour associer des points GPS aux images.

En rentrant de balade, il faut récupérer les photos, leur associer des points GPS et les envoyer chez Mapillary. Ils fournissent pour cela un ensemble de scripts Python fort pratique. Voici le script (à lancer dans un dossier contenant toutes vos photos et votre tace GPX) que j’utilise pour gérer tout ça :

#!/bin/sh
set -e
# Upload a set of images from dashcam Xiaomi Yi.
# Usage: ./xiaomi_photos.sh OFFSET_TIME
# where OFFSET_TIME is the camera time - GPS time (in seconds).

OFFSET_TIME=$1  # This is camera time - GPS time
PHOTOS_FILES=$(ls *.jpg)
GPX_PATH=$(ls *.gpx)
DUPLICATE_DISTANCE=1
MAPILLARY_USER_NAME="YOUR MAPILLARY USER NAME"  # To be edited

OUTPUT_PATH="out"

# Different steps
PROCESS=true
UPLOAD=true

# Ensure folders exist
if [ ! -d "${OUTPUT_PATH}" ]; then
    mkdir ${OUTPUT_PATH}
fi

# Make a copy of photos, to prevent the mapillary scripts from editing the
# original files
cp ${PHOTOS_FILES} ${OUTPUT_PATH}/

# Match photos with GPS coordinates
# Photos too close will be considered as duplicates and not sent.
if [ "$PROCESS" = true ] ; then
    mapillary_tools --advanced process \
        --import_path ${OUTPUT_PATH} \
        --geotag_source gpx --geotag_source_path ${GPX_PATH} \
        --device_make Xiaomi --device_model "Yi Action 2K" \
        --interpolate_directions \
        --flag_duplicates --duplicate_distance ${DUPLICATE_DISTANCE} \
        --local_time --offset_time ${OFFSET_TIME} \
        --user_name ${MAPILLARY_USER_NAME}
fi

# At this point, feel free to edit your photos in the out/ folder. Typically,
# delete any privacy-concerning photo etc. Only the remaining photos will be
# uploaded in next step.
if [ "$UPLOAD" = true ] ; then
    # Upload images
    read -p "Edit photos. Enter y when ready to upload. " -n 1 -r
    echo    # move to a new line
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        # Or alternatively, use the Mapillary uploader for easy visual
        # confirmation that everything went fine.
        mapillary_tools upload --import_path ${OUTPUT_PATH} --manual_done
    fi
fi

# Remove folders
read -p "Remove all temporary files. Enter y when ready to remove. " -n 1 -r
echo    # move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
    rm -r ${OUTPUT_PATH}
    rm -r ${TMP_PATH}
fi

Un exemple de ce mode de fonctionnement et des photos résultantes est visible ici.

Extraire des photos pour Mapillary d’une vidéo en mode caméra embarquée

Malheureusement, souvent, vous voulez quand même avoir votre caméra embarquée qui filme en permanence. C’est notamment le cas lorsque vous circulez en ville à vélo, pour avoir des images -(de plaques d’immatriculation en particulier) en cas d’éventuel accident et de délit de fuite. Dans ce cas, une autre solution est possible en extrayant des photos depuis les vidéos capturées et là encore, les outils Mapillary nous facilitent la tâche.

La limitation principale de ce mode est que votre vidéo est en général filmée en 2K à 30 images par seconde, ce qui est de bien moins bonne qualité qu’en mode “timelapse” (16M pixels, temps de pose court). Du coup, les photos extraites sont forcément de moins bonne qualité et plus facilement floue. Cependant, en ville, les résultats semblent plus qu’acceptables pour un certain nombre de tâches d’édition (revêtement, limitations de vitesses, confirmer la présence de tel ou tel commerce, confirmer un élément urbain, etc).

Dans mon cas, je filme toujours en mode “en boucle” quand je l’utilise comme une caméra embarquée. La caméra génère donc des fichiers vidéos de 10 minutes et les écrase au fur et à mesure, dès qu’elle manque de place. Voici le script (à lancer dans un dossier contenant toutes vos vidéos, les fichiers de miniatures contenant les informations EXIF, .THM, et votre tace GPX) que j’utilise pour recoller toutes les vidéos et gérer l’extraction de photos, l’association de coordonnées GPS et l’envoi à Mapillary :

#!/bin/sh
set -e
# Upload a set of images from video from dashcam Xiaomi Yi.
# Usage: ./xiaomi_videos.sh VIDEO_START_TIME
# where VIDEO_START_TIME is the starting time (as a timestamp, in
# milliseconds) of the video file.

VIDEO_FILES=$(ls *.mp4)
THM_FILES=$(ls *.THM)
GPX_PATH=$(ls *.gpx)
DUPLICATE_DISTANCE=1
MAPILLARY_USER_NAME="YOUR MAPILLARY USER NAME"

TMP_PATH="tmp"
OUTPUT_PATH="out"
CONCAT_VIDEO_FILE="tmp/out.mp4"
VIDEO_SAMPLE_INTERVAL=2

# Different steps
CONVERT=true
SAMPLE=true
PROCESS=true
UPLOAD=true

# Ensure folders exist
if [ ! -d "${OUTPUT_PATH}" ]; then
    mkdir ${OUTPUT_PATH}
fi
if [ ! -d "${TMP_PATH}" ]; then
    mkdir ${TMP_PATH}
fi

# First, concatenate all video files into a single one in a temporary file as
# Mapillary tools can only process single video files.
if [ "$CONVERT" = true ] ; then
    # Generate concatenation list of MP4 files
    if [ -f "${TMP_PATH}/concat_list.txt" ]; then
        rm ${TMP_PATH}/concat_list.txt
    fi
    for f in ${VIDEO_FILES}; do
        echo "file '../$(basename $f)'" >> ${TMP_PATH}/concat_list.txt
    done
    # Concatenate video files
    ffmpeg -f concat -safe 0 -i ${TMP_PATH}/concat_list.txt -c copy ${CONCAT_VIDEO_FILE}
fi

# Then, extract images from the video at a given sample interval (2 seconds
# typically)
if [ "$SAMPLE" = true ] ; then
    # Compute it from http://legacy.mapillary.com/map/upload/vi
    VIDEO_START_TIME=$1

    # Extract images
    mapillary_tools --advanced sample_video \
        --import_path ${OUTPUT_PATH} \
        --video_file ${CONCAT_VIDEO_FILE} --video_sample_interval ${VIDEO_SAMPLE_INTERVAL} \
        --video_start_time ${VIDEO_START_TIME}
fi

# Then, match each image with a GPS coordinate from the GPX track
# Photos too close will be considered as duplicates and not sent.
if [ "$PROCESS" = true ] ; then
    mapillary_tools --advanced process \
        --import_path ${OUTPUT_PATH} \
        --geotag_source gpx --geotag_source_path ${GPX_PATH} \
        --device_make Xiaomi --device_model "Yi Action 2K" \
        --interpolate_directions \
        --flag_duplicates --duplicate_distance ${DUPLICATE_DISTANCE} \
        --user_name ${MAPILLARY_USER_NAME}
fi

# At this point, feel free to edit your photos in the out/ folder. Typically,
# delete any privacy-concerning photo etc. Only the remaining photos will be
# uploaded in next step.
if [ "$UPLOAD" = true ] ; then
    # Upload images
    read -p "Edit videos. Enter y when ready to upload. " -n 1 -r
    echo    # move to a new line
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        mapillary_tools upload --import_path ${OUTPUT_PATH} --manual_done
    fi
fi

# Remove folders
read -p "Remove all temporary files. Enter y when ready to remove. " -n 1 -r
echo    # move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
    rm -r ${OUTPUT_PATH}
    rm -r ${TMP_PATH}
fi

Pour calculer l’heure de prise de vue, la solution la plus pratique que j’ai trouvée pour l’instant est d’utiliser le téléverseur de vidéos de Mapillary. Sélectionnez votre fichier vidéo et votre trace GPX, cherchez une intersection facilement reconnaissable et ajuster la position du point bleu sur la carte en suivant les instructions. Revenez ensuite au début de la vidéo et notez la valeur de “Video time” qu’il suffit ensuite de convertir en timestamp (en millisecondes) pour le passer au script.

Une autre possibilité, si vous connaissez précisément le décalage entre l’heure de votre caméra et celle de votre téléphone, est d’utiliser --offset-time comme précédemment. Cependant, je n’ai pas eu de très bons résultats sur des vidéos avec cette méthode, et l’utilisation de l’heure de démarrage de la vidéo, calculée depuis le téléverseur, m’a donné de meilleurs résultats.

Note : Vous pouvez aussi utiliser le téléverseur de Mapillary de bout en bout, mais vos vidéos seront intégralement envoyées sur leurs serveurs, ce qui me posait des problèmes de confidentialité (et il faudrait aller prédécouper les vidéos pour ne conserver que les séquences non problématiques pour la vie privée).

Un exemple de ce mode de fonctionnement et des images résultantes est visible ici.

Note : En général, la meilleure solution si vous souhaitez juste envoyer des images sur Mapillary est de prendre une image toutes les quelques secondes (2 secondes est un bon compromis en général, vous pouvez prendre moins d’images pour économiser la batterie ou plus d’images pour capturer plus de détails) et d’enregistrer les traces GPX avec une fréquence au moins aussi élevée. L’utilisation de vidéos donne généralement des images de moins bonne qualité en sortie, et son seul intérêt concret est d’avoir le film complet en cas d’accident.

Mise à jour : JOSM l’éditeur pour OpenStreetMap a un plugin pour gérer les tags GPS dans les photos “photo_geotagging”. C’est le meilleur moyen que je connaisse à ce jour pour ajuster facilement et (assez) rapidement la position de nombreuses photos avant envoi dans Mapillary. Le même plugin permet aussi de faire correspondre les photos avec une trace GPX (comme ce que font les scripts Mapillary précédents).