Since I got a crackberry cellphone that geotags images when I take them using its built in GPS, I have become a photo snapping lunatic. Of course one’s lunacy needs some way to manifest itself using FOSSGIS so I am going to decribe here a workflow to enable you to enjoy the thrills of geotagged imagery in QGIS even if you aren’t the proud owner of a completely proprietary crackberry phone! The process I describe below will allow you to geotag a directory full of images using a gpx track that you collect using your gps when you are out in the field. If your camera / phonecam already geotags your images, you can do step 1 and then skip straight down to step 10 below!

Step 1: Install dependencies:

sudo apt-get install gpscorrelate exiv2 python-pyexiv2

Step 2: Clean up your gpx file.

Be careful of using the QGIS editing tools to cut away any ropey looking or unneeded features – QGIS will delete the vertex attributes in the track! Rather use a text editor (like VIM!).

Step 3: Clean any existing geotags from the images:

gpscorrelate -r *.jpg;

Step 4: Find the timestamp of your first image:

exiv2 IMG_0594.jpg | grep timestamp

Image timestamp : 2009:07:31 13:02:53 IMG_0594.jpg

Step 5: Find the timestamp of the first trkpnt in the gpx file that matches the position where the photo was taken.


Step 6: Compute the time offset betweenn your camera and your gps

13 02 53 <-- photo
10 58 29 <-- gpx
 2  4 24 <-- difference

+ 2:00 hours gmt <-- timezone offset
-264 photo offset <-- difference (4min 24sec) in seconds, negative to show gps is behind the camera

Another example:

Here was a point at which we knew we had taken a picture (and we know the filename of the picture):


  685.07
  
  ACTIVE LOG
  22:10 11-Jan-10
  eTrex Venture
   0
   0

And then we got the exiv2 dump for the image:

File name       : IMG_2709.jpg
File size       : 960453 Bytes
MIME type       : image/jpeg
Image size      : 2816 x 1880
Camera make     : Canon
Camera model    : Canon EOS 1000D
Image timestamp : 2009:11:08 08:55:14
Image number    :
Exposure time   : 1/250 s
Aperture        : F8
Exposure bias   : 0 EV
Flash           : No, compulsory
Flash bias      : 0 EV
Focal length    : 70.0 mm
Subject distance: 0
ISO speed       : 100
Exposure mode   : Landscape mode
Metering mode   : Multi-segment
Macro mode      : Off
Image quality   : Normal
Exif Resolution : 2816 x 1880
White balance   : Auto
Thumbnail       : image/jpeg, 7605 Bytes
Copyright       :
Exif comment    :

From that we can work out something like this:

08 55 14 <-- photo
06 49 54 <-- gpx
 2 05 20 <-- difference
 +2hrs   <-- gmt offset
  320s   <-- second offset

Step 7: GeoTag your images using gpscorrelate:

For the first example:

gpscorrelate --timeadd +2:00 -g /tmp/knp_gpx_tim_interp.gpx --degmins -O -264 -m 1 *.jpg

Sometimes you need to make some manual adjustments to get the timestamps just right. For the images in our second example we ended up using:

gpscorrelate --timeadd +2:00 -g ../../KZN_tim.gpx --degmins -O -348 -m 30 *.jpg

Step 8: Exiv2 Image GeoTag display:

This is just to show what is going on internally - you can use the -pa option to exiv2 to see the geotags that have now been embedded in the images e.g.:

exiv2 -pa IMG_0700.jpg

produces output which includes something like this:

Exif.Image.GPSTag                            Long        1  8984
Exif.GPSInfo.GPSVersionID                    Byte        4  2.0.0.0
Exif.GPSInfo.GPSLatitudeRef                  Ascii       2  South
Exif.GPSInfo.GPSLatitude                     Rational    3  25deg 4.26000'
Exif.GPSInfo.GPSLongitudeRef                 Ascii       2  East
Exif.GPSInfo.GPSLongitude                    Rational    3  31deg 12.74000'
Exif.GPSInfo.GPSAltitudeRef                  Byte        1  Above sea level
Exif.GPSInfo.GPSAltitude                     Rational    1  675.5 m
Exif.GPSInfo.GPSTimeStamp                    SRational   3  13:25:59
Exif.GPSInfo.GPSMapDatum                     Ascii       7  WGS-84
Exif.GPSInfo.GPSDateStamp                    Ascii      11  2009:07:31

Step 9: Bonus material

gpscorrelate includes an interpolation option (enabled by default) that will derive a relative position between two vertices based on the timestamps. You can also use gpsbabel to interpolate extra vertices into your gpx file. For example I put in a vertex for every 1 second interval into the gpx file:

gpsbabel -i gpx -f knp_gpx_tim.gpx -x interpolate,time=1 -o gpx -F knp_gpx_tim_interp.gpx

Step 10: Loading in QGIS

GeoTagged image browsing with evis in QGIS

I have written a simple plugin which will create a shapefile from a directory full of geotagged images. You need to have exiv2 and python bindings for exiv2 in order for it to work, and the geotags must currently be written in degrees / decimal minutes format (which is achieved by using the --degmins option in the examples above). The plugin can be downloaded here. Point the plugin at your directory of geotagged images (it will recurse nested directories too) and afterwards a shapefile will appear in your map view. You can then query the image locations using the EVIS query tool (the EVIS plugin is included by default with QGIS).

You may also want to check out the Easy GeoTagger Project for manual options for embedding geotags into images. EasyGT also includes a vector driver which will treat a directory of geotagged images as vector layer in QGIS.

pixelstats trackingpixel