Visualizing (Wild)Fires in Sentinel-2 imagery through EO Browser

A newer version of this script is available! Click here!
Wildfires near Hanceville, British Columbia, Canada. Processed in Sinergise EO Browser
Wildfires near Hanceville, British Columbia, Canada. Processed in Sinergise EO Browser

I’m usually a big fan of manually processing satellite images (see an example here), especially for the purpose of just creating an aesthetically pleasing visualization. However, not all people are interested in processing images manually, be it because they don’t know how, a lack of time for the sometimes tedious process to get a nice result, or some other reason.

Lately we see a lot of services making satellite images available to the public, including different levels of processing this data and then displaying it in some form of browser and/or making it available for download.

One of those is the Sinergise EO Browser, one of its features being the ability to include your own scripts to influence the processing (custom rendering).

So here we have a small script, aimed at creating visually pleasing visualizations of wildfires from Sentinel-2 imagery. It is far from perfect and the fire detection is very basic, however, looking at images created with this script you will find that the detected fires line up quite well with the origins of smoke in those images.

The Script

// ***
// Visualizing (wild)fires in Sentinel-2 imagery
// For use in Sinergise EO Browser (http://apps.sentinel-hub.com/eo-browser)
// Pierre Markuse (@pierre_markuse)
// ***

// Functions
function A(a, b) {return a + b};
function stretch(val, min, max)  {
	return (val - min) / (max - min);

// Some basic colors
var BLACK = [0.0, 0.0, 0.0];
var WHITE = [1.0, 1.0, 1.0];
var RED = [0.9, 0.1, 0.1];
var YELLOW = [0.9, 0.9, 0.1];
var GREEN = [0.1, 0.9, 0.1];

// Band combinations
var NaturalColors = [stretch(3.1 * B04,0.05,0.9), stretch(3 * B03,0.05,0.9), stretch(3.0 * B02,0.05,0.9)];
var EnhancedNaturalColors = [stretch((3.1 * B04 + 0.1 * B05),0.05,0.9), stretch((3 * B03 + 0.15 * B08),0.05,0.9), stretch(3 * B02,0.05,0.9)];
var NIRSWIRColors = [stretch(2.6 * B12,0.05,0.9), stretch(1.9 * B08,0.05,0.9), stretch(2.7 * B02,0.05,0.9)];
var PanBand = [stretch(B08,0.01,0.99),stretch(B08,0.01,0.99),stretch(B08,0.01,0.99)];
var NaturalNIRSWIRMix = [stretch((2.1 * B04 + 0.5 * B12),0.01,0.99), stretch((2.2 * B03 + 0.5 * B08),0.01,0.99), stretch(3.2 * B02,0.01,0.99)];
var PanTintedGreen = [B08 * 0.2, B08, B08 * 0.2];
var Fire1OVL = [stretch((2.1 * B04 + 0.5 * B12),0.01,0.99)+1.1, stretch((2.2 * B03 + 0.5 * B08),0.01,0.99), stretch(2.1 * B02,0.01,0.99)];
var Fire2OVL = [stretch((2.1 * B04 + 0.5 * B12),0.01,0.99)+1.1, stretch((2.2 * B03 + 0.5 * B08),0.01,0.99)+0.5, stretch(2.1 * B02,0.01,0.99)];

// Choose a Color, Band Combination, or make up your own visual
// In case it doesn't have to look aesthetically pleasing you can put RED and YELLOW here 
var FIRE1 = Fire1OVL; // Outer fire zone, def = Fire1OVL
var FIRE2 = Fire2OVL; // Inner fire zone, def = Fire2OVL

// I recommend NaturalNIRSWIRMix or NIRSWIRColors for best visuals
// Try NaturalColors, EnhancedNaturalColors, PanTintedGreen, and PanBand as well
var NOFIRE = NaturalNIRSWIRMix;

// Using B12 and B11 to highlight possible fires in two zones to get some more distinction
// Increase SENSITIVITY for more possible fires and more wrong indications
var SENSITIVITY = 1.0;
return (A(B12, B11) > (1.0 / SENSITIVITY))
? (A(B12, B11) > (2.0 / SENSITIVITY)) ? FIRE2 : FIRE1

Feel free to experiment with it and change some settings, but it is a good start to quickly create nice wildfire images from Sentinel-2 data.

The script as it is produces images like the one you can see at the beginning of this post, combining a natural color background with some NIR/SWIR data to get more detail and highlights from B11 and B12 to show fires. Changing the settings can produce images like the following.

More examples

All images here, as well as the image at the beginning of the post, are directly taken from the Sinergise EO Browser without further manual processing.

Using more NIR/SWIR data to have better smoke penetration and better visible burn scars. Set NOFIRE to NIRSWIRColors for this result.

Natural colors with just red indicators of possible fires. Set NOFIRE to NaturalColors and FIRE1 and FIRE2 to RED for this result.

High-contrast image with colored fires and monochrome Pan band as background. Set NOFIRE to PanBand for this result.

Contains modified Copernicus Sentinel data [2017]

Similar Posts


  1. Pierre your javascript work on EO Browser is a real inspiration!

    I’ve been playing around with a copy of your script and it has produced some very nice results for me.

    A quick question. What does this function do?

    function A(a, b) {return a + b};

    return (A(B12, B11) > (1.0 / SENSITIVITY)) ? (A(B12, B11) > (2.0 / SENSITIVITY)) ? FIRE2 : FIRE1: NOFIRE;

    I understand that it combines the FIRE2 and FIRE1 with the NOFIRE visualisation based on sensitivity thresholds but could you talk me though it please?


    1. Hey, sorry for my late answer.

      function A(a, b) {return a + b}; just returns the sum of A + B

      The next line adds B12 and B11, in case the result is <= 1.0/SENSITIVITY it returns NOFIRE. In case the result is > 1.0/SENSITIVITY it further compares whether it is also > 2.0/SENSITIVITY, thereby creating two zones for the hot spot with different intensity (shown by a different color), giving a more natural look.

      Hope that helps 🙂

  2. Hello,
    thank you very much for all your work to create this type of magic code to visualize the fires in the image of satilite.
    for me, I want to understand one thing.
    given an image of 200 * 200 for example.
    the B12 is like a 200 * 200 matirx, or your processing goes through the whole image pixel by pixel.
    I just want to understand what it does in the backend


Leave a Reply

Your email address will not be published. Required fields are marked *