Repository navigation
Expand file tree
/
Copy pathdetect.py
More file actions
64 lines (52 loc) · 2.42 KB
/
Copy pathdetect.py
File metadata and controls
64 lines (52 loc) · 2.42 KB
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
from __future__ import annotations
import argparse
from pathlib import Path
try:
from PIL import Image
except ImportError:
Image = None
from ground import GroundError, _position, locate
from vision_client import VisionError
DEFAULT_CATEGORY = ("UI element (buttons, links, inputs, icons, labels, "
"headings, images, badges)")
def build_target(category: str | None) -> str:
target = (category or DEFAULT_CATEGORY).strip()
if not target.lower().startswith("every distinct "):
target = f"every distinct {target}"
if "exact visible text" not in target.lower():
target += " — include the exact visible text in each label"
return target
def format_inventory(matches, width: int, height: int) -> list[str]:
lines = []
for index, match in enumerate(matches, 1):
x1, y1, x2, y2 = match.bbox
position = _position(match.bbox, width, height)
lines.append(f"{index}. {position} {match.label} x1: {x1}, y1: {y1}, x2: {x2}, y2: {y2}")
return lines or ["no elements detected"]
def main() -> None:
parser = argparse.ArgumentParser(
prog="detect",
description="Inventory the elements in an image (or a region) with pixel bounding boxes",
)
parser.add_argument("image", type=Path, help="path to the image")
parser.add_argument("category", nargs="?",
help='restrict to a category, e.g. "buttons" or "icons" (default: all UI elements)')
parser.add_argument("--region", metavar="X1,Y1,X2,Y2",
help="inventory only this pixel box; output stays in original-image coordinates")
parser.add_argument("--fail-on-empty", action="store_true",
help="exit 1 with a stderr diagnostic when no elements are detected")
args = parser.parse_args()
try:
matches = locate(args.image.expanduser(), build_target(args.category), region=args.region)
if Image is None:
raise GroundError("detect requires Pillow; install the optional dependency pillow first")
with Image.open(args.image.expanduser()) as image:
width, height = image.size
except (GroundError, VisionError) as exc:
parser.exit(1, f"detect: {exc}\n")
if args.fail_on_empty and not matches:
parser.exit(1, "detect: no elements detected\n")
for line in format_inventory(matches, width, height):
print(line)
if __name__ == "__main__":
main()