Comfy-Org/ComfyUI · error · ValueError

At least 4 points are required to compute a homography.

Error message

At least 4 points are required to compute a homography.

What it means

Ray/pose utilities in DepthAnything 3 estimate a homography via weighted DLT, which needs at least 4 2D point correspondences to constrain the 8-DOF matrix. _find_homography_weighted_lsq() raises ValueError when fewer than 4 point pairs are supplied. This is a geometric impossibility, not a bug — with 3 or fewer pairs the solution is underdetermined.

Source

Thrown at comfy/ldm/depth_anything_3/ray_pose.py:45

    Q = Q * sign[None, :]  # scale columns of Q
    L = L * sign[:, None]  # scale rows of L
    return Q, L


def _homogenize_points(points: torch.Tensor) -> torch.Tensor:
    return torch.cat([points, torch.ones_like(points[..., :1])], dim=-1)


# -----------------------------------------------------------------------------
# Weighted-LSQ + RANSAC homography (batched)
# -----------------------------------------------------------------------------


def _find_homography_weighted_lsq(src_pts: torch.Tensor, dst_pts: torch.Tensor, confident_weight: torch.Tensor,) -> torch.Tensor:
    """Solve a single H with weighted least-squares (DLT)."""
    N = src_pts.shape[0]
    if N < 4:
        raise ValueError("At least 4 points are required to compute a homography.")
    w = confident_weight.sqrt().unsqueeze(1)  # (N, 1)
    x = src_pts[:, 0:1]
    y = src_pts[:, 1:2]
    u = dst_pts[:, 0:1]
    v = dst_pts[:, 1:2]
    zeros = torch.zeros_like(x)
    A1 = torch.cat([-x * w, -y * w, -w, zeros, zeros, zeros, x * u * w, y * u * w, u * w], dim=1)
    A2 = torch.cat([zeros, zeros, zeros, -x * w, -y * w, -w, x * v * w, y * v * w, v * w], dim=1)
    A = torch.cat([A1, A2], dim=0)        # (2N, 9)
    # CUDA SVD is not implemented for fp16/bf16; upcast just for this call.
    _, _, Vh = torch.linalg.svd(A.float())
    Vh = Vh.to(A.dtype)
    H = Vh[-1].reshape(3, 3)
    return H / H[-1, -1]


def _find_homography_weighted_lsq_batched(src_pts_batch: torch.Tensor, dst_pts_batch: torch.Tensor, confident_weight_batch: torch.Tensor) -> torch.Tensor:
    """Batched DLT solver. Inputs (B, K, 2) / (B, K); output (B, 3, 3)."""

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Check the correspondence count before calling: require >= 4 point pairs (in practice far more for RANSAC to be stable).
  2. Loosen the match-confidence threshold or increase the number of proposed matches so more correspondences survive filtering.
  3. Skip homography-based pose estimation for view pairs with insufficient overlap and fall back to an identity/known-pose assumption.

Example fix

# before
H = _find_homography_weighted_lsq(src, dst, w)

# after
if src.shape[0] < 4:
    raise SkipViewPair(f"only {src.shape[0]} correspondences")
H = _find_homography_weighted_lsq(src, dst, w)
Defensive patterns

Strategy: validation

Validate before calling

if src_pts.shape[0] < 4 or dst_pts.shape[0] < 4:
    raise ValueError(f"need >=4 correspondences, got {src_pts.shape[0]}")

Type guard

def has_min_correspondences(src_pts: "torch.Tensor", minimum: int = 4) -> bool:
    return src_pts.ndim == 2 and src_pts.shape[0] >= minimum and src_pts.shape[1] >= 2

Try / catch

try:
    H = _find_homography_weighted_lsq(src, dst, w)
except ValueError:
    H = None  # skip pose estimation for this view pair

Prevention

When it happens

Trigger: Calling the weighted-LSQ homography helper (directly or through the RANSAC wrapper) with a correspondence set of 0-3 points — e.g. when matching two views produced too few confident matches, or when confident-weight thresholding filtered nearly all correspondences away.

Common situations: Multi-view depth runs on image pairs with little overlap, low-texture scenes, or overly strict match-confidence filters; degenerate inputs like identical frames or pure-color images.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/5fdef1681566f3c9. Report an issue: GitHub.