Skip to content

Instantly share code, notes, and snippets.

@franzalex
Last active July 6, 2021 03:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • 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
)
@SirLotus
Copy link

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")
}

i'm sorry, i don't undestand ... classifiedPath... where i find it? because, you use that only in the ultimate script... and if i use that, R tell me that don't find classifiedPath... i need to know what is it that...

@franzalex
Copy link
Author

@SirLotus

i'm sorry, i don't undestand ... classifiedPath... where i find it? because, you use that only in the ultimate script... and if i use that, R tell me that don't find classifiedPath... i need to know what is it that...

The classifiedimage parameter is the path to the file that the output should be saved to. You can specify just the file name or the full path (including drive and parent directory). If you specify a relative path (i.e. just the file name), R will save the file in the current working directory. Specifying a relative path (i.e. drive, directory, file name), then R will save the file to the the path you specified.

I hope I clarified the issue for you.

@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