refactor(halcon): single-skill plugin layout → invoke as /halcon (not /halcon:halcon)

Move SKILL.md + references/ scripts/ evals/ from skills/halcon/ up to the
plugin root. Per Claude Code plugins-reference, a plugin with SKILL.md at its
root and no skills/ subdir is auto-loaded as a single-skill plugin (v2.1.142+),
so the invocation name = frontmatter name = halcon → clean /halcon.
Bump plugin.json 2.0.0 → 2.0.1 so existing installs receive the update.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-10 23:14:39 +08:00
parent 36eadffa87
commit 3fe919e37c
44 changed files with 1 additions and 1 deletions
+197
View File
@@ -0,0 +1,197 @@
# HALCON task recipes
Ready-to-adapt pipelines for common vision tasks. Each recipe is a **procedure**
(a reusable method), not a one-off — read the operator names, adapt parameters,
then run via HDevEngine (`scripts/run_procedure.py`) or `hrun`. For exact
parameter semantics open the referenced pages (see `doc-map.md`); for the
authoritative operator signature, target `reference_hdevelop.pdf`.
Conventions used below: `Image` = input, `Region`/`Roi` = ROI, `Contours` = XLD
(subpixel contours), `*Handle` = a model handle that must be `clear_*`ed.
## Meta-pattern: procedure + Python driver (the house style)
This is how the tested pipeline in `references/examples/` is built — copy it.
1. Write an `.hdvp` external procedure with **control** inputs/outputs only
(paths in, numbers/tuples out). No `draw_*`, no `stop()`. Validate inside and
`throw` on unexpected results.
2. Persist any human-taught ROI once with `teach_roi.py``roi.hobj`; the
procedure `read_region`s it.
3. Drive from Python with HDevEngine: loop images, `set_input_control_param_by_name`,
`execute` (wrapped in `try/except HDevEngineError`), `get_output_control_param_by_name`,
aggregate, write CSV.
Reference implementation (bundled): `references/examples/find_circles.hdvp` +
`references/examples/run_compare.py`. Skeleton procedure body:
```
read_image (Image, ImageFile)
read_region (Roi, RoiFile)
reduce_domain (Image, Roi, ImageReduced) * restrict processing to the ROI
* ... task-specific operators ...
if (|Result| != Expected)
throw ('unexpected count: ' + |Result|) * driver catches & skips
endif
```
## Blob analysis (segment by gray value, measure regions)
Goal: find objects that differ in brightness, count/measure them.
```
threshold (ImageReduced, Region, MinGray, MaxGray) * or auto_threshold / binary_threshold
connection (Region, ConnectedRegions) * split into individual blobs
select_shape (ConnectedRegions, Selected, 'area', 'and', MinArea, MaxArea)
area_center (Selected, Area, Row, Col) * features per blob
```
Key knobs: pick the threshold from the histogram (`gray_histo`), or use
`dyn_threshold` against a smoothed copy for uneven lighting. Morphology
(`opening_circle`, `closing_circle`) cleans speckle before `connection`.
Guide: `solution_guide_i.pdf` ch.4 (p33).
## Subpixel edges, contours, and shape fitting
Goal: precise geometry (circle/line/ellipse) from contours.
```
edges_sub_pix (ImageReduced, Edges, 'canny', Alpha, Low, High) * Alpha≈13, higher=smoother
select_contours_xld (Edges, Sel, 'contour_length', MinLen, MaxLen, -0.5, 0.5)
union_adjacent_contours_xld (Sel, Union, 10, 1, 'attr_keep') * join broken arcs
sort_contours_xld (Union, Sorted, 'character', 'true', 'column') * deterministic order
fit_circle_contour_xld (Sorted, 'algebraic', -1, 0, 0, 3, 2, Row, Col, Radius, S, E, Order)
* fit_line_contour_xld / fit_ellipse_contour_xld for other shapes
```
Gotchas: canny thresholds and the length window are the tuning that decides how
many contours survive — if the fitted count is wrong, adjust `MinLen/MaxLen` and
the ROI tightness before anything else. Guides: `solution_guide_i.pdf` ch.7,9
(p63, p79).
## 2D measuring — metrology model (robust circle/line/rectangle fitting)
Goal: high-accuracy, repeatable geometry with built-in edge measurement. This is
the metrology-model half of the tested `find_circles.hdvp`.
```
create_metrology_model (MetrologyHandle)
set_metrology_model_image_size (MetrologyHandle, Width, Height)
add_metrology_object_circle_measure (MetrologyHandle, Row, Col, Radius, RadiusTol, \
MeasureLen1, MeasureLen2, MeasureSigma, [], [], Indices)
set_metrology_object_param (MetrologyHandle, Indices, 'num_instances', 1)
set_metrology_object_param (MetrologyHandle, Indices, 'measure_transition', 'positive')
set_metrology_object_param (MetrologyHandle, Indices, 'min_score', 0.3)
apply_metrology_model (Image, MetrologyHandle)
get_metrology_object_result (MetrologyHandle, Indices, 'all', 'result_type', 'all_param', Param)
* circle params come back interleaved: Row=Param[0::3], Col=Param[1::3], Radius=Param[2::3]
clear_metrology_model (MetrologyHandle)
```
Seed the metrology objects from a rough fit (e.g. `fit_circle_contour_xld`), then
let the model refine. Tune `min_score`, `measure_transition`
(positive/negative/all), and the radius tolerance. Guide:
`solution_guide_iii_b_2d_measuring.pdf` (Basic Tools p11, Tool Selection p27,
Examples p35).
## 1D measuring (calipers along a line or arc)
Goal: edge positions/widths along a profile (e.g. pin pitch, gap width).
```
gen_measure_rectangle2 (Row, Col, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', Handle)
measure_pos (Image, Handle, Sigma, Threshold, 'all', 'all', RowEdge, ColEdge, Amp, Distance)
* gen_measure_arc + measure_pos for circular profiles
close_measure (Handle)
```
Use the fuzzy measure object (`fuzzy_measure_pos`) when edges are noisy/ambiguous.
Guide: `solution_guide_iii_a_1d_measuring.pdf`.
## 2D matching (locate a known template)
Goal: find where a trained pattern appears (with rotation/scale), get pose.
Default = **shape-based matching** (robust to illumination, occlusion):
```
* --- train once, persist the model ---
create_shape_model (TemplateImageReduced, 'auto', 0, rad(360), 'auto', 'auto', \
'use_polarity', 'auto', 'auto', ModelID)
write_shape_model (ModelID, 'model.shm')
* --- match at runtime ---
read_shape_model ('model.shm', ModelID)
find_shape_model (Image, ModelID, 0, rad(360), 0.5, 0, 0.5, 'least_squares', 0, 0.9, \
Row, Col, Angle, Score)
```
Alternatives (pick by `solution_guide_ii_b_matching.pdf` ch.3): NCC
(`create_ncc_model`) for pure translation/known illumination; component matching
for articulated parts; local-deformable/descriptor for deformation/perspective.
Guide overview: `solution_guide_i.pdf` ch.10 (p89).
## 2D data codes (DataMatrix, QR, PDF417) and bar codes
```
create_data_code_2d_model ('Data Matrix ECC 200', [], [], DataCodeHandle)
find_data_code_2d (Image, SymbolXLDs, DataCodeHandle, 'stop_after_result_num', 1, \
ResultHandles, DecodedStrings)
clear_data_code_2d_model (DataCodeHandle)
```
If decoding fails: raise `find_data_code_2d` search effort/timeout params, or
preprocess (contrast, `gray_range_rect`, `mean_image`) — see
`solution_guide_ii_c_2d_data_codes.pdf` ch.4 (Preprocessing p25), ch.5 (Problem
Handling p29). Bar codes: `create_bar_code_model` / `find_bar_code`
(`solution_guide_i.pdf` ch.16 p159). Print-quality grading: ch.6 (p45).
## Camera calibration & world coordinates
Goal: convert pixel measurements to metric units / correct lens distortion.
```
* grab N images of the HALCON calibration plate at varied poses
create_calib_data ('calibration_object', 1, 1, CalibHandle)
set_calib_data_cam_param (CalibHandle, 0, [], StartCamPar)
set_calib_data_calib_object (CalibHandle, 0, 'caltab.descr')
* for each image: find_calib_data_object / set_calib_data_observ_points
calibrate_cameras (CalibHandle, Error)
get_calib_data (CalibHandle, 'camera', 0, 'params', CamParam)
* then set_origin_pose / image_points_to_world_plane for metric measurement in a plane
```
Prefer the **Calibration Assistant** in HDevelop to generate this code
(`hdevelop_users_guide.pdf` p184). Theory + full workflow:
`solution_guide_iii_c_3d_vision.pdf` ch.2 (p13) and ch.3 (single-camera metric,
p59).
## 3D surface-based matching (point clouds)
Goal: find the 3D pose of an object in a point cloud / from a CAD model.
```
create_surface_model (ObjectModel3D, RelSamplingDist, [], [], SurfaceModelID)
find_surface_model (SurfaceModelID, SceneModel3D, RelSamplingDist, KeyPointFrac, \
MinScore, 'true', [], [], Pose, Score, SurfaceMatchingResultID)
```
Data must be a real 3D point cloud with normals. If matches are poor, work
through `surface_based_matching.pdf` ch.4 (Troubleshooting p17) and ch.5 (Tips
p22); remove the dominant background plane first (ch.6, p26).
## OCR & classification (brief)
- **Deep OCR** (default for reading text): `create_deep_ocr` / `apply_deep_ocr`
— pretrained, no training needed. `solution_guide_i.pdf` ch.19 (p209).
- **Classic OCR**: segment characters → `do_ocr_multi_class_mlp` with a
pretrained font. ch.18 (p183).
- **Feature classification** (MLP/SVM/GMM/k-NN): train on region features, then
classify. `solution_guide_ii_d_classification.pdf` ch.5 (p31).
## When a recipe isn't enough
1. Read the matching chapter/pages from `doc-map.md`.
2. Confirm exact operator parameters in `reference_hdevelop.pdf` (target pages,
don't browse).
3. Prototype interactively in HDevelop (or `runScriptInGui`), then freeze the
working logic into an `.hdvp` and drive it headless — see the meta-pattern.