Estimate time series of green and SWIR reflectances for multi-temporal cloud/shadow filtering
Timeseries is irregularly spaced, especially before Landsat 7, with possibility of large gaps
In [2]:
from __future__ import print_function, division
%load_ext autoreload
%autoreload 2
from datetime import datetime as dt
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib
matplotlib.rcParams['savefig.dpi'] = 2 * matplotlib.rcParams['savefig.dpi']
import pandas as pd
green = 1
swir1 = 4
# Read in data
x = np.load('../data/sample_x.npy')
Y = np.load('../data/px12_py27_Y.npy')
mask = (Y[7, :] <= 1)
x = np.array([_x.toordinal() for _x in x[mask]])
Y = Y[:7, mask]
In [3]:
# Plotter
def plotter(x, y, predx=None, predy=None, crit=400, compare='gt'):
plt.plot(x, y, 'ko')
if predx is not None and predy is not None:
plt.plot(predx, predy, 'b-')
match = np.in1d(predx, x)
match_x = predx[match]
match_y = predy[match]
assert all(match_x == x)
resid = (y - match_y)
#print('Residuals:')
#print(resid)
if compare == 'gt':
masked = resid > crit
elif compare == 'lt':
masked = resid < crit
if np.any(masked == True):
plt.plot(x[masked], y[masked], 'ro')
In [4]:
index = np.arange(0, 30)
plt.subplot(211)
plotter(x[index], Y[green, index])
plt.ylabel('Green')
plt.subplot(212)
plotter(x[index], Y[swir1, index])
plt.ylabel('SWIR1')
Out[4]:
In [5]:
niter = 50
n_year = np.ceil((x[index[-1]] - x[index[0]]) / 365.25)
def get_predX(x, n_year):
w = 2.0 * np.pi / 365.25
X = np.array([
np.ones_like(x),
np.cos(w * x),
np.sin(w * x),
np.cos(w / n_year * x),
np.sin(w / n_year * x)
])
# X = sm.add_constant(X)
return X
X = get_predX(x, n_year)
green_rlm = sm.RLM(Y[green, index], X[:, index].T,
M=sm.robust.norms.TukeyBiweight()).fit(maxiter=niter)
swir1_rlm = sm.RLM(Y[swir1, index], X[:, index].T,
M=sm.robust.norms.TukeyBiweight()).fit(maxiter=niter)
predx = np.linspace(x[index[0]], x[index[-1]], num=x[index[-1]] - x[index[0]] + 1).astype(np.int32)
predX = get_predX(predx, n_year)
plt.subplot(211)
plotter(x[index], Y[green, index],
predx=predx, predy=green_rlm.predict(predX.T))
plt.ylabel('Green')
plt.subplot(212)
plotter(x[index], Y[swir1, index],
predx=predx, predy=swir1_rlm.predict(predX.T),
crit=-400, compare='lt')
plt.ylabel('SWIR1')
Out[5]:
In [6]:
# Setup
span = 9
frac = span / x[index].shape[0]
delta = (x[index].max() - x[index].min()) * 0.01
green_lowess = sm.nonparametric.lowess(Y[green, index], x[index],
frac=frac, delta=delta)
swir1_lowess = sm.nonparametric.lowess(Y[swir1, index], x[index],
frac=frac, delta=delta)
plt.subplot(211)
plotter(x[index], Y[green, index],
predx=green_lowess[:, 0], predy=green_lowess[:, 1])
plt.ylabel('Green')
plt.subplot(212)
plotter(x[index], Y[swir1, index],
predx=swir1_lowess[:, 0], predy=swir1_lowess[:, 1],
crit=-400, compare='lt')
plt.ylabel('SWIR1')
Out[6]:
In [7]:
frac = span / x.shape[0]
delta = (x.max() - x.min()) * 0.01
green_lowess = sm.nonparametric.lowess(Y[green, :], x,
frac=frac, delta=delta)
swir1_lowess = sm.nonparametric.lowess(Y[swir1, :], x,
frac=frac, delta=delta)
plt.subplot(211)
plotter(x, Y[green, :],
predx=green_lowess[:, 0], predy=green_lowess[:, 1])
plt.ylabel('Green')
plt.subplot(212)
plotter(x, Y[swir1, :],
predx=swir1_lowess[:, 0], predy=swir1_lowess[:, 1],
crit=-400, compare='lt')
plt.ylabel('SWIR1')
Out[7]:
In [6]:
# Import wrapper by "andreas-h" for R's STL
! git clone https://gist.github.com/7808564.git
! cp 7808564/*.py .
! sed -i 's/DateRange/date_range/g' r_stl.py
In [7]:
from r_stl import stl
In [8]:
data = pd.Series(Y[green, index],
index=np.array([dt.fromordinal(_x) for _x in x[index]]))
stl(data, 5)