# Common Helper — `RansacFilter`

## Purpose

Thin wrapper around OpenCV's RANSAC + reprojection-residual computation. Used by the cross-domain matcher (C3 — RANSAC over 2D-2D correspondences for the per-candidate inlier count), the conditional refiner (C3.5 — recompute residual after AdHoP refinement), and the pose estimator (C4 — RANSAC inside `solvePnPRansac` is OpenCV-internal, but C4 also computes per-frame final reprojection residual via this helper for FDR provenance).

## Used By

- C3 — Cross-domain Matcher.
- C3.5 — AdHoP-conditional Refiner.
- C4 — Pose Estimation.

## Interface (sketch)

```
class RansacFilter:
    @staticmethod
    def filter_correspondences(
        correspondences: ndarray[N, 4],
        ransac_threshold_px: float,
        min_inliers: int,
    ) -> RansacResult

    @staticmethod
    def compute_reprojection_residual(
        correspondences: ndarray[I, 4],
        K: ndarray[3, 3],
        distortion: ndarray,
        pose: SE3,
    ) -> float                                      # median residual in pixels
```

```
RansacResult:
  inlier_correspondences:        ndarray[I, 4]
  inlier_count:                  int
  outlier_count:                 int
  median_residual_px:            float
```

## Implementation Notes

- Backed by `cv2.findHomography(..., cv2.RANSAC)` for the 2D-2D case and `cv2.projectPoints(...)` for the post-pose residual.
- Stateless; pure function.

## Caveats

- The RANSAC threshold is a tunable; defaults are documented per-component (C3, C3.5, C4) in their specs.
- For 2D-3D RANSAC inside C4's `solvePnPRansac`, OpenCV does it internally — this helper is for the standalone reprojection-residual computation that lives outside the PnP call.
