Detecting Cyanobacteria Using Satellite Images with Google Earth Engine

Nicolás Rondán
Digital Sense AI
Published in
7 min readMar 5, 2021

In this post we will learn how to use Google Earth Engine to load and process satellite images. We will analyze images from Uruguay’s shoreline in order to detect floating cyanobacteria on river waters.

Image of Montevideo’s shoreline with cyanobacteria floating on the river

Cyanobacteria in Uruguay

Cyanobacteria presence in river waters is a recurrent problem in Uruguay, particularly during the summer months. Exposure to cyanobacteria, for example by swimming in the river, can led to skin rash, gastrointestinal distress, hay fever-like symptoms or even more extreme reactions. Therefore, if the presence of these bacteria is detected, beaches need to be closed and people warned about the risk. Finally, the fact that algae blooming has a high correlation with the presence of cyanobacteria in the river can be exploited to provide an efficient early cyanobacteria warning system by detecting these blooming on satellite images

In this post we will showcase how to use Google Earth Engine using the cyanobacteria as a detection use case. We will learn to perform the following steps in order to detect green floating algae, which normally indicates the presence of cyanobacteria:

  1. Load an image collection.
  2. Select images corresponding with a particular date.
  3. Build natural color images and false color images using different bands from a source satellite image.
  4. Compute a Floating Algae Index (FAI) introduced in [1] to build a pseudo color image which shows the presence of cyanobacteria.
  5. Overlay layers on google maps to visualize composite images and natural color images.
  6. Segment cyanobacteria using FAI and a water mask provided by the image collection.

Getting started with Google Earth Engine

In order to work through this tutorial it is necessary to have access to Google Earth Engine (GEE) platform. GEE is a web-based platform which provides access to a set of public satellite images collections such as Landsat and Sentinel. In addition it provides a JavaScript API and a web based IDE in order to load and process these images. Further information about GEE can be found on the project’s web page: https://earthengine.google.com/

Google Earth Engine web based IDE

Access to Google Earth Engine can be requested using the following link: https://signup.earthengine.google.com/

Once access is granted the web-based code editor can be accessed at: https://code.earthengine.google.com/

Finding Cyanobacteria on Satellite Images

1. Loading and image collection in GEE for a particular world zone

Se start by selecting a geometry which defines the zone of the world in which we want to work. This can be done manually using the top left “draw shape” button on the IDE map or by code defining a geometry object.

Draw Shape button Google Earth Engine
var geometry = ee.Geometry.Polygon(
[[[-56.230183023013296, -34.871850985636634],
[-56.244945901431265, -34.90282920650864],
[-56.22812308648986, -34.927603373018584],
[-56.19791068414611, -34.943083429665684],
[-56.14744223932189, -34.9495560415385],
[-56.09079398492736, -34.94758617027773],
[-56.04478873590392, -34.9163433151602],
[-56.0162929473297, -34.891002536852646],
[-55.98367728570861, -34.87044260721582],
[-56.0162929473297, -34.85213149257432]]]);

Once the geometry polygon is defined, it is useful to center the map at our desired location. This can be done with the following code.

Map.centerObject(geometry, 12);

2. Loading an Image Collection and Filtering by zone

Google Earth Engine provides several datasets to load and process in this case we will work with Sentinel-2 MSI (Multispectral Instrument). As stated on earth engine’s developer page:

Sentinel-2 (S2) is a wide-swath, high-resolution, multispectral imaging mission with a global 5-day revisit frequency. The S2 Multispectral Instrument (MSI) samples 13 spectral bands: visible and NIR at 10 meters, red edge and SWIR at 20 meters, and atmospheric bands at 60 meters spatial resolution. It provides data suitable for assessing state and change of vegetation, soil, and water cover.

We will use the “Surface Reflectance” collection of images using this code:

ee.ImageCollection(“COPERNICUS/S2_SR”)

To load this image collection and filter images for our geometry we use the following code:

var image_collection = ee.ImageCollection("COPERNICUS/S2_SR");
var filtered_collection = image_collection.filterBounds(geometry);

At this point we will have a collection of images where our geometry is included. For this example we are working with a geometry which encloses Montevideo’s shoreline in Uruguay.

3. Selecting Images and overlaying layers on the map

Once the map is centered and the image collection is loaded we can select images to add as layers to our map. We will do this by filtering our collection by date and selecting the first image. We will select one image taken at summer time, specifically at a moment where cyanobacteria alert was raised, and one image from winter, when no alert was done.

var image_with_cyanobacteria = filtered_collection.filterDate(‘2019–01–30’, ‘2019–02–01’).first();
var image_without_cyanobacteria = filtered_collection.filterDate(‘2019–05–16’, ‘2019–05–17’).first();
Image without Cyanobacteria present
Image with Cyanobacteria present

We will use these two images throughout this tutorial to build several visualizations. But first we are going to add these two images on our map.

We can add layers to our map with the following code:

var natural_colors_bands = [‘B4’, ‘B3’, ‘B2’];Map.addLayer(image_with_cyanobacteria, {gamma: 1.3, min: 0, max: 2000, bands: natural_colors_bands}, ‘with cyanobacteria (natural color)’,false);
Map.addLayer(image_without_cyanobacteria, {gamma: 1.3, min: 0, max: 2000, bands: natural_colors_bands}, ‘without cyanobacteria (natural color)’,false);

The result is that we loaded in our map two layers with one image each, one with the presence of cyanobacteria and the other without cyanobacteria.

Layers loaded to our map in the selected zone

*Before loading the images to our map we made sure that no clouds were present in both images.

4. Creating False Color Images.

A useful technique to visualize images with information that is outside the visible spectrum is to create a false color image. For this purpose we will create an image composed of three bands, two of them outside the visible spectrum: we will use RED, NIR and SWIR bands. We will overlay these new images in our map adding more layers.

var red_nir_swir = [‘B4’, ‘B8’, ‘B11’];
Map.addLayer(image_with_cyanobacteria, {gamma: 1.3, min: 0, max: 2000, bands: red_nir_swir}, ‘with cyanobacteria (pseudo color)’,false);
Map.addLayer(image_without_cyanobacteria, {gamma: 1.3, min: 0, max: 2000, bands: red_nir_swir}, ‘without cyanobacteria (pseudo color)’,false);
False color image no Cyanobacteria
False color image with cyanobacteria

It can be clearly seen that creating a false color image using non visible spectrum bands as SWIR and NIR can highlight the algae that indicate the presence of cyanobacteria.

5. Calculating Floating Algae Index (FAI)

Our previous images let us clearly detect the presence of floating algae. However, there is and index specifically designed for this particular purpose called Floating Algae Index (FAI). FAI is a common use image composition index that can be calculated using multi-spectral images and was first proposed in [1]. This index can detect the presence of floating algae on a river, sea or ocean. The formula for FAI:

Where variable Rrc is the Rayleigh-corrected Reflectance. In practice we can use the value provided by the satellite multi spectral instrument for each band since Sentinel 2 Surface Reflectance collection already provides corrected images.

In order to apply this formula to each image we need to define an expression and apply it to both of our target images.

var fai_expression = ‘NIR — ((RED * (835–1613) + SWIR * (664–835))/(664–1613))’;var fai_with_cyanobacteria = image_with_cyanobacteria.expression(
fai_expression, {
‘NIR’: image_with_cyanobacteria.select(‘B8’),
‘RED’: image_with_cyanobacteria.select(‘B4’),
‘SWIR’: image_with_cyanobacteria.select(‘B11’)
});
var fai_without_cyanobacteria = image_without_cyanobacteria.expression(
fai_expression, {
‘NIR’: image_without_cyanobacteria.select(‘B8’),
‘RED’: image_without_cyanobacteria.select(‘B4’),
‘SWIR’: image_without_cyanobacteria.select(‘B11’)
});

6. FAI Image Visualization.

At this point we have created images which have the FAI value for every pixel of our target images. In order to visualize our new images we need to create a pseudo color image and adds it as a layer to our map. To do this we added the following code to our script.

Map.addLayer(fai_with_cyanobacteria, {min: -100, max: 100, palette: ['DC143C', '66CDAA']}, 'FAI (Cyanobacteria)',false);Map.addLayer(fai_without_cyanobacteria, {min: -100, max: 100, palette: ['DC143C', '66CDAA']}, 'FAI (No cyanobacteria)',false);
FAI index for image without Cyanobacteria
FAI index for image with Cyanobacteria

At this point, we can clearly seen that FAI index is useful to segment floating algae, indicative of cyanobacteria on river waters. In the next section we will do some post processing to segment algae floating on waters and generate a segmentation mask.

7. Detected Algae Masking (Segmentation)

We can create a cyanobacteria mask combining a water mask and our FAI generated map. We need to load a water mask for our map we can do this using the GPWv411: Water Mask collection. We can mask our FAI map with the water mask and threshold the values to only select those values which are greater than zero. Here is the code for this part.

Masking the presence of Cyanobacteria.

Final Comments

In this post we explained how to get started with Google Earth Engine by creating a simple example that lets you find the presence of algae indicative of cyanobacteria on river’s waters. We explained how to load an image collection and filter specific images, and also how to load map layers and build different false color and pseudo color images. Finally we showed how to mask images and segment the presence of algae floating on the water.

Bibliography

[1] Hu, C. (2009). A novel ocean color index to detect floating algae in the global oceans. Remote Sensing of Environment, 113(10), 2118–2129.

This tutorial was created by Digital Sense: a Computer Vision & Image Processing Company.

*All the code for this tutorial can be found in the following repository: cyanobacteria-detection-repository

--

--