Spaces:
Running
Running
File size: 10,430 Bytes
347d1a8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
"""
Shared visualization constants for debug output across all algorithms.
This module provides centralized configuration for fonts, colors, sizes, and
layout used in debug visualizations throughout the Ring Sizer system.
Used by:
- card_detection.py - Multi-strategy card detection debug output
- finger_segmentation.py - Hand/finger detection debug output
- geometry.py - Axis, zone, measurement debug output
- visualization.py - Final composite debug overlay
- confidence.py - Confidence visualization
Example usage:
from viz_constants import Color, FontScale, FontThickness, FONT_FACE
cv2.putText(img, "Title", (20, 100), FONT_FACE,
FontScale.TITLE, Color.WHITE,
FontThickness.TITLE_OUTLINE, cv2.LINE_AA)
"""
import cv2
from typing import Tuple
# ============================================================================
# FONT SETTINGS
# ============================================================================
# Font face used across all visualizations
FONT_FACE = cv2.FONT_HERSHEY_SIMPLEX
class FontScale:
"""
Font scale constants for text hierarchy levels.
Larger values = bigger text. These are base scales that may be
adjusted based on image size in some visualizations.
"""
TITLE = 3.5 # Main titles (e.g., "Card Detection", "Final Result")
SUBTITLE = 2.5 # Section headers (e.g., "Score: 0.85")
LABEL = 1.8 # Inline labels (e.g., "#1 Score:0.83")
BODY = 1.5 # Body text (normal annotations)
SMALL = 1.0 # Small text (fine details)
class FontThickness:
"""
Font thickness (stroke width) for text rendering.
Larger values = thicker/bolder text.
Use OUTLINE variants for background layer to create outlined text effect.
"""
# Main text thickness
TITLE = 7
SUBTITLE = 5
LABEL = 4
BODY = 2
# Outline/shadow thickness (draw first for outline effect)
TITLE_OUTLINE = 10
SUBTITLE_OUTLINE = 8
LABEL_OUTLINE = 6
BODY_OUTLINE = 4
# ============================================================================
# COLORS (BGR format for OpenCV)
# ============================================================================
class Color:
"""
Standard colors used across all visualizations.
All colors in BGR format (Blue, Green, Red) as required by OpenCV.
Example: (255, 255, 255) = White in BGR
Usage:
cv2.circle(img, center, radius, Color.GREEN, -1)
"""
# ========================================================================
# Basic Colors
# ========================================================================
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (0, 0, 255) # BGR: (0, 0, 255)
GREEN = (0, 255, 0) # BGR: (0, 255, 0)
BLUE = (255, 0, 0) # BGR: (255, 0, 0)
# ========================================================================
# Extended Palette
# ========================================================================
CYAN = (255, 255, 0) # BGR: (255, 255, 0)
YELLOW = (0, 255, 255) # BGR: (0, 255, 255)
MAGENTA = (255, 0, 255) # BGR: (255, 0, 255)
ORANGE = (0, 128, 255) # BGR: (0, 128, 255)
PINK = (128, 128, 255) # BGR: (128, 128, 255)
# ========================================================================
# Semantic Colors (what they represent in the system)
# ========================================================================
# Object colors
CARD = GREEN # Credit card outline
FINGER = MAGENTA # Finger contour
# Axis/geometry colors
AXIS_PALM = CYAN # Palm-side axis endpoint
AXIS_TIP = ORANGE # Fingertip axis endpoint
AXIS_LINE = YELLOW # Finger principal axis line
# Measurement colors
RING_ZONE = CYAN # Ring-wearing zone overlay
CROSS_SECTION = ORANGE # Cross-section lines
POINT = BLUE # Intersection/measurement points
# Text colors
TEXT_PRIMARY = WHITE # Primary text (titles, main info)
TEXT_SUCCESS = GREEN # Success messages
TEXT_ERROR = RED # Error messages
TEXT_WARNING = YELLOW # Warning messages
class StrategyColor:
"""
Colors for different card detection strategies.
Used to visually distinguish candidates from different detection methods
in debug visualizations.
"""
CANNY = Color.CYAN # Canny edge detection (cyan)
ADAPTIVE = Color.ORANGE # Adaptive thresholding (orange)
OTSU = Color.MAGENTA # Otsu's thresholding (magenta)
COLOR_BASED = Color.GREEN # Color-based detection (green)
ALL_CANDIDATES = Color.PINK # Combined candidates (pink/purple)
# ============================================================================
# DRAWING SIZES
# ============================================================================
class Size:
"""
Size constants for drawing geometric elements (circles, lines, etc.).
All sizes in pixels.
"""
# Circle radii
CORNER_RADIUS = 8 # Card corners, small points
ENDPOINT_RADIUS = 15 # Axis endpoints (palm/tip)
INTERSECTION_RADIUS = 8 # Cross-section intersection points
POINT_RADIUS = 5 # Generic points
# Line thicknesses
CONTOUR_THICK = 5 # Thick contours (finger, card)
CONTOUR_NORMAL = 3 # Normal contours (candidates)
LINE_THICK = 4 # Thick lines (axis)
LINE_NORMAL = 2 # Normal lines (cross-sections)
LINE_THIN = 1 # Thin lines (grid, reference)
# ============================================================================
# LAYOUT CONSTANTS
# ============================================================================
class Layout:
"""
Layout positioning constants for text and elements.
All positions in pixels from top-left corner.
"""
# Title positioning (top-left text block)
TITLE_Y = 100 # Y position for main title
SUBTITLE_Y = 200 # Y position for subtitle/secondary text
LINE_SPACING = 100 # Vertical spacing between text lines
# Text offsets
TEXT_OFFSET_X = 20 # Horizontal margin from left edge
TEXT_OFFSET_Y = 25 # Vertical offset for inline text
LABEL_OFFSET = 20 # Offset for labels near objects
# Result text area (final visualization)
RESULT_TEXT_Y_START = 60 # Starting Y for result text block
RESULT_TEXT_LINE_HEIGHT = 55 # Height between result text lines
RESULT_TEXT_X_OFFSET = 40 # X offset for result text
# ============================================================================
# HELPER FUNCTIONS
# ============================================================================
def get_scaled_font_size(base_scale: float, image_height: int,
reference_height: int = 1200,
min_scale: float = 1.5) -> float:
"""
Scale font size based on image dimensions for consistent appearance.
Args:
base_scale: Base font scale (e.g., FontScale.TITLE)
image_height: Height of the image in pixels
reference_height: Reference height for scaling (default: 1200px)
min_scale: Minimum scale to prevent text from being too small
Returns:
Scaled font size adjusted for image dimensions
Example:
# For a 2400px tall image, double the font size
scale = get_scaled_font_size(FontScale.TITLE, 2400)
# scale = 3.5 * 2 = 7.0
"""
scale_factor = image_height / reference_height
scaled = base_scale * scale_factor
return max(scaled, min_scale)
def create_outlined_text(image, text, position, font_scale,
color, outline_color=None,
thickness=None, outline_thickness=None):
"""
Draw text with outline for better visibility.
Args:
image: Image to draw on
text: Text string to draw
position: (x, y) position tuple
font_scale: Font scale (from FontScale)
color: Main text color (from Color)
outline_color: Outline color (default: Color.WHITE)
thickness: Main text thickness (auto-selected if None)
outline_thickness: Outline thickness (auto-selected if None)
Example:
create_outlined_text(img, "Title", (20, 100),
FontScale.TITLE, Color.GREEN)
"""
if outline_color is None:
outline_color = Color.WHITE
# Auto-select thickness based on font scale
if thickness is None:
if font_scale >= FontScale.TITLE:
thickness = FontThickness.TITLE
elif font_scale >= FontScale.SUBTITLE:
thickness = FontThickness.SUBTITLE
elif font_scale >= FontScale.LABEL:
thickness = FontThickness.LABEL
else:
thickness = FontThickness.BODY
if outline_thickness is None:
outline_thickness = thickness + 3
# Draw outline first (background layer)
cv2.putText(image, text, position, FONT_FACE,
font_scale, outline_color, outline_thickness, cv2.LINE_AA)
# Draw main text on top
cv2.putText(image, text, position, FONT_FACE,
font_scale, color, thickness, cv2.LINE_AA)
# ============================================================================
# VALIDATION (Optional: for type checking and debugging)
# ============================================================================
def validate_color(color: Tuple[int, int, int]) -> bool:
"""
Validate that a color tuple is in correct BGR format.
Args:
color: Tuple of (B, G, R) values
Returns:
True if valid, False otherwise
"""
if not isinstance(color, tuple) or len(color) != 3:
return False
return all(0 <= val <= 255 for val in color)
# ============================================================================
# EXPORTS
# ============================================================================
__all__ = [
# Font settings
'FONT_FACE',
'FontScale',
'FontThickness',
# Colors
'Color',
'StrategyColor',
# Sizes
'Size',
# Layout
'Layout',
# Helper functions
'get_scaled_font_size',
'create_outlined_text',
'validate_color',
]
|