7

I have been flying some drone surveys over the ocean and need to properly project and georeference my images. I have all the information I think I need: lat, lon, altitude, yaw, pitch, and roll along with sensor optics params. I have to imagine this can be done with some existing package, but I can't find any. So I've been using the cameratransform package to get the GPS positions of the corners of my image:

import cameratransform as ct

camera parameters

cam = ct.Camera(ct.RectilinearProjection(focallength_mm=f, sensor=sensor_size, image=image_size), ct.SpatialOrientation(elevation_m=img.altitude, tilt_deg=pitch+sensor_offset, roll_deg=roll, heading_deg=yaw))

gps pts are lat lon

cam.setGPSpos(img.latitude, img.longitude, img.altitude)

these are the coordinates of the image corners

coords = np.array([cam.gpsFromImage([0 , 0]),
cam.gpsFromImage([image_size[0]-1 , 0]),
cam.gpsFromImage([image_size[0]-1, image_size[1]-1]),
cam.gpsFromImage([0 , image_size[1]-1])])

From there I'm not certain what to do. I've tried basically saying these corners are GCPs and trying to warp the image in rasterio:

import rasterio

gcp1 = rasterio.control.GroundControlPoint(row=0, col=0, x=coords[0,1], y=coords[0,0], z=coords[0,2], id=None, info=None) gcp2 = rasterio.control.GroundControlPoint(row=image_size[0]-1, col=0, x=coords[1,1], y=coords[1,0], z=coords[1,2], id=None, info=None) gcp3 = rasterio.control.GroundControlPoint(row=image_size[0]-1, col=image_size[1]-1, x=coords[2,1], y=coords[2,0], z=coords[2,2], id=None, info=None) gcp4 = rasterio.control.GroundControlPoint(row=0, col=image_size[1]-1, x=coords[3,1], y=coords[3,0], z=coords[3,2], id=None, info=None)

Register GDAL format drivers and configuration options with a

context manager.

with rasterio.Env():

# open the original image to get some of the basic metadata
with rasterio.open(path_name, 'r') as src:
    profile = src.profile




# create rasterio transform
tsfm = rasterio.transform.from_gcps([gcp1,gcp2,gcp3,gcp4])

# I also tried this function but to no avail
#tsfm = rasterio.warp.calculate_default_transform(rasterio.crs.CRS({"init": "epsg:4326"}), rasterio.crs.CRS({"init": "epsg:4326"}), img.size()[0], img.size()[1], gcps=[gcp1,gcp2,gcp3,gcp4])

crs = rasterio.crs.CRS({"init": "epsg:4326"})

profile.update(
    dtype=rasterio.uint8,
    transform = tsfm,
    crs=crs)

with rasterio.open('example.tif', 'w', **profile) as dst:
    dst.write(src.read().astype(rasterio.uint8), 1)

This does produce an image but it is not properly warped. Since my sensor is a 40 deg off nadir the warping should be reasonably significant, when I warp it with cameratransform's cam.getTopViewOfImage() function I get this:

example image

Though I'm not sure how to go from that to a georeferenced version or I would just use that function.

clifgray
  • 409
  • 4
  • 18
  • Maybe some clues here: https://gis.stackexchange.com/questions/116672/georeferencing-raster-using-gdal-and-python or here if you have access to ArcGIS: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Warp/00170000007v000000/ – GBG Nov 26 '20 at 15:49
  • Perhaps my question and self-answer at https://gis.stackexchange.com/questions/384756/georeference-single-drone-image-from-exif-data?rq=1 will be helpful? (I've moved on to other things due to complexity with altitude changes) – Houska May 02 '22 at 13:58

0 Answers0