Skip to content

Commit

Permalink
added ndci and ndre and cloudless mosaic, eobrowserstats (#317)
Browse files Browse the repository at this point in the history
* added ndci and ndre and cloudless mosaic, eobrowserstats

fixed bad cloud filter in ndvi and added 3 new scripts

* changed input bands names to new names

* samples to sample for simple mosaicking

* samples to sample for simple mosaicking

* samples to sample for simple mosaicking

* avoid divison by zero, threshold on ndci, updated fcc and true color

* resolved comments from Jonas

* use index() for ndwi

* Added links, formatting

---------

Co-authored-by: Jonas Viehweger <[email protected]>
  • Loading branch information
matthew-ballard and jonasViehweger committed Jun 12, 2024
1 parent aed657f commit 9090f77
Show file tree
Hide file tree
Showing 20 changed files with 391 additions and 57 deletions.
18 changes: 18 additions & 0 deletions planet_scope/cloudless_mosaic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Cloudless Mosaic, PlanetScope
parent: PlanetScope
grand_parent: Planet
layout: script
permalink: /planet_scope/cloudless_mosaic/
nav_exclude: true
scripts:
- [Visualization, script.js]
---

## General description

The cloudless mosaic script composites together observations across a time range, which is set as 7 days in this script. Pixels which are not clear in the Useable Data Mask (UDM) are removed. There are two options for functions to select which scene to get the pixel from, `getLastObservation` and `getMedian`. `getLastObservation` will put the most recent non cloudy pixel on top. `getMedian` will remove outliers due to shadows or cloud haze that may have been missed by the UDM algorithm.

Below is an example of several PlanetScope scenes being composited across an area that spans several strips and contains gaps when viewed per day. The script returns a continuous image without gaps.

![Cloudless mosaic](fig/fig1.png)
Binary file added planet_scope/cloudless_mosaic/fig/fig1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions planet_scope/cloudless_mosaic/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//VERSION=3
//Cloudless Mosaic with PlanetScope

function setup() {
return {
input: ["red", "green", "blue", "dataMask", "clear"],
output: { bands: 4 },
mosaicking: "ORBIT",
};
}

function preProcessScenes(collections) {
collections.scenes.orbits = collections.scenes.orbits.filter(function (
orbit
) {
var orbitDateFrom = new Date(orbit.dateFrom);
const nAggregationDays = 7;
return (
orbitDateFrom.getTime() >=
collections.to.getTime() - nAggregationDays * 24 * 3600 * 1000
);
});
return collections;
}

function getLastObservation(arr) {
for (let i = arr.length - 1; i >= 0; i--) {
if (arr[i] !== 0) {
// optional check if you are sure all invalid observations are filtered out
return arr[i];
}
}
return 0;
}

function getMedian(sortedValues) {
var index = Math.floor(sortedValues.length / 2);
return sortedValues[index];
}

function evaluatePixel(samples, scenes) {
var reds = [];
var greens = [];
var blues = []; //empty arrays for reds greens and blues
var a = 0; //incrementer

for (var i = 0; i < samples.length; i++) {
//for each sample
var sample = samples[i]; //get current sample
var clear = sample.dataMask && sample.clear; //0 for clouds OR datamask, 1 for neither

if (clear === 1) {
//if not clouds nor datamask
reds[a] = sample.red; //assign values for that sample to the channel arrays
blues[a] = sample.blue;
greens[a] = sample.green;
a = a + 1; //increment a to represent that at this specific pixel, a value was detected
}
}

var rValue;
var gValue;
var bValue;

if (a > 0) {
rValue = getMedian(reds); // or call getLastObservation - which is less guaranteed to remove hazy images
gValue = getMedian(greens);
bValue = getMedian(blues);
transparency = 1;
} else {
rValue = 1;
gValue = 1;
bValue = 1;
transparency = 0;
}
return [rValue / 3000, gValue / 3000, bValue / 3000, transparency];
}
17 changes: 11 additions & 6 deletions planet_scope/false_color/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
//False Color

function setup() {
return {
input: ["nir", "green", "blue"],
output: { bands: 3 }
};
return {
input: ["nir", "green", "blue", "dataMask"],
output: { bands: 4 },
};
}

function evaluatePixel(sample) {
return [sample.nir / 3000, sample.green / 3000, sample.blue / 3000];
}
return [
sample.nir / 3000,
sample.green / 3000,
sample.blue / 3000,
sample.dataMask,
];
}
29 changes: 29 additions & 0 deletions planet_scope/ndci/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Normalized difference chlorophyll index, PlanetScope
parent: PlanetScope
grand_parent: Planet
layout: script
permalink: /planet_scope/ndci/
nav_exclude: true
scripts:
- [Visualization, script.js]
- [EO Browser, eob.js]
---

## General description

The normalized difference chlorophyll index, abbreviated NDCI, is defined as

$$NDCI := \mathtt{Index}(rededge,red) = \frac{rededge-red}{rededge+red}$$

This is an example script which can be used with EO Browser and is configured to return statistics in a format which can be used with the statistical info chart. For more information, see <a href = "https://www.sentinel-hub.com/faq/how-configure-your-layers-statistical-info-eo-browser/"> How Can I Configure My Layers For Statistical Information In EO Browser?</a>

## Representative image

NDCI over Lake Elsinore in California.

<img src="fig/fig1.png" height="300">


## References
Sachidananda Mishra, Deepak R. Mishra (2012) Normalized difference chlorophyll index: A novel model for remote estimation of chlorophyll-a concentration in turbid productive waters, Remote Sensing of Environment, 117:394-406, DOI: [10.1016/j.rse.2011.10.016](https://doi.org/10.1016/j.rse.2011.10.016)
56 changes: 56 additions & 0 deletions planet_scope/ndci/eob.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//VERSION=3
//PlanetScope NDCI EO Browser

function setup() {
return {
input: [
{
bands: ["red", "rededge", "green", "blue", "dataMask", "clear"],
},
],
output: [
{ id: "default", bands: 4 },
{ id: "index", bands: 1, sampleType: "FLOAT32" },
{ id: "eobrowserStats", bands: 2, sampleType: "FLOAT32" },
{ id: "dataMask", bands: 1 },
],
};
}

function evaluatePixel(sample) {
let ndci = index(sample.rededge, sample.red);
const clear = sample.dataMask && sample.clear;

let ndci_colored = colorBlend(
ndci,
[0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
[
[0, 0, 1], // Blue
[0, 0, 1], // Blue
[0, 1, 0], // Green
[0, 0.8, 0], // Yellow-green
[0, 0.6, 0], // Darker green
[0, 0.4, 0], // Even darker green
]
);

// Normalize true color bands
let true_color = [
sample.red / 3000,
sample.green / 3000,
sample.blue / 3000,
];

// Threshold value for switching between true color and ndci_map
let threshold = 0.3;

// Conditional logic to select either true_color or ndci_map
let ndci_colored_masked = ndci < threshold ? true_color : ndci_colored;

return {
default: [...ndci_colored_masked, clear],
index: [ndci],
eobrowserStats: [ndci, !clear],
dataMask: [sample.dataMask],
};
}
Binary file added planet_scope/ndci/fig/fig1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions planet_scope/ndci/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//PlanetScope NDCI
let ndci = index(rededge, red);

return colorBlend(
ndci,
[0.0, 0.5, 1.0],
[
[1, 0, 0],
[1, 1, 0],
[0.1, 0.31, 0],
]
);
28 changes: 28 additions & 0 deletions planet_scope/ndre/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: Normalized difference red edge index, PlanetScope
parent: PlanetScope
grand_parent: Planet
layout: script
permalink: /planet_scope/ndre/
nav_exclude: true
scripts:
- [Visualization, script.js]
- [EO Browser, eob.js]
---

## General description

The normalized difference red edge index, abbreviated NDRE, is defined as

$$NDRE := \mathtt{Index}(nir,rededge) = \frac{nir-rededge}{nir+rededge}$$

This is an example script which can be used with EO Browser and is configured to return statistics in a format which can be used with the statistical info chart. For more information, see <a href = "https://www.sentinel-hub.com/faq/how-configure-your-layers-statistical-info-eo-browser/"> How Can I Configure My Layers For Statistical Information In EO Browser?</a>

## Description of representative images

NDRE of agriculture fields in California.

<img src="fig/fig1.png" height="300">

## References
[1] Wikipedia, [Normalized Difference Vegetation Index](https://en.wikipedia.org/wiki/Normalized_Difference_Red_Edge_Index).
40 changes: 40 additions & 0 deletions planet_scope/ndre/eob.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//VERSION=3
//PlanetScope NDRE EO Browser

function setup() {
return {
input: [
{
bands: ["nir", "rededge", "dataMask", "clear"],
},
],
output: [
{ id: "default", bands: 4 },
{ id: "index", bands: 1, sampleType: "FLOAT32" },
{ id: "eobrowserStats", bands: 2, sampleType: "FLOAT32" },
{ id: "dataMask", bands: 1 },
],
};
}

function evaluatePixel(sample) {
let ndre = index(sample.nir, sample.rededge);
const clear = sample.dataMask && sample.clear;

let ndre_colored = colorBlend(
ndre,
[0.0, 0.5, 1.0],
[
[1, 0, 0],
[1, 1, 0],
[0.1, 0.31, 0],
]
);

return {
default: [...ndre_colored, clear],
index: [ndre],
eobrowserStats: [ndre, !clear],
dataMask: [sample.dataMask],
};
}
Binary file added planet_scope/ndre/fig/fig1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions planet_scope/ndre/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//PlanetScope NDRE
let ndre = index(nir, rededge);

return colorBlend(
ndre,
[0.0, 0.5, 1.0],
[
[1, 0, 0],
[1, 1, 0],
[0.1, 0.31, 0],
]
);
4 changes: 2 additions & 2 deletions planet_scope/ndvi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ $$NDVI := \mathtt{Index}(nir,red) = \frac{nir-red}{nir+red}.$$

This is an example script which can be used with EO Browser and is configured to return statistics in a format which can be used with the statistical info chart. For more information, see <a href = "https://www.sentinel-hub.com/faq/how-configure-your-layers-statistical-info-eo-browser/"> How Can I Configure My Layers For Statistical Information In EO Browser?</a>

## Description of representative images
## Representative images

NDVI of agriculture fields in Iowa.

![NDVI of agriculture fields in Iowa](fig/fig1.png)
<img src="fig/fig1.png" height="300">

## References
[1] Wikipedia, [Normalized Difference Vegetation Index](https://en.wikipedia.org/wiki/Normalized_Difference_Vegetation_Index). Accessed on October 4th 2017.
65 changes: 32 additions & 33 deletions planet_scope/ndvi/eob.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
//VERSION=3
//NDVI
//PlanetScope NDVI EO Browser

function setup() {
return {
input: [{
bands: [
"red",
"nir",
"dataMask",
"clear"
]
}],
output: [
{ id: "default", bands: 4 },
{ id: "index", bands: 1, sampleType: "FLOAT32" },
{ id: "eobrowserStats", bands: 2, sampleType: "FLOAT32" },
{ id: "dataMask", bands: 1 },
]
}
return {
input: [
{
bands: ["red", "nir", "dataMask", "clear"],
},
],
output: [
{ id: "default", bands: 4 },
{ id: "index", bands: 1, sampleType: "FLOAT32" },
{ id: "eobrowserStats", bands: 2, sampleType: "FLOAT32" },
{ id: "dataMask", bands: 1 },
],
};
}

function evaluatePixel(samples) {
let ndvi = (samples.nir - samples.red) / (samples.nir + samples.red);
const indexVal = samples.dataMask === 1 ? ndvi : NaN;
const clear = samples.dataMask * samples.clear;
function evaluatePixel(sample) {
let ndvi = index(sample.nir, sample.red);
const clear = sample.dataMask && sample.clear;

let id_default = colorBlend(ndvi, [0.0, 0.5, 1.0],
[
[1, 0, 0, clear],
[1, 1, 0, clear],
[0.1, 0.31, 0, clear],
])
let ndvi_colored = colorBlend(
ndvi,
[0.0, 0.5, 1.0],
[
[1, 0, 0],
[1, 1, 0],
[0.1, 0.31, 0],
]
);

return {
default: id_default,
index: [indexVal],
eobrowserStats: [indexVal, samples.clear],
dataMask: [samples.dataMask],
};
return {
default: [...ndvi_colored, clear],
index: [ndvi],
eobrowserStats: [ndvi, +!clear],
dataMask: [sample.dataMask],
};
}
Loading

0 comments on commit 9090f77

Please sign in to comment.