0

For my time series analysis, i need to use images of the three Landsat sensors (TM, ETM+ and OLI). I chose the already atmospheric corrected surface reflectance/Level-2 products. Due to the radiometric differences between the sensors, i still have to normalize them (i think) as a pre-processing step.

When i wanted to do this in R using a regression method via the relnorm-Function (landsat-package), i got the following Error Code despite the images having exactly the same values for dimensions and extent:

Error in array(x, c(length(x), 1L), if (!is.null(names(x))) list(names(x),  : 
  length of 'dimnames' [1] not equal to array extent

I use the following code to clip and normalize identical bands of the TM-product of different dates. The images don't contain any clouds, thus no mask is used:

library(landsat)
library(lmodel2)
library(RStoolbox)
library(raster)

ma <- raster("D:/Working_Directory/LT05_L1TP_144051_20041216_20161127_01_T1_sr_band1.tif")

to <- raster("D:/Working_Directory/LE07_L1TP_144051_19991109_20170216_01_T1_sr_band1.tif")

shp <- readOGR("D:/Working_Directory/transect.shp")

#Clipping both bands:
clipped_ma <- crop(ma, extent(shp))
clipped_ma <- mask(clipped_ma, shp)
clipped_to <- crop(to, extent(shp))
clipped_to <- mask(clipped_to, shp)

#Trying to use the relnorm-function (no mask, OLS-method):
normalized <- relnorm(master=clipped_ma, tofix=clipped_to, method = "OLS", nperm = 0)

What is wrong with the code or the data(-format), that is causing the aforementioned Error?

0

Read the help for relnorm:

Arguments:

  master: The target image, in SpatialGridDataFrame, data frame, matrix
          or vector format.

That does not include a raster object.

This duplicates your error:

> r = raster(matrix(runif(16),4,4))
> s = raster(matrix(runif(16),4,4))
> relnorm(r,s)
Error in array(x, c(length(x), 1L), if (!is.null(names(x))) list(names(x),  : 
  length of 'dimnames' [1] not equal to array extent

and conversion to matrix fixes it:

> relnorm(matrix(r),matrix(s))
RMA was not requested: it will not be computed.

$regression.results
  Method  Intercept    Slope Angle (degrees) P-perm (1-tailed)
[etc etc]
  • Thanks! This solves my issue and i can run the relnorm-function. However, i now face the problem that i can't make the conversion of the output file ($newimage) back to a raster file with the same spatial information as the input file ("clipped_to"). I tried the solution offered here: link But this returns another Error code: Error in setValues(ma, normalized$newimage) : length(values) is not equal to ncell(x), or to 1 – M. Sen. Nov 22 '18 at 11:11
0

The first answer by Spacedman is correct in pointing out that a wrong format (raster) of the input-objects (master- and tofix-image) caused the Error Message mentioned in the question.

Instead of converting the objects into a matrix however, it is better for pre-processing in GIS-applications to convert the input-files (.tif) into "SpatialGridDataFrames" (sp-package) to keep the spatial information and still be able to run the relnorm-function. After that, the output-image "$newimage" can be converted back into the raster format and be saved via writeRaster-function or kept loaded in the memory to later stack it with further output-files.

Here the final code (for one band):

library(landsat)
library(lmodel2)
library(RStoolbox)
library(raster)
library(sp)

#Loading the input-images and the shapefile for clipping/subsetting:
ma <- raster("D:/Working_Directory/LT05_L1TP_144051_20041216_20161127_01_T1_sr_band1.tif")

to <- raster("D:/Working_Directory/LE07_L1TP_144051_19991109_20170216_01_T1_sr_band1.tif")

shp <- readOGR("D:/Working_Directory/transect.shp")

#Clipping both bands:
clipped_ma <- crop(ma, extent(shp))
clipped_ma <- mask(clipped_ma, shp)
clipped_to <- crop(to, extent(shp))
clipped_to <- mask(clipped_to, shp)

#Converting into "SpatialGridDataFrames":
ma_grid <- as(clipped_image, "SpatialGridDataFrame")
to_grid <- as(clipped_image2, "SpatialGridDataFrame")

#Running relnorm-function (no mask, OLS-method):
normalized <- relnorm(master=clipped_ma, tofix=clipped_to, method = "OLS", nperm = 0)

#Converting back the output-image as raster class:
normalized_image <- normalized[["newimage"]]
normalized_raster <- as(normalized_image, "RasterBrick")

#Saving as raster file (.tif):
writeRaster(normalized_raster, choose.files(default = "", caption = "Save as rasterfile",
                                    multi = TRUE, filters = Filters,
                                    index = nrow(Filters)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.