π Floor Plan Parser
Parse floor plan images into structured data β walls with thickness, doors, windows, and automatically detected rooms.
Architecture
Floor Plan Image (raster or vector)
β
βΌ
ββββββββββββββββββββββββββββββββ
β 1. INITIAL PARSE β VLM extracts walls/doors/windows
β (VLM or vector parser) β into structured JSON schema
ββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββ
β 2. COMPUTE TOPOLOGY β Derive rooms from wall faces
β (computational geometry) β via planar subdivision (Shapely)
ββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββ
β 3. RENDER OVERLAY β Schema β SVG/PNG β alpha-composite
β (PIL / SVG) β on original image for verification
ββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββ
β 4. VERIFY & CORRECT β VLM sees overlay vs original,
β (VLM or human) β outputs field-level corrections
ββββββββββββββββββββββββββββββββ
β
βΌ converged? ββnoβββ back to step 1
yes
βΌ
Final structured schema (JSON)
The Schema
Walls are first-class. Everything else references them.
{
"walls": [
{
"id": "w1",
"centerline": [{"x": 0, "y": 0}, {"x": 6, "y": 0}],
"thickness": 0.24,
"openings": [
{
"id": "win1",
"type": "window",
"start": 1.5,
"length": 1.5
}
]
}
],
"rooms": [
{
"id": "r1",
"label": "bedroom",
"boundary": [
{"wall_id": "w1", "side": "right"},
{"wall_id": "w2", "side": "left"}
],
"area": 16.0
}
]
}
Key design decisions:
- Walls have thickness β exterior (0.20-0.30m) vs interior (0.10-0.15m)
- Openings live on walls β
start+lengthalong the centerline - Rooms are topological β defined by ordered wall-face references (left/right side), not duplicate coordinates
- Curved walls = polyline centerlines with many sample points
- Non-rectangular rooms fully supported (any angles)
Modules
| File | Purpose |
|---|---|
floorplan/schema.py |
Pydantic data models β Wall, Opening, Room, FloorPlan, Correction |
floorplan/geometry.py |
Computational geometry β wall polygons, room detection, centerline ops |
floorplan/renderer.py |
SVG + PIL rendering for visual verification and overlay |
floorplan/parser.py |
VLM-based parsing with iterative correction loop |
Quick Start
Demo (no API key needed)
pip install pydantic shapely numpy pillow
python example.py --demo
Renders a 2-bedroom apartment with angled walls β output/demo_floorplan.png + .svg + .json
Parse a real floor plan
pip install pydantic shapely numpy pillow openai
python example.py --image myfloorplan.png --api-key sk-...
Or with a local model (vLLM, Ollama, etc.):
python example.py --image myfloorplan.png --base-url http://localhost:8000/v1 --model qwen2.5-vl-72b
Python API
from floorplan import FloorPlan, Wall, Opening, OpeningType, Point2D
from floorplan import build_rooms, render_to_image, render_floorplan_svg
# Build a floor plan programmatically
walls = [
Wall(id="w1", centerline=[Point2D(x=0, y=0), Point2D(x=5, y=0)], thickness=0.24,
openings=[Opening(id="d1", type=OpeningType.DOOR, start=1.0, length=0.9)]),
Wall(id="w2", centerline=[Point2D(x=5, y=0), Point2D(x=5, y=4)], thickness=0.24),
Wall(id="w3", centerline=[Point2D(x=5, y=4), Point2D(x=0, y=4)], thickness=0.24),
Wall(id="w4", centerline=[Point2D(x=0, y=4), Point2D(x=0, y=0)], thickness=0.24),
]
rooms, room_polygons = build_rooms(walls)
fp = FloorPlan(walls=walls, rooms=rooms)
# Render
img = render_to_image(fp, room_polygons=room_polygons)
img.save("output.png")
# Export SVG
svg = render_floorplan_svg(fp, room_polygons=room_polygons)
# Serialize to JSON
print(fp.model_dump_json(indent=2))
VLM parsing with correction loop
from floorplan import parse_floorplan
fp, room_polygons, overlays = parse_floorplan(
image="floorplan.png",
api_key="sk-...",
model="gpt-4o",
max_iterations=4,
)
# overlays contains the render-on-original images for each iteration
for i, overlay in enumerate(overlays):
overlay.save(f"overlay_{i}.png")
Features
- β Wall thickness β not just centerlines
- β Non-rectangular rooms β any angles
- β Curved walls β polyline approximation
- β Automatic room detection β from wall topology via Shapely
- β Doors & windows β parametric on walls
- β SVG + PNG rendering β dual output
- β Overlay verification β rendered schema composited on original
- β Iterative VLM correction β parse β render β compare β correct β repeat
- β JSON serialization β full Pydantic roundtrip
- β Field-level corrections β modify, add, delete walls/openings
Dependencies
Core (always needed):
pydanticβ schema validationshapelyβ computational geometrynumpyβ array opspillowβ image rendering
VLM parsing (optional):
openaiβ for VLM API calls (works with any OpenAI-compatible endpoint)
License
MIT