Skip to main content

generate-templates

Create or change named image features using ok-script's ok_templates screenshots, COCO annotations, and split exporter; verify them with find_feature or find_one and reuse screenshots in tests.

Datos de origen

Repositorio
ok-oldking/ok-script
Última actividad en el origen
28 de octubre de 2026 a las 11:11
Idioma detectado de SKILL.md
inglés
Estrellas
813
Forks
234

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
generate-templates
description
Create or change named image features using ok-script's ok_templates screenshots, COCO annotations, and split exporter; verify them with find_feature or find_one and reuse screenshots in tests.
# Generate and use templates Work on the consuming application's screenshots, annotations, task code, and assets using the installed library. All project-relative paths below refer to that application's root, not the ok-script library directory. Use the existing pipeline: original screenshots in `ok_templates/`, annotations in `ok_templates/coco_annotations.json`, and `generate_templates` to generate split runtime assets. Keep source screenshots intact so both agents and the Template tab can inspect and reannotate them. The old compression APIs and dialog option are obsolete; use the split exporter for new or regenerated assets. For new named features, do not write standalone runtime crops into `assets/`, invent a template metadata format, or implement a separate `cv2.matchTemplate` registry/loader. Use `CocoTemplateStore` for authoring, `generate_templates` for runtime exports, and the library's named-feature matching APIs in tasks. A crop preview may be written outside the export folder for inspection, but it does not replace the source screenshot, COCO annotation, or generated split asset. Run from the automation project's root using its interpreter, following [use-venv](../use_venv/SKILL.md). For live capture and task execution follow [develop](../develop/SKILL.md), including reset, baseline verification, and application-level success checks. ## Capture and choose the rectangle Use an existing original screenshot or the MCP `screenshot()` result. Check its dimensions, `captured_at`, and `cached` before treating it as current evidence. Copy the original file into `ok_templates/` under an unused filename; reuse it if already there. Do not overwrite a different image with the same name. Keep files directly in this folder: the exporter resolves source images by basename. For an in-memory frame, `CocoTemplateStore.save_frame(frame)` saves a PNG and registers it in COCO; do not register the same frame repeatedly during iteration. View the actual screenshot before choosing a rectangle. COCO `bbox` is `[x, y, width, height]` in original screenshot pixels, not two corners or desktop coordinates. Map any resized preview coordinates back to the original. Choose a distinctive, stable patch; avoid animation, changing text, and flat colors. Save and inspect a crop preview before generating assets. Preserve full source dimensions and location because the matcher uses them for scaling and search. ## Update source annotations Use `ok.core.template_store.CocoTemplateStore`. Validate existing JSON with `json.load` before mutation: `store.load()` otherwise treats malformed JSON as empty. Serialize GUI and agent edits; the store's lock is only process-local. `replace_annotations(image_name, annotations)` replaces ALL annotations on that image. Read them first and preserve unrelated entries. Validate positive integer dimensions and bounds yourself because the store silently clamps rectangles. Use unique category names across the dataset; duplicate categories on different images are not supported appearance variants. Prefer Python identifiers such as `settings_save` if generating a label enum. Names beginning with `box_` are region annotations whose pixels are omitted during export; do not use that prefix for a visual template. Example after copying `settings-open.png` into `ok_templates` (adapt coordinates to the image you inspected): ```python import json from pathlib import Path import cv2 from ok.core.template_store import CocoTemplateStore store = CocoTemplateStore("ok_templates") if store.coco_path.exists(): with store.coco_path.open(encoding="utf-8") as stream: json.load(stream) # Stop on corrupt metadata before calling store.load(). image_name, name = "settings-open.png", "settings_save" x, y, width, height = 1480, 920, 160, 48 source = cv2.imread(str(store.image_path(image_name))) assert source is not None assert 0 <= x < x + width <= source.shape[1] assert 0 <= y < y + height <= source.shape[0] data = store.load() category_ids = {c["id"] for c in data["categories"] if c["name"] == name} image_ids = {i["id"] for i in data["images"] if i["file_name"] == image_name} assert not any(a["category_id"] in category_ids and a["image_id"] not in image_ids for a in data["annotations"]), "Feature name belongs to another image" annotations = store.annotations_for(image_name)["annotations"] annotations = [a for a in annotations if a["category"] != name] annotations.append({"category": name, "bbox": [x, y, width, height]}) store.replace_annotations(image_name, annotations) preview = Path("logs/template-preview") preview.mkdir(parents=True, exist_ok=True) assert cv2.imwrite(str(preview / f"{name}.png"), source[y:y+height, x:x+width]) ``` If intentionally moving an existing feature to another source image, remove its old annotation while preserving the others, then add the replacement. If editing COCO directly, preserve unique IDs, image/category references, dimensions, and all unrelated entries. Review the annotation diff before export. ## Generate runtime assets ### Split exports (default) The Template tab defaults to **Split(Recommend)**. Use its split exporter: ```python from ok.feature.FeatureSet import generate_templates template_folder = generate_templates( coco_json=str(store.coco_path), target_folder=str(Path("assets/templates").resolve()), image_folder=str(store.folder), generate_label_enmu=None, ) print(template_folder) ``` The Save dialog keeps `assets` and `ok_tasks/assets` as its destination choices; Split adds the `templates` subfolder. Use `assets/templates` for a standalone app (`template_matching.template_folder`, which defaults to `assets/templates`), or `ok_tasks/assets/templates` for custom scripts. Split exports contain one crop-sized PNG per feature, named `<original_name>_<width>x<height>_<x>_<y>.png`. Names are readable, with no prefix or encoding. Spaces, underscores, and Unicode names are supported; characters forbidden in Windows filenames produce an error. They need no COCO JSON at runtime. Keep the destination dedicated to template PNGs: both export and loading report unparseable filenames instead of ignoring them. The exporter preserves the authoring dataset and replaces/removes template crops. Keep source and destination separate. Use the original name in task code: `self.find_one("settings_save")` loads `settings_save_1920x1080_1480_920.png`. The PNG dimensions supply the crop size; the filename supplies the reference resolution and top-left position. Do not rename a crop to work around an annotation error: correct the source annotation and regenerate. Keep previews, notes, and unrelated files outside this folder; even a single-feature lookup validates all filenames in the selected folder. `template_matching.template_folder` and the existing `coco_feature_json` can coexist; split templates override matching COCO names in the same source group. Keep existing thresholds, processors, and anchor settings. Main application features retain priority over custom-script features. Imported split assets use `ok_import/<module>/assets/templates` and are addressed as `<module>/<original_name>`. See [the format documentation](../../../docs/feature-crops.md) for details. When migrating older encoded split exports, regenerate from the source COCO and screenshots into the same dedicated folder. The exporter replaces the old files with readable names. If an export folder contains an unparseable file, inspect and relocate that file before retrying; export leaves existing files intact on validation failure. Re-export with the current library to repair older Windows exports that viewers cannot open because of temporary-directory permissions. `generate_templates` uses the optional keyword `generate_label_enmu`. Its value is a dotted module/class path, e.g. `ok_tasks.LabelEnum`, not a filename. Use it only when the project uses enums; every category must be a valid Python identifier and not a keyword. Verify the generated enum imports successfully. ## Verify and use the feature First load generated assets in a fresh `FeatureSet` and match the original screenshot. This checks the full annotation/export/load path without a GUI: ```python from ok.feature.FeatureSet import FeatureSet features = FeatureSet(False, None, 0.002, 0.002, default_threshold=0.95, template_folder=template_folder) boxes = features.find_feature(source, name, threshold=0.95) assert len(boxes) == 1, boxes box = boxes[0] assert abs(box.x - x) <= 1 and abs(box.y - y) <= 1 assert box.width == width and box.height == height print(box) ``` Also test an independent positive screenshot and a negative screenshot when available, and relevant target sizes. A source-image self-match alone does not prove recognition is robust. Use the project's actual threshold, preprocessing, and anchor settings for representative verification. Keep evidence of what was tested and what remains unverified. Full screenshots in `ok_templates/` are also reusable offline test fixtures. Pass their paths directly to `TaskTestCase.set_image()` to test the application's real recognition methods, or load them as frames for `FeatureSet` tests using the generated runtime assets. Keep referenced screenshots with the project so tests remain reproducible; copying them to `tests/images/` is unnecessary. Retain independent positive/negative captures when available, and assert the expected state or match geometry rather than only checking that an image loads. Follow [write-test](../write-test/SKILL.md) for harness setup and isolation. In task code, use the existing methods: ```python box = self.find_one("settings_save", threshold=0.95) assert box is not None, "Save button not found" self.click_box(box) # Observe and assert the resulting application state. ``` `find_feature` returns a list; `find_one` returns a box or `None`. Pass `frame=` to match a particular screenshot in task code. Named features search near their annotated position by default. For a control that moves, provide an appropriate `box=` or explicit horizontal/vertical variances. Variances are fractions of the frame size, and zero inherits configured defaults. Diagnose capture size, scaling, crop, and search area before lowering a threshold. `screenshot=True` uses the existing screenshot worker and may write asynchronously; offline crop previews should use synchronous `cv2.imwrite` as above. After regeneration, cached features in a running process must be refreshed. The GUI Save action already calls `feature_set.process_data()`. For agent edits, after export finishes call `self.executor.feature_set.process_data()` from the executor-owned task before matching (after capture initializes frame dimensions), or restart the verified owned runtime. Do not regenerate files while a task is reading them or reload from a competing thread. Finish by reporting the original screenshot, source COCO, generated asset path, feature names, task usage, and verification evidence. Keep originals and source annotations for future edits; runtime code uses the generated assets.
Ver en GitHub