3D plant analysis

Development preview — not validated house_plant_20260919 · 269,833 gaussians · measured in metres from a gravity-aligned capture

What this measures, and why it needed 3D

A photograph flattens a plant. Leaves that sit above one another become one shape, a leaf seen edge-on has no measurable area, and a gap in a blade looks the same as a shadow. This capture is metric and gravity-aligned, so leaf count, leaf area, height and leaf area index stop being estimated from appearance and become geometry.

2.99leaf area index (LAI)
1.323 mplant height
146leaf surfaces found
1.415 m²observed leaf area
0.4735 m²ground rectangle
What one photo can measure canopy cover 0.52 What the 3D capture measures LAI 2.99 1.00 — the ceiling canopy cover can never pass

Canopy cover — the best a single top-down photo can do — is 0.52. It cannot exceed 1.00 no matter how leafy the plant is, because two leaves above each other shadow one patch of ground. The same plant measured in 3D has an LAI of 2.99: the 2D number under-reports the real leaf surface by 5.7×. Averaged over the footprint there are 2.65 leaf layers above every covered patch of ground; 65% of the footprint has two or more, 35% has three or more. A photograph sees only the top one.

1 · The plant, turnable

Drag to rotate, scroll to zoom, and set the splat size and how many are drawn. All 269,833 gaussians are rasterised the way a 3DGS renderer does them — an oriented, alpha-blended ellipse each, depth-sorted every frame, with view-dependent colour from the capture’s spherical harmonics. The measurements are drawn in the same space as the plant, so the rectangle and the height ruler are the actual quantities, not a legend.

The same turn, three ways

All three are live, from the same gaussians and the same splat-size and splats-drawn settings as the view above — drag the orbit slider and they turn together.

as captured
one colour per resolved leaflet
coloured by height, with the 1.323 m ruler

2 · Height and footprint

Height: 1.323 m

Measured along the capture's own gravity vector, which was recorded by the device rather than inferred. The canopy itself spans 1.211 m.

Measured on gaussian centres, deliberately. A disc's rim is a modelled extent, not observed surface, and at the pot base a few large splats push the floor down 57 mm; the canopy top moves 0.6 mm. So the extremum is taken where it is a sample of something a camera actually saw. Measured rim to rim instead, the model spans 1.380 m — 57 mm more, essentially all of it pot.

Ground rectangle: 0.714 × 0.663 m

The smallest rectangle that encloses the plant's footprint — the LAI denominator. It is a declared choice, and LAI means nothing without naming it.

0.714 m 0.663 m green = foliage footprint · dashed = minimum-area rectangle (0.4735 m²)
1.0 m leaf area per 5 cm band → peak 2276 cm²

3 · Every leaflet, measured

146leaflets resolved — the declared unit
95%of the leaf material sits inside one of them
35.6 cm²median area
0.685 m²summed outlines, scaled to all foliage — a floor
Cutting at creases and growing the labels back puts 95% of the leaf material inside a leaflet; the remaining 5% is surface no blade could claim, and it is drawn in olive in the viewer above under “Leaf instances”. So 146 is a count of resolved leaf surfaces, not a leaf count of the plant, and the summed-outline area is scaled up by that coverage rather than measured across the whole canopy. A hand count of the real plant is still the only thing that would turn it into a leaf count.

Each blade below is the viewer’s own render of that one leaflet, seen down its own normal with the rest of the plant hidden — the same gaussians and the same rasteriser as section 1, which is a view no single photograph of this plant contains. Largest first.

leaflet 0
#0 · 215 cm² · 50° · fill 0.61
leaflet 1
#1 · 168 cm² · 68° · fill 0.88
leaflet 2
#2 · 141 cm² · 79° · fill 0.33
leaflet 3
#3 · 141 cm² · 85° · fill 0.34
leaflet 4
#4 · 118 cm² · 88° · fill 0.61
leaflet 5
#5 · 107 cm² · 43° · fill 0.79
leaflet 6
#6 · 102 cm² · 78° · fill 0.90
leaflet 7
#7 · 95 cm² · 50° · fill 0.99
leaflet 8
#8 · 92 cm² · 51° · fill 0.94
leaflet 9
#9 · 92 cm² · 82° · fill 0.36
leaflet 10
#10 · 92 cm² · 44° · fill 0.71
leaflet 11
#11 · 91 cm² · 25° · fill 1.00
leaflet 12
#12 · 90 cm² · 21° · fill 0.91
leaflet 13
#13 · 88 cm² · 32° · fill 0.50
leaflet 14
#14 · 87 cm² · 51° · fill 0.94
leaflet 15
#15 · 87 cm² · 19° · fill 0.94
leaflet 16
#16 · 84 cm² · 24° · fill 0.91
leaflet 17
#17 · 83 cm² · 30° · fill 0.95
leaflet 18
#18 · 72 cm² · 24° · fill 0.62
leaflet 19
#19 · 72 cm² · 41° · fill 0.76
leaflet 20
#20 · 70 cm² · 18° · fill 0.95
leaflet 21
#21 · 68 cm² · 22° · fill 1.00
leaflet 22
#22 · 68 cm² · 26° · fill 0.93
leaflet 23
#23 · 66 cm² · 71° · fill 0.99

The same question asked in 2D and in 3D

questionwhat one photograph giveswhat the 3D capture gives
How many leaflets?91 at best, 82 typical — the rest are hidden behind the ones in front146, and the count barely moves when the capture is thinned eight-fold
How much leaf area?canopy cover 0.52, capped at 1.00 by construction1.415 m² → LAI 2.99
How tall?not measurable without a scale reference in frame1.323 m, from the device's own gravity vector
Is a dark patch a hole?indistinguishable from shadowan absence of surface, and rankable
What angle is each leaf at?not recoverable from one projectionper-leaf inclination, in degrees

The leaf-count row is measured, not asserted: each turntable viewpoint was re-rendered as a label image, and a leaf counts as visible only when its own surface survives occlusion into at least 120 pixels. That is the ceiling on what any single image could report.

Leaves with the most missing blade

Fill is the occupied blade divided by its outline. A low value means a gap in the surface: damage, a hole, or tissue the capture never saw. This is the defect a single photo genuinely cannot resolve — in projection a hole and a dark patch are the same pixels; in 3D one is an absence of surface. It does not separate real damage from poor coverage, so treat it as a ranking that tells you which leaves to look at, not as a damage measurement.

Ranked among leaves of at least 40 cm², where the fill fraction is meaningful.

leafletarea cm²fill
#21410.33
#31410.34
#9920.36
#40520.47
#44500.47
#13880.50

4 · How a leaflet is found

The same plant five times, the same camera. The question these answer is “why did it cut there?”, and it is the middle two panels: a boundary is either a bend or a step, and until this pass the method looked only for bends.

As captured
1. As captured
one branch, every gaussian, natural colour.
Where the surface bends
2. Where the surface bends
green where a facet agrees with every neighbour, red where it disagrees with any. Red is most of this canopy — the leaves overlap, fold and touch — and the green islands are the flat middles of blades.
Where it steps
3. Where it steps
the other half, and the one the method was missing: green where a neighbour lies on this facet’s own plane, red where it sits off it. Two leaves one in front of the other are parallel — the bend above sees nothing between them, and only this does.
Keep only the green
4. Keep only the green
the blade interiors fall apart on their own once the red is gone, one label each. Nothing here was told how big a leaflet is, or how many to look for.
Grow them back
5. Grow them back
each label spreads back over the red until it runs into another label, so the blade is whole again and the boundary lands on the crease that separated them.

Why this is a measurement and the old one was not

Region growing used to end a leaflet wherever its running normal had drifted far enough, which is an arbitrary place mid-blade: the instance count slid from 402 to 12 across settings that all looked reasonable. Cutting at creases instead holds the median leaflet to 31.9% across the whole sweep below, and the count to 13% across the plateau. A number that ignores its own knob is a property of the plant.

creaseleafletsmedian cm² median length cm
25°7752.513.1
30°9945.611.6
35°11638.411.5
40°12838.810.3
45°14635.810.6
50°14537.810.7
55°14737.210.9

What is a leaf here, then?

A money tree carries palmately compound leaves: one leaf is a petiole ending in a whorl of five to seven leaflets. The blade this pipeline resolves is a leaflet, and that is the unit every count in this report uses.

Grouping leaflets back into their whorls is not identifiable from this capture. The group count just follows the clustering distance and almost never lands on a whorl of five to seven, because the petiolule region is crease everywhere so it is cut away, and the inner canopy where petioles meet is exactly what a single planar camera ring never saw. Reported below for completeness, claimed as nothing.
junctiongroupswhorls of 5–7 singletons
5 cm100168
7 cm78340
9 cm62621
11 cm53914

5 · Is the plant healthy?

The app's generic symptom head cannot answer this: it has no healthy class and always names a symptom family. The D2 healthy/diseased head can, and it is run here over the real photographs.

51frames called healthy
20frames called diseased
0.16median p(diseased)
0.545fitted threshold

Over 71 real photographs of the same plant, the head disagrees with itself depending on the viewpoint: 20 of 71 frames cross the threshold. That disagreement is itself the finding — a single photo would have returned one of these two answers with no way to know which.

Scope. Development research only. This health head is not release-authoritative, has no mobile export, and its DINOv2 backbone has an unverified licence that taints derivatives.
Domain. Trained on PlantDoc and PlantVillage crop leaves. A houseplant is outside that domain, so its recorded accuracy does not transfer and a verdict here is an indication, not a measurement.

6 · The ones worth looking at

Picked by a measurement, not by eye. Each one is the extreme of a trait the 3D capture can compute and a single photograph cannot, which is the point of showing them.

leaflet 0
Largest blade
#0 · 215cm² · 215 cm²
the biggest single leaflet the capture resolved
no portrait
Smallest that still counts
#110 · 25 cm² · 25 cm²
the smallest blade above the floor these picks use
leaflet 2
Most missing blade
#2 · 0.33 · 141 cm²
lowest occupied-blade fraction inside its own outline
leaflet 11
Most complete
#11 · 1.00 · 91 cm²
the blade the capture saw most completely
no portrait
Flattest
#109 · 9° · 26 cm²
nearest to horizontal, so nearly its true area from above
no portrait
Steepest
#97 · 89° · 29 cm²
nearest to edge-on, where a photograph measures almost nothing
None of this is a disease call, and this pipeline cannot make one. Its leaf mask keeps only green-dominant gaussians, so discoloured tissue — the very thing a damage measure would need — is removed before a leaflet is ever assembled. Every leaflet here is therefore 100% green and 0% discoloured by construction, on any plant, however brown. The only damage-adjacent signal this capture supports is the fill fraction, which sees an absence of surface rather than a colour.

7 · The app, looking at the plant

This is the app’s own camera view, and the thing in front of it is the 3-D capture instead of the plant. Drag inside the phone to walk around it and to raise or lower the camera — from below the pot to almost straight down over the canopy — then press the shutter. The app runs on that view.

FieldPatho · development preview
the frame the app was given

Drag the plant to any angle, then press the shutter.

252angles the app was run from: every 10° of turn, at 7 heights from -30° to 80°
252/252put into a crop class the plant cannot be
188/252where the honesty chain declined to answer
3symptom families named, on one unchanging plant
Everything the app says here is wrong by construction. A money tree is in none of the app’s crop classes, so any crop-specific label is a mistake, and the generic head is differential-only — it has no healthy class and must name a symptom family whatever it is shown. That is the demo: walk around one unchanging plant and watch the answer change with where you stood (blight_or_necrosis_like, leaf_spot_like, mosaic_or_virus_like).
What is live here and what is not

The viewfinder is live: it is the same rasteriser and the same 269,833 gaussians as section 1, free in yaw and pitch, and the picture in the result panel is the exact frame that was on screen when you pressed the shutter. The verdict is not computed in your browser — a report is a single offline file and cannot carry the models. It was computed ahead of time by running the app’s real honesty chain over this same renderer at 252 poses, and the shutter looks up the nearest one, which is never further than 11° away. The images it ran on were rendered by the viewer you are looking at, not photographed.

Renders and photographs are not interchangeable for this: measured on this capture, renders misroute about twice as often as its own photographs. So these numbers describe the app on renders of this plant, which is what a simulator can honestly claim.

What this does not claim

Segmentation parameters
{
  "opacity_min": 0.3,
  "densify_spacing_m": 0.001,
  "densify_sigma": 1.0,
  "area_spacing_m": 0.0005,
  "area_voxel_m": 0.004,
  "facet_voxel_m": 0.003,
  "normal_tolerance_deg": 15.0,
  "region_tolerance_deg": 22.0,
  "min_facets": 43,
  "min_area_cm2": 5.0,
  "crease_deg": 45.0,
  "facet_step_m": 0.004,
  "absorb_tolerance_deg": 50.0,
  "absorbed_stragglers": true,
  "petiole_junction_m": 0.07
}

Appendix · How much of this is the plant, and how much is the method?

Two questions that had to be answered before any number above could be quoted: whether the leaf area is a property of the plant or of the estimator, and whether it is a property of the plant or of how many gaussians the reconstruction spent. Both are settled; the working is here rather than in the way.

A gaussian is a disc, not a point — and the area converges

3 · A gaussian is a disc, not a point

Measuring occupancy over gaussian centres counts samples, not surface — so it rose with however many gaussians the reconstruction happened to spend, and never settled. Every gaussian is now resampled across its own disc before anything is measured, and the same estimator has a plateau.

1.415 m²leaf area, at 0.50 mm sampling and a 4 mm voxel
1.7%spread across voxels from 2 mm to 12 mm — the answer no longer reads the voxel
1.379 m²summed disc areas: an independent, voxel-free upper bound
1.00 σthe declared disc radius
summed disc areas 1.379 m² — the overlap-free upper bound2.001.501.000.750.500.51.01.5 12 mm8 mm6 mm4 mm3 mm2 mm leaf area (m²) sample spacing (mm) — finer to the right
A declared choice, like the LAI denominator. A gaussian has no edge; it fades. Treating it as a disc of 1.00 σ on its two long axes is a convention, so it is declared here rather than buried, and swept so you can reprice it. It matters far less than it looks: doubling the radius from 0.75 σ to 1.50 σ moves the leaf area only 29%, because past about 1 σ the discs increasingly overlap each other instead of covering new surface.
disc radiusleaf area (m²)LAI
0.75 σ1.2762.69
1.00 σ1.4152.99
1.25 σ1.5353.24
1.50 σ1.6413.47

Two estimators bracket it. Summing the disc areas, 1.379 m², ignores overlap and so sits above the true surface; voxel occupancy, 1.415 m², counts a partly covered voxel in full and so does too. They agree to 2.6%, which puts the leaf area near 1.40 m² and the LAI at 2.91–2.99.

The full grid: sample spacing against area voxel
spacingfoliage points12 mm8 mm6 mm4 mm3 mm2 mm
2.00 mm399,5081.3001.2491.2111.1311.0360.805
1.50 mm659,3421.3411.2981.2741.2241.1630.988
1.00 mm1,354,2761.3781.3511.3421.3231.2991.205
0.75 mm2,193,0371.3981.3761.3731.3741.3671.310
0.50 mm3,876,2801.4131.4011.4041.4151.4211.397

Every gaussian is treated as a disc of the stated radius on its two long axes. That convention is declared because the leaf area scales with roughly its square, and the summed disc areas are reported beside the occupancy estimate as an overlap-free upper bound on the same quantity.

What the capture’s own density is worth

4 · How much of this is the plant, and how much is the capture?

Sampling is settled; how many gaussians the reconstruction spent is a separate question. The whole pipeline — densify, segment, measure — was re-run on thinned copies of the capture to find out which numbers notice.

2.2 mmthe most the height moves anywhere in the sweep, down to 12% of the points
0.7%footprint rectangle drift at half density
81%of the leaf area survives at half density
+7.7%leaf area still gained by the last quarter of the points
0k67k135k202k270k0.00.51.0 leaf area (m²) gaussians fed to the estimator voxel surface summed leaf outlines ◆ an independently built decimation

Robust: height and footprint

Both are extrema of the cloud, so they survive an eight-fold thinning almost unchanged — height moves 2.2 mm and the rectangle 0.7%. Quote them as measurements.

Bounded below: leaf area, LAI and the leaf count

A gaussian's disc is surface, so throwing gaussians away throws leaf away and these must fall — they are lower bounds on the real plant, not estimates of it. What the sweep shows is that the loss is sub-proportional: half the gaussians still carry 81% of the leaf area, because the discs that remain overlap what the discs that went covered. The last quarter of the gaussians added 7.7%, so a capture with more gaussians would measure a little more leaf surface, not a lot.

Every other reconstruction of this capture on disk was checked, cropped to the same volume: 2 of them contain the identical 269,833 gaussians over the plant. There is no denser model of this plant — this is the whole reconstruction, not a sample of it.

The sweep, and every sibling reconstruction
DensityGaussiansLeavesHeight (m) Rectangle (m²)Voxel area (m²)Outlines (m²)LAI
100.0%269,8331461.3230.47351.4150.6852.99
75.0%202,3751281.3220.47301.3050.6632.76
50.0%134,9161331.3220.47041.1480.6372.44
25.0%67,4581291.3220.46930.8470.5761.81
12.5%33,729811.3200.46950.5590.4571.19

Deterministic uniform subsets of the SAME capture, measured by the same pipeline. Thinning a cloud can only remove surface, never add it, so every area here is a lower bound and the full-density row is the least-bad one.

Sibling PLYGaussians in file Inside the plant volumeLeaf area (m²)
plant_3ft_thintiles_297k.ply296,568269,8331.415
plant_full_926k.ply925,973269,8481.416
plant_lite_150k.ply150,00043,6450.659