# Forest Change Detection
Spatially and temporally explicit information of forest ecosystems is essential for a broad range of applications and Earth observation has become a key instrument for forest management and for monitoring forest cover dynamics. Forest change detection tries to identify critical variations in the time series signal, with a strong focus on forests (e.g., illegal deforestation, wind throw, fire). Forests follow a seasonal growth: during the summer months, they carry more leaves which leads to higher surface reflectance whereas in winter the reflectance will be much lower. This up and down in the surface reflectance of vegetated areas, can be mapped as a sinusoidal function with peaks in the vegetative periods (summer) and valleys in between. Knowing the shape of this sinusoidal function allow us to inspect disturbances, checking how much the new signal differ from the reference harmonic behavior.
This approach can be applied to single pixels, looking into a particular area of interest, or more in general over a wide area, where each pixel time series is treated independently.
In this section, we will show how to combine openEO functionality into a basic change detection pipeline.
# Data preparation
To correctly find the right fitting for the harmonic function, we need cloud-free data if using optical data, or shadow masked data if using radar data, over a timeseries of at least two years (but more is better!). Pixels covered by clouds or shadows deviate from the expected trend of the vegetation and therefore we must start with pre-processed data.
# Seasonal curve fitting
Supposing that the training input data is a cloud-free Sentinel-2 timeseries we can write the following code using the openEO clients to find the optimal function coefficients:
import openeo from openeo.processes import cos, sin, array_element def fitFunction(x:ProcessBuilder, parameters:ProcessBuilder): t = 2 * math.pi / 31557600 * x return parameters + parameters * cos(t) + parameters * sin(t) curve_fitting = l2a_bands.fit_curve( parameters=[1,1,1], # Initial guess of the parameters dimension="t", # Fit the function along the temporal dimension function=fitFunction )
# Predicting values
With the seasonal function coefficients, we can predict the expected value for a particular time step. In the following case, we are computing the values following the seasonal trend for the training time steps:
temporal_labels = l2a_bands.dimension_labels('t') curve_prediction = l2a_bands.predict_curve(parameters=curve_fitting,dimension='t',function=fitFunction,labels=temporal_labels)
The difference between the training data and the predicted values following the seasonal model is a key information, which is used to perform the change detection with new data. Please have a look at the reference notebook (opens new window) for the complete pipeline.