The two things a finished atlas usually needs at once: fewer vertices, and its voxel staircase rounded off. Doing them separately means deciding which order they go in, and the answer is not obvious - rounding adds vertices, so smoothing after simplifying undoes some of the reduction, while simplifying after smoothing replaces the new curves with straight chords and puts the staircase back.
atlas_polish() owns that order so a build does not have to rediscover it.
Usage
atlas_polish(
atlas,
keep = 0.1,
smoothness = 0.4,
method = c("close", "chaikin", "ksmooth", "spline"),
close_gaps = TRUE,
labels = NULL,
exclude = NULL
)Arguments
- atlas
A
ggseg_atlas.- keep
Proportion of the original vertices to aim for. See details.
- smoothness
Smoothing strength between 0 and 1, passed to
atlas_smooth().- method
Smoothing method, passed to
atlas_smooth()."close"rounds solid shapes; the others keep holes open.- close_gaps
Whether to hand back the slivers the operations open between neighbouring regions. See
atlas_smooth().- labels
Which labels to polish: a regular expression, or a function that takes the atlas and returns one. Pass
context_pattern, without calling it, to select the atlas's context.- exclude
Optional regex. Matching labels are left alone.
Details
keep is a budget on the result, not on an intermediate: the atlas is
simplified to keep of the vertices it arrived with, then rounded under
atlas_smooth()'s "preserve" budget, which simplifies the rounding back
towards that same count.
It is a dial rather than a guarantee, and the low end is the loose end.
Simplification will not take a ring below the handful of vertices that
holds its shape, so an atlas of many small rings lands well above what was
asked. On ggsegJHU's tract atlas (14,667 vertices):
keep | asked | atlas_simplify() alone | atlas_polish() |
| 0.05 | 733 | 2,636 | 3,989 |
| 0.10 | 1,467 | 3,341 | 4,890 |
| 0.20 | 2,933 | 4,729 | 6,437 |
| 0.50 | 7,334 | 8,570 | 10,417 |
Most of that gap is the floor, not the rounding: atlas_simplify() on its
own misses the same target the same way. Rounding then adds roughly a third
more, which the "preserve" budget takes back only as far as the floor
allows. Ask for what you want, then look at what you got.
See also
atlas_simplify() and atlas_smooth() for the separate steps,
when a build needs to interleave them differently.
Other atlas geometry:
atlas_dilate(),
atlas_simplify(),
atlas_smooth(),
count_vertices()
Examples
dk <- ggseg.formats::dk()
sum(count_vertices(dk))
#> [1] 5391
polished <- atlas_polish(dk, keep = 0.2)
sum(count_vertices(polished))
#> [1] 3904
if (FALSE) { # \dontrun{
# The usual shape of a build: the context silhouette and the structures
# want different budgets, so they get a call each.
dk |>
atlas_polish(
keep = 0.4,
smoothness = 0.4,
method = "chaikin",
labels = context_pattern
) |>
atlas_polish(keep = 0.1, smoothness = 0.4, exclude = context_pattern)
} # }