Skip to content

Commit 6e7a1c4

Browse files
author
Gin
committed
Improve image viewer script
1 parent 70438f4 commit 6e7a1c4

File tree

2 files changed

+96
-10
lines changed

2 files changed

+96
-10
lines changed

SerialPrograms/Scripts/check_detector_regions.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
# ==================================================================
3636
# Home summary screen finish loading detector
37-
add_infer_box_to_image(raw_image, 0.388, 0.238, 0.109, 0.062, image)
37+
# add_infer_box_to_image(raw_image, 0.388, 0.238, 0.109, 0.062, image)
3838

3939
# ==================================================================
4040
# LZA Hyperspace Timer detection
@@ -94,6 +94,17 @@
9494
# add_infer_box_to_image(raw_image, 0.630, 0.444, 0.226, 0.319, image)
9595

9696

97+
# ==================================================================
98+
# New LZA box system cursor detection
99+
# triangle_upper_edge_width = 0.008
100+
# traingle_full_height = 0.035
101+
# for row in range(6):
102+
# y = (0.122 if row == 0 else 0.333 + (0.797 - 0.331)/ 4.0 * (row-1)) - 0.003
103+
# for col in range(6):
104+
# x = 0.0545 + col*(0.386 - 0.059)/5.0
105+
# add_infer_box_to_image(raw_image, x, y, 0.025, traingle_full_height, image)
106+
107+
97108
# ==================================================================
98109
# LZA box system cursor detection
99110
# triangle_upper_edge_width = 0.008
@@ -102,7 +113,9 @@
102113
# y = 0.122 if row == 0 else 0.333 + (0.797 - 0.331)/ 4.0 * (row-1)
103114
# for col in range(6):
104115
# x = 0.058 + col*(0.386 - 0.059)/5.0
105-
# add_infer_box_to_image(raw_image, x, y, 0.018, traingle_full_height, image)
116+
# # add_infer_box_to_image(raw_image, x, y, 0.018, traingle_full_height, image)
117+
# add_infer_box_to_image(raw_image, x+0.011, y-0.009, 0.023, 0.031, image)
118+
106119
# Pixel (x,y) = (775, 136), (0.404, 0.126), rgb=[255,188,245,71] hsv=[ 80 181 245]
107120
# Pixel (x,y) = (759, 135), (0.395, 0.125), rgb=[255,182,233,70] hsv=[ 81 178 233]
108121
# Pixel (x,y) = (796, 135), (0.415, 0.125), rgb=[255,181,239,63] hsv=[ 80 188 239]

SerialPrograms/Scripts/image_viewer.py

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"""
2424

2525

26+
import argparse
2627
import cv2
2728
import numpy as np
2829

@@ -60,7 +61,7 @@ def _set_color_to_buffer(self, coord, color):
6061
if x >= 0 and x < self.width and y >= 0 and y < self.height:
6162
self.buffer[y, x] = self._solid_color(color)
6263

63-
def _render(self):
64+
def update_buffer(self) -> None:
6465
self.buffer = self.image.copy()
6566
if self.selected_pixel[0] >= 0 and self.selected_pixel[1] >= 0:
6667
p = self.selected_pixel
@@ -83,6 +84,8 @@ def _render(self):
8384
color = (0, 0, 255) if i == self.cur_rect_index else (255, 0, 0)
8485
self.buffer = cv2.rectangle(self.buffer, (rect[0], rect[1]), (rect[2], rect[3]), color, width)
8586

87+
def _render(self) -> None:
88+
self.update_buffer();
8689
cv2.imshow(self.window_name, self.buffer)
8790
# self.fullscreen = False
8891

@@ -190,7 +193,6 @@ def _mouse_callback(self, event, x, y, flags, param):
190193
self._render()
191194

192195
def run(self):
193-
194196
cv2.imshow(self.window_name, self.buffer)
195197
cv2.setWindowProperty(self.window_name, cv2.WND_PROP_TOPMOST, 1)
196198
cv2.setMouseCallback(self.window_name, self._mouse_callback)
@@ -243,18 +245,89 @@ def run(self):
243245
print(f"Pressed key {key}")
244246
self._render()
245247

248+
249+
def parse_box(box_str: str):
250+
"""
251+
Parse a box string in the format "start_x,start_y,width,height".
252+
All values should be floats between 0.0 and 1.0 (inclusive).
253+
Returns a tuple of (start_x, start_y, width, height).
254+
"""
255+
try:
256+
parts = box_str.split(',')
257+
if len(parts) != 4:
258+
raise ValueError(f"Box must have exactly 4 values, got {len(parts)}")
259+
260+
values = [float(v) for v in parts]
261+
for i, v in enumerate(values):
262+
if not (0.0 <= v <= 1.0):
263+
raise ValueError(f"Value at position {i} ({v}) is not between 0.0 and 1.0")
264+
265+
return tuple(values)
266+
except ValueError as e:
267+
raise argparse.ArgumentTypeError(f"Invalid box format '{box_str}': {e}")
268+
269+
246270
if __name__ == '__main__':
247-
import sys
248-
assert len(sys.argv) == 2
271+
parser = argparse.ArgumentParser(
272+
description='Interactive image viewer with pixel inspection and box drawing capabilities.',
273+
epilog="""
274+
Controls:
275+
Left click: Select pixel and show info
276+
Left drag: Draw a box
277+
Right click: Select existing box
278+
w/s/a/d: Move selected pixel
279+
i: Print info for all boxes
280+
Backspace/Delete: Delete selected box (or last box if none selected)
281+
ESC: Exit
282+
283+
Box format:
284+
Each box is specified as "start_x,start_y,width,height" where all values
285+
are floats between 0.0 and 1.0 (inclusive), representing normalized coordinates.
286+
""",
287+
formatter_class=argparse.RawDescriptionHelpFormatter
288+
)
249289

250-
filename = sys.argv[1]
290+
parser.add_argument(
291+
'image',
292+
help='Path to the image file to view'
293+
)
294+
295+
parser.add_argument(
296+
'--box',
297+
action='append',
298+
type=parse_box,
299+
metavar='START_X,START_Y,WIDTH,HEIGHT',
300+
help='Add a box to render on the image. Format: "start_x,start_y,width,height" '
301+
'where each value is a float between 0.0 and 1.0. Can be specified multiple times.'
302+
)
303+
304+
args = parser.parse_args()
251305

252306
# bgr or bgra channel order
253-
image = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
254-
assert image is not None
307+
image = cv2.imread(args.image, cv2.IMREAD_UNCHANGED)
308+
if image is None:
309+
parser.error(f"Could not load image from '{args.image}'")
255310

256311
height = image.shape[0]
257312
width = image.shape[1]
258-
print(f"Load image from {filename}, size: {width} x {height}")
313+
print(f"Load image from {args.image}, size: {width} x {height}")
314+
259315
viewer = ImageViewer(image)
316+
317+
# Add boxes from command line arguments
318+
if args.box:
319+
for box in args.box:
320+
start_x, start_y, box_width, box_height = box
321+
# Convert normalized coordinates to absolute pixel coordinates
322+
abs_start_x = int(start_x * width)
323+
abs_start_y = int(start_y * height)
324+
abs_end_x = int((start_x + box_width) * width)
325+
abs_end_y = int((start_y + box_height) * height)
326+
327+
# Add to viewer's rect list in the format [start_x, start_y, end_x, end_y]
328+
viewer.rects.append([abs_start_x, abs_start_y, abs_end_x, abs_end_y])
329+
print(f"Added box: ({start_x:.3f}, {start_y:.3f}, {box_width:.3f}, {box_height:.3f}) -> "
330+
f"pixels ({abs_start_x}, {abs_start_y}, {abs_end_x}, {abs_end_y})")
331+
viewer.update_buffer()
332+
260333
viewer.run()

0 commit comments

Comments
 (0)