{"id":15051480,"url":"https://github.com/bleutner/rstoolbox","last_synced_at":"2025-04-14T08:55:06.689Z","repository":{"id":16703275,"uuid":"19460005","full_name":"bleutner/RStoolbox","owner":"bleutner","description":"Remote Sensing Data Analysis in R 🛰","archived":false,"fork":false,"pushed_at":"2025-02-05T22:15:50.000Z","size":215541,"stargazers_count":277,"open_issues_count":29,"forks_count":82,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-04-07T01:11:12.714Z","etag":null,"topics":["cran","ggplot2","land-cover-mapping","r","r-package","remote-sensing","spectral-unmixing","supervised-classification","unsupervised-classification"],"latest_commit_sha":null,"homepage":"","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bleutner.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-05-05T15:08:49.000Z","updated_at":"2025-04-03T08:59:03.000Z","dependencies_parsed_at":"2023-09-24T16:45:09.508Z","dependency_job_id":"968776b5-fed9-4132-85ae-66637654ebd7","html_url":"https://github.com/bleutner/RStoolbox","commit_stats":{"total_commits":794,"total_committers":14,"mean_commits":"56.714285714285715","dds":0.2896725440806045,"last_synced_commit":"e7587e2f9b150cc09a8982580c0f4552750d11dc"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bleutner%2FRStoolbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bleutner%2FRStoolbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bleutner%2FRStoolbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bleutner%2FRStoolbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bleutner","download_url":"https://codeload.github.com/bleutner/RStoolbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248852109,"owners_count":21171839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cran","ggplot2","land-cover-mapping","r","r-package","remote-sensing","spectral-unmixing","supervised-classification","unsupervised-classification"],"created_at":"2024-09-24T21:35:52.152Z","updated_at":"2025-04-14T08:55:06.657Z","avatar_url":"https://github.com/bleutner.png","language":"R","readme":"# RStoolbox \u003cimg src=\"man/figures/logo.png\" align=\"right\" width=\"150\" /\u003e\n\n[![CI](https://github.com/bleutner/RStoolbox/actions/workflows/rcmdcheck.yaml/badge.svg)](https://github.com/bleutner/RStoolbox/actions/workflows/rcmdcheck.yaml)\n[![CRAN version](https://www.r-pkg.org/badges/version/RStoolbox)](https://CRAN.R-project.org/package=RStoolbox)\n[![codecov](https://codecov.io/gh/bleutner/RStoolbox/branch/master/graph/badge.svg)](https://app.codecov.io/gh/bleutner/RStoolbox)\n[![Downloads](https://cranlogs.r-pkg.org/badges/grand-total/RStoolbox)](https://cranlogs.r-pkg.org/badges/grand-total/RStoolbox)\n\n`RStoolbox` is an R package providing a wide range of tools for your every-day remote sensing processing needs. The available tool-set covers many aspects from data import, pre-processing, data analysis, image classification and graphical display. `RStoolbox` builds upon the `terra` package, which makes it suitable for processing large data-sets even on smaller workstations.\n\nFind out more on the [`RStoolbox` webpage](https://bleutner.github.io/RStoolbox/).\n\n## Installation\nThe package is available on CRAN and can be installed as usual via\n\n```R\ninstall.packages(\"RStoolbox\")\n```\n\nTo install the latest version from GitHub you need to have r-base-dev (Linux) or Rtools (Windows) installed.\nThen run the following lines:\n\n```R\nlibrary(devtools)\ninstall_github(\"bleutner/RStoolbox\")\n```\n    \n## Get started\n\n`RStoolbox` implements a variety of [remote sensing methods and workflows](https://bleutner.github.io/RStoolbox/reference/RStoolbox.html). Below are a few examples to get started. Further examples can be found in the [documentation of the respective functions](https://bleutner.github.io/RStoolbox/reference/index.html).\n\n### Example 1: Classifications\n\nThe example below shows an unsupervised classification workflow based on *kmeans* clustering:\n\n``` r\nlibrary(RStoolbox)\n\n# unsupervised classification with 3 classes\nuc \u003c- unsuperClass(lsat, nClasses = 3)\n\n# plot result using ggplot\nggR(uc$map, geom_raster = T, forceCat = T) +\n  scale_fill_manual(values = c(\"darkgreen\", \"blue\", \"sandybrown\"))\n```\n\n![](https://i.imgur.com/aUqzcxV.png)\u003c!-- --\u003e\n\n\nIf training data are available, e.g. labeled polygons, `RStoolbox` can be used to conduct a supervised classification. The workflow below employs *randomForest* to train a classification model:\n\n``` r\nlibrary(RStoolbox)\nlibrary(caret)\nlibrary(randomForest)\nlibrary(ggplot2)\nlibrary(terra)\n\n# example: training data from digitized polygons\ntrain \u003c- readRDS(system.file(\"external/trainingPolygons_lsat.rds\", package=\"RStoolbox\"))\n\n# plot input data\nggRGB(lsat, r = 3, g = 2, b=1, stretch = \"lin\") +\n  geom_sf(data = train, aes(fill = class)) + \n  scale_fill_manual(values = c(\"yellow\", \"sandybrown\", \"darkgreen\", \"blue\"))\n#\u003e Coordinate system already present. Adding new coordinate system, which will\n#\u003e replace the existing one.\n```\n\n![](https://i.imgur.com/s071ieD.png)\u003c!-- --\u003e\n\n``` r\n\n# fit random forest (splitting training into 70\\% training data, 30\\% validation data)\nsc \u003c- superClass(lsat, trainData = train, responseCol = \"class\",\n                 model = \"rf\", tuneLength = 1, trainPartition = 0.7)\n\n# print model performance and confusion matrix\nsc$modelFit\n#\u003e [[1]]\n#\u003e   TrainAccuracy TrainKappa method\n#\u003e 1     0.9992293  0.9988032     rf\n#\u003e \n#\u003e [[2]]\n#\u003e Cross-Validated (5 fold) Confusion Matrix \n#\u003e \n#\u003e (entries are average cell counts across resamples)\n#\u003e  \n#\u003e             Reference\n#\u003e Prediction   cleared fallen_dry forest water\n#\u003e   cleared      141.6        0.0    0.0   0.0\n#\u003e   fallen_dry     0.0       22.0    0.0   0.0\n#\u003e   forest         0.4        0.0  255.0   0.0\n#\u003e   water          0.0        0.0    0.0  99.4\n#\u003e                             \n#\u003e  Accuracy (average) : 0.9992\n\n# plotting: convert class IDs to class labels (factorize) and plot\nr \u003c- as.factor(sc$map)\nlevels(r) \u003c- data.frame(ID = 1:4, class_supervised = levels(train$class))\nggR(r, geom_raster = T, forceCat = T) + scale_fill_manual(values = c(\"yellow\", \"sandybrown\", \"darkgreen\", \"blue\"))\n```\n\n![](https://i.imgur.com/uYgRj03.png)\u003c!-- --\u003e\n\n\u003csup\u003eCreated on 2024-04-19 with [reprex v2.1.0](https://reprex.tidyverse.org)\u003c/sup\u003e\n\n### Example 2: Spectral Unmixing\n\n`RStoolbox` offers spectral unmixing by implementing the Multiple Endmember Spectral Mixture Analysis (MESMA) approach for estimating fractions of spectral classes, such as spectra of surfaces or materials, on a sub-pixel scale. The following workflow shows a simple Spectral Mixture Analysis (SMA) with single endmembers per class, extracted from the `lsat` example image by cell id:\n\n``` r\nlibrary(RStoolbox)\nlibrary(terra)\n\n#  to perform a SMA, use a single endmember per class, row by row:\nem \u003c- data.frame(lsat[c(5294, 47916)])\nrownames(em) \u003c- c(\"forest\", \"water\")\n\n# umix the lsat image\nprobs \u003c- mesma(img = lsat, em = em)\nplot(probs)\n```\n\n![](https://i.imgur.com/OqZVYc2.png)\u003c!-- --\u003e\n\nInstead, one can define multiple endmembers per class to conduct a Multiple Endmember Spectral Mixture Analysis (MESMA):\n\n``` r\nlibrary(RStoolbox)\nlibrary(terra)\n\n\n# to perform a MESMA, use multiple endmembers per class, differntiating them\n# by a column named 'class':\nem \u003c- rbind(\n  data.frame(lsat[c(4155, 17018, 53134, 69487, 83704)], class = \"forest\"),\n  data.frame(lsat[c(22742, 25946, 38617, 59632, 67313)], class = \"water\")\n)\n\n# unmix the lsat image\nprobs \u003c- mesma(img = lsat, em = em)\nplot(probs)\n```\n\n![](https://i.imgur.com/0PQGZa2.png)\u003c!-- --\u003e\n\n``` r\n# MESMA can also be performed on more than two endmember classes:\nem \u003c- rbind(\n  data.frame(lsat[c(4155, 17018, 53134, 69487, 83704)], class = \"forest\"),\n  data.frame(lsat[c(22742, 25946, 38617, 59632, 67313)], class = \"water\"),\n  data.frame(lsat[c(4330, 1762, 1278, 1357, 17414)], class = \"shortgrown\")\n)\n\n# unmix the lsat image\nprobs \u003c- mesma(img = lsat, em = em)\nplot(probs)\n```\n\n![](https://i.imgur.com/a7QACjl.png)\u003c!-- --\u003e\n\n### Example 3: Cloud Masking\n\n`RStoolbox` comes with a suite of pre-processing functions, including `cloudMask` to identify clouds in optical satellite imagery:\n\n``` r\nlibrary(ggplot2)\n\n# lsat example scene, with two tiny clouds in the east\nggRGB(lsat, stretch = \"lin\")\n```\n\n![](https://i.imgur.com/NJ86OKE.png)\u003c!-- --\u003e\n\n``` r\n# calculate cloud index\ncldmsk    \u003c- cloudMask(lsat, blue = 1, tir = 6)\nggR(cldmsk, 2, geom_raster = TRUE) \n```\n\n![](https://i.imgur.com/bvgUd74.png)\u003c!-- --\u003e\n\n``` r\n# mask by threshold, region-growing around the core cloud pixels\ncldmsk_final \u003c- cloudMask(cldmsk, threshold = 0.1, buffer = 5) \n\n## plot cloudmask \nggRGB(lsat, stretch = \"lin\") +\n  ggR(cldmsk_final[[1]], ggLayer = TRUE, forceCat = TRUE, geom_raster = TRUE) +\n  scale_fill_manual(values = c(\"red\"), na.value = NA)\n#\u003e Warning: Removed 88752 rows containing missing values or values outside the scale range\n#\u003e (`geom_raster()`).\n```\n\n![](https://i.imgur.com/wwjXK3v.png)\u003c!-- --\u003e\n\n\n### Example 4: Radiometric and atmospheric correction\n\nWith `radCor`, users can compute radiometric and simple atmospheric corrections (based on dark object substraction):\n\n\n``` r\nlibrary(terra)\n\n# import Landsat meta data\nmtlFile  \u003c- system.file(\"external/landsat/LT52240631988227CUB02_MTL.txt\", package=\"RStoolbox\")\nmetaData \u003c- readMeta(mtlFile)\nlsat_t \u003c- stackMeta(mtlFile)\n\n# convert DN to top of atmosphere reflectance and brightness temperature\nlsat_ref \u003c- radCor(lsat_t, metaData = metaData, method = \"apref\")\n\n# correct DN to at-surface-reflecatance with DOS (Chavez decay model)\nlsat_sref \u003c- radCor(lsat_t, metaData = metaData)\n\n# correct DN to at-surface-reflecatance with simple DOS and automatic haze estimation\nhazeDN    \u003c- estimateHaze(lsat_t, hazeBands = 1:4, darkProp = 0.01, plot = FALSE)\nlsat_sref \u003c- radCor(lsat_t, metaData = metaData, method = \"sdos\",\n                    hazeValues = hazeDN, hazeBands = 1:4)\n\n# plot result\nggRGB(lsat_sref, r = 3, g = 2, b = 1, stretch = \"lin\")\n```\n\n![](https://i.imgur.com/IEi9own.png)\u003c!-- --\u003e\n\n\n\u003csup\u003eCreated on 2024-04-19 with [reprex v2.1.0](https://reprex.tidyverse.org)\u003c/sup\u003e\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbleutner%2Frstoolbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbleutner%2Frstoolbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbleutner%2Frstoolbox/lists"}