Ray1ee01's picture
Upload folder using huggingface_hub
2cf467c verified
Raw
History Blame Contribute Delete
4.38 kB
"""Alignment constraint processor."""
import torch
import torch.nn.functional as F
from typing import List, Tuple
from .base import ConstraintProcessor
class AlignmentProcessor(ConstraintProcessor):
"""Processor for alignment constraints."""
def can_handle(self, constraint_type: str) -> bool:
return constraint_type == "alignment"
def process(self, constraint: dict, bboxes: List[Tuple[float, float, float, float]],
device: str = "cpu") -> torch.Tensor:
"""Process alignment constraints.
Args:
constraint: Dictionary with "alignment" key containing alignment constraint
bboxes: List of (x, y, w, h) bounding boxes
device: Device for tensors
Returns:
Loss tensor
"""
alignment_constraint = constraint.get("alignment", {})
if not alignment_constraint:
return torch.tensor(0.0, device=device)
L_alignment = torch.tensor(0.0, device=device)
direction = alignment_constraint.get("direction", "horizontal") # "horizontal" or "vertical"
value = alignment_constraint.get("value", "center") # "left", "center", "right", "top", "bottom"
if not bboxes:
return L_alignment
# Get container size (should be passed separately, but for now estimate from bboxes)
# Calculate bounding box of all elements
all_x = [x for x, _, _, _ in bboxes]
all_y = [y for _, y, _, _ in bboxes]
all_w = [w for _, _, w, _ in bboxes]
all_h = [h for _, _, _, h in bboxes]
container_w = max(x + w for x, w in zip(all_x, all_w)) if all_x else 1000.0
container_h = max(y + h for y, h in zip(all_y, all_h)) if all_y else 1000.0
if direction == "horizontal":
# Horizontal alignment: align elements along x-axis
if value == "left":
# All elements should align to left edge
for x, _, _, _ in bboxes:
x_t = torch.tensor(x, device=device)
L_alignment += x_t ** 2
elif value == "center":
# All elements should be centered horizontally
for x, _, w, _ in bboxes:
x_t = torch.tensor(x, device=device)
w_t = torch.tensor(w, device=device)
center_x = x_t + 0.5 * w_t
target_center = torch.tensor(container_w / 2.0, device=device)
L_alignment += (center_x - target_center) ** 2
elif value == "right":
# All elements should align to right edge
for x, _, w, _ in bboxes:
x_t = torch.tensor(x, device=device)
w_t = torch.tensor(w, device=device)
right_x = x_t + w_t
target_right = torch.tensor(container_w, device=device)
L_alignment += (right_x - target_right) ** 2
elif direction == "vertical":
# Vertical alignment: align elements along y-axis
if value == "top":
# All elements should align to top edge
for _, y, _, _ in bboxes:
y_t = torch.tensor(y, device=device)
L_alignment += y_t ** 2
elif value == "center":
# All elements should be centered vertically
for _, y, _, h in bboxes:
y_t = torch.tensor(y, device=device)
h_t = torch.tensor(h, device=device)
center_y = y_t + 0.5 * h_t
target_center = torch.tensor(container_h / 2.0, device=device)
L_alignment += (center_y - target_center) ** 2
elif value == "bottom":
# All elements should align to bottom edge
for _, y, _, h in bboxes:
y_t = torch.tensor(y, device=device)
h_t = torch.tensor(h, device=device)
bottom_y = y_t + h_t
target_bottom = torch.tensor(container_h, device=device)
L_alignment += (bottom_y - target_bottom) ** 2
return L_alignment
def get_weight_key(self) -> str:
return "w_alignment"