spot-the-diff / src /services /answer_visualizer.py
RiceZero
v1.2
1d1bd8c
Raw History Blame Contribute Delete
2.65 kB
"""Answer visualization: draws red circles on differences."""
from __future__ import annotations
import cv2
import numpy as np
from src.models.difference import Difference
class AnswerVisualizer:
"""Visualizes answers by drawing red circles around differences."""
def __init__(self, circle_color: tuple[int, int, int] = (0, 0, 255), thickness: int = 3):
"""Initialize the answer visualizer.
Args:
circle_color: BGR color for circles (default: red).
thickness: Circle line thickness.
"""
self._color = circle_color
self._thickness = thickness
def draw_answers(
self,
image: np.ndarray,
differences: list[Difference],
padding_ratio: float = 0.15,
) -> np.ndarray:
"""Draw red circles around each difference on the image.
Args:
image: BGR image (H, W, 3) uint8.
differences: List of differences to mark.
padding_ratio: Extra padding around bbox as ratio of bbox size.
Returns:
Image with red circles drawn around differences.
"""
result = image.copy()
for diff in differences:
x1, y1, x2, y2 = diff.bbox
# Calculate center and radius
center_x = (x1 + x2) // 2
center_y = (y1 + y2) // 2
# Calculate radius as diagonal distance from center to corner, plus padding
width = x2 - x1
height = y2 - y1
radius = int(np.sqrt(width**2 + height**2) / 2 * (1 + padding_ratio))
# Ensure radius is at least visible
radius = max(radius, 20)
# Draw circle
cv2.circle(result, (center_x, center_y), radius, self._color, self._thickness)
# Optionally draw a smaller filled circle at center for emphasis
cv2.circle(result, (center_x, center_y), 5, self._color, -1)
return result
def create_answer_overlay(
self,
original: np.ndarray,
modified: np.ndarray,
differences: list[Difference],
) -> tuple[np.ndarray, np.ndarray]:
"""Create answer overlays for both original and modified images.
Args:
original: Original image.
modified: Modified image with differences.
differences: List of differences.
Returns:
Tuple of (original_with_answers, modified_with_answers).
"""
original_marked = self.draw_answers(original, differences)
modified_marked = self.draw_answers(modified, differences)
return original_marked, modified_marked