Commit 10a08758 authored by Monnet Jean-Matthieu's avatar Monnet Jean-Matthieu
Browse files

WIP 4.0.5

parent e7c38612
No related merge requests found
Showing with 188 additions and 181 deletions
+188 -181
Package: lidaRtRee Package: lidaRtRee
Type: Package Type: Package
Version: 4.0.4 Version: 4.0.5
Title: Forest Analysis with Airborne Laser Scanning (LiDAR) Data Title: Forest Analysis with Airborne Laser Scanning (LiDAR) Data
Date: 2022-09-14 Date: 2023-04-05
Authors@R: c( Authors@R: c(
person("Jean-Matthieu", "Monnet", email = "jean-matthieu.monnet@inrae.fr", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-9948-9891")), person("Jean-Matthieu", "Monnet", email = "jean-matthieu.monnet@inrae.fr", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-9948-9891")),
person("Pascal", "Obstétar", email = "pascal.obstetar@onf.fr", role = c("ctb"), comment = c(ORCID = "0000-0002-2811-7548"))) person("Pascal", "Obstétar", email = "pascal.obstetar@onf.fr", role = c("ctb"), comment = c(ORCID = "0000-0002-2811-7548")))
......
This diff is collapsed.
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
# Changelog # Changelog
4.0.5 (April 2023) max.width parameter in function maxima_detection is expect to be in raster units if a SpatRaster is provided; default value is now 11. Function tree_segmentation now expects arguments passed to sub function as ... rather than names arguments; default values for those sub-functions were modified to match with the default values which were used in tree_segmentation ; a warning is issued in case max.width argument (passed to maxima_detection) is not consistent with the dmin or dprop arguments (passed to maxima_selection).
4.0.3 (July 2022) fixes the number of decimals for WKT coordinates of crown in function `tree_extraction`. 4.0.3 (July 2022) fixes the number of decimals for WKT coordinates of crown in function `tree_extraction`.
4.0.2 (July 2022) adds a global function `tree_detection` which includes both the segmentation and extraction, and can be applied to SpatRaster, LAS or LAS-catalog objects. The function `gap_detection` now also accepts LAS and LAS-catalog objects as input. 4.0.2 (July 2022) adds a global function `tree_detection` which includes both the segmentation and extraction, and can be applied to SpatRaster, LAS or LAS-catalog objects. The function `gap_detection` now also accepts LAS and LAS-catalog objects as input.
......
...@@ -28,7 +28,7 @@ chm_cim <- raster2Cimg(chm_chablais3) ...@@ -28,7 +28,7 @@ chm_cim <- raster2Cimg(chm_chablais3)
chm_cim_filt <- dem_filtering(chm_cim, chm_cim_filt <- dem_filtering(chm_cim,
nl_filter = "Closing", nl_filter = "Closing",
nl_size = 3, nl_size = 3,
sigmap = 0 sigma = 0
)$non_linear_image )$non_linear_image
# convert to SpatRaster # convert to SpatRaster
......
...@@ -8,8 +8,9 @@ dem_filtering( ...@@ -8,8 +8,9 @@ dem_filtering(
dem, dem,
nl_filter = "Closing", nl_filter = "Closing",
nl_size = 5, nl_size = 5,
sigmap = 0.3, sigma = 0.3,
padding = TRUE padding = TRUE,
sigmap = NULL
) )
} }
\arguments{ \arguments{
...@@ -19,11 +20,12 @@ SpatRaster object (e.g. obtained with \code{\link[terra]{rast}})} ...@@ -19,11 +20,12 @@ SpatRaster object (e.g. obtained with \code{\link[terra]{rast}})}
\item{nl_filter}{string. type of non-linear filter to apply: "None", "Closing" \item{nl_filter}{string. type of non-linear filter to apply: "None", "Closing"
or "Median"} or "Median"}
\item{nl_size}{numeric. kernel width in pixel for non-linear filtering} \item{nl_size}{numeric. kernel width in pixels for non-linear filtering}
\item{sigmap}{numeric or matrix. if a single number is provided, sigmap is \item{sigma}{numeric or matrix. If a single number is provided, \code{sigma} is
the standard deviation of the Gaussian filter in pixel, 0 corresponds to no the standard deviation of the Gaussian filter, 0 corresponds to no
smoothing. In case of matrix, the first column corresponds to the standard smoothing. Unit is pixel in case \code{dem} is a cimg object, SpatRaster units
otherwise. In case of a matrix, the first column corresponds to the standard
deviation of the filter, and the second to thresholds for image values (e.g. deviation of the filter, and the second to thresholds for image values (e.g.
a filter of standard deviation specified in line \code{i} is applied to pixels a filter of standard deviation specified in line \code{i} is applied to pixels
in image which values are between thresholds indicated in lines \code{i} and in image which values are between thresholds indicated in lines \code{i} and
...@@ -31,6 +33,10 @@ in image which values are between thresholds indicated in lines \code{i} and ...@@ -31,6 +33,10 @@ in image which values are between thresholds indicated in lines \code{i} and
\item{padding}{boolean. Whether image should be padded by duplicating edge \item{padding}{boolean. Whether image should be padded by duplicating edge
values before filtering to avoid border effects} values before filtering to avoid border effects}
\item{sigmap}{deprecated (numeric or matrix). (old name for \code{sigma} parameter,
retained for backward compatibility, overwrites \code{sigma} if provided, unit is
pixel whatever the class of \code{dem})}
} }
\value{ \value{
A list of two cimg objects or a SpatRaster object with image after non-linear A list of two cimg objects or a SpatRaster object with image after non-linear
...@@ -50,13 +56,13 @@ data(chm_chablais3) ...@@ -50,13 +56,13 @@ data(chm_chablais3)
chm_chablais3 <- terra::rast(chm_chablais3) chm_chablais3 <- terra::rast(chm_chablais3)
# filtering with median and Gaussian smoothing # filtering with median and Gaussian smoothing
im <- dem_filtering(chm_chablais3, nl_filter = "Median", nl_size = 3, sigmap = 0.8) im <- dem_filtering(chm_chablais3, nl_filter = "Median", nl_size = 3, sigma = 0.8)
# filtering with median filter and value-dependent Gaussian smoothing # filtering with median filter and value-dependent Gaussian smoothing
# (less smoothing for values between 0 and 15) # (less smoothing for values between 0 and 15)
im2 <- dem_filtering(chm_chablais3, im2 <- dem_filtering(chm_chablais3,
nl_filter = "Median", nl_size = 3, nl_filter = "Median", nl_size = 3,
sigmap = cbind(c(0.2, 0.8), c(0, 15)) sigma = cbind(c(0.2, 0.8), c(0, 15))
) )
# plot original image # plot original image
......
...@@ -14,15 +14,15 @@ SpatRaster object (e.g. obtained with \code{\link[terra]{rast}})} ...@@ -14,15 +14,15 @@ SpatRaster object (e.g. obtained with \code{\link[terra]{rast}})}
object, \code{dem.res} is extracted from the object by \code{\link[terra]{res}}} object, \code{dem.res} is extracted from the object by \code{\link[terra]{res}}}
\item{max.width}{numeric. maximum kernel width to check for local maximum, in \item{max.width}{numeric. maximum kernel width to check for local maximum, in
pixels if dem is a cimg, in SpatRaster units otherwise} pixels if \code{dem} is a cimg, in SpatRaster units otherwise}
\item{jitter}{boolean. indicates if noise should be added to image values to \item{jitter}{boolean. indicates if noise should be added to image values to
avoid the adjacent maxima due to the adjacent pixels with equal values} avoid adjacent maxima due to the adjacent pixels with equal values}
} }
\value{ \value{
A cimg object or SpatRaster object which values are the radius (n) A cimg object / SpatRaster object which values correspond to the radius
in meter of the square window (width 2n+1) where the center pixel is global (n) in pixels / meters of the square window (width 2n+1) where the center pixel is global
maximum maximum (tested up to the \code{max.width} parameter)
} }
\description{ \description{
Variable window size maxima detection is performed on the image to extract Variable window size maxima detection is performed on the image to extract
...@@ -44,5 +44,6 @@ terra::plot(chm_chablais3, main = "Initial image") ...@@ -44,5 +44,6 @@ terra::plot(chm_chablais3, main = "Initial image")
terra::plot(maxi, main = "Local maxima") terra::plot(maxi, main = "Local maxima")
} }
\seealso{ \seealso{
\code{\link{dem_filtering}}, \code{\link{maxima_selection}} \code{\link{dem_filtering}}, \code{\link{maxima_selection}},
\code{\link{tree_segmentation}}
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
\alias{maxima_selection} \alias{maxima_selection}
\title{Image maxima selection based on values and neighborhood of local maxima} \title{Image maxima selection based on values and neighborhood of local maxima}
\usage{ \usage{
maxima_selection(maxi, dem_nl, hmin = 0, dmin = 0, dprop = 0) maxima_selection(maxi, dem_nl, hmin = 5, dmin = 0, dprop = 0.05)
} }
\arguments{ \arguments{
\item{maxi}{cimg object or SpatRaster object. image with local maxima \item{maxi}{cimg object or SpatRaster object. image with local maxima
...@@ -28,14 +28,18 @@ maximum and which fulfill the selection criteria ...@@ -28,14 +28,18 @@ maximum and which fulfill the selection criteria
} }
\description{ \description{
In a maxima image (output of \code{\link{maxima_detection}}), sets values to In a maxima image (output of \code{\link{maxima_detection}}), sets values to
zero for pixels which zero for pixels which:
\enumerate{ \enumerate{
\item value in the initial image (from which maxima were detected) are below \item values in the initial image (from which maxima were detected) are below
a threshold a threshold
\item values in the maxima image (corresponding to the radius of the \item values in the maxima image (corresponding to the radius of the
neighborhood where they are global maxima) are below a threshold depending on neighborhood where they are global maxima) are below a threshold depending on
the initial image value. the initial image value.
} }
Make sure that the \code{max.width} parameter in \code{\link{maxima_detection}}
is consistent with the selection parameters (e.g. do not select with
\code{dmin = 7} if values were only tested up to \code{max.width} the default
value which is approx. 5.5 m).
} }
\examples{ \examples{
data(chm_chablais3) data(chm_chablais3)
...@@ -46,8 +50,8 @@ maxi <- maxima_detection(chm_chablais3) ...@@ -46,8 +50,8 @@ maxi <- maxima_detection(chm_chablais3)
# several maxima selection settings # several maxima selection settings
selected_maxi_hmin <- maxima_selection(maxi, chm_chablais3, hmin = 15) selected_maxi_hmin <- maxima_selection(maxi, chm_chablais3, hmin = 15)
selected_maxi_dm <- maxima_selection(maxi, chm_chablais3, dm = 2.5) selected_maxi_dm <- maxima_selection(maxi, chm_chablais3, dmin = 2.5)
selected_maxi <- maxima_selection(maxi, chm_chablais3, dm = 1, dprop = 0.1) selected_maxi <- maxima_selection(maxi, chm_chablais3, dmin = 1, dprop = 0.1)
# corresponding count number of remaining maxima # corresponding count number of remaining maxima
table(terra::values(maxi)) table(terra::values(maxi))
...@@ -63,5 +67,5 @@ terra::plot(maxi, main = "Local maxima") ...@@ -63,5 +67,5 @@ terra::plot(maxi, main = "Local maxima")
terra::plot(selected_maxi, main = "Selected maxima") terra::plot(selected_maxi, main = "Selected maxima")
} }
\seealso{ \seealso{
\code{\link{maxima_detection}} \code{\link{maxima_detection}}, \code{\link{tree_segmentation}}
} }
...@@ -27,7 +27,7 @@ chm_chablais3 <- terra::rast(chm_chablais3) ...@@ -27,7 +27,7 @@ chm_chablais3 <- terra::rast(chm_chablais3)
# median filter # median filter
chm_chablais3 <- dem_filtering(chm_chablais3, chm_chablais3 <- dem_filtering(chm_chablais3,
nl_filter = "Median", nl_size = 3, nl_filter = "Median", nl_size = 3,
sigmap = 0 sigma = 0
)$non_linear_image )$non_linear_image
# maxima detection # maxima detection
......
...@@ -38,7 +38,7 @@ chm_chablais3 <- terra::rast(chm_chablais3) ...@@ -38,7 +38,7 @@ chm_chablais3 <- terra::rast(chm_chablais3)
# median filter # median filter
chm_chablais3 <- dem_filtering(chm_chablais3, chm_chablais3 <- dem_filtering(chm_chablais3,
nl_filter = "Median", nl_size = 3, nl_filter = "Median", nl_size = 3,
sigmap = 0 sigma = 0
)$non_linear_image )$non_linear_image
# maxima detection and selection # maxima detection and selection
......
...@@ -26,7 +26,7 @@ chm_chablais3 <- terra::rast(chm_chablais3) ...@@ -26,7 +26,7 @@ chm_chablais3 <- terra::rast(chm_chablais3)
# median filter # median filter
chm_chablais3 <- dem_filtering(chm_chablais3, chm_chablais3 <- dem_filtering(chm_chablais3,
nl_filter = "Median", nl_size = 3, nl_filter = "Median", nl_size = 3,
sigmap = 0 sigma = 0
)$non_linear_image )$non_linear_image
# maxima detection # maxima detection
......
...@@ -4,54 +4,34 @@ ...@@ -4,54 +4,34 @@
\alias{tree_segmentation} \alias{tree_segmentation}
\title{Preprocessing and segmentation of raster image for tree identification} \title{Preprocessing and segmentation of raster image for tree identification}
\usage{ \usage{
tree_segmentation( tree_segmentation(dem, dtm = NULL, crown_prop = NULL, crown_hmin = NULL, ...)
dem,
nl_filter = "Closing",
nl_size = 5,
sigma = 0.3,
dmin = 0,
dprop = 0.05,
hmin = 5,
crown_prop = 0.3,
crown_hmin = 2,
dtm = NULL
)
} }
\arguments{ \arguments{
\item{dem}{raster object or string indicating location of raster file \item{dem}{raster object or string indicating location of raster file
(typically a canopy height model or a digital surface model; in the latter (typically a canopy height model or a digital surface model; in the latter
case the dtm parameter should be provided)} case the dtm parameter should be provided)}
\item{nl_filter}{string. specifies the non-linear filter for image pre-processing,
should be an option of function \code{\link{dem_filtering}}}
\item{nl_size}{numeric. width of kernel of non-linear filter in pixels}
\item{sigma}{numeric or matrix. if a single number is provided, sigmap is the
standard deviation of Gaussian filter in meters, 0 corresponds to no smoothing.
In case of matrix, the first column corresponds to the standard deviation of
the filter, and the second to thresholds for image values (e.g. a filter of
standard deviation specified in line \code{i} is applied to pixels in image
which values are between thresholds indicated in lines \code{i} and
\code{i+1}). Threshold values should be ordered in increasing order.}
\item{dmin}{numeric. treetop minimum distance to next higher pixel in meters}
\item{dprop}{numeric. number defining the treetop minimum distance as
proportion of height to next higher pixel}
\item{hmin}{numeric. minimum treetop height}
\item{crown_prop}{numeric. minimum height of tree crown as proportion of
treetop height}
\item{crown_hmin}{numeric. minimum crown height}
\item{dtm}{raster object or string indicating location of raster file with \item{dtm}{raster object or string indicating location of raster file with
the terrain model. If provided, the maxima extraction and watershed segmentation the terrain model. If provided, the maxima extraction and watershed segmentation
are performed on the dem (this avoids the deformation of crown because of the are performed on the dem (this avoids the deformation of crown because of the
normalisation with terrain), but maxima selection and segment adjustment are normalisation with terrain), but maxima selection and segment adjustment are
performed on 'dem-dtm' because the selection criteria is the height to terrain.} performed on 'dem-dtm' because the selection criteria are based on the height to terrain.}
\item{crown_prop}{(deprecated) numeric. (overrides \code{prop} parameter
passed to \code{\link{seg_adjust}}, for backward compatibility)}
\item{crown_hmin}{(deprecated) numeric. (overrides \code{min.value} parameter
passed to \code{\link{seg_adjust}}, for backward compatibility)}
\item{...}{arguments passed to functions \code{\link{dem_filtering}}
(e.g. \code{nl_filter}, \code{nl_size}, \code{sigma}),
\code{\link{maxima_detection}}, \code{\link{maxima_selection}},
\code{\link{maxima_selection}} (\code{dmin}: treetop minimum distance to next
higher pixel in meters, \code{dprop}: number defining the treetop minimum
distance as proportion of its height to next higher pixel, \code{hmin}:
minimum treetop height), \code{\link{seg_adjust}} (\code{prop}: minimum
height of tree crown base as proportion of treetop height, \code{min.value}:
minimum crown base height)}
} }
\value{ \value{
A SpatRaster with 4 layers: selected local maxima (values = A SpatRaster with 4 layers: selected local maxima (values =
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment