Skip to content

Commit 2bed82b

Browse files
committed
add detials for priors
1 parent 8b01dfb commit 2bed82b

2 files changed

Lines changed: 147 additions & 1 deletion

File tree

docs/observation/scale_observation.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,78 @@ Common aliases are normalised before lookup. Examples include `sofa` → `couch`
209209

210210
---
211211

212+
## How the Priors Were Generated
213+
214+
ScaleObservation relies on two distinct per-class tables, derived in two
215+
different ways. Both live in
216+
[`vizion3d/observation/defaults.py`](https://github.com/OlafenwaMoses/vizion3D/blob/main/vizion3d/observation/defaults.py).
217+
218+
### 1. Size priors — hand-authored physical references
219+
220+
The size priors (`SCALE_SIZE_PRIORS_M`, made up of the COCO and YOLOE tables)
221+
are **not fitted from any dataset**. Each class stores, per dimension, a
222+
`(mean_m, sigma_m)` pair plus a coarse per-class reliability weight `r`:
223+
224+
- `mean_m` — a representative real-world size in metres.
225+
- `sigma_m` — a deliberately wide spread, because these are *priors*, not exact
226+
measurements. High-variance classes (vase, potted plant, box) get large sigmas
227+
and low `r`.
228+
- `r` — how much the class is trusted to drive scene scale at all.
229+
230+
The means and sigmas are taken from public reference catalogues, and the source
231+
for each class is recorded inline in `defaults.py`. The families used are:
232+
233+
| Class group | Reference source |
234+
|---|---|
235+
| `person` | CDC/NCHS adult stature tables (height); broad body-envelope for width/depth |
236+
| `chair` | BIFMA / ergonomic chair ranges and product dimensions |
237+
| `couch`, `bed`, `dining table`, `sink` | Dimensions.com collections and common product sizes |
238+
| `toilet` | Rempros / Angi toilet dimension guides |
239+
| `tv` | Dimensions.com display references (43–55 in) |
240+
| `refrigerator` | RTINGS refrigerator size guide |
241+
| `microwave`, `oven`, electronics | KitchenAid / Wayfair guides and common product specifications |
242+
| Expanded YOLOE furniture, fixtures, appliances | Common product-dimension references, authored the same way |
243+
244+
A per-class/per-dimension **reliability table**
245+
(`DIMENSION_RELIABILITY_BY_LABEL`) is likewise hand-tuned. It encodes which axes
246+
of a class are stable enough to influence scene scale — for example a person's
247+
height is trusted while their depth is not, and a TV's thin depth is treated as
248+
near-useless.
249+
250+
### 2. Calibration corrections — learned from ground truth
251+
252+
The calibration table (`CALIBRATED_SCALE_CORRECTION_BY_LABEL_DIM`) **is** learned
253+
from data. It is applied as a per-class/per-dimension multiplier on each
254+
candidate's proposed scale, correcting systematic biases in how the monocular
255+
depth backend sizes objects.
256+
257+
It was derived from a full **SUN RGB-D** pipeline run (originally the first
258+
object-consensus pass). For every accepted object/dimension candidate:
259+
260+
1. Recover the candidate's uncalibrated scale.
261+
2. Compare it to the ground-truth **dimension-specific scene scale**, i.e.
262+
`gt_bounds[dim] / generated_bounds[dim]` for that axis.
263+
3. Take the per-`(label, dimension)` correction as the robust **median** of
264+
those ratios.
265+
4. **Shrink toward 1.0** when a class has little support, so rarely-seen classes
266+
do not receive over-confident corrections.
267+
268+
Because the depth backend systematically over-sizes objects, most learned
269+
factors are below `1.0` (for example `tv` height ≈ `0.46`, `chair` height ≈
270+
`0.57`). Classes and dimensions without an entry default to `1.0`
271+
(uncalibrated) — this currently includes all the expanded YOLOE classes.
272+
273+
The derivation is reproducible (and extensible to new classes) with the research
274+
script:
275+
276+
```bash
277+
uv run python research/SCALE_OBSERVATION_RESEARCH/derive_scale_calibration.py \
278+
research/SCALE_OBSERVATION_RESEARCH/outputs/scale_observation_v4_current \
279+
--min-support 8 --shrink-k 12
280+
```
281+
282+
---
283+
212284
## Command Parameters
213285

214286
`ScaleObservationCommand` is the direct Python input contract.

vizion3d/observation/defaults.py

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,86 @@
1-
"""Defaults and semantic priors for ScaleObservation."""
1+
"""Defaults and semantic priors for ScaleObservation.
2+
3+
How these tables were generated
4+
-------------------------------
5+
ScaleObservation uses two distinct kinds of per-class knowledge, derived two
6+
different ways:
7+
8+
1. **Size priors** (``SCALE_SIZE_PRIORS_M`` = COCO + YOLOE tables below). These
9+
are *hand-authored* broad physical priors, NOT fitted from any dataset. Each
10+
entry is ``{dimension: (mean_m, sigma_m), ..., "r": reliability}`` where
11+
``mean_m``/``sigma_m`` are a real-world size estimate and its spread in
12+
metres, and ``r`` is a coarse per-class trust weight. Means/sigmas are taken
13+
from public reference catalogues (anthropometric stature tables, furniture
14+
and appliance size guides, common product specifications); the per-class
15+
``# Source:`` comments record where each came from. Sigmas are intentionally
16+
wide -- these are size *priors*, not exact dimensions.
17+
18+
2. **Calibration corrections** (``CALIBRATED_SCALE_CORRECTION_BY_LABEL_DIM``).
19+
These ARE learned from data -- see the comment on that table for the method
20+
and the reproduction script.
21+
22+
The per-dimension reliability weights (``DIMENSION_RELIABILITY_BY_LABEL``) are
23+
also hand-tuned: they encode which axes of a class are stable enough to drive
24+
scene scale (e.g. a person's height is trustworthy, their depth is not).
25+
"""
226

327
from __future__ import annotations
428

29+
# COCO-aligned size priors, in metres. Intentionally broad physical priors, not
30+
# exact object dimensions. Each value is ``(mean_m, sigma_m)``; ``r`` is the
31+
# per-class reliability weight. Sources are cited per class below.
532
COCO_SIZE_PRIORS_M: dict[str, dict[str, object]] = {
33+
# Source: CDC/NCHS adult stature references for height; width/depth are broad
34+
# body-envelope priors, not a fixed anthropometric standard.
635
"person": {"height": (1.70, 0.15), "width": (0.45, 0.10), "depth": (0.30, 0.10), "r": 0.80},
36+
# Source: BIFMA/ergonomic chair ranges and common dining/office chair product dimensions.
737
"chair": {"height": (0.85, 0.18), "width": (0.50, 0.12), "depth": (0.55, 0.14), "r": 0.70},
38+
# Source: Dimensions.com sofa/couch references and common 2-3 seat sofa product ranges.
839
"couch": {"height": (0.85, 0.18), "width": (2.00, 0.45), "depth": (0.90, 0.20), "r": 0.65},
40+
# Source: Dimensions.com queen bed / Sleep Foundation queen mattress dimensions;
41+
# height includes a broad mattress/frame allowance.
942
"bed": {"height": (0.60, 0.18), "width": (1.60, 0.35), "depth": (2.05, 0.30), "r": 0.75},
43+
# Source: Dimensions.com dining table collection and common 4-person table dimensions.
1044
"dining table": {
1145
"height": (0.75, 0.08),
1246
"width": (1.40, 0.40),
1347
"depth": (0.90, 0.25),
1448
"r": 0.65,
1549
},
50+
# Source: Rempros/Angi toilet dimension guides; height/depth cover tank and bowl envelope.
1651
"toilet": {"height": (0.75, 0.10), "width": (0.38, 0.08), "depth": (0.70, 0.12), "r": 0.80},
52+
# Source: Dimensions.com TV display references and common 43-55 inch TV sizes.
1753
"tv": {"height": (0.65, 0.25), "width": (1.10, 0.40), "depth": (0.08, 0.05), "r": 0.60},
54+
# Source: common 13-15 inch laptop product specifications; very weak height prior.
1855
"laptop": {"height": (0.02, 0.01), "width": (0.34, 0.06), "depth": (0.24, 0.04), "r": 0.45},
56+
# Source: common full-size keyboard specifications, approximately 17 x 5.5 inches.
1957
"keyboard": {"height": (0.03, 0.01), "width": (0.43, 0.08), "depth": (0.14, 0.04), "r": 0.45},
58+
# Source: common desktop mouse product specifications.
2059
"mouse": {"height": (0.04, 0.02), "width": (0.065, 0.02), "depth": (0.11, 0.03), "r": 0.35},
60+
# Source: ISO/US common book trim sizes; intentionally broad due to high variation.
2161
"book": {"height": (0.03, 0.02), "width": (0.18, 0.08), "depth": (0.25, 0.08), "r": 0.35},
62+
# Source: RTINGS refrigerator size guide and common full-size fridge product ranges.
2263
"refrigerator": {
2364
"height": (1.70, 0.25),
2465
"width": (0.75, 0.15),
2566
"depth": (0.75, 0.15),
2667
"r": 0.80,
2768
},
69+
# Source: KitchenAid/Wayfair microwave size guides; typical countertop/OTR envelope.
2870
"microwave": {"height": (0.30, 0.08), "width": (0.50, 0.10), "depth": (0.40, 0.08), "r": 0.65},
71+
# Source: common 24 inch built-in/range oven product dimensions.
2972
"oven": {"height": (0.75, 0.15), "width": (0.60, 0.10), "depth": (0.60, 0.10), "r": 0.70},
73+
# Source: Dimensions.com kitchen sink collection and common 22 x 30 inch sink guides.
3074
"sink": {"height": (0.20, 0.10), "width": (0.55, 0.18), "depth": (0.45, 0.15), "r": 0.45},
75+
# Source: common decorative vase product dimensions; high variance, low reliability.
3176
"vase": {"height": (0.30, 0.18), "width": (0.16, 0.10), "depth": (0.16, 0.10), "r": 0.30},
77+
# Source: common beverage bottle dimensions; high category variance.
3278
"bottle": {"height": (0.25, 0.12), "width": (0.08, 0.04), "depth": (0.08, 0.04), "r": 0.35},
79+
# Source: Dimensions.com coffee mug/cup references and common mug product dimensions.
3380
"cup": {"height": (0.10, 0.04), "width": (0.08, 0.03), "depth": (0.08, 0.03), "r": 0.30},
81+
# Source: common cereal/soup bowl product dimensions; high category variance.
3482
"bowl": {"height": (0.08, 0.04), "width": (0.18, 0.08), "depth": (0.18, 0.08), "r": 0.30},
83+
# Source: common indoor potted plant product ranges; intentionally weak prior.
3584
"potted plant": {
3685
"height": (0.70, 0.45),
3786
"width": (0.45, 0.30),
@@ -42,6 +91,10 @@
4291

4392
DEFAULT_DIMENSION_RELIABILITY = {"height": 0.75, "width": 0.65, "depth": 0.35}
4493

94+
# Hand-tuned per-class/per-dimension trust weights in [0, 1]. The prior means
95+
# above stay as broad size references; these weights control whether a given
96+
# axis is stable enough to drive scene scale (e.g. person height is reliable,
97+
# person depth is not; a tv's thin depth is near-useless).
4598
DIMENSION_RELIABILITY_BY_LABEL: dict[str, dict[str, float]] = {
4699
"person": {"height": 0.90, "width": 0.25, "depth": 0.10},
47100
"chair": {"height": 0.65, "width": 0.55, "depth": 0.45},
@@ -68,6 +121,13 @@
68121
COCO_PRIOR_LABELS = frozenset(COCO_SIZE_PRIORS_M)
69122

70123

124+
# Expanded prompt-free YOLOE size priors, in metres. Same authoring method and
125+
# format as COCO_SIZE_PRIORS_M above: hand-set ``(mean_m, sigma_m)`` from common
126+
# furniture/fixture/appliance/electronics product-dimension references, not
127+
# fitted from data. These are consumed only when ObjectMaskAnnotation3D is run
128+
# with the YOLOE prompt-free checkpoint, which emits this wider label set.
129+
# NOTE: these classes have no entry in CALIBRATED_SCALE_CORRECTION_BY_LABEL_DIM
130+
# yet, so their calibration factor defaults to 1.0 (uncalibrated).
71131
YOLOE_SIZE_PRIORS_M: dict[str, dict[str, object]] = {
72132
"armchair": {"height": (0.90, 0.18), "width": (0.78, 0.22), "depth": (0.82, 0.20), "r": 0.62},
73133
"office chair": {
@@ -315,6 +375,20 @@
315375
}
316376

317377

378+
# Learned (not hand-authored) per-class/per-dimension scale corrections, applied
379+
# as multipliers on each candidate's proposed scale at
380+
# scale.py:calibration_factor(). Derivation: from a full SUN RGB-D pipeline run
381+
# (originally the first v2_scene_object_consensus pass), each accepted
382+
# object/dimension candidate's *uncalibrated* scale was compared to the
383+
# ground-truth dimension-specific scene scale (gt_bounds[dim] / generated_bounds[dim]);
384+
# the per-(label, dimension) correction is the robust median of those ratios,
385+
# shrunk toward 1.0 when class support is low. Values < 1.0 dominate because the
386+
# monocular-depth backend systematically over-sizes objects. Classes/dimensions
387+
# absent here default to 1.0.
388+
#
389+
# Reproduce / extend (e.g. to add the YOLOE classes) with:
390+
# uv run python research/SCALE_OBSERVATION_RESEARCH/derive_scale_calibration.py \
391+
# research/SCALE_OBSERVATION_RESEARCH/outputs/scale_observation_v4_current
318392
CALIBRATED_SCALE_CORRECTION_BY_LABEL_DIM: dict[str, dict[str, float]] = {
319393
"bed": {"depth": 0.6757},
320394
"book": {"height": 1.0, "width": 0.6788, "depth": 0.4039},

0 commit comments

Comments
 (0)