All Projects → ytarazona → forestools

ytarazona / forestools

Licence: MIT license
Tools for detecting deforestation and forest degradation

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to forestools

piradar
Radar using Red Pitaya for RF: using Raspberry Pi 3 for quad-core radar signal processing
Stars: ✭ 59 (+168.18%)
Mutual labels:  remote-sensing
speckle2void
Speckle2Void: Deep Self-Supervised SAR Despeckling with Blind-Spot Convolutional Neural Networks
Stars: ✭ 31 (+40.91%)
Mutual labels:  remote-sensing
sarbian
We’ve built a plug’n play Operation System (based on Debian Linux) with all the freely and openly available SAR processing software. No knowledge of installation steps needed, just download and get started with SAR data processing. SARbian is free for use in research, education or operational work.
Stars: ✭ 49 (+122.73%)
Mutual labels:  remote-sensing
PyTorch-Segmentation-Zoo
A PyTorch collection of semantic segmentation tools.
Stars: ✭ 33 (+50%)
Mutual labels:  remote-sensing
satproc
🛰️ Python library and CLI tools for processing geospatial imagery for ML
Stars: ✭ 27 (+22.73%)
Mutual labels:  remote-sensing
ee extra
A ninja python package that unifies the Google Earth Engine ecosystem.
Stars: ✭ 42 (+90.91%)
Mutual labels:  remote-sensing
MHCLN
Deep Metric and Hash Code Learning Network for Content Based Retrieval of Remote Sensing Images
Stars: ✭ 30 (+36.36%)
Mutual labels:  remote-sensing
dfc2020 baseline
Simple Baseline for the IEEE GRSS Data Fusion Contest 2020
Stars: ✭ 44 (+100%)
Mutual labels:  remote-sensing
awesome-spectral-indices
A ready-to-use curated list of Spectral Indices for Remote Sensing applications.
Stars: ✭ 357 (+1522.73%)
Mutual labels:  remote-sensing
ChangeOS
ChangeOS: Building damage assessment via Deep Object-based Semantic Change Detection - (RSE 2021)
Stars: ✭ 33 (+50%)
Mutual labels:  remote-sensing
wildfire-forecasting
Forecasting wildfire danger using deep learning.
Stars: ✭ 39 (+77.27%)
Mutual labels:  remote-sensing
whiteboxgui
An interactive GUI for WhiteboxTools in a Jupyter-based environment
Stars: ✭ 94 (+327.27%)
Mutual labels:  remote-sensing
pylandsat
Search, download, and preprocess Landsat imagery 🛰️
Stars: ✭ 49 (+122.73%)
Mutual labels:  remote-sensing
Start maja
To process a Sentinel-2 time series with MAJA cloud detection and atmospheric correction processor
Stars: ✭ 47 (+113.64%)
Mutual labels:  remote-sensing
solar-panel-segmentation
A U-Net for solar panel identification and segmentation
Stars: ✭ 25 (+13.64%)
Mutual labels:  remote-sensing
programming-for-gis-and-rs
Materials for the Intro to Programming for GIS and Remote Sensing Course that I teach at Saint Louis University. They include the updates I made for the spring 2020 and fall 2020 semesters.
Stars: ✭ 61 (+177.27%)
Mutual labels:  remote-sensing
gsky
Distributed Scalable Geospatial Data Server
Stars: ✭ 23 (+4.55%)
Mutual labels:  remote-sensing
SAR2SAR
SAR2SAR: a self-supervised despeckling algorithm for SAR images - Notebook implementation usable on Google Colaboratory
Stars: ✭ 23 (+4.55%)
Mutual labels:  remote-sensing
deepwatermap
a deep model that segments water on multispectral images
Stars: ✭ 81 (+268.18%)
Mutual labels:  remote-sensing
cars
CARS is a dedicated and open source 3D tool to produce Digital Surface Models from satellite imaging by photogrammetry.
Stars: ✭ 147 (+568.18%)
Mutual labels:  remote-sensing

License: MIT Donate PyPI version

forestools

forestools is a Python package that was created to provide tools for monitoring and mapping vegetation cover, especially detecting deforestation. The PVts-Beta approach, a non-seasonal detection approach (time-series-based), is implemented in this package.

IEEE Geoscience and Remote Sensing Letters

Citation

This repository is part of the paper Mapping deforestation using fractions indices and the PVts-beta approach submitted to IEEE Geoscience and Remote Sensing Letters.

Please, to cite the forestools package in publications, use this paper:

Tarazona, Y. (2022). Mapping deforestation using fractions indices and the PVts-beta approach, IEEE Geoscience and Remote Sensing Letters, DOI: 10.1109/LGRS.2021.3137277.

Introduction

forestools is a Python package mainly focused on mapping and monitoring deforestation, although it can be used for monitoring forest degradation or detecting early warnings. The detection algorithm embedded in this package is a non-seasonal detection approach - unlike seasonal algorithms - that does not model the seasonal component of a time series, is intuitive, has only one calibration parameter, and can be run with vegetation indices such as NDVI and EVI, photosynthetic vegetation from CLASlite software, with radar polarizations, and with NDFI fraction indices. In fact, this package includes an algorithm that is capable of obtaining NDFI indices, which until now was only possible to obtain from Google Earth Engine.

forestools is intended for students, professionals, researchers, and organizations dedicated to forest monitoring and assessment, and any public interested in mapping the changes experienced by the different forests on the planet due to anthropogenic disturbances but also to minor natural disturbances.

Installation

To used forestools it is necessary to install first. There are three options:

1. From PyPI

forestools is available on PyPI, so to install it, run this command in your terminal:

pip install forestools

2. Installing from source

It is also possible to install the latest development version directly from the GitHub repository with:

pip install git+https://github.com/ytarazona/forestools

Examples

1. Obtaining NDFI index

Landsat 8 OLI (Operational Land Imager) was used to obtain the NDFI index in this example. This image contain bands: B2, B3, B4, B5, B6, B7. This image will be downloaded using the following codes:

import requests, zipfile
from io import BytesIO

# Defining the zip file URL
url = 'https://github.com/ytarazona/ft_data/raw/main/data/LC08_232066_20190727.zip'

# Split URL to get the file name
filename = url.split('/')[-1]

# Downloading the file by sending the request to the URL
req = requests.get(url)

# extracting the zip file contents
file = zipfile.ZipFile(BytesIO(req.content))
file.extractall()

Once it has been done, let´s obtain NDFI index.

from forestools.ndfiSMA import ndfiSMA
import rasterio
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
np.seterr(divide='ignore', invalid='ignore')

# Read raster bands
imgRas = rasterio.open('LC08_232066_20190727.jp2')
    
# Raster to Numpay arrays
image = imgRas.read()
    
# Obtaining NDFI from Surface Reflectance
ndfi = ndfiSMA(x = image, procesLevel = 'SR')

# Let's define the color palette
palette = mpl.colors.ListedColormap([
            "#FFFFFF","#FFFCFF","#FFF9FF","#FFF7FF","#FFF4FF","#FFF2FF","#FFEFFF","#FFECFF","#FFEAFF","#FFE7FF",
            "#FFE5FF","#FFE2FF","#FFE0FF","#FFDDFF","#FFDAFF","#FFD8FF","#FFD5FF","#FFD3FF","#FFD0FF","#FFCEFF",
            "#FFCBFF","#FFC8FF","#FFC6FF","#FFC3FF","#FFC1FF","#FFBEFF","#FFBCFF","#FFB9FF","#FFB6FF","#FFB4FF",
            "#FFB1FF","#FFAFFF","#FFACFF","#FFAAFF","#FFA7FF","#FFA4FF","#FFA2FF","#FF9FFF","#FF9DFF","#FF9AFF",
            "#FF97FF","#FF95FF","#FF92FF","#FF90FF","#FF8DFF","#FF8BFF","#FF88FF","#FF85FF","#FF83FF","#FF80FF",
            "#FF7EFF","#FF7BFF","#FF79FF","#FF76FF","#FF73FF","#FF71FF","#FF6EFF","#FF6CFF","#FF69FF","#FF67FF",
            "#FF64FF","#FF61FF","#FF5FFF","#FF5CFF","#FF5AFF","#FF57FF","#FF55FF","#FF52FF","#FF4FFF","#FF4DFF",
            "#FF4AFF","#FF48FF","#FF45FF","#FF42FF","#FF40FF","#FF3DFF","#FF3BFF","#FF38FF","#FF36FF","#FF33FF",
            "#FF30FF","#FF2EFF","#FF2BFF","#FF29FF","#FF26FF","#FF24FF","#FF21FF","#FF1EFF","#FF1CFF","#FF19FF",
            "#FF17FF","#FF14FF","#FF12FF","#FF0FFF","#FF0CFF","#FF0AFF","#FF07FF","#FF05FF","#FF02FF","#FF00FF",
            "#FF00FF","#FF0AF4","#FF15E9","#FF1FDF","#FF2AD4","#FF35C9","#FF3FBF","#FF4AB4","#FF55AA","#FF5F9F",
            "#FF6A94","#FF748A","#FF7F7F","#FF8A74","#FF946A","#FF9F5F","#FFAA55","#FFB44A","#FFBF3F","#FFC935",
            "#FFD42A","#FFDF1F","#FFE915","#FFF40A","#FFFF00","#FFFF00","#FFFB00","#FFF700","#FFF300","#FFF000",
            "#FFEC00","#FFE800","#FFE400","#FFE100","#FFDD00","#FFD900","#FFD500","#FFD200","#FFCE00","#FFCA00",
            "#FFC600","#FFC300","#FFBF00","#FFBB00","#FFB700","#FFB400","#FFB000","#FFAC00","#FFA800","#FFA500",
            "#FFA500","#F7A400","#F0A300","#E8A200","#E1A200","#D9A100","#D2A000","#CA9F00","#C39F00","#BB9E00",
            "#B49D00","#AC9C00","#A59C00","#9D9B00","#969A00","#8E9900","#879900","#7F9800","#789700","#709700",
            "#699600","#619500","#5A9400","#529400","#4B9300","#439200","#349100","#2D9000","#258F00","#1E8E00",
            "#168E00","#0F8D00","#078C00","#008C00","#008C00","#008700","#008300","#007F00","#007A00","#007600",
            "#007200","#006E00","#006900","#006500","#006100","#005C00","#005800","#005400","#005000","#004C00"])
            
# Displaying the index
fig, axes = plt.subplots(figsize = (12,12))
img = axes.imshow(ndfi, cmap = palette)
axes.set(title = 'NDFI - Landsat-8 OLI')
plt.colorbar(img, fraction = 0.035, pad = 0.05)
plt.show()

2. Breakpoint in an NDFI series

Here an NDFI series between 2000 and 2019 from -1 to 1.

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

# NDFI series
serie = np.array([0.84, 0.93, 0.89, 0.75, 0.87, 0.89, 0.845, 0.8425, 0.70, 0.89, 0.95,
0.90, 0.94, 0.95, 0.89, 0.805, 0.8025, 0.80, 0.20, -0.40])
              
# Index between 2000 - 2019
time = np.arange('2000', '2020', dtype = 'datetime64[Y]')

# Displaying the series
fig, axes = plt.subplots(figsize = (11,6))
axes.plot(time, serie, marker = '.', ms = 7, linewidth = 0.7, color = 'gray', 
          label ='NDFI series')
axes.set(xlabel = 'Time', ylabel = 'NDFI Value')
axes.legend(loc = "lower left", fontsize = 20)
plt.show()

2.1 Applying a smoothing

Before detecting a breakpoint, it is necessary to apply a smoothing to remove outliers. So, we'll use the smootH function from the forestools package. This function accepts 1d array and 2d array, so that if we are working with time series we will need to convert to array -> serie.to_numpy().

from forestools.smootH import smootH
import numpy as np
import matplotlib.pyplot as plt

# Apply a smoothing
ndfi_smooth = smootH(x = serie)
time = np.arange('2000', '2020', dtype='datetime64[Y]')

# Displaying the series
# Series without smoothing
fig, axes = plt.subplots(figsize = (11,6))
axes.plot(time, serie, marker='.', ms = 7, linewidth = 0.7, color = 'silver', 
          label='NDFI series')
# Series with smoothing
axes.plot(time, ndfi_smooth, marker='.', ms = 7, linewidth = 1, color = 'blue', 
          label='NDFI series - smoothed')
axes.set(xlabel = 'Time', ylabel = 'NDFI Value')
axes.legend(loc="lower left", fontsize = 20)
plt.show()

2.2 Detecting a change

Let's detect change in 2018. For this, we will used the pvts function. First, numpy.ndarray will be used to detect change, and then we will do the same using pandas.core.series.Series.

Although detecting changes using numpy.ndarray is recommended and avoid indexing confusion.

2.2.1 Using numpy.ndarray

Let's use the output of the smootH function (ndfi_smooth), but we'll need to convert to 1d array with ravel().

Parameters:

  • x: smoothed series preferably to optimize detections.
  • startm: monitoring year, index 18 (i.e., year 2018)
  • endm: year of final monitoring, index 18 (i.e., also year 2018)
  • threshold: detection threshold (for NDFI series we will use 5). If you are using PV series, NDVI or EVI series you can use 5, 3 or 3 respectively. Please see Tarazona et al. (2018) for more details.

Note: You can change the detection threshold if you need to.

from forestools.pvts import pvts

# Let's detect change
cd = pvts(x = ndfi_smooth.ravel(), startm = 18, endm = 18, threshold = 5)

# The output
cd

Then, we can visualize the breakpoint in an graphic using the plot function of the forestools package.

from forestools.plot import plot

# Let´s plot the graphic
plt.figure(figsize=(11, 6))
plot(cd, xlabel = 'Index', ylabel = 'NDFI')
plt.show()

If you need to save the image, you can follow these codes.

# Saving the graphic
gra = plot(cd, xlabel = 'Index', ylabel = 'NDFI')
fig = gra.get_figure()
fig.savefig('name.png')

Example of Breakpoint not detected

# Let's detect change
cd = pvts(x = ndfi_smooth.ravel(), startm = 17, endm = 17, threshold = 5) # No change in 2017

# The output is a dictionary
cd
from forestools.plot import plot

# Let´s plot the graphic
plt.figure(figsize=(11, 6))
plot(cd, xlabel = 'Index', ylabel = 'NDFI')
plt.show()

2.2.2 Using pandas.core.series.Series

Let's use again the output of the smootH function (ndfi_smooth), but we'll need to convert to time series.

Parameters:

  • x: smoothed series preferably to optimize detections.
  • startm: monitoring year, '2018-12-31' (i.e., year 2018).
  • endm: year of final monitoring '2018-12-31' (i.e., also year 2018).
  • threshold: for NDFI series we will use $5$.

IMPORTANTE NOTE: Whenever we use pandas.core.series.Series to detect change, we must put both start and end on the last day of the last month of the year. For example, if our monitoring year is 2010, then start = '2010-12-31' and end = '2010-12-31'. If our monitoring period is from 2000 to 2010, then start = '2000-12-31' and end = '2010-12-31'.

from forestools.pvts import pvts
import pandas as pd

# Serie between 2000 - 2019
index = pd.date_range('2000', '2020', freq ='A')
ndfi_serie = pd.Series(ndfi_smooth.ravel(), index = index)

# Let's detect change
cd = pvts(x = ndfi_serie, startm = '2018-12-31', endm = '2018-12-31', threshold = 5)

# The output
cd

Then, we can visualize the breakpoint in an graphic using the plot function.

from forestools.plot import plot

# Let´s plot the graphic
plt.figure(figsize=(11, 6))
plot(cd, xlabel = 'Index', ylabel = 'NDFI')
plt.show()

Example of Breakpoint not detected

# Let's detect change - No change in 2017
cd = pvts(x = ndfi_serie, startm = '2015-12-31', endm = '2015-12-31', threshold = 5) 

# The output is a dictionary
cd
from forestools.plot import plot

# Let´s plot the graphic
plt.figure(figsize=(11, 6))
plot(cd, xlabel = 'Index', ylabel = 'NDFI')
plt.show()

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].