pixel wise maths in hdf5 file in R

60 Views Asked by At

I have hdf5 raster file containing hyperspectral data.

in R programming language I did

f <- paste0(wd,"img1.h5")
View(h5ls(f,all=T))

output is of reflectance data is:

/SITE-NAME/Reflectance/Reflectance_Data

with dimension (3311, 678, 425) of (rows, columns, bands).

I need to do some calculations not as band maths but as spectral math i.e., pixel wise calculations.

Every spectrum (pixel) x is replaced by xbn, defined as x divided by the length of its vector||x||. Equation for calculation

How it is to be done.

I have no idea how would I do that in R.. I able to do band calculations.

2

There are 2 best solutions below

0
Patrick On

Disregarding any complicating side issues (such as RAM overloading and performance related to different data storage models in the file and in R), the basic function to calculate xbn is relatively straightforward:

# x is a vector of spectral values for a single pixel
xbn <- function(x) {
  x / sqrt(sum(x^2))
}

This gives you the 425 bn values for every spectral band that makes up the pixel.

Applying this function over your entire image is equally straightforward:

# Load your data into R, calling it here img1

img1bn <- apply(img1, MARGIN = c(1, 2), xbn) |> aperm(c(2, 3, 1))

The apply() function runs a function (xbn() here) over one or more dimensions of an array, in this case the first two dimensions representing the column and rows of your data. apply() then takes the data in the remaining dimension(s) (your spectral data) and feeds that to the supplied function.

Somewhat annoyingly (but understandable from a performance perspective), the result has its dimensions swapped, with the dimension(s) over which the function is applied coming first and the margin dimensions following. That is fixed using the aperm() function.

0
Robert Hijmans On

Start with something like this

library(terra)
x <- rast(f)
# or 
x <- sds(f)

And figure out how to subset the variable of interest. I cannot tell you how since I do not have the file.

After that you can do

bn <- app(x, \(i) i / sqrt(sum(i^2)))