About this research: This benchmark was built by the team behind UndertoneOnline and the ToneFit app, to choose the white-balance settings the app ships with. It uses synthetic colors, not photographs of real people. We publish it because the main finding applies to every photo-based color analysis app, including ours — and one of its results is unflattering to the method we use.
Key findings
- Lighting alone can flip an undertone reading. Without correction, strong warm light cut agreement with the neutral-light result from 100% to 57%. A cool, fair complexion read as warm; a neutral one also read as warm.
- With a neutral background, correction nearly eliminates the problem. Across 294 cases with a white, off-white, or light gray wall, white-balance correction raised agreement from 79.6% to 99.7%, rescued 59 cases, and made none worse.
- With a colored background, correction makes things worse. Across 343 cases with beige, wood, cream, pink, or blue walls, the same correction lowered agreement from 79.6% to 73.8% — it rescued 32 cases and broke 52.
- No amount of pixel math can fully separate the two situations. A neutral wall under warm light and a beige wall under neutral light can produce nearly the same pixels. The only reliable fix is on the user's side: photograph against a plain white or gray wall.
Why this happens
A camera does not record skin color. It records skin color multiplied by the color of the light. A warm tungsten bulb adds red and removes blue from everything in the frame — including your skin — so a cool undertone can look warm, and a neutral one can look golden.
Phone cameras already apply automatic white balance, but it is tuned to make photos look pleasing, not to measure skin. What remains after it is a residual color cast, and that residual is what a color analysis app has to deal with.
Most correction methods estimate the light from the scene itself. The classic assumption, from the gray-world model (Buchsbaum, 1980), is that the scene averages out to gray, so any overall tint must come from the light. Shades of Gray (Finlayson & Trezzi, 2004) generalizes this with a Minkowski norm and is more robust in practice. Both work well when the assumption holds — and fail predictably when it does not. A beige wall is not gray on average, so the method concludes the light is beige and "corrects" your skin in the wrong direction.
That is also why different apps disagree. Some correct, some do not, and they estimate the light from different parts of the image. Put the same face in front of the same warm lamp and a beige wall, and each app is solving a slightly different, ambiguous problem.
Method
The benchmark is a 178-line Python simulation. Every parameter is listed here so the setup can be reproduced.
Cases: 7 skin colors × 7 lights × 13 backgrounds = 637 cases.
Skin colors (sRGB):
| Sample | RGB | Reading under neutral light |
|---|---|---|
| Cool, fair | 240, 200, 196 | cool |
| Cool, medium-deep | 176, 128, 124 | cool |
| Neutral | 232, 192, 172 | neutral |
| Neutral, medium-deep | 168, 136, 120 | neutral |
| Warm, fair | 245, 195, 145 | warm |
| Warm, olive | 200, 180, 140 | warm |
| Deep | 120, 85, 62 | neutral |
Lights are modeled as per-channel multipliers on sRGB (R, G, B), approximating the cast left over after a camera's automatic white balance: neutral (1.00, 1.00, 1.00); warm mild / moderate / strong (1.06, 1.00, 0.92), (1.10, 1.00, 0.85), (1.16, 1.00, 0.76); cool mild / moderate / strong (0.94, 1.00, 1.07), (0.88, 1.00, 1.14), (0.82, 1.00, 1.22).
Backgrounds each have five shading levels (0.55 to 1.08 of the base color), so clipping affects only highlights rather than whole surfaces:
- Neutral (6): white wall, off-white wall, light gray wall, white wall with wood furniture, white wall with a green plant, white wall with a dark corner
- Colored (7): beige wall, wood-paneled wall, blue-gray wall, bright cream wall, sunlit wood wall, pink bedroom wall, light blue wall
Undertone rule: the skin color is converted to hue and saturation. Saturation below 5% reads neutral; otherwise hue below 14° reads cool, 26° or above reads warm, and anything between reads neutral.
Ground truth: each skin color's reading under neutral light. This measures consistency — whether lighting changes the answer — not agreement with a human analyst.
Correction (the method ToneFit ships):
- Estimate the light from the background only, never from the skin, using a Shades of Gray mean with Minkowski norm p = 6 in linear light, ignoring near-black and near-clipped pixels
- Apply per-channel gains in linear light, capped at 1.8×; when a cap is hit, all three channels are scaled down together so the correction keeps its direction
- Abstain when the background's color is too close to the skin's (log-chromaticity distance below 0.20), because the estimate is then measuring the subject, not the light
Results in detail
By lighting and background (agreement with the neutral-light reading, before → after correction):
| Light | Neutral backgrounds | Colored backgrounds |
|---|---|---|
| Neutral | 100% → 100% | 100% → 76% |
| Warm, mild | 86% → 100% | 86% → 76% |
| Warm, moderate | 71% → 100% | 71% → 78% |
| Warm, strong | 57% → 98% | 57% → 71% |
| Cool, mild | 100% → 100% | 100% → 73% |
| Cool, moderate | 71% → 100% | 71% → 69% |
| Cool, strong | 71% → 100% | 71% → 73% |
The colored-background column shows the trade-off most clearly: under neutral light, where no correction is needed, a colored wall alone drags agreement from 100% down to 76%.
Parameter sweeps (all 637 cases; the uncorrected baseline is 79.6%):
| Setting | Values tested → overall agreement |
|---|---|
| Minkowski norm p | 1 → 81.6% · 2 → 84.5% · 4 → 85.4% · 6 → 85.7% · 8 → 85.7% |
| Gain cap | 1.15 → 81.3% · 1.4 → 84.5% · 1.8 → 85.7% · 2.2 → 84.9% · 3.0 → 84.0% |
| Abstain threshold | off → 82.1% · 0.12 → 82.6% · 0.20 → 85.7% · 0.30 → 84.9% |
Higher gain caps rescue a few more cases but break more than they rescue. The abstain threshold matters most: without it, the method "corrects" close-up shots where the background is mostly the subject.
Limitations
- Synthetic, not photographic. The skin and wall colors are single RGB values, not real faces, and the light model is a simple channel multiplier. Real photos add sensor noise, uneven light, shadows, and each phone's own processing.
- Consistency, not accuracy. Ground truth is the reading under neutral light, not a trained analyst's judgment. The benchmark shows how much lighting moves a reading, not whether the reading is right.
- A deliberately simple classifier. The hue rule reads the deep skin sample as neutral, which a human analyst might not. Any real app uses more information than one averaged color.
- One correction method. Other methods, or learned models, may behave differently — but any method that estimates light from the scene faces the same ambiguity between a colored wall and colored light.
What this means when you take a color analysis photo
These apply to any photo-based app, not only ours:
- Stand in front of a plain white or light gray wall. This is the single biggest factor you control. Avoid beige, wood, pink, or blue walls.
- Use indirect daylight near a window. Avoid warm bulbs, direct sun, and mixed light sources.
- Skip makeup and tinted skincare on the areas the app reads.
- If two apps disagree, reshoot before you trust either one. A different result in better conditions is more informative than a confident result in poor ones.
ToneFit's capture screens tell you to avoid colored backgrounds for exactly this reason: the correction it applies depends on it. For how other apps handle your photo, see our comparison of 10 color analysis apps; to check your undertone without a camera, try the free undertone test.
References
- Buchsbaum, G. (1980). A spatial processor model for object colour perception. Journal of the Franklin Institute, 310(1), 1–26.
- Finlayson, G. D., & Trezzi, E. (2004). Shades of Gray and Colour Constancy. Proceedings of the IS&T/SID Color Imaging Conference, 37–41.
