A patient with lung cancer lies on the CT couch and breathes. A four dimensional CT records the chest at every phase of that breath, and the radiation oncology team needs to know where each piece of tissue travels between full inhalation and full exhalation. On the ten thoracic cases of the DIR-Lab benchmark, expert landmarks sit 8.46 mm apart on average between those two phases, and in one case the gap is 14.99 mm. Mapping that motion voxel by voxel is deformable image registration, and it sits quietly underneath treatment planning, dose accumulation and contour propagation.
A team at the University of Chicago, with a collaborator at Emory University, now reports a registration method that needs no training on registration data and no anatomical labels, and that works across lung CT, cardiac MRI and abdominal MR to CT pairs. The most interesting part of their preprint is what did not work.
Key points
- FlexiMIND chains two training free stages inside the ConvexAdam optimizer. Frozen FlexiCT-2D encoder features find the coarse alignment, then MIND-SSC descriptors refine it.
- Under one shared protocol it reached a mean target registration error of 1.27 mm on DIR-Lab lung CT, a Dice of 0.807 on ACDC cardiac MRI and an organ averaged Dice of 0.825 on abdominal MR to CT, ahead of plain ConvexAdam, a reimplemented DINO-Reg and the encoder alone.
- Five tighter ways of fusing the two feature types were tested. Only 4 of 15 strategy and dataset comparisons beat the plain cascade, by at most 0.0043 Dice, while losses reached 20.6 percent in TRE and 37.9 percent in Dice.
- Accuracy changes tracked changes in deformation smoothness, so a fusion gain reported elsewhere could be a regularization effect in disguise.
- On lung CT the gain over plain ConvexAdam comes almost entirely from removing large failures. Median landmark error barely moved.
- This is a preprint tested on 10, 50 and 8 cases, with code promised on acceptance. Nothing here is a clinical validation.
Medical disclaimer. This article explains published research on medical image registration. It is not medical advice, diagnosis or treatment, and it does not evaluate any clinical product. Registration software used in radiotherapy or diagnosis must be validated and supervised by qualified professionals. If you have questions about your own imaging or treatment, please talk to your care team.
Why lining up two scans is harder than it looks
Registration sounds like a solved chore. You have two images of the same anatomy, you find the transformation that maps one onto the other, and you move on. In practice that transformation is a dense field of displacements, one for every voxel, and each displacement has to be justified by something visible in the images. When both images come from the same scanner a moment apart, intensity is a decent guide. Bright tissue stays bright and dark tissue stays dark.
That guide breaks in two common situations. The first is a change of modality. On CT a liver is a fairly even grey, while on MRI it can be brighter or darker than its neighbors depending on the sequence, so a method that matches intensities directly will happily align the wrong things. The second is ambiguity. A lung is full of vessels that resemble other vessels, and the wall of the heart at end systole looks a lot like itself at end diastole a few millimeters away. Local patterns repeat, and the right correspondence often depends on context that a small neighborhood cannot supply.
Classical work answered the first problem with similarity measures that ignore absolute intensity. Mutual information, introduced for multimodality registration by Maes and colleagues in 1997, and normalized gradient fields from Haber and Modersitzki both belong to that family. A different idea is to translate both images into a feature space where a voxel is described by its structure rather than its brightness, and then register the feature maps instead of the pictures. FlexiMIND belongs to that second tradition, and it asks a question the tradition has mostly avoided. If you hold two good feature families, should you fuse them, and if so, how tightly?
Two feature families with opposite blind spots
What MIND-SSC sees
The Modality Independent Neighborhood Descriptor, known as MIND, came from Mattias Heinrich and colleagues in Medical Image Analysis in 2012. Its trick is to stop looking at intensity and look at self similarity instead. For each voxel it asks how similar the small patch around it is to patches a short distance away. A tissue boundary produces a strong pattern of dissimilarity in one direction, a flat region produces none, and that pattern holds whether the boundary is bright on CT or dark on MRI. The self similarity context variant, MIND-SSC, compares pairs of neighboring patches with each other rather than with the central patch, which makes it less fragile when the center voxel is noisy.
Paired with ConvexAdam, the fast optimization scheme from Siebert, Hansen and Heinrich, MIND-SSC has been a stubbornly strong baseline in the Learn2Reg challenge described by Hering and colleagues, and it needs no training whatsoever. Its weakness is built into its strength. A descriptor computed from a few voxels around each point knows about a few voxels around each point. Two vessels with the same local shape receive the same description, and the optimizer has no way to tell them apart.
What a pretrained encoder sees
Self supervised vision transformers such as DINOv2 from Oquab and colleagues learn features that carry information from much further away, because attention lets every patch token consult the whole image. Xinrui Song and colleagues showed with DINO-Reg in IEEE Transactions on Medical Imaging that PCA reduced DINOv2 features can drive a ConvexAdam style optimizer without training a registration network on the target data. The Chicago group followed with DINOv3 features and test time optimization of the deformation field at SPIE Medical Imaging 2026. DINO models learn by a form of self distillation, and if that teacher and student vocabulary is new to you, our explainer on the mathematics of knowledge distillation covers the core idea.
These features have the opposite profile to MIND-SSC. They are semantic and wide but spatially coarse, because a vision transformer works on patch tokens, here 8 by 8 pixels each. When the encoder is two dimensional and applied slice by slice to a volume, it also knows little about what happens between slices. So the obvious hypothesis writes itself. Context from the encoder plus local precision from MIND-SSC should beat either alone, and a clever fusion should beat a naive one. The paper confirms the first half of that sentence and finds the second half mostly false.
How FlexiMIND puts the pieces together
FlexiMIND comes from Mojtaba Safari, Xiaofeng Yang and colleagues in the Department of Radiation and Cellular Oncology and the Department of Radiology at the University of Chicago, with Suyang Xi of Emory University. It is posted on arXiv as a preprint and it is deliberately plain. Two registration calls run in sequence in the same solver, and the hand crafted descriptor goes second.
Stage one, encoder features for the big picture
Every axial slice of both volumes passes through FlexiCT-2D, a vision encoder pretrained on CT by Li and colleagues, with a patch size of 8. Its weights stay frozen. Features from the last four transformer layers are concatenated into 3456 channels per token. Each slice is resized to a fixed token grid before encoding, 80 by 70 tokens for DIR-Lab and ACDC and 112 by 96 tokens for the abdominal data, and the slice features are stacked and upsampled to the registration grid.
Thousands of channels per voxel is far too many to search over, so the features are compressed to 24 channels with principal component analysis, using a seeded randomized singular value decomposition. The detail that matters, as we will see later, is that the basis is estimated from the fixed image alone and then applied to both images.
Fixed image PCA projection
$$ W = \mathrm{PCA}_q\!\left(F_{\mathrm{fix}}\right) \in \mathbb{R}^{C_{\mathrm{in}} \times q}, \qquad q = 24 $$ $$ F^{q}_{\mathrm{fix}} = W^{\top} F_{\mathrm{fix}}, \qquad F^{q}_{\mathrm{mov}} = W^{\top} F_{\mathrm{mov}} $$One basis, learned from the fixed image, describes both images in the same 24 dimensional language.
ConvexAdam then does two things with these 24 channel maps. It first runs a discrete search that scores the squared feature distance for every integer displacement inside a small window, on a coarse grid with a spacing of 6 voxels, and regularizes the resulting choices with a coupled convex relaxation over 15 iterations that also enforces inverse consistency between the forward and backward directions. It then refines the field continuously with the Adam optimizer under a diffusion penalty. For this encoder stage the authors use 500 Adam iterations at a learning rate of 6.0 on a full resolution parameter grid, two box filters of width 7, and a regularization weight of 1 for the single modality datasets and 2 for MR to CT.
Registration energy and discrete matching cost
$$ E(u) = \int_{\Omega} \mathcal{D}\big[\Phi_{\mathrm{fix}}(x),\, \Phi_{\mathrm{mov}}(x + u(x))\big]\,dx \;+\; \lambda \int_{\Omega} \lVert \nabla u(x) \rVert^{2}\,dx $$ $$ C_{\Phi}(x, u) = \big\lVert \Phi_{\mathrm{fix}}(x) – \Phi_{\mathrm{mov}}(x + u) \big\rVert_{2}^{2} $$The first term rewards feature agreement, the second penalizes rough displacement fields. \(\Phi\) is whichever representation the stage uses.
Stage two, MIND-SSC for the fine print
The moving image is warped by the stage one field \(u_1\). MIND-SSC descriptors are then recomputed from the fixed image and the warped moving image at full working resolution, with a patch radius of 1 and a dilation of 2 voxels, giving twelve channels per voxel. A second ConvexAdam call estimates the residual field \(u_2\), this time with 80 Adam iterations at a learning rate of 1.0, a parameter grid spacing of 2, three box filters of width 3 and a regularization weight of 1.25. Because the two stages use different grid spacings, the authors warn that their regularization weights are not directly comparable.
MIND-SSC channels
$$ m_k(x) = \exp\!\left(-\frac{D_k(x)}{V(x)}\right), \quad k = 1, \dots, 12 $$ $$ M^{12} = [m_1, \dots, m_{12}] $$\(D_k(x)\) is the sum of squared differences between the two patches of the \(k\)th neighborhood pair and \(V(x)\) is the mean of those differences at \(x\). Each channel is then normalized by its maximum.
The final transformation composes an affine alignment, the encoder field and the residual MIND field. For DIR-Lab and ACDC the affine step is a rigid then affine SimpleITK registration driven by mutual information with 32 histogram bins on a seeded 10 percent sample of voxels, computed once per pair and cached so that every compared method starts from exactly the same place. For the abdominal MR to CT pairs there is no affine step at all, and registration runs directly on the released grid of 192 by 160 by 192 voxels at 2 mm.
The sequential cascade
$$ u_1 = S\big[F^{q};\, 0\big], \qquad u_2 = S\big[\tilde{M}^{12};\, 0\big] $$ $$ \varphi = \varphi_{\mathrm{affine}} \circ \varphi_{u_1} \circ \varphi_{u_2} $$\(S[\Phi; v_0]\) is one ConvexAdam call. \(\tilde{M}^{12}\) is MIND-SSC computed after warping the moving image by \(u_1\).
Nothing in this pipeline learns from the evaluation data. Training free here means that no parameters are fitted to registration data, although the encoder itself was pretrained elsewhere. Label free means that no segmentations are used while optimizing. Both claims hold as stated, and together they explain why one configuration can move between CT, cine MRI and MR to CT without retraining.
Key takeaway
FlexiMIND is less a new architecture than a controlled experiment built around a strong default. Its value lies in holding the solver, resolution, preprocessing and regularization fixed while only the way the features interact is allowed to change.
A fair comparison, by design
Most papers that compare feature representations for registration change several things at once. A new descriptor arrives with a new solver, a different working resolution or a retuned smoothness weight, and the improvement cannot be pinned on any one of them. The authors say plainly that they wanted to avoid this. Within each dataset, every configuration shares preprocessing, solver settings, working resolution and affine initialization, and the solver parameters were never tuned on the evaluated data.
Three public benchmarks cover three modality pairings. DIR-Lab 4DCT from Castillo and colleagues supplies ten thoracic CT cases with 300 expert landmarks each between the extreme breathing phases, scored by target registration error in millimeters after the DIR-Lab convention of rounding moved landmarks to the nearest voxel center. ACDC from Bernard and colleagues supplies 50 test subjects with cine MRI at end systole and end diastole, plus expert segmentations of the right ventricular cavity, the myocardium and the left ventricular cavity, scored by Dice overlap. The Learn2Reg Abdomen MR to CT task supplies eight paired volumes with the liver, spleen and both kidneys labelled, with MR as the fixed image and CT as the moving one, scored with the official challenge software.
Every comparison is paired, because every method sees the same image pairs, and uncertainty comes from bias corrected and accelerated bootstrap intervals over 4000 resamples. With ten and eight cases on two of the datasets, that choice is sensible. A significance test on eight pairs would promise more than the data can give.
Deformation quality is reported next to accuracy. The main statistic is SDlogJ, the spread of the log Jacobian determinant over the evaluation region, computed the way the Learn2Reg code computes it. The authors also report the share of voxels where the Jacobian determinant is zero or negative. Those voxels mark local folding, the physically impossible situation in which tissue passes through itself.
Deformation regularity as Learn2Reg computes it
$$ \mathrm{SDlogJ} = \left[\frac{1}{|\Omega_{\mathrm{eval}}|} \sum_{x \in \Omega_{\mathrm{eval}}} \big(g_u(x) – \bar{g}_u\big)^{2}\right]^{1/2} $$ $$ g_u(x) = \log\big(\det J_u(x) + 3\big), \qquad J_u = \mathrm{Id} + \nabla u $$Higher values mean a less uniform deformation. Keep an eye on the added 3, because it comes back later.
What the headline numbers show
| Configuration | DIR-Lab 4DCT, TRE mm | ACDC, Dice | Abdomen MR to CT, Dice |
|---|---|---|---|
| Unregistered | 8.4612 | 0.5801 | 0.3732 (0.3709) |
| ConvexAdam with MIND-SSC | 1.5300 | 0.7428 | 0.7583 (0.7777) |
| DINO-Reg, reimplemented | 2.2992 | 0.7447 | 0.7720 (0.7850) |
| Encoder only | 1.6954 | 0.7939 | 0.7767 (0.7880) |
| FlexiMIND | 1.2677 1.1305 to 1.3769 | 0.8067 0.7870 to 0.8231 | 0.8129 (0.8250) 0.6513 to 0.8829 |
On DIR-Lab, FlexiMIND reached a mean TRE of 1.2677 mm, against 1.5300 mm for ConvexAdam with MIND-SSC, 1.6954 mm for the encoder alone and 2.2992 mm for the reimplemented DINO-Reg. On ACDC its subject averaged Dice was 0.8067, ahead of 0.7939 for the encoder alone and roughly 0.74 for both ConvexAdam and DINO-Reg. On the abdominal MR to CT pairs it scored 0.8129 subject averaged and 0.8250 organ averaged.
The paired intervals add texture that the means hide. Against the encoder alone, the advantage is tight on every dataset, 0.2823 to 0.5885 mm on DIR-Lab and 0.0097 to 0.0164 Dice on ACDC, so the MIND-SSC refinement reliably helps. Against ConvexAdam with MIND-SSC on DIR-Lab, the interval for the 0.2623 mm reduction runs from 0.0004 to 1.1455 mm and almost touches zero. On the abdominal pairs the interval against ConvexAdam runs from 0.0066 to 0.1345 Dice. Those are honest intervals from small samples, and the authors flag them as such.
ACDC is the most convincing of the three. There the gain over ConvexAdam with MIND-SSC is 0.0640 Dice with an interval of 0.0521 to 0.0799 across 50 subjects, and the per case distributions in the paper show a broad shift rather than a handful of rescued patients. It is also the dataset where an encoder pretrained on CT is being asked to read cardiac MRI, and it still supplies most of the gain. The encoder alone, at 0.7939, already beats ConvexAdam at 0.7428.
The lung result lives in the tail
The landmark analysis on DIR-Lab is the part of the paper we would show a skeptical colleague first. Across all 3000 landmarks, using unrounded errors, FlexiMIND beat ConvexAdam with MIND-SSC on only 1496 of them, which is 49.9 percent. The pooled median errors are 1.1578 mm and 1.1437 mm. For a typical landmark the encoder stage changes nothing at all.
What changes is the worst case. The share of landmarks with errors above 5 mm falls from 2.73 percent to 0.60 percent, and above 10 mm from 1.67 percent to 0.20 percent. Sixty nine landmarks crossed below the 5 mm line, and five crossed the other way. The spread of case level TRE tells the same story from another angle, with a standard deviation of 0.7348 mm for ConvexAdam against 0.1950 mm for FlexiMIND. DIR-Lab case 8 is the vivid example. It starts at 14.99 mm, ConvexAdam brings it to 3.62 mm and FlexiMIND brings it to 1.38 mm.
That pattern fits the motivating story better than an average ever could. Local descriptors are precise when they lock onto the right structure and badly wrong when they lock onto a lookalike. A coarse but contextual first pass removes the lookalikes, and the local pass then does what it always did well. For radiotherapy the distinction is far from academic. A method that removes rare large errors protects exactly the cases that would otherwise need manual correction, and a summary statistic that hides this behavior also hides the risk.
Key takeaway
On lung CT the pretrained encoder earns its place by preventing large correspondence failures, not by sharpening typical alignment. Registration methods deserve to be judged on their error tails as well as their means.
The runtime story has two readings
| Configuration | DIR-Lab SDlogJ | DIR-Lab s | ACDC SDlogJ | ACDC s | Abdomen SDlogJ | Abdomen s |
|---|---|---|---|---|---|---|
| ConvexAdam with MIND-SSC | 0.0430 | 29.2 | 0.0582 | 19.7 | 0.1069 | 4.6 |
| DINO-Reg, reimplemented | 0.0633 | 608.8 | 0.0966 | 324.9 | 0.1972 | 413.3 |
| Encoder only | 0.0634 | 153.6 | 0.0877 | 103.4 | 0.1272 | 184.7 |
| FlexiMIND | 0.0643 | 159.0 | 0.0960 | 106.4 | 0.1448 | 187.4 |
The authors frame runtime against the encoder alone and against DINO-Reg. Adding the MIND-SSC stage costs 3.5, 2.9 and 1.5 percent extra time on the three datasets, and the full cascade runs 3.8, 3.1 and 2.2 times faster than the reimplemented DINO-Reg. Both statements are accurate.
The comparison they leave implicit is with plain ConvexAdam. By our own arithmetic from the paper’s Table 2, FlexiMIND takes about 5.4 times as long as ConvexAdam with MIND-SSC on DIR-Lab (159.0 against 29.2 seconds) and on ACDC (106.4 against 19.7 seconds), and about 41 times as long on the abdominal pairs (187.4 against 4.6 seconds). Nearly all of that time belongs to feature extraction and the 500 iteration encoder stage. Two or three minutes per pair is fine for offline planning. It is a real cost for anything close to interactive use, and it is the price of the tail protection described above. The same table shows that ConvexAdam produces the smoothest fields on all three datasets, so FlexiMIND buys its accuracy partly with rougher deformations.
Five ways to fuse, and why none of them won
Here is the experiment that makes the paper worth reading. The authors kept every other setting fixed and changed only how the two representations interact, in five different ways.
- Random projection swaps the PCA basis for a seeded random projection of the same size, which tests whether the data adaptive basis matters.
- Confidence gating scales the first stage displacement voxel by voxel according to how sharp the encoder’s matching cost is, so uncertain matches move less.
- Cost volume fusion adds normalized encoder and MIND-SSC costs during the first discrete search, so both representations vote on correspondences at the same time.
- Composed fields runs a second encoder registration after the first and composes the two fields before the MIND-SSC refinement.
- MIND on the token grid applies a local self similarity descriptor to the reduced encoder features themselves before matching.
| Configuration | DIR-Lab TRE | SDlogJ | ACDC Dice | SDlogJ | Abdomen Dice | SDlogJ |
|---|---|---|---|---|---|---|
| FlexiMIND reference | 1.2677 | 0.0643 | 0.8067 | 0.0960 | 0.8129 | 0.1448 |
| Random projection | 1.4854 | 0.0824 | 0.7948 | 0.1267 | 0.5047 | 0.4022 |
| Confidence gate | 1.2898 | 0.0653 | 0.8082 | 0.0987 | 0.8133 | 0.1451 |
| Cost volume fusion | 1.2838 | 0.0651 | 0.8082 | 0.0973 | 0.8104 | 0.1451 |
| Composed fields | 1.3655 | 0.0825 | 0.8110 | 0.1187 | 0.8082 | 0.1863 |
| MIND on the token grid | 1.5294 | 0.0446 | 0.7498 | 0.0609 | 0.7759 | 0.1088 |
None of the five improved on FlexiMIND for lung CT. TRE rose by 0.0161 mm for cost volume fusion, 0.0221 mm for confidence gating, 0.0978 mm for composed fields, 0.2177 mm for random projection and 0.2617 mm for MIND on the token grid, which works out at 1.3 to 20.6 percent worse. Across all fifteen strategy and dataset pairs only four came out ahead, and every one of those gains was small. Confidence gating added 0.0015 Dice on ACDC and 0.0004 on the abdominal data, cost volume fusion added 0.0015 on ACDC, and composed fields delivered the largest gain, 0.0043 Dice on ACDC, while losing ground on the other two datasets.
The losses were much larger. Random projection dropped the abdominal subject averaged Dice from 0.8129 to 0.5047, a fall of 37.9 percent. MIND on the token grid lost 0.0569 Dice on ACDC and 0.0370 on the abdominal pairs. No strategy improved consistently across the three settings.
Should we read this as proof that fusion never helps? No, and the authors do not claim it. Five strategies is a small sample of the design space, each ran with the reference cascade’s fixed solver settings, and a fusion method designed with its own regularization in mind might behave differently. What the result does establish is narrower and more useful. Inside one controlled pipeline, owning two representations with different spatial properties did not by itself make tighter integration pay. The simplest arrangement, context first and local refinement second, was the one to beat.
“neither increasing nor decreasing regularity relative to the reference cascade consistently improved registration accuracy”
Safari and colleagues, on what the five coupling strategies revealed
Regularity, the variable hiding in plain sight
Why did the strategies behave the way they did? The paper’s best answer comes from plotting accuracy against SDlogJ for every configuration it measured. The two strategies whose deformation smoothness stayed closest to the reference, confidence gating and cost volume fusion, also stayed closest in accuracy. Confidence gating changed SDlogJ by less than about 3 percent on every dataset. Random projection and composed fields produced rougher fields and lost accuracy in most settings. On the abdominal pairs, random projection pushed SDlogJ from 0.1448 to 0.4022, and 28.0 percent of voxels ended up with a zero or negative Jacobian determinant, against 0.14 percent for FlexiMIND.
MIND on the token grid is the instructive exception. It produced smoother fields than the reference on all three datasets, with SDlogJ falling from 0.0643 to 0.0446 on DIR-Lab, from 0.0960 to 0.0609 on ACDC and from 0.1448 to 0.1088 on the abdominal data. Accuracy fell everywhere. So smoother is not automatically better and rougher is not automatically better. Moving away from the reference operating point in either direction cost accuracy.
This is the paper’s methodological contribution, and it reaches well beyond FlexiMIND. A change of feature representation changes the cost surface that the discrete search sees, and that in turn changes how hard the smoothing machinery has to work. If a new fusion method improves Dice while also shifting SDlogJ substantially, the improvement could come from new correspondence information or from a different point on the trade off between accuracy and smoothness. The authors are careful to say that their data show association rather than causation. Their recommendation stands either way. Report deformation regularity next to accuracy, and where possible compare representations at matched regularity instead of at a single fixed smoothness weight.
There is a second, smaller lesson about the metrics themselves. The Learn2Reg implementation of SDlogJ adds 3 to the Jacobian determinant before taking the logarithm, and its folding count uses a threshold of minus 3 on the determinant. In this study the official folding count was zero for every configuration, including those with visibly irregular fields and measurable shares of negative determinants. The offset also compresses differences in SDlogJ between fields. The authors ran an offset free check and report that the direction of the regularity change held in 17 of 18 comparisons, although the offset free values themselves are not tabulated. Anyone benchmarking against Learn2Reg numbers should know that the official folding statistic can read zero while tissue is folding.
The PCA detail that nearly broke multimodal registration
The quietest finding in the paper may be the most practical. Fitting the PCA basis jointly on the fixed and moving features sounds more principled, and it made no meaningful difference on the two single modality datasets, 1.2646 mm against 1.2677 mm on DIR-Lab and 0.8083 against 0.8067 Dice on ACDC. On MR to CT it was a disaster. Organ averaged Dice fell from 0.8250 to 0.6524, and SDlogJ more than doubled, from 0.1448 to 0.3444.
The authors’ explanation is that a joint basis becomes sensitive to modality dependent differences when the two feature distributions diverge. Our reading of the mechanism is simple. MR and CT features for the same organ can sit in different regions of feature space, and a joint basis spends some of its 24 components describing that modality gap rather than anatomy. A basis fitted to the fixed image alone describes anatomy as the fixed image sees it, and both images are then projected into that shared vocabulary. Two further normalization tweaks on the abdominal data told the same story. Per channel whitening gave an organ averaged Dice of 0.5942 with an SDlogJ of 1.3646, and global scaling gave 0.7039 with an SDlogJ of 1.2515.
The paper concludes that dimensionality reduction is part of the registration representation and not a purely computational preprocessing step. We agree, and would put it more bluntly. If you build a registration pipeline on foundation model features and your multimodal results look poor, check the projection before you blame the encoder.
Where this sits among published results
The paper also places FlexiMIND against numbers reported elsewhere, and these comparisons deserve a lighter touch because protocols differ. On DIR-Lab its 1.27 mm is below the 1.51 mm reported for the learned AD-RegNet attention framework. The observer uncertainty for the DIR-Lab landmarks is listed as 0.88 mm, so there is still a gap to the precision of expert annotation. The authors also note that pretrained features do not close the remaining gap to the strongest classical methods on this dataset, although this paper does not name or tabulate those methods.
On ACDC the 0.8067 Dice exceeds the 0.7952 reported for the label free Slicer Network and falls well short of the 0.8961 reported for MemWarp, a MICCAI 2024 method that is trained with anatomical labels. Comparing a training free method with a label supervised one is not a fair contest in either direction, and the paper keeps the two apart. On the abdominal data the 0.8250 organ averaged Dice exceeds the 0.785 published for DINO-Reg, and the authors’ own reimplementation of DINO-Reg reached 0.7850, which is reassuring evidence that the reimplementation is faithful.
For readers who follow learned registration, TransMorph from Chen and colleagues and the 2025 survey of deep learning registration in Medical Image Analysis are the natural contrast. Those methods train a network on registration data and can be very fast at inference. FlexiMIND trades inference speed for the ability to drop into a new modality pairing without any training data, which is a different tool for a different situation. On this site our article on CardioMorphNet and Bayesian cardiac motion estimation shows the learned side of that trade on cardiac images.
Clinical translation gap
What would have to happen before something like FlexiMIND helps a real patient? The distance is larger than the clean benchmark numbers suggest, for four reasons.
First, registration in the clinic is rarely an end in itself. It feeds contour propagation, dose accumulation across treatment fractions, motion modeling for planning and the fusion of MR into CT based plans. Each use has its own tolerance, and a mean TRE or a Dice score does not translate directly into a dosimetric or clinical outcome. The paper does not attempt that translation, and it does not claim to.
Second, the benchmarks are narrow. Ten lung CT cases from a benchmark published in 2009, 50 cardiac MRI subjects with thick slices and eight abdominal MR and CT pairs are a fair research test bed. Real clinical data brings metal implants, contrast agents, tumors that grow or shrink between scans, and partial fields of view, and none of these is represented here in any depth.
Third, speed matters differently in different workflows. Two to three minutes on a 48 GB workstation GPU is acceptable for offline treatment planning. In an adaptive workflow, where the patient waits on the couch while a plan is updated, the gap to plain ConvexAdam becomes part of the clinical cost.
Fourth, failure detection is missing. The tail analysis shows that the method removes many large errors. It does not remove all of them, and the pipeline offers no built in signal that tells a user when a particular pair has gone wrong. In a clinical setting, knowing when not to trust a registration is as valuable as a better average.
Regulatory and safety note, our reading
Deformable registration that alters contours or dose in a treatment plan sits inside a regulated medical device workflow in most jurisdictions, and radiotherapy practice expects commissioning and case by case quality assurance of registration results. A research preprint evaluated on public benchmarks is the first step on that path and no substitute for it. Clinical use would require validation on local data, review of deformed contours by qualified staff and the normal approval route for any software that wraps the method.
Limitations, sample size and bias
The authors write a candid limitations section, and the points below build on it with details from the paper’s own numbers.
- Small cohorts. DIR-Lab has ten cases and the abdominal set eight pairs, which is why the intervals are wide and why the authors used bootstrap estimates rather than hypothesis tests. A 0.2623 mm advantage whose interval starts at 0.0004 mm is a hint, not a verdict.
- Benchmark age and reuse. DIR-Lab dates to 2009 and has been used by many methods, so the field’s sense of what counts as good on it is partly shaped by repeated reuse. The qualitative abdominal example, pair 0008, was picked because it is a favorable case with all four organs visible in one plane, which the authors state openly.
- A two dimensional encoder on three dimensional data. Features come from axial slices, so information between slices is limited. ACDC volumes have native voxels of about 1.64 by 1.64 by 10 mm, and the discussion gives a through plane range of 5 to 10 mm, while registration runs at 1.0 mm isotropic. Much of the vertical detail is interpolated.
- Different solver interfaces. The MIND-SSC stage uses the reference ConvexAdam implementation, while the encoder stage uses its parameterized interface, and the authors note the two are not numerically identical. That limits how cleanly the MIND only and encoder based configurations can be compared.
- Stage specific hyperparameters. The two stages differ in iteration count, learning rate, grid spacing and regularization weight. These were fixed rather than tuned on the test data, but the paper does not describe how they were chosen, so their sensitivity is unknown.
- Conditional fusion results. Every coupling strategy ran with the reference cascade’s solver settings, so a strategy that needs different regularization could be penalized for it. The authors propose regularity matched comparisons as future work.
- Dataset bias. All three benchmarks are public research collections with curated pairs. The paper gives no breakdown by pathology, scanner or patient group, so performance on populations or hardware absent from these collections is unknown.
- One hardware platform and unreleased code. Runtimes come from a single GPU, and the code is announced for release on acceptance, so independent reproduction is not yet possible.
- Preprint status. This is version 1 of an arXiv preprint dated 25 October 2026 and it has not been through peer review.
What practitioners can take from this
If you build registration pipelines, three habits from this paper are worth copying. Put context before precision, so a contextual first pass removes gross mismatches and a local descriptor finishes the job. Fit dimensionality reduction to a single reference image whenever the inputs differ in modality. Report SDlogJ and the fraction of non positive Jacobian determinants next to every accuracy number, and look at the upper tail of landmark errors rather than only the mean.
If you research feature fusion, the paper raises the bar for evidence. A claimed improvement should survive a check that the regularity of the deformation field did not move with it, or it should come with an argument for why the change in regularity is the point.
The scale separated idea also travels. Any alignment problem where a learned representation is good at coarse semantics and a hand crafted one is good at local geometry could try the same cascade before reaching for a learned fusion module. The weakness of slice by slice features also echoes our piece on graph based cross slice segmentation, where the information between slices is the whole point. For organ contours guided by text prompts, see our article on the TEAMS Mamba snake. And if vision transformers are your main interest, our review of the four secrets behind video vision transformers covers how attention handles context across frames. More studies of this kind sit in our Medical AI section.
Conclusion
FlexiMIND shows that a training free and label free registration pipeline can reach a mean TRE of 1.27 mm on DIR-Lab lung CT, a Dice of 0.807 on ACDC cardiac MRI and an organ averaged Dice of 0.825 on abdominal MR to CT, with a single design and no retraining between modality pairs. Under a protocol that held every other component fixed, it beat ConvexAdam with MIND-SSC, the reimplemented DINO-Reg and its own encoder stage on all three datasets. For a method built from a frozen CT encoder, a classic descriptor and an existing optimizer, that is a strong and useful result.
The conceptual shift is in the negative results. The intuition that two complementary feature families should be fused as tightly as possible did not survive contact with a controlled experiment. Sequencing beat fusing. Context resolved the large ambiguities first, local self similarity cleaned up the residual, and attempts to blend the two inside one matching step either changed almost nothing or made things worse. Along the way the paper showed that deformation regularity moves with representation changes, which makes it a confounder that the field has rarely controlled for.
The lessons travel. The fixed image PCA finding applies to any pipeline that compresses foundation model features for matching across modalities. The tail analysis applies to any registration method that reports a mean error. And the scale separated design applies wherever a coarse semantic model and a fine geometric one can be run in order, from microscopy to remote sensing.
The limits are real. The cohorts are small, the encoder is two dimensional, the two stages run through slightly different solver interfaces, the method is several times slower than plain ConvexAdam, and the code is not yet public. The work is a preprint and has not been peer reviewed. None of this undermines the controlled comparison, but all of it bounds how far the numbers can be pushed.
The authors point to three dimensional or multi plane encoders, hand crafted descriptors with larger three dimensional receptive fields and comparisons run at matched regularity as next steps. We would add two more. An independent reproduction on clinical radiotherapy data, and some form of per case failure signal, would do more for clinical relevance than another decimal place on a benchmark.
Sometimes the smartest way to combine two good ideas is to let each one finish its job before the other starts.
A reference implementation in PyTorch
The authors’ code is announced for release on acceptance at the FlexiMIND repository on GitHub, so the listing below is our own editorial reconstruction from the paper’s description, not their implementation. It covers the MIND-SSC descriptor, a frozen slice wise encoder, fixed image PCA with the random and joint variants, a ConvexAdam style solver with discrete search, coupled convex smoothing, inverse consistency and Adam refinement, the two stage cascade, the cost volume fusion variant and the evaluation metrics, including SDlogJ with and without the Learn2Reg offset.
FlexiCT-2D weights are not bundled, so the encoder here is a fixed random convolutional stand in with the same patch size. Replace it before drawing any conclusion. The smoke test runs on synthetic volumes on a CPU in under a minute. On a same modality toy pair, the stand in encoder stage raised mean Dice from 0.652 to 0.868 and the MIND-SSC refinement took it to 0.883. On a toy pair with inverted intensities, MIND-SSC alone reached 0.778 while the cascade with the random stand in encoder collapsed to 0.225, a small illustration of why the first stage needs an encoder whose features hold up across modalities. These toy numbers say nothing about real anatomy and should not be compared with the paper’s results.
"""
FlexiMIND reference sketch in PyTorch
=====================================
An editorial reconstruction of the two stage cascade described in
Safari et al., "FlexiMIND: Combined Pretrained Vision Features and Local
Structure for Training-Free Deformable Medical Image Registration",
arXiv:2610.34600 (2026). This is NOT the authors' code. Their repository,
github.com/mosaf/FlexiMIND, is announced for release on acceptance.
What is here
* MIND-SSC descriptor (12 channels, patch radius r, dilation d) Eq. 3-4
* Frozen slice wise 2D encoder stand in (swap in FlexiCT-2D weights)
* Fixed image PCA projection to q channels (plus random / joint PCA) Eq. 5
* ConvexAdam style solver: discrete search + coupled convex
smoothing + inverse consistency, then Adam with a diffusion penalty Eq. 2, 6
* The FlexiMIND cascade u1 = S[F^q; 0], u2 = S[M~; 0] Eq. 7
* Cost volume fusion coupling strategy from Table 1 (optional)
* Metrics: Dice, TRE, SDlogJ with the Learn2Reg +3 offset, folding Eq. 1
* A runnable smoke test on synthetic volumes (CPU, about a minute)
There is no network training. "Training free" means every optimisation
below is instance specific test time optimisation of a displacement field.
Displacements are in voxels and channels are ordered (dz, dy, dx).
"""
import math
import time
import torch
import torch.nn as nn
import torch.nn.functional as F
# ---------------------------------------------------------------------------
# 1. Spatial helpers
# ---------------------------------------------------------------------------
def voxel_grid(shape, device):
"""Voxel coordinates (1, 3, D, H, W) ordered z, y, x."""
zz, yy, xx = torch.meshgrid(*[torch.arange(s, device=device, dtype=torch.float32)
for s in shape], indexing="ij")
return torch.stack([zz, yy, xx])[None]
def warp(vol, disp, mode="bilinear"):
"""Sample vol at x + disp(x). vol (B,C,D,H,W), disp (B,3,D,H,W) in voxels."""
B, _, D, H, W = disp.shape
pos = voxel_grid((D, H, W), disp.device) + disp
size = torch.tensor([D, H, W], device=disp.device, dtype=torch.float32).view(1, 3, 1, 1, 1)
norm = 2.0 * pos / (size - 1) - 1.0
grid = norm.permute(0, 2, 3, 4, 1)[..., [2, 1, 0]] # grid_sample wants x, y, z
return F.grid_sample(vol, grid, mode=mode, padding_mode="border", align_corners=True)
def compose(u_outer, u_inner):
"""Displacement of phi_outer o phi_inner, i.e. x -> x + u_inner(x) + u_outer(x + u_inner(x))."""
return u_inner + warp(u_outer, u_inner)
def box3d(x, width):
"""Box filter with replicate padding, used for smoothing fields and features."""
p = width // 2
return F.avg_pool3d(F.pad(x, [p] * 6, mode="replicate"), width, stride=1)
# ---------------------------------------------------------------------------
# 2. MIND-SSC descriptor (Heinrich et al. 2012, 2013), Eq. 3 and Eq. 4
# ---------------------------------------------------------------------------
class MINDSSC(nn.Module):
"""Self similarity context. Twelve channels, one per pair of six neighbourhood
offsets that sit sqrt(2)*d apart. D_k is the patch SSD between the two
shifted copies of the image, V is the mean of D_k over k, and
m_k = exp(-D_k / V), normalised by its maximum over channels."""
def __init__(self, radius=1, dilation=2, eps=1e-6):
super().__init__()
self.radius, self.dilation, self.eps = radius, dilation, eps
six = [(1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1)]
pairs = []
for i in range(6):
for j in range(i + 1, 6):
a, b = six[i], six[j]
if sum((p - q) ** 2 for p, q in zip(a, b)) == 2: # orthogonal axes only
pairs.append((a, b))
assert len(pairs) == 12
self.pairs = pairs
def shift(self, img, off):
d = self.dilation
pad = F.pad(img, [d] * 6, mode="replicate")
z, y, x = (o * d for o in off)
D, H, W = img.shape[-3:]
return pad[..., d + z:d + z + D, d + y:d + y + H, d + x:d + x + W]
def forward(self, img): # img (B,1,D,H,W)
ssd = []
for a, b in self.pairs:
diff2 = (self.shift(img, a) - self.shift(img, b)) ** 2
ssd.append(box3d(diff2, 2 * self.radius + 1))
Dk = torch.cat(ssd, dim=1) # (B,12,D,H,W)
V = Dk.mean(dim=1, keepdim=True)
V = V.clamp(min=V.mean() * 1e-3 + self.eps, max=V.mean() * 1e3 + self.eps)
m = torch.exp(-Dk / V)
return m / (m.amax(dim=1, keepdim=True) + self.eps)
# ---------------------------------------------------------------------------
# 3. Frozen slice wise encoder stand in
# ---------------------------------------------------------------------------
class FrozenSliceEncoder(nn.Module):
"""Placeholder for the frozen FlexiCT-2D ViT (patch size 8, last four layers
concatenated to 3456 channels). Here a fixed random conv stack with patch
size 8 produces C_in channels per axial slice so the pipeline runs end to
end. Replace `encode_slices` with the real encoder for real experiments."""
def __init__(self, c_in=96, patch=8, seed=0):
super().__init__()
g = torch.Generator().manual_seed(seed)
self.patch = patch
self.stem = nn.Conv2d(1, 32, 3, padding=1)
self.embed = nn.Conv2d(32, c_in, patch, stride=patch)
self.mix = nn.Conv2d(c_in, c_in, 3, padding=1)
for m in self.modules():
if isinstance(m, nn.Conv2d):
with torch.no_grad():
m.weight.copy_(torch.randn(m.weight.shape, generator=g) /
math.sqrt(m.weight[0].numel()))
m.bias.zero_()
for p in self.parameters():
p.requires_grad_(False) # weights stay frozen throughout
@torch.no_grad()
def encode_slices(self, slices): # (S,1,h,w)
h = F.gelu(self.stem(slices))
h = F.gelu(self.embed(h))
return self.mix(h) + h
@torch.no_grad()
def forward(self, vol, token_grid):
"""vol (1,1,D,H,W). Each axial slice is resized to token_grid * patch,
encoded, then the stacked tokens are upsampled to the working grid."""
_, _, D, H, W = vol.shape
th, tw = token_grid
slices = vol[0].permute(1, 0, 2, 3) # (D,1,H,W)
slices = F.interpolate(slices, size=(th * self.patch, tw * self.patch),
mode="bilinear", align_corners=False)
tokens = self.encode_slices(slices) # (D,C,th,tw)
feat = tokens.permute(1, 0, 2, 3)[None] # (1,C,D,th,tw)
return F.interpolate(feat, size=(D, H, W), mode="trilinear", align_corners=False)
# ---------------------------------------------------------------------------
# 4. Dimensionality reduction, Eq. 5
# ---------------------------------------------------------------------------
def fit_projection(F_fix, F_mov, q=24, mode="fixed_pca", seed=0):
"""Returns (W, mean). 'fixed_pca' fits on the fixed image only (the paper's
reference). 'joint_pca' fits on both images, 'random' is a seeded random
projection of the same shape (ablation in Table 1)."""
C = F_fix.shape[1]
X = F_fix.flatten(2)[0].T # (N, C)
if mode == "joint_pca":
X = torch.cat([X, F_mov.flatten(2)[0].T], 0)
mean = X.mean(0, keepdim=True)
if mode == "random":
g = torch.Generator().manual_seed(seed)
W = torch.randn(C, q, generator=g) / math.sqrt(C)
return W, mean
torch.manual_seed(seed) # randomized SVD is seeded
_, _, V = torch.pca_lowrank(X - mean, q=q, center=False, niter=4)
return V[:, :q], mean
def project(Fvol, W, mean):
B, C, D, H, Wd = Fvol.shape
X = Fvol.flatten(2)[0].T - mean
Z = (X @ W).T.reshape(1, W.shape[1], D, H, Wd)
return Z / (Z.std() + 1e-6) # global scale for a stable cost
# ---------------------------------------------------------------------------
# 5. ConvexAdam style solver S[Phi; v0]
# ---------------------------------------------------------------------------
def displacement_set(hw, device):
r = torch.arange(-hw, hw + 1, device=device, dtype=torch.float32)
dz, dy, dx = torch.meshgrid(r, r, r, indexing="ij")
return torch.stack([dz.flatten(), dy.flatten(), dx.flatten()], 1) # (L,3)
def cost_volume(f_fix, f_mov, hw):
"""C(x, u) = || Phi_fix(x) - Phi_mov(x + u) ||^2 on a coarse grid, Eq. 6.
Inputs are already pooled to the coarse grid. Returns (L, d, h, w)."""
_, C, d, h, w = f_fix.shape
pad = F.pad(f_mov, [hw] * 6, mode="replicate")
costs = []
for (z, y, x) in displacement_set(hw, f_fix.device).long().tolist():
sl = pad[..., hw + z:hw + z + d, hw + y:hw + y + h, hw + x:hw + x + w]
costs.append(((f_fix - sl) ** 2).sum(1))
return torch.cat(costs, 0)
def coupled_convex(cost, hw, iters=15, coeffs=(0.003, 0.01, 0.03, 0.1, 0.3, 1.0)):
"""Alternate between a smoothed field and a pointwise argmin of
cost(u) + alpha * ||u - u_smooth||^2 with growing coupling alpha."""
L, d, h, w = cost.shape
disps = displacement_set(hw, cost.device) # (L,3)
cost = cost / (cost.mean() + 1e-8)
idx = cost.argmin(0)
u = disps[idx].permute(3, 0, 1, 2)[None] # (1,3,d,h,w)
schedule = [coeffs[min(i * len(coeffs) // iters, len(coeffs) - 1)] for i in range(iters)]
for alpha in schedule:
u_s = box3d(box3d(u, 3), 3)
dist = ((disps.view(L, 3, 1, 1, 1) - u_s[0][None]) ** 2).sum(1)
u = disps[(cost + alpha * dist).argmin(0)].permute(3, 0, 1, 2)[None]
return box3d(u, 3)
def discrete_stage(feats_fix, feats_mov, grid_sp=6, hw=4, iters=15, weights=None):
"""feats_* are lists so that cost volume fusion can add normalised costs
from several representations (Table 1). One entry is the plain case."""
weights = weights or [1.0] * len(feats_fix)
full = feats_fix[0].shape[-3:]
def total_cost(A, B):
c = 0
for a, b, wgt in zip(A, B, weights):
ca = cost_volume(F.avg_pool3d(a, grid_sp), F.avg_pool3d(b, grid_sp), hw)
c = c + wgt * ca / (ca.mean() + 1e-8)
return c
u_fw = coupled_convex(total_cost(feats_fix, feats_mov), hw, iters)
u_bw = coupled_convex(total_cost(feats_mov, feats_fix), hw, iters)
u_ic = 0.5 * (u_fw - warp(u_bw, u_fw)) # inverse consistency
u = F.interpolate(u_ic * grid_sp, size=full, mode="trilinear", align_corners=False)
return u
def adam_stage(f_fix, f_mov, u0, iters=80, lr=1.0, grid=2, lam=1.25, box_w=3, n_box=3):
"""Instance optimisation of Eq. 2. The displacement lives on a parameter grid
of spacing `grid`, is upsampled, smoothed by n_box box filters of width
box_w, and scored by feature SSD plus lambda times the diffusion penalty."""
full = f_fix.shape[-3:]
coarse = [max(2, s // grid) for s in full]
param = nn.Parameter(F.interpolate(u0 / grid, size=coarse, mode="trilinear",
align_corners=False))
opt = torch.optim.Adam([param], lr=lr)
for _ in range(iters):
opt.zero_grad()
u = param
for _ in range(n_box):
u = box3d(u, box_w)
u_full = F.interpolate(u * grid, size=full, mode="trilinear", align_corners=False)
data = ((f_fix - warp(f_mov, u_full)) ** 2).mean()
reg = diffusion_penalty(u) # on the parameter grid
loss = data + lam * reg
loss.backward()
opt.step()
with torch.no_grad():
u = param
for _ in range(n_box):
u = box3d(u, box_w)
return F.interpolate(u * grid, size=full, mode="trilinear", align_corners=False)
def diffusion_penalty(u):
dz = u[:, :, 1:] - u[:, :, :-1]
dy = u[:, :, :, 1:] - u[:, :, :, :-1]
dx = u[..., 1:] - u[..., :-1]
return (dz ** 2).mean() + (dy ** 2).mean() + (dx ** 2).mean()
class ConvexAdamSolver:
"""One registration call S[Phi; v0]. Stage specific settings follow the paper:
MIND stage lam=1.25, 80 iters, lr 1.0, grid 2, three boxes of width 3.
Encoder stage 500 iters, lr 6.0, grid 1, two boxes of width 7, lam 1 or 2."""
def __init__(self, grid_sp=6, hw=4, cc_iters=15, adam_iters=80, lr=1.0,
param_grid=2, lam=1.25, box_w=3, n_box=3):
self.grid_sp, self.hw, self.cc_iters = grid_sp, hw, cc_iters
self.adam_iters, self.lr, self.param_grid = adam_iters, lr, param_grid
self.lam, self.box_w, self.n_box = lam, box_w, n_box
def __call__(self, feats_fix, feats_mov, v0=None, fusion_weights=None):
if not isinstance(feats_fix, (list, tuple)):
feats_fix, feats_mov = [feats_fix], [feats_mov]
u = discrete_stage(feats_fix, feats_mov, self.grid_sp, self.hw, self.cc_iters,
fusion_weights)
if v0 is not None:
u = u + v0
return adam_stage(feats_fix[0], feats_mov[0], u, self.adam_iters, self.lr,
self.param_grid, self.lam, self.box_w, self.n_box)
# ---------------------------------------------------------------------------
# 6. The FlexiMIND cascade, Eq. 7
# ---------------------------------------------------------------------------
class FlexiMIND(nn.Module):
def __init__(self, encoder, q=24, token_grid=(10, 10), projection="fixed_pca",
enc_solver=None, mind_solver=None, coupling="cascade", seed=0):
super().__init__()
self.encoder, self.q, self.token_grid = encoder, q, token_grid
self.projection, self.coupling, self.seed = projection, coupling, seed
self.mind = MINDSSC(radius=1, dilation=2)
self.enc_solver = enc_solver or ConvexAdamSolver(adam_iters=500, lr=6.0,
param_grid=1, lam=1.0,
box_w=7, n_box=2)
self.mind_solver = mind_solver or ConvexAdamSolver()
@torch.no_grad()
def encoder_features(self, fix, mov):
Ff = self.encoder(fix, self.token_grid)
Fm = self.encoder(mov, self.token_grid)
W, mean = fit_projection(Ff, Fm, self.q, self.projection, self.seed)
return project(Ff, W, mean), project(Fm, W, mean)
def forward(self, fix, mov):
"""fix, mov: (1,1,D,H,W), already affinely pre aligned. Returns the total
deformable displacement and the two stage fields."""
Fq_fix, Fq_mov = self.encoder_features(fix, mov)
if self.coupling == "cost_fusion": # Table 1, cost volume fusion
u1 = self.enc_solver([Fq_fix, self.mind(fix)], [Fq_mov, self.mind(mov)],
fusion_weights=[1.0, 1.0])
else: # reference sequential cascade
u1 = self.enc_solver(Fq_fix, Fq_mov)
mov_w = warp(mov, u1) # warp, then recompute MIND-SSC
u2 = self.mind_solver(self.mind(fix), self.mind(mov_w))
u = compose(u1, u2) # phi_u1 o phi_u2
return u, u1, u2
# ---------------------------------------------------------------------------
# 7. Evaluation, Eq. 1 and the metrics in Section 2.1
# ---------------------------------------------------------------------------
def jacobian_det(u):
"""Determinant of Id + grad u with central differences. u (1,3,D,H,W)."""
g = [torch.gradient(u[0, i], dim=(0, 1, 2)) for i in range(3)]
J = torch.stack([torch.stack(gi) for gi in g]) # J[i][j] = du_i / dx_j
J = J + torch.eye(3).view(3, 3, 1, 1, 1)
a, b, c = J[0, 0], J[0, 1], J[0, 2]
d, e, f = J[1, 0], J[1, 1], J[1, 2]
g_, h, i = J[2, 0], J[2, 1], J[2, 2]
return a * (e * i - f * h) - b * (d * i - f * g_) + c * (d * h - e * g_)
def sdlogj(u, mask=None, offset=3.0):
"""Learn2Reg style SDlogJ, log(det J + 3) clipped, Eq. 1. offset=0 gives the
offset free variant the paper used as a sensitivity check."""
det = jacobian_det(u)
gval = torch.log((det + offset).clamp(min=1e-9, max=1e9))
if mask is not None:
gval = gval[mask]
return gval.std().item()
def folding_fraction(u, mask=None):
det = jacobian_det(u)
if mask is not None:
det = det[mask]
return (det <= 0).float().mean().item()
def dice(a, b, labels):
out = {}
for l in labels:
A, B = a == l, b == l
denom = A.sum() + B.sum()
out[l] = (2 * (A & B).sum() / denom).item() if denom > 0 else float("nan")
return out
def tre(u, lm_fix, lm_mov, spacing=(1.0, 1.0, 1.0), round_to_voxel=True):
"""Mean Euclidean distance (mm) between moved fixed landmarks and the moving
landmarks. DIR-Lab convention rounds transformed points to voxel centres."""
pts = lm_fix.float()
idx = pts.round().long()
disp = u[0][:, idx[:, 0], idx[:, 1], idx[:, 2]].T
moved = pts + disp
if round_to_voxel:
moved = moved.round()
sp = torch.tensor(spacing)
return (((moved - lm_mov.float()) * sp).norm(dim=1)).mean().item()
@torch.no_grad()
def evaluate(u, seg_fix, seg_mov, labels, mask=None):
warped = warp(seg_mov.float(), u, mode="nearest").long()
d = dice(seg_fix, warped, labels)
return {"dice_mean": sum(d.values()) / len(d), "dice": d,
"sdlogj": sdlogj(u, mask), "sdlogj_no_offset": sdlogj(u, mask, offset=0.0),
"folding": folding_fraction(u, mask)}
# ---------------------------------------------------------------------------
# 8. Smoke test on synthetic volumes
# ---------------------------------------------------------------------------
def synthetic_pair(size=40, seed=0, invert_moving=True):
"""Three ellipsoid 'organs' in a body, a smooth random deformation, and an
intensity inverted moving image to imitate a change of modality."""
g = torch.Generator().manual_seed(seed)
D = H = W = size
c = voxel_grid((D, H, W), "cpu")[0]
def ell(cz, cy, cx, rz, ry, rx):
return (((c[0] - cz) / rz) ** 2 + ((c[1] - cy) / ry) ** 2 + ((c[2] - cx) / rx) ** 2) <= 1
body = ell(20, 20, 20, 17, 16, 18)
seg = torch.zeros(D, H, W, dtype=torch.long)
seg[ell(14, 16, 14, 5, 6, 5)] = 1
seg[ell(24, 24, 26, 6, 5, 5)] = 2
seg[ell(22, 14, 25, 4, 4, 4)] = 3
img = 0.2 * body.float() + 0.25 * seg.float()
img = box3d(img[None, None], 3) + 0.02 * torch.randn(1, 1, D, H, W, generator=g)
coarse = torch.randn(1, 3, 5, 5, 5, generator=g) * 2.5
u_true = F.interpolate(coarse, size=(D, H, W), mode="trilinear", align_corners=True)
mov = warp(img, u_true)
seg_mov = warp(seg[None, None].float(), u_true, mode="nearest").long()
if invert_moving:
mov = (mov.max() - mov) * body[None, None].float()
return img, mov, seg[None, None], seg_mov, body
if __name__ == "__main__":
torch.manual_seed(0)
torch.set_num_threads(2)
labels = [1, 2, 3]
show = lambda r: {k: round(v, 4) for k, v in r.items() if k != "dice"}
enc = FrozenSliceEncoder(c_in=96, patch=8) # stand in, NOT FlexiCT-2D
# Small search ranges and iteration counts so the test runs on a laptop CPU.
fast_enc = ConvexAdamSolver(grid_sp=4, hw=2, adam_iters=60, lr=2.0, param_grid=1,
lam=1.0, box_w=5, n_box=2)
fast_mind = ConvexAdamSolver(grid_sp=4, hw=2, adam_iters=40, lr=1.0, param_grid=2,
lam=1.25, box_w=3, n_box=3)
mind = MINDSSC()
# --- A. same modality toy pair: the full cascade and two coupling variants
fix, mov, seg_fix, seg_mov, body = synthetic_pair(invert_moving=False)
zero = torch.zeros(1, 3, *fix.shape[-3:])
print("A. same modality")
print(" before ", show(evaluate(zero, seg_fix, seg_mov, labels, mask=body)))
for name, kw in {"fleximind": dict(coupling="cascade", projection="fixed_pca"),
"random_proj": dict(coupling="cascade", projection="random"),
"cost_fusion": dict(coupling="cost_fusion", projection="fixed_pca")}.items():
t0 = time.time()
model = FlexiMIND(enc, q=12, token_grid=(10, 10), enc_solver=fast_enc,
mind_solver=fast_mind, **kw)
u, u1, u2 = model(fix, mov)
if name == "fleximind":
print(" encoder only ", show(evaluate(u1, seg_fix, seg_mov, labels, mask=body)))
u_flex = u
print(f" {name:15s}", show(evaluate(u, seg_fix, seg_mov, labels, mask=body)),
f"{time.time() - t0:.1f}s")
lm_f = torch.stack([(seg_fix[0, 0] == l).nonzero().float().mean(0) for l in labels])
lm_m = torch.stack([(seg_mov[0, 0] == l).nonzero().float().mean(0) for l in labels])
print(" centroid TRE before", round(tre(zero, lm_f, lm_m), 3),
"after", round(tre(u_flex, lm_f, lm_m), 3))
# --- B. inverted intensities, a crude stand in for a change of modality
fix, mov, seg_fix, seg_mov, body = synthetic_pair(invert_moving=True)
print("B. inverted moving image")
print(" before ", show(evaluate(zero, seg_fix, seg_mov, labels, mask=body)))
u_m = fast_mind(mind(fix), mind(mov))
r_m = evaluate(u_m, seg_fix, seg_mov, labels, mask=body)
print(" MIND-SSC only ", show(r_m))
model = FlexiMIND(enc, q=12, token_grid=(10, 10), enc_solver=fast_enc, mind_solver=fast_mind)
u, _, _ = model(fix, mov)
print(" cascade, random stand in encoder", show(evaluate(u, seg_fix, seg_mov, labels, mask=body)))
print(" (expected to fail: random conv features are not modality invariant,")
print(" which is exactly the job a pretrained encoder such as FlexiCT-2D does)")
assert math.isfinite(r_m["sdlogj"]) and r_m["dice_mean"] > 0.6
print("smoke test passed")
Frequently asked questions
What is FlexiMIND?
FlexiMIND is a training free and label free deformable image registration method from researchers at the University of Chicago. It runs two ConvexAdam registrations in sequence. Frozen FlexiCT-2D encoder features estimate a coarse deformation, then MIND-SSC descriptors refine the residual alignment. No network is trained on registration data.
How accurate is FlexiMIND?
Under the authors’ common protocol it reached a mean target registration error of 1.27 mm on DIR-Lab 4DCT lung CT, a Dice of 0.807 on ACDC cardiac MRI and an organ averaged Dice of 0.825 on Learn2Reg abdominal MR to CT. It was ahead of ConvexAdam with MIND-SSC, a reimplemented DINO-Reg and the encoder alone on all three datasets.
Does fusing pretrained features with MIND-SSC improve registration?
Not in this study. Five tighter coupling strategies were tested on three datasets. Only 4 of 15 comparisons beat the simple sequential cascade, by at most 0.0043 Dice, while the worst losses reached 20.6 percent in TRE and 37.9 percent in Dice.
Why does deformation regularity matter when comparing registration methods?
Changing the feature representation also changes how smooth the estimated deformation is, and smoothness affects landmark and overlap scores on its own. In the FlexiMIND ablations, accuracy changes closely tracked changes in SDlogJ, so a reported gain can reflect a different smoothness operating point rather than better correspondence.
Is FlexiMIND faster than other registration methods?
It ran 2.2 to 3.8 times faster than the authors’ reimplementation of DINO-Reg, and the MIND-SSC stage added only 1.5 to 3.5 percent to the encoder stage’s runtime. It was much slower than plain ConvexAdam, taking 106.4 to 187.4 seconds per pair against 4.6 to 29.2 seconds on the same GPU.
Can FlexiMIND be used in radiotherapy or diagnosis today?
No. It is an arXiv preprint evaluated on 10, 50 and 8 public cases, its code is promised on acceptance, and it has no regulatory clearance. Clinical registration needs validation on local data and review of the results by qualified staff.
Read the paper and explore the data
The full preprint includes per case distributions, the landmark scatter for all 3000 DIR-Lab points and the regularity plots behind the ablation. The abdominal MR to CT pairs and the official evaluation code come from the Learn2Reg challenge.
Safari, M., Hu, M., Wang, S., Xi, S., Lorenz, J., Pitroda, S., Oto, A., Weichselbaum, R. R., and Yang, X. FlexiMIND, combined pretrained vision features and local structure for training free deformable medical image registration. arXiv preprint arXiv:2610.34600v1, 25 October 2026. The work was supported in part by the National Institutes of Health, and the authors declare no conflicts of interest.
This analysis is based on the published paper and an independent evaluation of its claims.
