Geospatial representation drone camera coordinates with Python and Folium - Tutorial
/If you have a set of drone imagery and you want to know the location and direction of the camera, this tutorial might be interesting for you. We have done an applied example that retrieves the geospatial metadata from the drone camera for a group of images and makes a geostapatial repretacion on a map with the image name available as popup. The tutorial is done under a Jupyter notebook with Python and Folium.
For this tutorial you need a geospatial conda environment. Please follow this other tutorial:
Tutorial
Code
#!pip install exif
#!pip install folium
import os
import folium
import numpy as np
import pandas as pd
from exif import Image
imageFolder = '../VUELO1/'
imageList = os.listdir(imageFolder)
#filter list to image files
imageList = [i for i in imageList if i[-4:]=='.JPG']
imageList[:5]
['DJI_0591.JPG',
'DJI_0592.JPG',
'DJI_0593.JPG',
'DJI_0594.JPG',
'DJI_0595.JPG']
For one image
imagePath = os.path.join(imageFolder, imageList[0])
imageRead = open(imagePath,'rb')
imageObject = Image(imageRead)
imageObject.list_all()[:5]
['image_description', 'make', 'model', 'orientation', 'x_resolution']
#show geospatial exif records
print(imageObject.gps_latitude)
print(imageObject.gps_longitude)
print(imageObject.gps_latitude_ref)
print(imageObject.gps_longitude_ref)
(15.0, 27.0, 59.0756)
(74.0, 42.0, 40.3897)
S
W
def getCoords(imageObject):
latTuple = imageObject.gps_latitude
lonTuple = imageObject.gps_longitude
latRef = imageObject.gps_latitude_ref
lonRef = imageObject.gps_longitude_ref
latCoord = latTuple[0] + latTuple[1]/60 + latTuple[2]/3600
lonCoord = lonTuple[0] + lonTuple[1]/60 + lonTuple[2]/3600
#for negatives lats and lons
if latRef == 'S':
latCoord = -latCoord
if lonRef == 'W':
lonCoord = -lonCoord
return latCoord, lonCoord
#get lat and lon for one image
lat, lon = getCoords(imageObject)
print(lat, lon)
-15.466409888888888 -74.71121936111112
Working for all images
#get an pandas dataframe for lats and lons
latLonDf = pd.DataFrame(columns=["Lat","Lon"])
for image in imageList:
imagePath = os.path.join(imageFolder, image)
imageRead = open(imagePath,'rb')
imageObject = Image(imageRead)
lat, lon = getCoords(imageObject)
#print(lat, lon)
latLonDf.loc[image,"Lat"]=lat
latLonDf.loc[image,"Lon"]=lon
latLonDf.head()
Lat | Lon | |
---|---|---|
DJI_0591.JPG | -15.46641 | -74.711219 |
DJI_0592.JPG | -15.468541 | -74.714916 |
DJI_0593.JPG | -15.468456 | -74.714952 |
DJI_0594.JPG | -15.468331 | -74.714941 |
DJI_0595.JPG | -15.468186 | -74.714919 |
### Plotting images coordinates
meanLat = latLonDf.Lat.mean()
meanLon = latLonDf.Lon.mean()
m = folium.Map(location=[meanLat,meanLon], zoom_start=17, control_scale=True)
for index, row in latLonDf.iterrows():
folium.CircleMarker(location=[row.Lat,row.Lon], radius=2, popup=index).add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook
latLonDf.to_csv('imagesLatLon')
Input data
You can download the input data from this link.