[GRASS-user] Pansharpening using PCA in R
Georg Kaspar
georg at muenster.de
Fri Apr 2 11:38:38 EDT 2010
Hi,
I'm trying to apply pansharpening to a set of 4 quickbird channels by
exchanging the first principal component with the panchromatic channel.
Since an inverse PCA is not possible using GRASS (alone) I used the
following workflow:
R:
1. import data into R using spgrass6
2. eliminate NAs
3. calculate covariance matrix using cov
4. calculate eigenvalues and eigenvectors using eigen
GRASS:
1. calculate pc-layers by multiplying initial layers with eigenvector *
sqrt(eigenvalue)
2. since the pc-layers seem to be inverted, create an inverted version
of the panchromatic channel rescaled to the range of first pc.
3. set region to resolution of panchromatic channel
4. calculate pansharpened channels by inverting first step and replacing
1st pc with pan-channel
Problem is, that the results do not seem to be pansharpened at all...
Would be nice if someone could have a look at the attached workflow to
see if there are any obvious mistakes...
Best regards & thanks,
Georg
-------------- next part --------------
library(spgrass6)
G = gmeta6()
# import data from grass
qbird = readRAST6(c('szene1_mul.1', 'szene1_mul.2', 'szene1_mul.3', 'szene1_mul.4'))
# work around NAs
qbird.nas = which(is.na(qbird at data$szene1_mul.1) & is.na(qbird at data$szene1_mul.2) & is.na(qbird at data$szene1_mul.3) & is.na(qbird at data$szene1_mul.4))
qbird.values = which(!is.na(qbird at data$szene1_mul.1) & !is.na(qbird at data$szene1_mul.2) & !is.na(qbird at data$szene1_mul.3) & !is.na(qbird at data$szene1_mul.4))
qbird.nonas = qbird at data[qbird.values, ]
# calculate covariance matrix
qbird.cov = cov(qbird.nonas)
# calculate eigenvalues and eigenvectors of covariance matrix
eigen(qbird.cov)
$values
[1] 20456.53596 6349.30655 132.17551 29.54617
$vectors
[,1] [,2] [,3] [,4]
[1,] 0.14080443 -0.6333085 0.74920435 -0.13336911
[2,] 0.11099650 -0.6563785 -0.47295220 0.57720293
[3,] 0.07533621 -0.3617352 -0.46332379 -0.80548320
[4,] -0.98090690 -0.1929644 0.01844232 -0.01569314
-------------- next part --------------
# set region to match extend and resolution of multispectral data
g.region rast=szene1_mul.1
# calculate pc channels based on pca results in R
r.mapcalc "szene1_pca.1 = 20.13874 * szene1_mul.1 + 15.87542 * szene1_mul.2 + 10.77506 * szene1_mul.3 - 140.29553 * szene1_mul.4"
r.mapcalc "szene1_pca.2 = -50.46363 * szene1_mul.1 - 52.30191 * szene1_mul.2 - 28.82398 * szene1_mul.3 - 15.37589 * szene1_mul.4"
r.mapcalc "szene1_pca.3 = 8.6134232 * szene1_mul.1 - 5.4374184 * szene1_mul.2 - 5.3267228 * szene1_mul.3 + 0.2120269 * szene1_mul.4"
r.mapcalc "szene1_pca.4 = -0.72494637 * szene1_mul.1 + 3.13746694 * szene1_mul.2 - 4.37831615 * szene1_mul.3 - 0.08530223 * szene1_mul.4"
# set region to match resolution of panchromatic data
g.region res=0.6
# since 1st pc seems to be inverted when compared to panchromatic channel, an inverted copy of the panchromatic channel is created
r.mapcalc "szene1_pan_inv=szene1_pan*-1+2047"
# data range of panchromatic channel is set to match the 1st pc
r.info -r szene1_pca.1
min=-219802.73799
max=-4871.05689
r.rescale in=szene1_pan_inv out=szene1_pan_inv_re to=-219802.73799,-4871.05689
# calculate pansharpened channels
r.mapcalc "szene1_mul_pan.1=20.13874 * szene1_pan_inv_re - 90.57980 * szene1_pca.2 + 107.15596 * szene1_pca.3 - 19.07530 * szene1_pca.4"
r.mapcalc "szene1_mul_pan.2=8.844483 * szene1_pan_inv_re - 52.301905 * szene1_pca.2 - 37.686031 * szene1_pca.3 + 45.992993 * szene1_pca.4"
r.mapcalc "szene1_mul_pan.3=0.8661224 * szene1_pan_inv_re - 4.1587827 * szene1_pca.2 - 5.3267228 * szene1_pca.3 - 9.2604477 * szene1_pca.4"
r.mapcalc "szene1_mul_pan.4=-5.33185610 * szene1_pan_inv_re - 1.04888494 * szene1_pca.2 + 0.10024578 * szene1_pca.3 - 0.08530223 * szene1_pca.4"
More information about the grass-user
mailing list