Fixed critical issue where depth-based FOV was being overestimated
(118° vs actual 39°) due to vanishing points too close to center.
Root Cause:
- Vanishing points near center indicate wide FOV
- For narrow FOV (39°), VP should be far from center (>1.4x width)
- Minimum focal length was too permissive (0.3x width = 136° FOV)
Fixes Applied:
1. Stricter Focal Length Validation:
- Increased minimum from 0.3x to 0.5x width (~90° max FOV)
- Reject VPs closer than this - use fallback instead
- Better horizontal vs Euclidean distance logic
2. Improved Line Filtering:
- Focus on near-vertical lines (20-70° and 110-160°)
- Filter out short lines (< 5% of image dimension)
- Require minimum 5 good converging lines
- Longer minimum line length (1/8 vs 1/10 of dimension)
3. Better Vanishing Point Detection:
- Filter intersections: only use those >40% width from center
- Tighter clustering threshold (10% vs 15%)
- Require stronger support (5+ vs 3+ intersections)
- Prefer VPs farther from center (narrow FOV case)
4. Conservative Fallback Values:
- Reduced defaults to realistic camera FOVs (45-90°)
- Better aspect ratio-based heuristics
These changes make the depth-based estimator more conservative and
accurate, especially for narrow FOV images. Will now correctly reject
bad vanishing point detections rather than producing wildly wrong FOVs.
Implemented new DepthFOVEstimatorNode that uses depth maps for more
robust geometric analysis. This is the recommended method for accurate
FOV and tilt estimation.
New Features:
- Depth map input support (compatible with MiDaS, Depth Anything, etc.)
- Depth discontinuity detection using Sobel gradients
- Bilateral filtering for edge-preserving smoothing
- Depth-based vanishing point detection
- Depth gradient analysis for fallback tilt estimation
- Handles various depth map formats (1/3 channel, normalized/unnormalized)
Architecture:
- Modular design following ComfyUI patterns
- Accepts depth map + original image inputs
- Same output interface as RGB node for easy switching
- Separate node registration: "FOV & Tilt Estimator (Depth)"
Advantages over RGB method:
- Depth discontinuities represent real 3D geometry
- Independent of texture, lighting, and shadows
- More robust to image artifacts and reflections
- Better fallback behavior for scenes without clear lines
- Cleaner edge detection from structural boundaries
Both nodes now available:
1. FOV & Tilt Estimator (RGB) - Direct RGB analysis
2. FOV & Tilt Estimator (Depth) - Depth-based (recommended)
Updated README with:
- Complete depth-based workflow documentation
- Comparison between RGB and depth methods
- Tips for both estimation approaches
- Recommended depth estimation nodes
- Detailed technical implementation notes
Replaced the previous angular separation method with a more accurate
focal length-based approach using the pinhole camera model.
New FOV estimation algorithm:
- Filters non-horizontal lines (converging lines like buildings/roads)
- Uses RANSAC-like clustering to find dominant vanishing point
- Calculates focal length from distance between image center and VP
- Converts focal length to FOV: hfov = 2 × arctan(width / (2 × f))
- More conservative aspect ratio-based fallback defaults
Key improvements:
- Much more accurate FOV estimation (tested: real 39° vs previous 65°)
- Robust to outliers through clustering and voting
- Based on well-established pinhole camera model
- Better handling of images without clear vanishing points
Technical details:
- Performance optimization: limits pairwise line intersections
- Dynamic clustering threshold based on image size
- Requires minimum 3 supporting intersections for reliability
- Removed old _calculate_fov_from_vanishing_points method
Updated README with detailed explanation of new algorithm and
improved technical documentation.
Changed tilt calculation to use the actual estimated horizontal FOV
rather than assuming a fixed 60° vertical FOV.
Changes:
- Estimate FOV before tilt (reversed order)
- Pass estimated horizontal FOV to tilt calculation
- Calculate vertical FOV from horizontal FOV using aspect ratio:
tan(vfov/2) = tan(hfov/2) / aspect_ratio
- Use calculated vertical FOV to convert pixel offset to tilt angle
This makes the tilt estimation more accurate and consistent with the
actual camera properties detected in the image.
Updated README to reflect the new calculation order and method.
Changed tilt estimation logic to measure camera vertical angle based on
horizon position rather than line rotation angle.
New behavior:
- Tilt = 0° when horizon is at frame center
- Tilt < 0° when horizon is above center (camera looking up)
- Tilt > 0° when horizon is below center (camera looking down)
Implementation changes:
- Calculate where horizon line intersects frame center
- Measure vertical offset from center in pixels
- Convert to degrees using estimated vertical FOV (60°)
- Use median for robustness against outliers
Updated README to document new tilt calculation method.
Convert coordinates to float before arithmetic operations to prevent
overflow when multiplying large integer coordinate values.
Fixes RuntimeWarning: overflow encountered in scalar multiply
Implements a custom ComfyUI node that estimates:
- Field of View (FOV) in degrees using vanishing point detection
- Tilt/horizon angle in degrees using line detection
Features:
- Canny edge detection for robust edge finding
- Hough line transform for line and horizon detection
- Vanishing point analysis for FOV estimation
- Configurable thresholds for different image types
- Visual debugging with annotated output images
- Batch processing support
Files added:
- __init__.py: ComfyUI node registration
- fov_estimator_node.py: Main implementation with FOVEstimatorNode class
- requirements.txt: Dependencies (numpy, opencv-python, torch)
- README.md: Comprehensive documentation and usage guide