The exact formatting of geo-tagged videos can vary between
manufacturers and models.
I have a Garmin Dashcam 60, which creates a separate geotagged mpeg
video every minute.
I create the following bash script to create geotagged images to be
uploaded to mapillary (or others).
------
#!/bin/sh
function getEpoch()
{
vFilename=${1}
# The Garmin created only save the date and time of creation, not for
each gps point
# so extract the 'Create Date' string from the video
vCreate=$(exiftool -ee $vFilename | grep -m 1 "Create Date")
# echo $vCreate
#
# Posix function to split the string into parts, Date is $4/Time is
$5
set -- $vCreate
vDate=$4
vTime=$5
#
# Use the cut function to split the date into year/month/day
vYear="$(cut -d':' -f 1 <<< $vDate)"
vMon="$(cut -d':' -f 2 <<< $vDate)"
vDay="$(cut -d':' -f 3 <<< $vDate)"
# Use the cut function to split the time into hour/minute/second
vHour="$(cut -d':' -f 1 <<< $vTime)"
vMin="$(cut -d':' -f 2 <<< $vTime)"
vSec="$(cut -d':' -f 3 <<< $vTime)"
#
# Generate the epcoch time for the start of each sequence
# Helps avoid issues with timezones and DST
vEpoch=$(date -d "$vYear-$vMon-$vDay $vHour:$vMin:$vSec" +%s)
echo $vEpoch
}
function extractGPX()
{
vFilename=${1}
echo $vFilename
#
# Ensure that gpx folder exists
mkdir -p gpx
#
# Generate a gpx file for each video file with extracted gpx data
exiftool -p /home/phil/Image-ExifTool-11.93/fmt_files/gpx.fmt -ee
$vFilename > gpx/$vFilename.gpx
}
function dateTimeFiles()
{
vFilename=${1}
vEpoch=${2}
# Generate a timestamp and apply to video and gpx
iTime='--date @'"$(($vEpoch))"''
touch ${iTime} gpx/$vFilename.gpx
touch ${iTime} $vFilename
}
function extractImages()
{
vFilename=${1}
#
# Create a folder to put the images if it doesn't already exist
mkdir -p images
#
# Extract images from video at 1 frame per second
nice -n 100 ffmpeg -i $vFilename -vf fps=1
images/$vFilename.%02d.jpg
}
function dateTimeImages()
{
vFilename=${1}
vEpoch=${2}
#
# An image for each of the 60 seconds has been created
# Set the creation time of each
for i in {1..60}
do
printf -v j "%02d" $i
iFile='images/'${vFilename}'.'$j'.jpg'
iTime='--date @'"$(($vEpoch + $i - 1))"
touch ${iTime} $iFile
done
}
function geoTagImages()
{
#
# Geotag images based on file time of image
exiftool -geotag gpx/$vFilename.gpx "-geotime<filemodifydate"
images/$vFilename.*
# Geotag images from an externally generated gpx file
# exiftool -geotag gpx/garmin.gpx "-geotime<filemodifydate"
images/$vFilename.*
rm images/*jpg_original
for i in {1..60}
do
printf -v j "%02d" $i
iFile='images/'${vFilename}'.'$j'.jpg'
iTime='--date @'"$(($vEpoch + $i - 1))"
touch ${iTime} $iFile
done
}
function processVideo()
{
vEpoch=$(getEpoch $vFilename)
vv=$(extractGPX $vFilename)
vv=$(dateTimeFiles $vFilename $vEpoch)
vv=$(extractImages $vFilename )
vv=$(dateTimeImages $vFilename $vEpoch)
vv=$(geoTagImages $vFilename $vEpoch)
}
if [ $1 ]
then
vFilename=${1}
$(processVideo $vFilename)
else
for vFilename in *.mp4
do
$(processVideo $vFilename)
done
fi
------
That certainly works and I have been using it for some years now,
although I did find I needed a second script to postprocess the files
to ensure there is at least 4m of movements between images, otherwise
mapillary becomes a movie at junctions.
------
#!/bin/sh
#
# Floor function
# Returns the floor value as an integer from a float
function floor()
{
float_in=$1
floor_val=${float_in/.*}
}
#
# Count values
vEmpty=0
vNoFix=0
vNotMoved=0
#
# Initialise values for comparison
aLat=0
aLon=0
for vFilename in images/*.jpg
do
#
# When the dashcam stops, we end up with empty files, these
# need to be removed
minimumsize=1
actualsize=$(du -k "$vFilename" | cut -f 1)
if [ $actualsize -gt 0 ];
then
#
# Get the Lat/Lon from the file
bLat=$(exiftool -s -s -s -gpslatitude -n $vFilename)
bLon=$(exiftool -s -s -s -gpslongitude -n $vFilename)
#
# If there is no gps fix, the values returned will be ±180
# Only need to check latitude to be able to filter out photos
# without a valid fix
floor $bLat
# echo $vFilename $bLat $floor_val
if [ $floor_val -ne 180 ] && [ $floor_val -ne -180 ] && [
$floor_val -gt 1 ]
then
# Photo has a valid fix
# Get the distance travelled since last picture in metre
geoGetDistance $aLat $aLon $bLat $bLon
dist=$?
if [ $dist -gt 4 ]
then
# Distance travelled is greater than minimum, so save
and move on to
# next
aLat=$bLat;
aLon=$bLon;
else
# Not moved far enough, so delete
rm $vFilename
((vNotMoved++))
fi
else
# No fix so delete
rm $vFilename
((vNoFix++))
fi
else
# File is empty, so delete
rm $vFilename
((vEmpty++))
fi
done
echo Deleted $vNotMoved files with no movement
echo Deleted $vNoFix files with no fix
echo Deleted $vEmpty empty files
------
Phil (trigpoint)
_______________________________________________
Talk-GB mailing list
[email protected]
https://lists.openstreetmap.org/listinfo/talk-gb