rrasterrgdalrasterize

R: Georeference single drone image from metadata file


In my example, I have a single dji image in *JPG:

library(terra)
single.image <-stack("https://github.com/Leprechault/trash/raw/main/DJI_0274.JPG")
plotRGB(single.image,  r = 3, g = 2, b = 1, stretch = "lin")
# class      : RasterStack 
# dimensions : 3648, 4864, 17743872, 3  (nrow, ncol, ncell, nlayers)
# resolution : 1, 1  (x, y)
# extent     : 0, 4864, 0, 3648  (xmin, xmax, ymin, ymax)
# crs        : NA 
# names      : DJI_0274_1, DJI_0274_2, DJI_0274_3 

testcanopy

and the correspond Metadata in *jgw file:

single.image.mtd <- read.table("https://github.com/Leprechault/trash/raw/main/DJI_0274.jgw", header = FALSE, skip=1)
single.image.mtd
#              V1
# 1 -3.532000e-07
# 2  2.600000e-09
# 3  3.100000e-09
# 4  2.976000e-07
# 5 -5.170865e+01
# 6 -1.973617e+01

This values are:

# X-cell size
# rotation (usually 0)
# rotation (usually 0)
# Y-cell size (always negative)
# Upper left X
# Upper left Y

I'd like to know if is possible to use the metadata in order to have a georeferenced image and save it in geoTIFF format?

Thanks in advance!

Alexandre


Solution

  • From my point of view, reading your jpg file works on-the-fly if you used {terra} for importing instead of {raster}. Meta data present in *.jgw seems to be utilized automatically if the files are placed in the same directory.

    However, it seems like you have to change the leading signs of your lines 1 and 4 of the *.jgw file (y is "always negative") to respect compliance with ESRI World File format. So proceeding with the following *.jgw file leads to following results:

    0.0000003532
    0.0000000026
    0.0000000031
    -0.0000002976
    -51.7086484997
    -19.7361691253
    
    library(terra)
    #> terra 1.6.49
    
    # load data without *.jgw --> res, extent, crs missing
    r1 <- rast("DJI_0274.JPG")
    #> Warning: [rast] unknown extent
    r1
    #> class       : SpatRaster 
    #> dimensions  : 3648, 4864, 3  (nrow, ncol, nlyr)
    #> resolution  : 1, 1  (x, y)
    #> extent      : 0, 4864, 0, 3648  (xmin, xmax, ymin, ymax)
    #> coord. ref. :  
    #> source      : DJI_0274.JPG 
    #> colors RGB  : 1, 2, 3 
    #> names       : DJI_0274_1, DJI_0274_2, DJI_0274_3
    
    # copy DJI_0274.jgw to same directory as DJI_0274.JPG
    
    # load data with *.jgw copied to same directory --> looks better
    r2 <- rast("DJI_0274.JPG")
    #> Warning: [rast] the data in this file are rotated. Use 'rectify' to fix that
    r2
    #> class       : SpatRaster 
    #> dimensions  : 3648, 4864, 3  (nrow, ncol, nlyr)
    #> resolution  : 3.532e-07, 2.976e-07  (x, y)
    #> extent      : -51.70865, -51.70693, -19.73725, -19.73617  (xmin, xmax, ymin, ymax)
    #> coord. ref. : lon/lat WGS 84 
    #> source      : DJI_0274.JPG 
    #> colors RGB  : 1, 2, 3 
    #> names       : DJI_0274_1, DJI_0274_2, DJI_0274_3
    
    r_rect <- rectify(r2)
    r_rect
    #> class       : SpatRaster 
    #> dimensions  : 3648, 4864, 3  (nrow, ncol, nlyr)
    #> resolution  : 3.555963e-07, 3.011079e-07  (x, y)
    #> extent      : -51.70865, -51.70692, -19.73725, -19.73616  (xmin, xmax, ymin, ymax)
    #> coord. ref. : lon/lat WGS 84 
    #> source(s)   : memory
    #> names       : DJI_0274_1, DJI_0274_2, DJI_0274_3 
    #> min values  :          0,          0,          0 
    #> max values  :        255,        255,        255
    
    # write to disk as geoTIFF
    writeRaster(r_rect, "DJI_0274.tif")
    

    Note that it was necessary to execute rectify() to adjust the rotated SpatRaster into a non-rotated object - otherwise R crashed when executing writeRaster().