File size: 3,216 Bytes
b400ace 8c9c413 b400ace 8c9c413 b400ace 8c9c413 b400ace 8c9c413 b400ace 8c9c413 b400ace 8c9c413 b400ace 8c9c413 b400ace 8c9c413 b400ace | 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 | from dataclasses import dataclass
import cv2
from src.logger import logger
from src.utils.image import ImageUtils
# ✅ Safe import for headless environments
try:
from screeninfo import get_monitors
monitor_window = get_monitors()[0]
SCREEN_WIDTH, SCREEN_HEIGHT = monitor_window.width, monitor_window.height
except Exception as e:
# Headless fallback — e.g., Hugging Face Spaces, servers, CI
print(f"[Headless Mode] No monitor detected. Using default size. Error: {e}")
SCREEN_WIDTH, SCREEN_HEIGHT = 1920, 1080
@dataclass
class ImageMetrics:
# Window dimensions
window_width: int = SCREEN_WIDTH
window_height: int = SCREEN_HEIGHT
# For positioning image windows
window_x: int = 0
window_y: int = 0
reset_pos = [0, 0]
class InteractionUtils:
"""Perform primary functions such as displaying images and reading responses"""
image_metrics = ImageMetrics()
@staticmethod
def show(name, origin, pause=1, resize=False, reset_pos=None, config=None):
image_metrics = InteractionUtils.image_metrics
if origin is None:
logger.info(f"'{name}' - NoneType image to show!")
if pause:
cv2.destroyAllWindows()
return
# Resize if required
if resize:
if not config:
raise Exception("config not provided for resizing the image to show")
img = ImageUtils.resize_util(origin, config.dimensions.display_width)
else:
img = origin
# Try to show the image only if display is available
try:
if not is_window_available(name):
cv2.namedWindow(name)
cv2.imshow(name, img)
cv2.moveWindow(name, image_metrics.window_x, image_metrics.window_y)
except cv2.error:
# Skip visualization entirely in headless environments
logger.info(f"Skipping cv2.imshow for '{name}' (headless mode).")
# Update next window position
h, w = img.shape[:2]
margin = 25
w += margin
h += margin
w, h = w // 2, h // 2
if image_metrics.window_x + w > image_metrics.window_width:
image_metrics.window_x = 0
if image_metrics.window_y + h > image_metrics.window_height:
image_metrics.window_y = 0
else:
image_metrics.window_y += h
else:
image_metrics.window_x += w
if pause:
logger.info(f"Showing '{name}' (press Q to continue, Ctrl+C to exit)")
wait_q()
InteractionUtils.image_metrics.window_x = 0
InteractionUtils.image_metrics.window_y = 0
@dataclass
class Stats:
files_moved = 0
files_not_moved = 0
def wait_q():
esc_key = 27
try:
while cv2.waitKey(1) & 0xFF not in [ord("q"), esc_key]:
pass
cv2.destroyAllWindows()
except cv2.error:
# Skip in headless mode
pass
def is_window_available(name: str) -> bool:
"""Checks if a window is available"""
try:
cv2.getWindowProperty(name, cv2.WND_PROP_VISIBLE)
return True
except Exception:
return False
|