library(tidyverse)
library(sf)
library(terra)
The following materials are modified from curriculum developed by Earth Lab and the Raster Analysis with terra
book.
1. Background
In Lab #6, you explored various band combinations and plotted false color images with tm_rgb()
from {tmap}
. False color images allow you to visually highlight specific features in an image that may otherwise not be readily discernible. To add to your toolbelt, you will now be plotting false color images with plotRGB()
from {terra}
.
You can plot false color composites with ggplot2
too! Check out this tutorial.
The plotRGB()
function allows you to apply a stretch to normalize the colors in an image. You can either apply a linear stretch or histogram equalization. A linear stretch distributes the values across the entire histogram range defined by the max/min lower bounds of the original raster. A histogram equalization stretches dense parts of the histogram and condenses sparse parts.
But why would you want to normalize the colors in an image?
“When the range of pixel brightness values is closer to 0, a darker image is rendered by default. You can stretch the values to extend to the full 0-255 range of potential values to increase the visual contrast of the image. When the range of pixel brightness values is closer to 255, a lighter image is rendered by default. You can stretch the values to extend to the full 0-255 range of potential values to increase the visual contrast of the image.”
You are provided Landsat data for the site of the Cold Springs fire that occurred near Nederland, CO. The fire occurred from July 10-14, 2016 and the Landsat images are from June 5, 2016 (pre-fire) and August 8, 2016 (post-fire). The multispectral bands, wavelength range, and associated spatial resolution of the first 7 bands in the Landsat 8 sensor are listed below.
Band | Wavelength range (nanometers) | Spatial Resolution (m) | Spectral Width (nm) |
---|---|---|---|
Band 1 - Coastal aerosol | 430 - 450 | 30 | 2.0 |
Band 2 - Blue | 450 - 510 | 30 | 6.0 |
Band 3 - Green | 530 - 590 | 30 | 6.0 |
Band 4 - Red | 640 - 670 | 30 | 0.03 |
Band 5 - Near Infrared (NIR) | 850 - 880 | 30 | 3.0 |
Band 6 - Short-Wave Infrared 1 (SWIR1) | 1570 - 1650 | 30 | 8.0 |
Band 7 - Short-Wave Infrared 2 (SWIR2) | 2110 - 2290 | 30 | 18 |
2. Get Started
- Create an
.Rproj
as your version controlled project for Week 6 - Create a Quarto document inside your
.Rproj
- Download this data folder from Google Drive and move it inside your
.Rproj
- Load all necessary packages, read spatial objects, and define
nbr_fun
function
# Set directory for folder
<- here::here("data", "LC80340322016189-SC20170128091153")
pre_fire_dir
# Create a list of all images that have the extension .tif and contain the word band
<- list.files(pre_fire_dir,
pre_fire_bands pattern = glob2rx("*band*.tif$"),
full.names = TRUE)
# Create a raster stack
<- rast(pre_fire_bands)
pre_fire_rast
# Read mask raster
<- rast(here::here("data", "LC80340322016189-SC20170128091153", "LC80340322016189LGN00_cfmask_crop.tif")) pre_mask
# Set directory for folder
<- here::here("data", "LC80340322016205-SC20170127160728")
post_fire_dir
# Create a list of all images that have the extension .tif and contain the word band
<- list.files(post_fire_dir,
post_fire_bands pattern = glob2rx("*band*.tif$"),
full.names = TRUE)
# Create a raster stack
<- rast(post_fire_bands)
post_fire_rast
# Read mask raster
<- rast(here::here("data", "LC80340322016189-SC20170128091153", "LC80340322016205LGN00_cfmask_crop.tif")) post_mask
<- function(nir, swir2){
nbr_fun - swir2)/(nir + swir2)
(nir }
3. Your Task
Now, to meet this week’s learning objectives, your task:
- Rename the bands of the
pre_fire
andpost_fire
rasters usingnames()
Next, for each of the pre_fire
and post_fire
rasters…
- Mask out clouds and shadows with the
pre_mask
andpost_mask
rasters
- Hint: Set
mask > 0
toNA
“Extreme cloud cover and shadows can make the data in those areas, un-usable given reflectance values are either washed out (too bright - as the clouds scatter all light back to the sensor) or are too dark (shadows which represent blocked or absorbed light)” (Earth Lab)
- Plot a true color composite using
plotRGB()
- Map the red band to the red channel, green to green, and blue to blue
- Apply a linear stretch
“lin”
or histogram equalization“hist”
To make an informed choice about whether to apply a linear stretch or histogram equalization, check the distribution of reflectance values of the bands in each raster:
# View histogram for each band
hist(pre_fire_rast,
maxpixels = ncell(pre_fire_rast),
col = "orange")
- Plot two false color composite using
plotRGB()
- Map the SWIR2 band to the red channel, NIR to green, and green to blue
- Apply a linear stretch
“lin”
or histogram equalization“hist”
“Combining SWIR, NIR, and Red bands highlights the presence of vegetation, clear-cut areas and bare soils, active fires, and smoke; in a false color image” (EOS Data Analytics)
- Calculate the normalized burn ratio (NBR)
- Hint: Use
lapp()
like you previously did for NDVI and NDWI in Week 4
Let’s bring it home!
- Find the difference NBR, where \(dNBR = prefireNBR - postfireNBR\)
- Plot the
dnBR
raster
- Bonus Challenge: Use
classify()
to assign the severity levels below:
Severity Level | dNBR Range |
---|---|
Enhanced Regrowth | < -.1 |
Unburned | -.1 to +.1 |
Low Severity | +.1 to +.27 |
Moderate Severity | +.27 to +.66 |
High Severity | > .66 |