VitaProva

Methodology

This page is being written as the work is done.

Sections marked as placeholders are waiting on measurements that do not exist yet. We would rather show you the shape of the method and say what is missing than publish a finished-looking page with invented numbers. The measured results are on the benchmark page.

The short version

VitaProva estimates how much food is on the plate, identifies what it is, looks up its energy density, and combines those with their uncertainties into a range. Every step runs on your phone. Each step contributes error, and the range is our estimate of the total.

Depth capture

The hardest part of estimating a meal's energy from a photograph is estimating volume. A photograph alone does not say how deep a bowl of rice is.

  • LiDAR. On phones with a depth sensor we measure the surface directly and fit the plane of the table or plate to work out height above it.
  • Monocular depth. Without a depth sensor we estimate depth from the image alone. This is less certain, so the range is wider, and the app says which mode produced your estimate.
  • User-stated container. When no usable surface can be found, you tell us what the food is in — a plate, a bowl, a cup, a takeaway box — and we use the typical dimensions of that container. The range widens again.

These three are calibrated and reported separately. They are different measurements and blending them would hide the difference.

Container handling

the container classes, their assumed dimensions, and how a stated container widens the interval. Arrives with the in-house collection protocol.

Volume estimation

the volume integration, including how the food region is determined and how the plate plane is fitted. In the first published reference results the pipeline integrates over a single plate-level food region per dish rather than per-ingredient masks — the benchmark page says so for each run, because it changes what the number means.

Density model

the energy-density priors per dish class, where they come from, and how they are updated.

How the range is built

The range is not a fixed percentage. It is built from the measured spread of our own errors on weighed plates, per depth mode, and it is asymmetric because the errors are: it is easier to underestimate a dense dish than to overestimate a light one.

The 80% band is what the app shows by default — the 10th to 90th percentile of where we think the true value lies. The 90% band is in the detail view. The single point estimate is available on tap, never by default.

the interval construction per depth mode, and the calibration coefficients, once the in-house plates are collected and fitted.

Combining a plate with several components

A mixed dish is estimated per component and the components are combined. Their errors are not independent — if we have misjudged the portion size of one thing on a plate we have probably misjudged the others the same way — so they are combined with a correlation rather than added as if unrelated.

The within-plate correlation is fitted from our own residuals and labelled an estimate on every result that uses it. The across-meal correlation used for daily and weekly totals is set by policy at 0.8: it is a deliberately conservative choice rather than a measurement, and we state it here so the daily band can be read for what it is.

Where the nutrition numbers come from

  • USDA FoodData Central for energy and macronutrients, embedded in the app so it works offline. It is in the public domain; we credit it as a courtesy.
  • Open Food Facts for packaged foods, queried live when you scan a barcode. It is licensed under the Open Database Licence. We query it and never merge it into our own database.

The in-house collection protocol

Open datasets are captured under controlled conditions. Ours is captured the way people actually photograph food: hand-held, at the angle you happen to hold the phone, in the light the room happens to have. Every plate is weighed per ingredient before it is photographed.

the capture matrix, the weighing procedure, container and cuisine coverage, and the plate counts. Arrives from the collection protocol.

How we evaluate

A coverage figure measured on the same plates used to calibrate is meaningless. So:

  • Nutrition5k is evaluated only on its own published test split, with the calibration fitted on its training split.
  • Our in-house plates are split into two folds and each fold is evaluated using coefficients fitted on the other. Both folds are published.
  • The split is at plate level: every photograph of a given plate — both phones, every angle, every lighting condition — sits in the same fold, so a plate can never be in the fit set and the evaluation set at once.
  • The fit and evaluation plate lists are linked from the benchmark page so the split can be checked rather than taken on trust.

Nutrition5k informs the food-class and density priors and the coefficients for its own depth conditions only. The coefficients for hand-held LiDAR, monocular depth and stated containers come from our own plates alone. Nutrition5k's RGB-D data is fixed overhead rig depth, not phone LiDAR, and we never report it as a LiDAR result.

Limitations

  • Food we cannot recognise. Recognition breadth comes from a licensed model, and it does not know everything. When confidence is low the app asks you rather than guessing. The benchmark page reports results with our recogniser as well as with perfect labels, and the gap between them is the honest measure of this limitation.
  • Hidden ingredients. Oil absorbed in cooking, sugar in a sauce and butter in a mash are not visible in a photograph. This is a floor on how well any photo-based method can do.
  • Occlusion and stacking. Food hidden under other food is estimated, not measured.
  • Restaurant portions vary. The same dish differs between kitchens.
  • A range is still sometimes wrong. An 80% band is wrong about one time in five by construction. That is what the number means, and it is why we publish how often it held.