Open-source camera-based flood depth visualization with actual measurement capabilities
See potential flood levels overlaid on your camera feed with REAL measurement accuracy. Uses reference objects (doors, people) to calculate true pixel-per-inch scale for accurate water height visualization.
- 📏 REAL Measurement System: Uses doors/people as reference for accurate pixel-per-inch scaling
- 📷 Real-time Camera Overlay: Stream your device camera and overlay flood water visualization
- 🎯 Two-Tap Calibration: Tap top & bottom of reference object for instant scale calculation
- 🚪 Multiple References: Standard door (80"), adult male (5'9"), adult female (5'4"), or custom
- 📊 Flexible Configuration: Use risk scores (0-10) or custom depths in meters/feet
- 💾 Screenshot & Share: Capture and share your visualization with measurement data
- 🔒 Privacy-First: All processing happens locally in your browser - no data uploaded
- 📱 Mobile & Desktop: Works on all modern devices with camera access
- ⚡ Zero Dependencies: Pure vanilla JavaScript + Tailwind CSS
- 🎓 No ML Required: Simple math achieves ±5-10% accuracy
-
Download the files:
index.html- Main applicationar-flood.js- Core AR logic
-
Serve over HTTPS (camera API requirement):
# Using Python python -m http.server 8000 # Or using Node.js npx http-server
-
Open in browser: Navigate to
https://localhost:8000 -
Grant camera access when prompted
-
Enter Configuration:
- Location/address (optional)
- Flood risk score (0-10) OR custom depth in m/ft
- Click "Start AR Camera"
-
Select Reference Object:
- Standard Door (80" / 6'8") - RECOMMENDED
- Adult Male (69" / 5'9")
- Adult Female (64" / 5'4")
- Custom Height (enter your own)
-
Tap TOP of Reference:
- Point camera at your reference (e.g., door frame)
- Tap the TOP of the object (e.g., top of door frame)
- Green crosshair appears
-
Tap BOTTOM of Reference:
- Tap the BOTTOM of the same object (e.g., floor level)
- Red crosshair appears
- System calculates:
pixelsPerInch = pixelDistance / referenceHeight
-
Water Appears:
- Water drawn at accurate height using your scale
- Shows measurement in meters and feet
- "MEASURED" badge confirms calibration
- Water height:
waterY = bottomY - (waterInches × pixelsPerInch)
-
Capture & Share:
- Tap "Photo" to download screenshot with measurements
- Tap "Share" to use native share (mobile)
Why This Works:
- User selects known-size reference (e.g., standard door = 80 inches)
- Taps top and bottom of reference in camera view
- System calculates pixels-per-inch scale from pixel distance
- Water drawn using real-world measurement, not estimation
Math:
// Step 1: Calculate pixel distance
pixelDistance = Math.sqrt(
(bottomX - topX)² + (bottomY - topY)²
)
// Step 2: Calculate scale
referenceHeight = 80 inches // for standard door
pixelsPerInch = pixelDistance / referenceHeight
// Step 3: Draw water at accurate height
waterHeightInches = waterDepthMeters × 39.3701
waterHeightPixels = waterHeightInches × pixelsPerInch
waterY = bottomPoint.y - waterHeightPixelsAccuracy: ±5-10% (good enough for visualization without machine learning)
- Standardized: Most interior doors are exactly 80" (6'8")
- Vertical: Easy to tap top and bottom
- Common: Found in every home/building
- At Ground Level: On same plane as floor for accurate measurement
2D Camera Overlay with Measurement:
- Uses
getUserMedia()API for camera access - Canvas draws: camera feed FIRST, then water overlay on top
- Pixel-per-inch scale enables real-world accuracy
- No ML or depth sensors needed
Flood Depth Source:
// Score-based (0-10)
score <= 3: 0.3m / 12" (ankle-deep)
score 4-6: 0.6m / 24" (knee-deep)
score 7-8: 1.2m / 48" (waist-deep)
score 9-10: 1.8m / 72" (chest-deep)
// Or use custom depth in meters/feet
// Converted to inches for pixel calculationREFERENCE_OBJECTS = {
door: 80 inches, // Standard interior door height
male: 69 inches, // Average adult male (5'9")
female: 64 inches, // Average adult female (5'4")
custom: user input // Your own measurement
}<!-- Reference Selection -->
<select id="reference-select">
<option value="door">Standard Door (80")</option>
<option value="male">Adult Male (5'9")</option>
<option value="female">Adult Female (5'4")</option>
<option value="custom">Custom Height</option>
</select>
<!-- Custom Height -->
<input id="custom-height-input" type="number" placeholder="Height in inches">
<!-- Flood Configuration -->
<input id="address-input" placeholder="Location">
<input id="score-slider" type="range" min="0" max="10">
<input id="depth-input" type="number" step="0.1">
<select id="depth-unit">
<option value="meters">meters</option>
<option value="feet">feet</option>
</select>// Set reference object
referenceObject = 'door'; // 'door' | 'male' | 'female' | 'custom'
customHeight = 60; // inches, if using 'custom'
// Calibration state
calibrationStep = 'select_ref'; // 'select_ref' | 'tap_top' | 'tap_bottom' | 'complete'
topPoint = { x, y }; // First tap coordinates
bottomPoint = { x, y }; // Second tap coordinates
pixelsPerInch = null; // Calculated scale
// Water calculation
waterHeightInches = waterDepthMeters * 39.3701;
waterHeightPixels = waterHeightInches * pixelsPerInch;
waterY = bottomPoint.y - waterHeightPixels;// In REFERENCE_OBJECTS constant
REFERENCE_OBJECTS = {
door: { height: 80 }, // Change if non-standard doors
male: { height: 69 }, // Adjust for regional averages
female: { height: 64 },
custom: { height: 60 } // Default custom value
}// In drawFrame() function
// TOP marker: Green
ctx.strokeStyle = '#10b981';
ctx.fillStyle = '#10b981';
// BOTTOM marker: Red
ctx.strokeStyle = '#ef4444';
ctx.fillStyle = '#ef4444';
// Connecting line: Purple
ctx.strokeStyle = '#a855f7';const TARGET_FPS = 30; // Lower for older devices (e.g., 20)- Use Standard Doors: Most reliable reference (80" exactly)
- Ensure Vertical Reference: Object should be perpendicular to ground
- Same Plane as Ground: Reference should be at same depth as area you're measuring
- Steady Camera: Hold device still during tapping
- Good Lighting: Helps you see reference boundaries clearly
- Tap Precisely: Tap exact top and bottom edges
- Home Evacuation Planning: Visualize water in your rooms
- Educational Demos: Show students real flood depths
- Emergency Preparedness: Train staff on flood scenarios
- Risk Communication: Help clients understand flood impact
- Property Assessment: Show potential damage zones
| Browser | Desktop | Mobile | Notes |
|---|---|---|---|
| Chrome | ✅ | ✅ | Best performance |
| Safari | ✅ | ✅ | Requires HTTPS |
| Firefox | ✅ | ✅ | Full support |
| Edge | ✅ | ✅ | Chromium-based |
Requirements:
- HTTPS connection (or localhost)
- Camera permission granted
- Modern browser (ES6+ support)
This is an EDUCATIONAL VISUALIZATION TOOL with measurement capabilities:
- ✅ Provides ±5-10% measurement accuracy using reference objects
- ✅ Great for educational demos and scenario visualization
- ✅ Helps understand flood depths in relatable terms
- ❌ NOT a precise flood prediction model
- ❌ NOT for emergency decision-making
- ❌ NOT a replacement for official FEMA flood maps
- ❌ NOT a survey-grade measurement tool
Measurement Limitations:
- Assumes reference object is at same depth plane as measurement area
- Accuracy depends on camera angle and user tapping precision
- Does not account for camera lens distortion
- Simple 2D calculation, not true 3D spatial measurement
Always consult:
- Official FEMA flood maps for regulatory decisions
- Local emergency management authorities
- Professional surveyors for property assessments
- Licensed engineers for structural planning
- No data collection: Nothing sent to servers
- No tracking: No analytics or cookies
- Local processing: All rendering happens in browser
- No storage: Camera feed not saved (unless you screenshot)
- Open source: Audit the code yourself
MIT License - feel free to use, modify, and distribute!
Contributions welcome! Ideas:
- Horizontal reference support (door width for side views)
- Auto-detection of door frames using edge detection
- Multiple calibration points for better accuracy
- 3D depth visualization with perspective correction
- Lens distortion compensation
- Historical flood event presets
- Multi-language support
- Accessibility improvements (voice guidance)
Originally developed for RisqMap - a comprehensive climate risk intelligence platform.
Measurement technique inspired by Grok AI's suggestion to use real-world reference objects for pixel-per-inch scale calculation. Open-sourced to help the community visualize flood risk with actual measurement capabilities.
Camera won't open:
- Ensure HTTPS connection (or use localhost)
- Check browser permissions for camera access
- Try different browser (Chrome recommended)
- On iOS: Safari only, Chrome uses Safari engine
Wrong water height:
- Ensure reference object is on same ground plane
- Use standard door for best accuracy (80" exactly)
- Tap precisely at top and bottom edges
- Hold camera steady during calibration
- Ensure good lighting to see boundaries
Calibration markers not showing:
- Check that you've selected a reference object
- Verify camera stream is active
- Try tapping more firmly/precisely
- Refresh page and try again
Water appears in wrong position:
- Complete full two-tap calibration
- Ensure reference is vertical (perpendicular to ground)
- Check that bottomPoint is actually at floor level
- Camera angle should be roughly horizontal
Performance issues:
- Lower TARGET_FPS to 20 (from 30)
- Close other browser tabs
- Use newer device if possible
- Ensure good WiFi/network (though processing is local)
- Check browser permissions (Settings > Privacy > Camera)
- Ensure HTTPS connection
- Try different browser
Water appears wrong height:
- Use calibration feature
- Tap on actual floor/door frame
- Check that camera is level
Performance issues:
- Lower TARGET_FPS in JavaScript
- Close other tabs
- Try on newer device
Screenshot not working:
- Check browser storage permissions
- Try different browser
Having issues? Open an issue on GitHub or contact us.
Made with ❤️ for disaster preparedness education