Stain Shift
Stain normalisation and stain augmentation: Macenko vectors, inter-lab shift and its effect on an attention-MIL network
🎯 Learning objectives
- Explain the difference between pixel intensity and optical density, and why stain is linear in OD space
- Show stain vectors and concentrations on a patch; say what Macenko estimation does
- Apply the three steps of normalisation (unmix → scale → recolour) and read the result in the image and in the measurement
- State the difference between normalisation and augmentation, and how the two cure the same trap by different routes
- List the limits of normalising to a single reference and of tissue-dependent vector estimation
The simulation
Why stain lives in OD space
A camera measures pixel intensity; a stain absorbs light. By the Beer–Lambert law absorbance is linear in stain amount and logarithmic in intensity. So the first step is converting every channel to optical density: OD = −log((I+1)/256). In OD space pure haematoxylin is one direction, pure eosin another; any pixel’s colour is the sum of those two directions weighted by concentrations. Colour deconvolution (Ruifrok and Johnston 2001) inverts that sum; QuPath’s stain separation and its “stain vectors” setting are exactly this.
Where do the vectors come from? The Macenko method (Macenko et al. 2009) finds them without supervision: take the tissue’s OD cloud, project it onto the plane of its two widest axes, and pick the directions at the cloud’s two extremes (the 1st and 99th percentiles of angle) as H and E. Step 1 of the simulation runs this on 30 patches of each lab and finds an angle of about 14° between the two labs’ H vectors and 99th-percentile concentrations of 2.35 versus 1.40. Structure-preserving (sparse) separation (Vahadane et al. 2016) does the same job more robustly; the principle is the same.
What normalising means
Take a patch from B: unmix it into concentrations with B’s vectors, scale each stain’s concentration to A’s 99th percentile, recolour with A’s vectors. The middle square of the triptych is that. In the histogram beside it, the two labs’ x₆ distributions (mean H concentration per patch) are separate when raw and coincide after normalisation.
Normalisation and augmentation: two cures for one trap
The trap in Slide Bag Net was this: with 90% of training mutants from lab B, the network learned the stain instead of the biology and test AUROC fell. This time the same network is trained with four preprocessing choices:
- None: the trap as it is.
- Normalise: training and test patches are normalised onto A; x₆ no longer tells the labs apart and most of the measurement distortion goes.
- Augment: the image is left alone; during training every slide’s measurements are perturbed each epoch by a random stain shift (t ∈ [−1.2, 1.2] along the distortion axis plus a random shift of x₆). The network cannot rely on stain. Training-only.
- Both.
The two cures leave different traces: normalisation raises test AUROC most but the network still reads x₆ (stain weight 3.3); augmentation makes the network nearly abandon x₆ (0.4). The literature shows the same picture: augmentation gives the most consistent gain, the contribution of normalisation varies by method and dataset, and the combination is safest (Tellez et al. 2019). Recall how site-specific signatures inflate predictors (Howard et al. 2021); preprocessing is only part of the cure, site-stratified splits are the other part.
Lecture recipe (35 min)
1
Stains. Show the two strips; B is paler and more purple. In the OD scatter, show that B’s cloud is shorter along the H axis and the arrow pairs point in different directions; read the angle.
2
Normalise. Pick a B patch; explain the middle square of the triptych. Show the distributions collapsing in the histogram. Read the distortion table and say that it is an assumption.
3
Train · none. Confound on, preprocessing none. 200 epochs; the row is added automatically. Point out the size of the stain weight and the highlighted x₆ column in the weight map.
4
Normalise → augment → both. Reset and train for each. Read the four-row table together: the AUROC column and the stain-weight column tell different stories.
5
Switch the confound off, add one more row with none. Preprocessing pays only where there is shift.
6
Test. Run the exam; look at the lab-B dots in the strip of calls. Then read the single-reference trap.
Limits of a single reference
Normalisation needs a target and hides three things. A’s own variability becomes the standard. Macenko vectors depend on tissue content: necrosis, ink, blood or a mostly-stromal region produce a different “stain vector”, which is why QuPath asks you to estimate vectors on a representative area. And a lab C never seen in training, with a different eosin and scanner, may not be fixed by normalisation, which is nothing more than two pairs of vectors; augmentation is more robust there. In a real pipeline both operations act on patch pixels, not on measurements; foundation models are mostly pretrained with augmentation and used without normalisation.
Check yourself
Why convert to optical density first instead of working with pixel intensity?
In the table, normalisation lifts test AUROC to 0.94 but the stain weight stays at 3.3; augmentation gives 0.93 with a stain weight of 0.4. What does the difference tell you?
What happens if you run Macenko estimation on a region with necrosis and ink?
References
Works cited on this page are listed below; for the whole series see References.