Rectangle Fitting: Sequential Four-Edge RANSAC with Orthogonality Constraints
VisionLab fits rectangles by finding four edges sequentially with RANSAC, enforcing parallel and perpendicular constraints at each step β more robust than fitting all edges simultaneously.
Rectangle fitting is harder than it looks. You cannot just detect all edges and label them β the algorithm needs to know which edges are parallel, which are perpendicular, and how to handle partial occlusion where one or two sides may be missing. VisionLab solves this with a sequential four-edge RANSAC that bakes geometric constraints directly into the search order.
Why Simultaneous Fitting Fails
The naive approach β detect all edges, then try to group them into two parallel pairs β produces combinatorial ambiguity. On a real part image, there may be 10β30 significant edge segments, and selecting the four that form a consistent rectangle from combinations is expensive and error-prone.
Sequential RANSAC reduces this to four small, constrained sub-problems.
Sequential Four-Edge Algorithm
Step 1: RANSAC on all edge points β Line 1 (most-supported edge)
Step 2: Remove Line 1 inliers. RANSAC with parallel constraint β Line 2
angle constraint: |ΞΈβ β ΞΈβ| < angle_tolerance
distance constraint: height_min < dist(L1, L2) < width_max
Step 3: Remove Lines 1+2 inliers. RANSAC with perpendicular constraint β Line 3
angle constraint: |ΞΈβ β ΞΈβ β 90Β°| < angle_tolerance
Step 4: Remove Lines 1+2+3 inliers. RANSAC with parallel-to-Line-3 constraint β Line 4
angle constraint: |ΞΈβ β ΞΈβ| < angle_tolerance
distance constraint: height_min < dist(L3, L4) < width_max
After four lines are found, their pairwise intersections give the four corner points.
The Parallel Distance Constraint
Measuring the pixel distance between two parallel lines is not trivial because the Hough-space values are not directly comparable when lines have different normal vector orientations. VisionLab uses a projection method:
Given Line 1 in normal form and candidate Line 2 :
This gives the true pixel distance between the two parallel lines regardless of their common orientation.
Corner Point Calculation
Each pair of non-parallel lines intersects at exactly one point. Given lines in normal form:
With four corners computed, cv::minAreaRect fits the final rotated rectangle and validates aspect ratio.
Angle Normalisation for Perpendicularity
Lines have a 180Β° ambiguity in their normal direction. The perpendicularity check must account for this:
float angleDiff90(float a, float b) {
float d = std::abs(norm180(a) - norm180(b));
if (d > 90.f) d = 180.f - d;
return d; // should be close to 90Β° for perpendicular lines
}
Accuracy and Parameters
| Parameter | Role |
|---|---|
angle_tolerance | Max deviation from parallel/perpendicular (typically 5β10Β°) |
height_min / width_max | Expected rectangle width range in pixels |
ransac_iter | Iterations per edge (500β1000) |
inlier_dist | Point-to-line distance threshold (1β3 px) |
Expected corner accuracy: Β±0.5 px under clean edges. Degraded to Β±1β2 px when two opposite sides have significant occlusion.
Robustness to Partial Occlusion
Because each edge is found independently with its own RANSAC, a partially occluded side still produces a valid line as long as > min_inliers points remain on that side. Even with one side 60% occluded, the algorithm typically recovers all four corners.
Algorithm Comparison Summary
| Shape | Min points | Accuracy | Speed | Complexity |
|---|---|---|---|---|
| Circle | 3 | Β±0.1 px | Fast | Low |
| Line | 2 | Β±0.2 px | Very fast | Low |
| Ellipse | 5 | Β±0.3 px | Medium | Medium |
| Rectangle | 8 | Β±0.5 px | Slow | High |
Rectangle fitting is the most expensive because it runs four sequential RANSAC passes. For time-critical applications, restrict the search ROI tightly around the expected part location.