|
| 1 | +Fuse & Order On-Screen Element Boxes |
| 2 | +==================================== |
| 3 | + |
| 4 | +``set_of_marks.mark_elements`` numbers a single, already-clean element list — but |
| 5 | +nothing *produces* that list. A real screen parse yields three overlapping sources |
| 6 | +(OCR text boxes, icon/shape boxes, accessibility boxes) with heavy duplication and no |
| 7 | +consistent order. This module is the missing connective tissue between the locators |
| 8 | +(``locate_text``, ``find_shapes``, the a11y tree) and ``set_of_marks``: de-duplicate |
| 9 | +by overlap, union the sources keeping the most trustworthy box, and sort into reading |
| 10 | +order with a stable index. |
| 11 | + |
| 12 | +Every box is a plain ``dict`` with ``x, y, width, height`` (plus any extra keys such |
| 13 | +as ``text`` / ``source`` / ``score``), so the whole module is pure-stdlib and fully |
| 14 | +unit-testable. Imports no ``PySide6``. |
| 15 | + |
| 16 | +Headless API |
| 17 | +------------ |
| 18 | + |
| 19 | +.. code-block:: python |
| 20 | +
|
| 21 | + from je_auto_control import iou, merge_boxes, fuse_elements, reading_order |
| 22 | +
|
| 23 | + iou(box_a, box_b) # overlap of two boxes, 0..1 |
| 24 | + deduped = merge_boxes(raw_boxes, iou_threshold=0.9) |
| 25 | +
|
| 26 | + # Union three detector outputs; on overlap the a11y box wins, then OCR, then icon. |
| 27 | + elements = fuse_elements(ocr_boxes=ocr, icon_boxes=icons, a11y_boxes=tree) |
| 28 | +
|
| 29 | + # Sort top-to-bottom, left-to-right and add an "index" to each. |
| 30 | + for el in reading_order(elements): |
| 31 | + print(el["index"], el.get("text"), el["x"], el["y"]) |
| 32 | +
|
| 33 | +``iou`` returns the intersection-over-union of two boxes. ``merge_boxes`` keeps the |
| 34 | +largest of any cluster overlapping above ``iou_threshold``. ``fuse_elements`` tags |
| 35 | +each input with its ``source``, then drops cross-source overlaps preferring |
| 36 | +``source_priority`` (default ``a11y`` > ``ocr`` > ``icon``, then larger area). |
| 37 | +``reading_order`` bands rows within ``row_tol`` pixels, orders by ``x`` within each |
| 38 | +row, and returns new dicts carrying a sequential ``index``. |
| 39 | + |
| 40 | +Executor commands |
| 41 | +----------------- |
| 42 | + |
| 43 | +``AC_fuse_elements`` (``ocr`` / ``icon`` / ``a11y`` JSON arrays + ``iou_threshold`` |
| 44 | +→ ``{count, elements}``) and ``AC_reading_order`` (``elements`` + ``row_tol`` → |
| 45 | +``{count, elements}``). They are exposed as the MCP tools ``ac_fuse_elements`` / |
| 46 | +``ac_reading_order`` and as Script Builder commands under **Image**. |
0 commit comments