Skip to content

Instantly share code, notes, and snippets.

@franzalex
Last active July 6, 2021 03:02
Show Gist options
  • Save franzalex/a95e227cab9b146a6092 to your computer and use it in GitHub Desktop.
Save franzalex/a95e227cab9b146a6092 to your computer and use it in GitHub Desktop.
Random Forest image classification in R
# Random Forest image classification
# 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")
}
setwd("C:/data/") # set the working directory to the directory where the data is stored
randomForest.classify("multispectral.img", # file name of the unclassified image
"trainingSamples.shp", # point shape file of the locations of the training samples
"Class_Name", # the column in the training samples shape file which contain the class names
"classifiedImage.img" # file name of the classified image
)
@franzalex
Copy link
Author

franzalex commented Apr 7, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment