Skip to main content

Module evolution

Module evolution 

Source
Expand description

BET surface evolution algorithm

Based on: Smith, S.M. (2002) “Fast robust automated brain extraction” Human Brain Mapping, 17(3):143-155

Aligned with FSL-BET2 implementation.

§Reference pipeline

  • Defaults. FSL BET2 (Bostrix/FSL-BET2 d5acd7f, bet2.cpp): -f 0.5 (:133), -g 0 (:136), smoothness -w 1 (:139), 1000 iterations (:792), curvature radii 3.33–10 mm scaled by the smoothness (:788-789), surface from make_mesh_from_icosa(5, m) (:772). BetParams::default has the same f, g, smoothness and iterations, and subdivisions: 4: bet2’s make_mesh_from_icosa(subdivisions + 1), 2562 vertices.
  • Input. BET was developed on structural (T1-, T2-, PD-weighted) head images (Smith 2002) and works in mm (the search distances and curvature limits above), so it assumes human-scale anatomy; see BetParams::voxel_scale for rodents. It needs no orientation: the initial sphere comes from the image’s intensity centre of gravity. -g is a gradient along the voxel z axis.
  • Ported from bet2 step by step (astewartau/QSM.rs#327):
    • the mesh is bet2’s own icosahedron, make_mesh_from_icosa: its orientation, the triangle order and winding, and retessellate (super::icosphere::bet2_icosa);
    • vertex normals are Mpoint::local_normal, the normalised sum of the unnormalised triangle normals (area-weighted);
    • intensities are sampled at the nearest voxel, (int)(p/dim + 0.5), not interpolated. Inside the search loop this includes newimage’s unchecked value(), which past an edge reads a neighbouring row’s voxel;
    • l is the mean over vertices of the mean distance to their neighbours, recomputed at the start of iterations 0, 50, 100, 200, …;
    • t2/t98 are newimage’s robustmin/robustmax (find_thresholds, a histogram method), and tm is the ⌊n/2⌋-th smallest value;
    • -f, -w and -g are rounded to single precision, as bet2 reads them;
    • the mask is make_mask_from_mesh: the triangles drawn as bet2’s draw_mesh draws them, then a 6-connected spread from the mesh’s mean point, with no hole filling;
    • FSL reverses x of a neurologically stored image (positive determinant) before bet2 runs (FslLeftRightOrder).
  • Agreement with bet2 (Bostrix/FSL-BET2 d5acd7f built from source; measured 2026-10-31):
    • Travelling head: on prisma-bridge-run1’s echo-1 magnitude after ANTs N4, the masks are identical, at -f 0.5 and at -f 0.2 (0 of 6.0 M voxels differ). Before the port, Dice was 0.9857 and 0.9916, with QSM.rs’s masks 1.25 % and 0.64 % larger.
    • Synthetic head of tests/bet_bet2_parity.rs: Dice 0.9991 (-f 0.5, 5 voxels) and 1.0000 (-f 0.2). That piecewise-constant head is sensitive at this level. Before the port: 0.9903 and 0.9922.
    • Undefined behaviour in bet2: a sample index outside the whole volume buffer is read as 0 here.
  • In QSM pipelines. MEDI runs BET on iMag = sqrt(sum(abs(iField).^2,4)), the RSS over echoes, with f = 0.5 (MEDI_toolbox README.m:92,111) or f = 0.1 (MEDI_full_process.m:109,128). QSMART runs bet2 -f 0.2 -m on the first echo’s coil-RSS magnitude after N4 (QSMART_toolbox_v1.0/brainmask.m:7-14). QSM.jl’s README runs bet on the last echo with -f 0.5 and erodes the mask by 5 voxels (README.md:34-38).

Structs§

BetParameters 🔒
Brain parameters struct (like FSL’s bet_parameters)
BetParams
BET algorithm parameters

Enums§

FslLeftRightOrder
How FSL stores an image’s left-right axis, which decides whether FSL flips it on reading (FslGetLeftRightOrder2, fslio.c; read_volume calls makeradiological()): an image whose sform (or, without one, qform) has a negative determinant is radiological and read as it is; one with a positive determinant is neurological and FSL reverses its x axis before bet2 sees it (and back when saving). The mesh is not symmetric, so the flip changes the mask.

Constants§

MAX_PASSES 🔒
Maximum number of recovery passes (matches FSL-BET2)
SELF_INTERSECTION_THRESHOLD 🔒
Self-intersection threshold (matches FSL-BET2)

Functions§

estimate_brain_parameters 🔒
Estimate brain parameters from the image (matches FSL-BET2’s adjust_initial_mesh)
evolution_pass 🔒
Run a single pass of surface evolution
find_thresholds 🔒
newimage’s find_thresholds (Steve Smith’s robust 2 %/98 % limits; FSL-BET2 d5acd7f newimage/newimage.cc), for a volume<float>: a 1000-bin histogram between the minimum and maximum, the bins holding the lowest and highest 2 %, and while those limits span less than a tenth of the range, the histogram redone between them (up to 10 passes, the last ignoring the end bins). Returns (robustmin, robustmax).
run_bet
Run BET brain extraction, as FSL’s bet2 (see the module docs).
run_bet_as_stored 🔒
sample_intensities_fsl 🔒
Sample min/max intensities along inward normal (matches FSL-BET2’s step_of_computation)
surface_to_mask 🔒
Convert surface mesh to binary mask using flood fill