Random Forest image classification
July 1, 2020 ยท View on GitHub
Adapted from http://gis.stackexchange.com/a/57786/12899
#' Performs a random forest classification of the specified raster. #' #' @param rasterPath The full path to the raster file to be classified. #' @param samplesPath The full path to the .SHP file of the training samples. #' @param samplesCol The column in the training samples shape file that contains the class names. #' @param classifiedPath The full path to the output classified image. #' #' @author Franz Alex Gaisie-Essilfie randomForest.classify <- function(rasterPath, samplesPath, samplesCol="CLASS", classifiedPath=NA){
Install the required packages that aren't already installed
toInstall <- setdiff(c("randomForest", "sp", "rgdal", "raster", "tcltk"), rownames(installed.packages())) if (length(toInstall)) install.packages(toInstall)
Add required libraries
require(randomForest) require(sp) require(rgdal) require(raster)
Ensure we have a valid path to the training samples
if (is.na(samplesPath) || !file.exists(samplesPath)){ shapeFileFilter <- matrix(c("All Files", ".", "Shape Files", "*.shp"), ncol=2, byrow=T) samplesPath <- tcltk::tk_choose.files(caption="Select training samples shape file", filters=shapeFileFilter, multi=F) } if (length(samplesPath) == 0 || !file.exists(samplesPath)) stop("Could not locate training samples.")
Load the training samples
samples <- readOGR(dirname(samplesPath), tools::file_path_sans_ext(basename(samplesPath)))
Ensure we have a valid path to the unclassified image
if (is.na(rasterPath) || !file.exists(rasterPath)){ rasterFilter <- matrix(c("All Files", ".", "TIFF Image", ".tif", "ERDAS IMAGINE", ".img"), ncol=2, byrow=T) rasterPath <- tcltk::tk_choose.files(caption="Select unclassified image", filters=rasterFilter, multi=F) } if (length(rasterPath) == 0 || !file.exists(rasterPath)) stop("Could not locate raster file for classification.")
Read the image to be classified
multispectral <- stack(rasterPath)
Use sample points to extract raster signatures
samples@data <- data.frame(samples@data, extract(multispectral, samples))
Create RandomForest model
rf.mdl <- randomForest(x=samples@data[, names(multispectral)], y=samples@data[, samplesCol], ntree=501, proximity=T, importancce=T)
Ensure we have a valid path to the classified image
if (is.na(classifiedPath) || file.exists(classifiedPath)){ rasterFilter <- paste('{"All Files" {"."}}', '{"TIFF Image" {".tif"}} ', '{"ERDAS IMAGINE" {".img"}}', sep=" ") default <- file.path(dirname(rasterPath), paste(tools::file_path_sans_ext(basename(rasterPath)), "classified", tools::file_ext(rasterPath), sep=".")) classifiedPath <- tcltk::tkgetSaveFile(title="Save classified image as", initialfile=default, filetypes=rasterFilter) if (nchar(classifiedPath <- as.character(classifiedPath)) == 0) stop("No raster file selected for saving classified image.") }
Predict classified raster
predict(multispectral, rf.mdl, filename=classifiedPath, type="response", na.rm=T, overwrite=T, progress="text", datatype="INT2U") }