Reduce a binary image to its one-pixel-wide skeleton using one of the supported thinning algorithms.
Usage
thin(
image,
method = c("zhang_suen", "guo_hall", "lee", "k3m", "hilditch", "opta", "holt"),
max_iter = 1000L
)Arguments
- image
A binary image: a matrix or array where non-zero values are foreground and zero values are background. Logical, integer, and numeric inputs are all accepted.
NAvalues are rejected with an error rather than silently coerced (a background pixel would change the skeleton). The image is treated as a 2-D matrix; arrays with more than two dimensions are not yet supported.- method
Algorithm to use. One of
"zhang_suen"(default),"guo_hall","lee"(2-D adaptation of Lee, Kashyap & Chu 1994),"k3m"(Saeed et al. 2010),"hilditch"(Hilditch 1969),"opta"(Naccache & Shinghal 1984), or"holt"(Holt et al. 1987). Seevignette("choosing-a-method")for guidance on which to pick, andvignette("correctness-properties")for the edge-handling and connectivity guarantees shared by every method.- max_iter
Maximum number of passes. Default 1000. Real binary images of typical sizes converge well under 50 passes; the limit is a safety bound against pathological inputs.
Value
A matrix of the same shape and storage mode as image, with
foreground pixels marking the thinned skeleton and the rest set to
background.
Edge handling
Every kernel inspects an 8-neighbourhood, so a naive implementation
can never delete a pixel in the outermost row or column and leaves
shapes that touch the matrix border two or three pixels thick. thin()
therefore surrounds the image with a one-pixel background margin before
thinning and crops it back afterwards, so a shape is skeletonised
identically whether or not it touches the frame. This applies uniformly
to all seven methods.
Connectivity
Thinning only ever deletes foreground pixels, and each method deletes
in an order that keeps 8-connected components connected: an object that
starts as one connected component thins to one connected component. In
particular a two-pixel-wide stroke thins to a connected one-pixel line
rather than fragmenting. See vignette("correctness-properties").
Examples
# A 3x3 solid square thins to a single foreground pixel.
m <- matrix(c(0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0),
nrow = 5, byrow = TRUE)
thin(m, method = "zhang_suen")
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0 0 0 0 0
#> [2,] 0 0 0 0 0
#> [3,] 0 0 1 0 0
#> [4,] 0 0 0 0 0
#> [5,] 0 0 0 0 0
thin(m, method = "guo_hall")
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0 0 0 0 0
#> [2,] 0 0 0 0 0
#> [3,] 0 0 1 0 0
#> [4,] 0 0 0 0 0
#> [5,] 0 0 0 0 0
thin(m, method = "hilditch")
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0 0 0 0 0
#> [2,] 0 0 0 0 0
#> [3,] 0 0 1 0 0
#> [4,] 0 0 0 0 0
#> [5,] 0 0 0 0 0