Function to find spectral peak shift
Script below shows how to calculate band shift for hyperspectral object (map). First find.max
function is defined, then we set the spectral range for the search of maximum. The output of the function find.max
is the position of the maximum (wavenumber) not its amplitude.
Subsequently we use standard R fuction apply
to use find.max
function on whole hyperspectral object (spc1). Final steps are for the visualization purpose: converting bandpos into matrix, melting data to long data format (longmat) and ploting this data frame with ggplot2 system.
In order to have the colour scale with white for mean value of the bandpos matrix as well as red and blue shifts we calculated mean value of
longmat$value and define following scale gradient:
scale_fill_gradient2(midpoint=mid1, low="red", mid="white", high="blue", space ="Lab")
# define the function
find.max <- function (y, x){
pos <- which.max (y) + (-1:1)
X <- x [pos] - x [pos [2]]
Y <- y [pos] - y [pos [2]]
X <- cbind (1, X, X^2)
coef <- qr.solve (X, Y)
- coef [2] / coef [3] / 2 + x [pos [2]]
}
# set the range
x1<-1000
x2<-1200
# calculate shift
bandpos <- apply (spc1[[,, x1~x2]], 1, find.max, wl(spc1 [,, x1~x2]))
mat1<-matrix(bandpos, nrow=128,ncol=128)
# melt data to long format
longmat<-melt(mat1)
mid1<-mean(longmat$value)
# plot map of shifts
ggplot(longmat, aes(x = Var2, y = Var1)) +
geom_raster(aes(fill=value)) +
scale_fill_gradient2(midpoint=mid1, low="red", mid="white",
high="blue", space ="Lab" )+
theme_bw() + theme(axis.text.x=element_text(size=9, angle=0, vjust=0.3),
axis.text.y=element_text(size=9),
plot.title=element_text(size=11))
# save plot to file
ggsave("Frequency_Shift_1108.png", width=9, height=8)
