<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Gaussian Splatting on Boris Dupoux</title><link>https://borisdupoux.com/tags/gaussian-splatting/</link><description>Recent content in Gaussian Splatting on Boris Dupoux</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Thu, 01 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://borisdupoux.com/tags/gaussian-splatting/index.xml" rel="self" type="application/rss+xml"/><item><title>Handheld Video to Photogrammetry and Gaussian Splatting</title><link>https://borisdupoux.com/research/photogrammetry-splatting/</link><pubDate>Thu, 01 Oct 2026 00:00:00 +0000</pubDate><guid>https://borisdupoux.com/research/photogrammetry-splatting/</guid><description>&lt;h2 id="context"&gt;&lt;a href="#context" class="header-anchor"&gt;&lt;/a&gt;Context
&lt;/h2&gt;&lt;p&gt;Indoor sites are often documented with a handheld gimbal camera rather than a
survey-grade scanner. The goal was to turn such video into usable 3D deliverables
(dense cloud, textured mesh, plan and elevation orthoviews, a Gaussian Splatting
scene and lightweight web exports) with no manual steps between capture and output.
The pipeline runs natively on Windows on an RTX 5090 (Blackwell, sm_120) that is
&lt;strong&gt;shared with other long-running GPU workloads&lt;/strong&gt;, so it must never pre-empt them.&lt;/p&gt;
&lt;h2 id="approach"&gt;&lt;a href="#approach" class="header-anchor"&gt;&lt;/a&gt;Approach
&lt;/h2&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TB
 A["inbox/project/videos + GO file"] --&gt; B["Keyframe extraction&lt;br/&gt;optical-flow overlap + sharpness"]
 B --&gt; C["COLMAP 4.2.1 SfM&lt;br/&gt;SIFT, global mapper"]
 C --&gt; D{"QC: registration, reprojection,&lt;br/&gt;trajectory continuity"}
 D -- fail --&gt; C2["Fallback: incremental mapper"] --&gt; D
 D -- pass --&gt; E["OpenMVS 2.4 (sm_120 build)&lt;br/&gt;densify, mesh, refine, texture"]
 E --&gt; F["Ortho alignment&lt;br/&gt;gravity, floor RANSAC, Manhattan yaw"]
 F --&gt; G["Blender renders&lt;br/&gt;orthos, axonometries, orbit"]
 E --&gt; H["gsplat training&lt;br/&gt;MCMC or default strategy"]
 G --&gt; I["Web exports&lt;br/&gt;Potree, GLB, SOG"]
 H --&gt; I
 I --&gt; J["outbox: deliverables, report.json, STATUS"]&lt;/pre&gt;&lt;h2 id="methods"&gt;&lt;a href="#methods" class="header-anchor"&gt;&lt;/a&gt;Methods
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Overlap-driven keyframe selection.&lt;/strong&gt; KLT tracking with a RANSAC similarity
transform estimates overlap with the last keyframe. A frame is emitted when overlap
drops below 0.80, tracking is lost or a time limit passes. The sharpest candidate
(variance of the Laplacian) is the one kept.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SfM with explicit QC.&lt;/strong&gt; COLMAP&amp;rsquo;s global mapper is fast but non-deterministic.
In testing it produced reconstructions that met registration and reprojection
criteria but were geometrically incoherent. A trajectory-continuity check (jumps
above 25× the median camera step) triggers an automatic fallback to the
incremental mapper. Below 20 points per image the step fails.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MVS hardening.&lt;/strong&gt; The official OpenMVS Windows binary has only sm_89 kernels, so
it was rebuilt for sm_120. The object ROI is off for rooms because it cropped the
cloud. Refinement is dropped when it diverges, and seam leveling (which blackened
faces) is off.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metric-ready orthoviews.&lt;/strong&gt; The up axis comes from camera orientations. A RANSAC
floor plane sets z = 0 and a histogram of wall-normal azimuths (mod 90°) sets
Manhattan yaw. An optional two-point reference fixes scale. The 4×4 transform is
stored so it can be applied again to the mesh and the splat.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gaussian Splatting.&lt;/strong&gt; gsplat 1.6.0 was compiled for sm_120 with CUDA 13 under
MSVC, which required local patches. Training uses the MCMC strategy with a
Gaussian budget and falls back to the default 3DGS strategy when MCMC diverges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operations.&lt;/strong&gt; Projects start in watch-folder mode when a GO file appears.
Stages can be resumed or redone. A GPU guard waits until enough VRAM has been
free for a stable period, serialises GPU stages through a lock file and records
peak VRAM per stage in &lt;code&gt;report.json&lt;/code&gt;. Degraded QC produces a &lt;code&gt;DONE_WITH_ALERTS&lt;/code&gt;
status instead of a silent success.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="results"&gt;&lt;a href="#results" class="header-anchor"&gt;&lt;/a&gt;Results
&lt;/h2&gt;&lt;p&gt;First real deployment: five locations inside a commercial showroom, one 4K
handheld video per location, processed unattended in about 30 minutes per location.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Location&lt;/th&gt;
					&lt;th&gt;Images&lt;/th&gt;
					&lt;th&gt;SfM registered / points / reproj.&lt;/th&gt;
					&lt;th&gt;Dense cloud&lt;/th&gt;
					&lt;th&gt;Splat PSNR / SSIM&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;116&lt;/td&gt;
					&lt;td&gt;116/116 · 21,458 · 1.49 px&lt;/td&gt;
					&lt;td&gt;1.40 M&lt;/td&gt;
					&lt;td&gt;23.2 / 0.86&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;2&lt;/td&gt;
					&lt;td&gt;103&lt;/td&gt;
					&lt;td&gt;103/103 · 18,972 · 1.75 px&lt;/td&gt;
					&lt;td&gt;1.23 M&lt;/td&gt;
					&lt;td&gt;20.6 / 0.81&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;3&lt;/td&gt;
					&lt;td&gt;47&lt;/td&gt;
					&lt;td&gt;47/47 · 13,167 · 1.17 px&lt;/td&gt;
					&lt;td&gt;1.26 M&lt;/td&gt;
					&lt;td&gt;23.1 / 0.86&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;4&lt;/td&gt;
					&lt;td&gt;121&lt;/td&gt;
					&lt;td&gt;121/121 · 11,970 · 1.34 px&lt;/td&gt;
					&lt;td&gt;1.99 M&lt;/td&gt;
					&lt;td&gt;21.9 / 0.85 (default strategy)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;5&lt;/td&gt;
					&lt;td&gt;64&lt;/td&gt;
					&lt;td&gt;64/64 · 12,106 · 1.48 px&lt;/td&gt;
					&lt;td&gt;0.91 M&lt;/td&gt;
					&lt;td&gt;21.8 / 0.83&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;All frames were registered in every location. Reprojection error was 1.17–1.75 px.&lt;/li&gt;
&lt;li&gt;Measured VRAM peaks: SIFT +1.3 GB, matching +1.6 GB, texturing +0.5 GB,
Blender +5.4 GB, and splatting with 3 M Gaussians at 1920 px +25.2 GB.&lt;/li&gt;
&lt;li&gt;The sm_120 OpenMVS build densified the synthetic smoke test in 17 s. The CPU
fallback took about 40 min.&lt;/li&gt;
&lt;li&gt;Metadata analysis showed shutter speeds of 1/50–1/100 s (about 14 px of motion
blur at 4K) and automatic ISO and white balance. Exposure compensation in gsplat
(&lt;code&gt;ppisp&lt;/code&gt;) gave no gain (PSNR 20.5 vs 20.6). The quality limit is in the capture,
not the solver.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="limitations--next-steps"&gt;&lt;a href="#limitations--next-steps" class="header-anchor"&gt;&lt;/a&gt;Limitations &amp;amp; next steps
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;PSNR in the low 20s reflects motion blur and auto-exposure. The capture protocol
now requires a 1/250–1/500 s shutter, locked exposure and white balance, and a
dedicated floor pass.&lt;/li&gt;
&lt;li&gt;Merging videos from different locations caused false matches and an incoherent
model, so each location is processed separately.&lt;/li&gt;
&lt;li&gt;Dark glossy tiled floors reconstruct poorly. Manhattan alignment is not yet
reliable with furniture and glazing.&lt;/li&gt;
&lt;li&gt;CPU stages are the bottleneck on a 4-vCPU virtual machine.&lt;/li&gt;
&lt;li&gt;Planned: comparison with a commercial photogrammetry suite on the same frames, and
retesting mesh refinement with the sm_120 build.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="stack"&gt;&lt;a href="#stack" class="header-anchor"&gt;&lt;/a&gt;Stack
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Python 3.11&lt;/code&gt; · &lt;code&gt;OpenCV&lt;/code&gt; · &lt;code&gt;Open3D&lt;/code&gt; · &lt;code&gt;NumPy&lt;/code&gt; · &lt;code&gt;COLMAP 4.2.1&lt;/code&gt; · &lt;code&gt;OpenMVS 2.4&lt;/code&gt; · &lt;code&gt;gsplat 1.6.0&lt;/code&gt; · &lt;code&gt;PyTorch 2.14 (CUDA 13)&lt;/code&gt; · &lt;code&gt;Blender 5.2&lt;/code&gt; · &lt;code&gt;FFmpeg&lt;/code&gt; · &lt;code&gt;PotreeConverter&lt;/code&gt; · &lt;code&gt;glTF-Transform&lt;/code&gt; · &lt;code&gt;splat-transform&lt;/code&gt;&lt;/p&gt;</description></item></channel></rss>