Files
goldyard2025 3fe919e37c 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>
2026-07-10 23:14:39 +08:00

198 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.