Kunitomi's picture
Upload folder using huggingface_hub
196c526 verified
"""Polygon utility functions."""
from typing import List, Tuple
import numpy as np
import cv2
def simplify_polygon(
polygon: List[Tuple[float, float]],
epsilon_percent: float = 1.0
) -> List[Tuple[float, float]]:
"""Simplify polygon using Douglas-Peucker algorithm.
Args:
polygon: List of (x, y) coordinates
epsilon_percent: Epsilon as percentage of perimeter
Returns:
Simplified polygon
"""
if len(polygon) < 3:
return polygon
# Convert to numpy array
points = np.array(polygon, dtype=np.float32)
# Calculate epsilon based on perimeter
perimeter = cv2.arcLength(points, True)
epsilon = epsilon_percent * perimeter / 100
# Simplify
simplified = cv2.approxPolyDP(points, epsilon, True)
# Convert back to list of tuples
return [(float(p[0][0]), float(p[0][1])) for p in simplified]
def polygon_area(polygon: List[Tuple[float, float]]) -> float:
"""Calculate area of polygon using shoelace formula.
Args:
polygon: List of (x, y) coordinates
Returns:
Area of polygon
"""
if len(polygon) < 3:
return 0.0
# Shoelace formula
n = len(polygon)
area = 0.0
for i in range(n):
j = (i + 1) % n
area += polygon[i][0] * polygon[j][1]
area -= polygon[j][0] * polygon[i][1]
return abs(area) / 2.0
def polygon_centroid(polygon: List[Tuple[float, float]]) -> Tuple[float, float]:
"""Calculate centroid of polygon.
Args:
polygon: List of (x, y) coordinates
Returns:
Centroid (x, y)
"""
if not polygon:
return (0.0, 0.0)
x_sum = sum(p[0] for p in polygon)
y_sum = sum(p[1] for p in polygon)
return (x_sum / len(polygon), y_sum / len(polygon))
def polygon_bbox(polygon: List[Tuple[float, float]]) -> Tuple[float, float, float, float]:
"""Calculate bounding box of polygon.
Args:
polygon: List of (x, y) coordinates
Returns:
Bounding box (x1, y1, x2, y2)
"""
if not polygon:
return (0.0, 0.0, 0.0, 0.0)
xs = [p[0] for p in polygon]
ys = [p[1] for p in polygon]
return (min(xs), min(ys), max(xs), max(ys))
def validate_polygon(polygon: List[Tuple[float, float]], min_points: int = 3) -> bool:
"""Validate polygon has minimum requirements.
Args:
polygon: List of (x, y) coordinates
min_points: Minimum number of points
Returns:
True if valid
"""
return len(polygon) >= min_points and polygon_area(polygon) > 0