Reactiv Script

var polar=['VV', 'VH'];
var one_day = 1000 * 60 * 60 * 24 ;
var reducing_coeff = 0.8;

function hsv2rgb(h,s,v) {
  h = 360*h;
  let f = (n,k=(n+h/60)%6) => v - v*s*Math.max( Math.min(k,4-k,1), 0);
  return [f(5),f(3),f(1)];

function HSVtoRGB(h, s, v) {
  var r, g, b, i, f, p, q, t;
  if (arguments.length === 1) {
    s = h.s, v = h.v, h = h.h;
  i = Math.floor(h * 6);
  f = h * 6 - i;
  p = v * (1 - s);
  q = v * (1 - f * s);
  t = v * (1 - (1 - f) * s);
  switch (i % 6) {
    case 0: r = v, g = t, b = p; break;
    case 1: r = q, g = v, b = p; break;
    case 2: r = p, g = v, b = t; break;
    case 3: r = p, g = q, b = v; break;
    case 4: r = t, g = p, b = v; break;
    case 5: r = v, g = p, b = q; break;
  return [r, g, b];

function get_date_difference_in_days(t1, t2) {
  return Math.floor(Math.abs(
    Math.round(t1 - t2) / one_day

function setup() {
  return {
    input: [{
      bands: polar
    output: { bands: 3 },
    mosaicking: "ORBIT"

// Selection of dates
function preProcessScenes (collections) {
  collections.scenes.orbits = collections.scenes.orbits.sort(
    (s1, s2) => new Date(s1.dateFrom) - new Date(s2.dateFrom)
  return collections

// RGB visualization
function mean(arr) {
  // Defines the mean computation for the input array arr
  return arr.reduce((a,b) => a + b) / arr.length;

function std(arr, m = mean(arr)) {
  // Defines the standard deviation computation for the input array arr and optional input mean
  return Math.sqrt( => Math.pow(x - m, 2)).reduce((a, b) => a + b) / arr.length);

function clamp(n, min, max) {
  // Defines the clamping function: given a number n, returns min if n < min or max if n > max
  return n > max ? max : n < min ? min : n;

function evaluatePixel(samples, scenes) {
  // Compute coefficient of variation
  var Kmax = 0
  var Imax = 0  
  var delta_date = get_date_difference_in_days(
    scenes[scenes.length-1].date, scenes[0].date
  );// Selection of polarization  

  // Computing saturation value //
  var signal_vv = => Math.sqrt(a.VV));
  var mean_signal_vv = mean(signal_vv);
  var std_signal_vv = std(signal_vv, mean_signal_vv);
  var variation_coeff_vv = std_signal_vv / mean_signal_vv;

  var signal_vh = => Math.sqrt(a.VH));
  var mean_signal_vh = mean(signal_vh);
  var std_signal_vh = std(signal_vh, mean_signal_vh);
  var variation_coeff_vh = std_signal_vh / mean_signal_vh;

  // Comparison of variation coeff of both polars with SAR constants deduced with the look number L
  var L = 4.9;
  var mu = 0.2286;
  var alpha = 0.1616;

  var R_vv = (variation_coeff_vv - mu)/(alpha*10.0) + 0.25;
  R_vv = clamp(R_vv, 0, 1)

  var R_vh = (variation_coeff_vh - mu)/(alpha*10.0) + 0.25;
  R_vh = clamp(R_vh, 0, 1)
  // Retained variation coeff is the maximum between the two polar-wise variation coeff
  var R = Math.max(R_vv, R_vh);
  // Computing Hue & Value //

  // Retrieves max from each polar then the max of the two values
  var imax_vv = Math.max(...signal_vv);
  var imax_vh = Math.max(...signal_vh);
  var imax = Math.max(imax_vv, imax_vh);
  var imax_idx = signal_vv.indexOf(imax);
  if (imax_idx == -1) {
  	imax_idx = signal_vh.indexOf(imax);
  var indexk = get_date_difference_in_days(
  var Kmax = indexk / delta_date;
  var imax = clamp(0.8*imax, 0, 1);
  // Creating HSV & RGB convertion //

  // Regulating potential saturation by averaging max signal value with average value of max value at each signal timestep
  var intensities = => Math.max(a.VV, a.VH));
  var mean_intensity = intensities.reduce((a, b) => a + b) / samples.length;
  var value = (imax + 0.8*mean_intensity)/2;
  hsv = {h:0.9*Kmax, s:R, v:value}; // Setting the max possible hue value to 0.9
  rgb = HSVtoRGB(hsv);
  return rgb;

Evaluate and Visualize

General description of the script

Script Introduction

This code was developed at Onera as part of the MEDUSA project. It is a visualization of a stack of SAR images highlighting change detection. Exploiting the HSV, it focuses on the temporal dimension for calculation and does not rely on any spatial computation. For this project, Sentinel-1 IW VV-VH images were used. The orbit was also fixed whether to ASCENDING or to DESCENDING when manipulating time-series. Its ultimate objective is to synthesize activity information embedded into a temporal data profile, all within a single colored image, emphasizing the presence or absence of significant change in bright colors.

Intents & Motivations

Difficult to interpret because of their geometry and speckle noise, SAR images are however very useful and effective in change detection. Until the advent of Sentinel-1 data from the Copernicus program, access to temporal stacks of data was scarce, and most algorithms focused on the spatial component of images. The recent context of big data opens many possibilities for SAR image processing, and one of the most remarkable is the access and the analysis of time-series. Exploiting the time dimension can be useful for filtering speckle noise. Indeed, in the absence of change, we have access, in a single pixel, to N realizations of a random signal. In the algorithm proposed here, we wish not only to improve the signal-to-noise ratio, but also to detect all the pixels for which a change occurred between the first and the last observation date. These generic changes can be either short changes in time (e.g. boats) or longer/permanent changes (e.g. a construction site). The REACTIV algorithm can display insights in different circumstances, such as monitoring of:

  • port areas, for highlighting maritime shipping routes;
  • urban areas, for the observation of city sprawl
  • environment, to quickly map changes in forest cover;
  • agricultural practices, to monitor the occupation of cultivated plots and improve cultivation methods.

Script Description

The HSV space consists of 3 components: the Hue, the Saturation and the Value. We detail below how these three components are used in the representation.

See also the supplementary material for details.

The Hue component: the time dimension

The Hue component represents which color of the color wheel is used. The Hue component encodes the dating information of the event. We select the time index of maximum signal value for the pixel pij across all polarisation l. We then calculate a time difference between the maximal time index and this time index, that we then divide by the difference between the maximal and minimal time index. To simplify, we rescale the relative time measure of change event to be between 0 and 1. Additionally, our Hue color range is defined as a number between 0 and 1. However, we noticed a huge resemblance between the extreme start and end color of the spectrum. For that matter, we decided to fix the maximum value of the interval to a, with a being here 0.9. We do so by multiplying the final Hue value by 0.9 to reduce the initial [0,1] range to a simpler [0, 0.9] range.

The Saturation component: change intensity

The Saturation component, responsible for how intense the color picked by the hue value will be, is bound to the change intensity: the bigger the change, the more saturated the color will appear. This means that white spots on the map represent places with low changes over time. The closer to 1, the more vivid the color; oppositely, the closer to 0, the duller the color. See the supplementary material for details.

The Value component: usual radar intensity

Finally, to keep the usual SAR Image look, the value component ranging from dark to bright, represents the maximum value of the input signal over both polarization. We empirically found that this setting does not provide sufficient details for change to be localizable but also contextualized, i.e. for surroundings to be recognizable: hence, the intensity has been averaged with the mean max signal of the pixel at each timestep. See the supplementary material for details.

Details of the script

This script was developed using the Sentinel Hub EO Browser and explored the potential of time series analysis using the timespan option of the platform. The script has an adaptive linear change detection range that is expressed in relative values, i.e. between 0 and 1 (0 being closer to the start of the temporal stack and 1 being closer to the end). This enables our algorithm to perform over different periods, of different sizes and to have somewhat comparable results. Additionally, it does not suffer from resolution issues as no spatial computation is performed: it is a fully temporal analysis algorithm and hence is not subject to any problem that may happen when processing spatial SAR information. Furthermore, the PolSAR aspect of the algorithm is not crucial to its functioning: it has been tested on single polarisation data as well by isolating VH and VV data channels for Sentinel-1 imagery. Additionally, it is able to adapt to many different situations and geographical context, as proven with the following pictures. However, it may suffer from noisiness in highly changing regions.

Authors of the script

Thomas Di Martino, Elise Colin-Koeniguer, Regis Guinvarc’h, Laetitia Thirion-Lefevre

Description of representative images

  1. Maritime Routes: Shanghai Port

In this Shanghai Port image, and thanks to the REACTIV method, maritime routes are very explicit. Additionally, the time dimension represented by the chosen color seems to indicate that the northern entry path to the port is only opened during certain parts of the year as only red and shaded blue boats appear to be there. This provides insights on the functioning of ports and possible maritime legislation.

Maritime Routes: Shanghai Port

  1. Vegetation monitoring: Shanghai Wetlands

Situated close to the Chongming Dongtan birds national nature reserve in Shanghai, the Shanghai wetlands are a very distinct ecosystem that is usually flooded with water on seasonal occasions, inducing huge variability in its environment and in its dielectric properties, crucial for SAR imagery. This variability is expected to be found and to be localised. As we can see this picture, we do have change being detected cohesively across the different subsurfaces of wetland. This is manifested by regions portrayed as green for some and pink for others. When checking the Hue range, we notice that green is located around the first third of the time interval, meaning around the end of 2018 while the pink values are located at the end of the interval, meaning the end of 2020. These similar yearly periods show how the REACTIV method successfully captured a seasonal and periodical event within the Shanghai wetlands.

Vegetation monitoring: Shanghai Wetlands

  1. Urban sprawl: Wuhan City

Given recent events and the efforts deployed by the Chinese government to build emergency hospitals, the city of Wuhan displayed interesting results with regards to change detection tasks. Most recent buildings, plots with colors of the end of the Hue spectrum (i.e. shades of pink) are noticeable throughout this map. One particular example is the Huoshenshan Hospital located on the Zhiyinhu Boulevard. As displayed in the zoomed image, we notice violet (shaded dark-pink) which represents high activity spike in the last months of recording, which correlates with the cityís plans to build emergency hospitals. Other locations around the city have similar color spots that most probably also are constructions built in the context of COVID-19.

Urban sprawl: Wuhan City

Urban sprawl: Wuhan City - Hospital zoom


The REACTIV method was developed and presented in [1]. Additionally, a french paper has also been redacted: [2] which received the first price of the french CFPT congress. Finally, existing code implementing this method can be found in the following link with Python and GEE implementations.


[1] Elise Colin Koeniguer, Alexandre Boulch, Pauline Trouve-Peloux and Fabrice Janez. Colored visualization of multitemporal data for change detection: issues and methods. EUSAR, 2018.

[2] Elise Colin Koeniguer, Jean-Marie Nicolas, Beatrice Pinel-Puyssegur, J.-M. Lagrange and Fabrice Janez. Visualisation des changements sur s¥eries temporelles radar : m¥ethode REACTIV ¥evalu¥ee `a lí¥echelle mondiale sous Google Earth Engine. (French) RFPT, N. 217-218, 2018