Skip to content

Instantly share code, notes, and snippets.

@cquest
Created March 13, 2023 06:58
Show Gist options
  • Save cquest/990cdb41d88e6a4c9cbf889753122ce2 to your computer and use it in GitHub Desktop.
Save cquest/990cdb41d88e6a4c9cbf889753122ce2 to your computer and use it in GitHub Desktop.
This script converts dashcam videos into geotagged still images
#! /bin/bash
# This script converts dashcam videos into geotagged still images
# - extraction with ffmpeg of key images
# - extraction of GPS location and time using OCR
# - sub-second metadata generation
# - image cropping and optimization
#
# Tested with ThiEYE carview4 dashcam (front and back)
if [ $# = 0 ]
then
echo "Usage: vid2pix.sh VIDEO_PATH [COMMON_EXIF_TAGS]"
echo " 170° front camera: vid2pix.sh myvideo.MP4 \"-make=ThiEYE -mode=Carview4 -FocalLength=1 -FocalLengthIn35mmFormat=2 -FocusDistance=0\""
echo " 140° back camera: vid2pix.sh myvideo.MP4 \"-make=ThiEYE -mode=Carview4 -FocalLength=2 -FocalLengthIn35mmFormat=6 -FocusDistance=0\""
exit
fi
VIDEO=$1
EXIF=$2
DIR=$(dirname $VIDEO)_$(basename "$VIDEO" .MP4)
mkdir -p $DIR
if [ ! -e "$DIR/frame-0001.jpg" ]
then
ffmpeg -loglevel 0 -skip_frame nokey -i $VIDEO -f image2 -threads 1 -vsync 0 -qscale:v 2 $DIR/frame-%04d.jpg
fi
for FRAME in $(ls -1 $DIR/frame-*.jpg)
do
# generate 1:8 preview
convert $FRAME -resize 6.25% -strip $DIR/temp.jpg
# generate cropped time/GPS extract from picture
convert $FRAME -gravity SouthWest -crop 270x90+0+0 -brightness-contrast 0x80 -colorspace gray -negate $DIR/temp.png
# OCR it !
tesseract --dpi 72 --psm 6 --user-patterns patterns.txt $DIR/temp.png $DIR/temp conf
TIMESTAMP=20$(egrep -o '[0-9]{2}/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]' $DIR/temp.txt)
# could not find DATE and TIME ?
if [ "$TIMESTAMP" = "20" ]
then
# extract TIME
TIME=$(egrep -o '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]' $DIR/temp.txt)
# use previous DATE
TIMESTAMP=$(echo $PREV_TIME | sed 's/ .*/ /')$TIME
fi
LAT=$(egrep -o '([NS]) ?[0-9]+[\.,]?[0-9]{5}' $DIR/temp.txt | sed 's/,/./;s/ //g;s/S/-/;s/N//;s/\([0-9]\)\([0-9]\{5\}\)$/\1.\2/')
LON=$(egrep -o '([EFW]) ?[0-9]+[\.,]?[0-9]{5}' $DIR/temp.txt | sed 's/,/./;s/ //g;s/W/-/;s/E//;s/F//;s/\([0-9]\)\([0-9]\{5\}\)$/\1.\2/')
echo "$FRAME - $TIMESTAMP - $LAT - $LON"
cat $DIR/temp.txt
# subsec
if [ "$TIMESTAMP" = "$PREV_TIME" ]
then
SUBSEC="500"
else
SUBSEC="000"
LAT=$LAT"0"
LON=$LON"0"
LAT2=$(echo "scale=6;($LAT+$PREV_LAT)/2" | bc)
LON2=$(echo "scale=6;($LON+$PREV_LON)/2" | bc)
if [ "$LAT $LON" = "$LAT2 $LON2" ]
then
# no move ? delete
rm $PREV
else
# adjust interpolated location
exiftool -q -overwrite_original -GPSLatitude="$LAT2" -GPSLongitude="$LON2" $PREV
touch -d "$PREV_TIME" $PREV
fi
fi
exiftool -q -overwrite_original -DateTimeOriginal="$TIMESTAMP" -SubSecTimeOriginal="$SUBSEC" -GPSLatitude="$LAT" -GPSLongitude="$LON" "-thumbnailimage<=$DIR/temp.jpg" $EXIF $FRAME
# crop, optimize & rename JPEG file
WIDTH_HEIGHT=$(file $FRAME| egrep -o '[0-9]+x[0-9]+')
WIDTH=$(echo "$WIDTH_HEIGHT" | sed 's/x.*//')
HEIGHT=$(echo "$WIDTH_HEIGHT" | sed 's/.*x//')
CROP="$WIDTH"x$(echo "$HEIGHT-120" |bc)
OUTPUT=$(dirname $FRAME)/$(echo "$TIMESTAMP.$SUBSEC" | sed 's! !T!g;s!/!-!g').jpg
jpegtran -optimize -progressive -copy all -crop $CROP $FRAME > "$OUTPUT"
# adjust file modification date-time to capture time
touch -d "$TIMESTAMP" $OUTPUT
# echo "$OUTPUT > $LAT / $LON @ $TIMESTAMP.$SUBSEC"
PREV=$OUTPUT
PREV_LAT=$LAT
PREV_LON=$LON
PREV_TIME=$TIMESTAMP
done
rm $DIR/temp* $DIR/frame*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment