Intelligent_PID / detection_utils.py
msIntui
feat: initial clean deployment
910e0d4
import numpy as np
from typing import List, Tuple
import math
def robust_merge_lines(lines: List[Tuple[float, float, float, float]],
angle_thresh: float = 5.0,
dist_thresh: float = 5.0) -> List[Tuple[float, float, float, float]]:
"""
Merge similar line segments using angle and distance thresholds.
Args:
lines: List of line segments [(x1,y1,x2,y2),...]
angle_thresh: Maximum angle difference in degrees
dist_thresh: Maximum endpoint distance
Returns:
List of merged line segments
"""
if not lines:
return []
# Convert to numpy array for easier manipulation
lines = np.array(lines)
# Calculate line angles
angles = np.arctan2(lines[:,3] - lines[:,1],
lines[:,2] - lines[:,0])
angles = np.degrees(angles) % 180
# Group similar lines
merged = []
used = set()
for i, line1 in enumerate(lines):
if i in used:
continue
# Find similar lines
similar = []
for j, line2 in enumerate(lines):
if j in used:
continue
# Check angle difference
angle_diff = abs(angles[i] - angles[j])
angle_diff = min(angle_diff, 180 - angle_diff)
if angle_diff > angle_thresh:
continue
# Check endpoint distances
dist1 = np.linalg.norm(line1[:2] - line2[:2])
dist2 = np.linalg.norm(line1[2:] - line2[2:])
if min(dist1, dist2) > dist_thresh:
continue
similar.append(j)
used.add(j)
# Merge similar lines
if similar:
points = lines[similar].reshape(-1, 2)
direction = np.array([np.cos(np.radians(angles[i])),
np.sin(np.radians(angles[i]))])
# Project points onto line direction
proj = points @ direction
# Get extreme points
min_idx = np.argmin(proj)
max_idx = np.argmax(proj)
merged_line = np.concatenate([points[min_idx], points[max_idx]])
merged.append(tuple(merged_line))
return merged
def compute_line_angle(x1: float, y1: float, x2: float, y2: float) -> float:
"""Compute angle of line segment in degrees"""
return math.degrees(math.atan2(y2 - y1, x2 - x1)) % 180