sairusses commited on
Commit
8c9c413
·
1 Parent(s): 2ceb729

fix for headless environments

Browse files
Files changed (1) hide show
  1. src/utils/interaction.py +37 -38
src/utils/interaction.py CHANGED
@@ -1,20 +1,27 @@
1
  from dataclasses import dataclass
2
-
3
  import cv2
4
- from screeninfo import get_monitors
5
-
6
  from src.logger import logger
7
  from src.utils.image import ImageUtils
8
 
9
- monitor_window = get_monitors()[0]
 
 
 
 
 
 
 
 
10
 
11
 
12
  @dataclass
13
  class ImageMetrics:
14
- # TODO: Move TEXT_SIZE, etc here and find a better class name
15
- window_width, window_height = monitor_window.width, monitor_window.height
16
- # for positioning image windows
17
- window_x, window_y = 0, 0
 
 
18
  reset_pos = [0, 0]
19
 
20
 
@@ -26,11 +33,14 @@ class InteractionUtils:
26
  @staticmethod
27
  def show(name, origin, pause=1, resize=False, reset_pos=None, config=None):
28
  image_metrics = InteractionUtils.image_metrics
 
29
  if origin is None:
30
  logger.info(f"'{name}' - NoneType image to show!")
31
  if pause:
32
  cv2.destroyAllWindows()
33
  return
 
 
34
  if resize:
35
  if not config:
36
  raise Exception("config not provided for resizing the image to show")
@@ -38,28 +48,21 @@ class InteractionUtils:
38
  else:
39
  img = origin
40
 
41
- if not is_window_available(name):
42
- cv2.namedWindow(name)
43
-
44
- cv2.imshow(name, img)
45
-
46
- if reset_pos:
47
- image_metrics.window_x = reset_pos[0]
48
- image_metrics.window_y = reset_pos[1]
49
-
50
- cv2.moveWindow(
51
- name,
52
- image_metrics.window_x,
53
- image_metrics.window_y,
54
- )
55
-
56
  h, w = img.shape[:2]
57
-
58
- # Set next window position
59
  margin = 25
60
  w += margin
61
  h += margin
62
-
63
  w, h = w // 2, h // 2
64
  if image_metrics.window_x + w > image_metrics.window_width:
65
  image_metrics.window_x = 0
@@ -71,10 +74,7 @@ class InteractionUtils:
71
  image_metrics.window_x += w
72
 
73
  if pause:
74
- logger.info(
75
- f"Showing '{name}'\n\t Press Q on image to continue. Press Ctrl + C in terminal to exit"
76
- )
77
-
78
  wait_q()
79
  InteractionUtils.image_metrics.window_x = 0
80
  InteractionUtils.image_metrics.window_y = 0
@@ -82,19 +82,19 @@ class InteractionUtils:
82
 
83
  @dataclass
84
  class Stats:
85
- # TODO Fill these for stats
86
- # Move qbox_vals here?
87
- # badThresholds = []
88
- # veryBadPoints = []
89
  files_moved = 0
90
  files_not_moved = 0
91
 
92
 
93
  def wait_q():
94
  esc_key = 27
95
- while cv2.waitKey(1) & 0xFF not in [ord("q"), esc_key]:
 
 
 
 
 
96
  pass
97
- cv2.destroyAllWindows()
98
 
99
 
100
  def is_window_available(name: str) -> bool:
@@ -102,6 +102,5 @@ def is_window_available(name: str) -> bool:
102
  try:
103
  cv2.getWindowProperty(name, cv2.WND_PROP_VISIBLE)
104
  return True
105
- except Exception as e:
106
- print(e)
107
  return False
 
1
  from dataclasses import dataclass
 
2
  import cv2
 
 
3
  from src.logger import logger
4
  from src.utils.image import ImageUtils
5
 
6
+ # Safe import for headless environments
7
+ try:
8
+ from screeninfo import get_monitors
9
+ monitor_window = get_monitors()[0]
10
+ SCREEN_WIDTH, SCREEN_HEIGHT = monitor_window.width, monitor_window.height
11
+ except Exception as e:
12
+ # Headless fallback — e.g., Hugging Face Spaces, servers, CI
13
+ print(f"[Headless Mode] No monitor detected. Using default size. Error: {e}")
14
+ SCREEN_WIDTH, SCREEN_HEIGHT = 1920, 1080
15
 
16
 
17
  @dataclass
18
  class ImageMetrics:
19
+ # Window dimensions
20
+ window_width: int = SCREEN_WIDTH
21
+ window_height: int = SCREEN_HEIGHT
22
+ # For positioning image windows
23
+ window_x: int = 0
24
+ window_y: int = 0
25
  reset_pos = [0, 0]
26
 
27
 
 
33
  @staticmethod
34
  def show(name, origin, pause=1, resize=False, reset_pos=None, config=None):
35
  image_metrics = InteractionUtils.image_metrics
36
+
37
  if origin is None:
38
  logger.info(f"'{name}' - NoneType image to show!")
39
  if pause:
40
  cv2.destroyAllWindows()
41
  return
42
+
43
+ # Resize if required
44
  if resize:
45
  if not config:
46
  raise Exception("config not provided for resizing the image to show")
 
48
  else:
49
  img = origin
50
 
51
+ # Try to show the image only if display is available
52
+ try:
53
+ if not is_window_available(name):
54
+ cv2.namedWindow(name)
55
+ cv2.imshow(name, img)
56
+ cv2.moveWindow(name, image_metrics.window_x, image_metrics.window_y)
57
+ except cv2.error:
58
+ # Skip visualization entirely in headless environments
59
+ logger.info(f"Skipping cv2.imshow for '{name}' (headless mode).")
60
+
61
+ # Update next window position
 
 
 
 
62
  h, w = img.shape[:2]
 
 
63
  margin = 25
64
  w += margin
65
  h += margin
 
66
  w, h = w // 2, h // 2
67
  if image_metrics.window_x + w > image_metrics.window_width:
68
  image_metrics.window_x = 0
 
74
  image_metrics.window_x += w
75
 
76
  if pause:
77
+ logger.info(f"Showing '{name}' (press Q to continue, Ctrl+C to exit)")
 
 
 
78
  wait_q()
79
  InteractionUtils.image_metrics.window_x = 0
80
  InteractionUtils.image_metrics.window_y = 0
 
82
 
83
  @dataclass
84
  class Stats:
 
 
 
 
85
  files_moved = 0
86
  files_not_moved = 0
87
 
88
 
89
  def wait_q():
90
  esc_key = 27
91
+ try:
92
+ while cv2.waitKey(1) & 0xFF not in [ord("q"), esc_key]:
93
+ pass
94
+ cv2.destroyAllWindows()
95
+ except cv2.error:
96
+ # Skip in headless mode
97
  pass
 
98
 
99
 
100
  def is_window_available(name: str) -> bool:
 
102
  try:
103
  cv2.getWindowProperty(name, cv2.WND_PROP_VISIBLE)
104
  return True
105
+ except Exception:
 
106
  return False