244 lines
8.4 KiB
YAML
244 lines
8.4 KiB
YAML
# ============================================================
|
||
# 双目相机螺栓测量系统配置文件 (C++ port)
|
||
#
|
||
# 这是 Python 项目 e:/02_Modules/StereoVisionBoltMeasurement/config.yaml
|
||
# 的镜像。两者必须保持参数一致——任何一边改值,另一边同步。
|
||
# 数据路径用 Python 项目的绝对路径(见 paths 段末尾)。
|
||
# ============================================================
|
||
|
||
# ---------- 工作距离 ----------
|
||
# 从标定推导视差范围,替代 SGBM 固定 [288,1024]。
|
||
# z_min=1200 → disp_max≈1089,覆盖近处螺杆(disp~1060)。
|
||
working_distance:
|
||
z_min_mm: 900
|
||
z_max_mm: 4000
|
||
|
||
# ---------- 图像基本参数 ----------
|
||
image:
|
||
width: 4096
|
||
height: 3000
|
||
channels: 1
|
||
expected_dtype: "uint8"
|
||
allowed_extensions: [".tiff", ".tif", ".bmp", ".png"]
|
||
|
||
# ---------- 图像输入自检 ----------
|
||
image_validation:
|
||
min_max_value: 10
|
||
max_saturation_ratio: 0.20
|
||
|
||
# ---------- ChArUco 标定板参数 ----------
|
||
charuco:
|
||
rows: 9
|
||
cols: 9
|
||
square_length_mm: 50.0
|
||
marker_length_mm: 37.0
|
||
dict_id: 11 # DICT_6X6_1000
|
||
min_corners_per_image: 30
|
||
|
||
# ---------- 标定模块参数 ----------
|
||
calibration:
|
||
source: "xml"
|
||
xml_path: "calib/stereo_calib_20260621_202857_ascii.xml"
|
||
min_image_pairs: 15
|
||
max_skip_ratio: 0.30
|
||
max_single_rms: 0.40
|
||
max_stereo_rms: 0.80
|
||
expected_baseline_range: [80, 600]
|
||
use_fix_intrinsic: true
|
||
|
||
# ---------- 校正模块参数 ----------
|
||
# alpha=1.0 是硬约束,详见 CLAUDE.md 隐式决策 #1。
|
||
rectification:
|
||
alpha: 1.0
|
||
interpolation: "cubic"
|
||
validation_feature_count: 500
|
||
validation_match_count: 10
|
||
epipolar_inlier_threshold_pixel: 5.0
|
||
min_epipolar_inlier_count: 3
|
||
max_epipolar_error_pixel: 5.0
|
||
min_valid_roi_ratio: 0.25
|
||
|
||
# ---------- SGBM 立体匹配参数 ----------
|
||
# min_disparity / num_disparities 依赖 f_rect·B;如标定改了必须重算。
|
||
# 当前值假设 f_rect≈3190, B≈235mm(alpha=1.0 下)。
|
||
sgbm:
|
||
min_disparity: 288
|
||
num_disparities: 736
|
||
block_size: 5
|
||
P1: 600
|
||
P2: 2400
|
||
disp12_max_diff: 1
|
||
uniqueness_ratio: 10
|
||
speckle_window_size: 100
|
||
speckle_range: 2
|
||
pre_filter_cap: 63
|
||
mode: "SGBM_3WAY"
|
||
|
||
# ---------- WLS 滤波 ----------
|
||
wls:
|
||
lambda_value: 8000.0
|
||
sigma_color: 1.5
|
||
|
||
# ---------- 视差自检 ----------
|
||
disparity_validation:
|
||
min_valid_pixel_ratio: 0.10
|
||
min_disparity_range: 50
|
||
max_nan_ratio: 0.90
|
||
|
||
# ---------- 点云参数 ----------
|
||
# z_min_mm / z_max_mm / expected_wd_range are FALLBACK only — when run_pipeline /
|
||
# c_api are wired (the standard path) SceneRuntime derives the real reachable
|
||
# Z range from (f_rect, baseline, sgbm.min_disparity, sgbm.num_disparities) and
|
||
# overrides these values per frame. See docs/L_100_SCENE_HANDOFF.md §6.2 and
|
||
# include/stereo_bolt/scene_runtime.hpp. Keep the fallback values conservative
|
||
# enough to cover every supported workpiece distance.
|
||
pointcloud:
|
||
z_min_mm: 600
|
||
z_max_mm: 3000
|
||
expected_wd_range: [600, 3000]
|
||
min_num_points: 50000
|
||
max_z_std_mm: 800
|
||
min_bbox_extent_x_mm: 200
|
||
min_bbox_extent_y_mm: 100
|
||
sor_nb_neighbors: 30
|
||
sor_std_ratio: 2.0
|
||
voxel_downsample_min_points: 500000
|
||
voxel_size_mm: 0.5
|
||
roi_mask:
|
||
enabled: false
|
||
method: "hsv_threshold"
|
||
hsv_lower: [0, 0, 210]
|
||
hsv_upper: [180, 50, 255]
|
||
morph_close_kernel: 15
|
||
dilate_px: 100
|
||
min_area_ratio: 0.02
|
||
|
||
# ---------- 2D 检测(左图分割) ----------
|
||
# mask_method: 决定 foam_mask(支撑面像素 mask) 怎么算
|
||
# "brightness" — 亮度阈值 + 最大连通域(只对原始低曝光泡沫板场景有效;
|
||
# rectify ROI 外恒为 0,所以 mask 会等于 ROI 矩形)
|
||
# "ransac" — 在 dense xyz_map 上 RANSAC 找主导平面,
|
||
# 把"到平面 < ransac.distance_thresh_mm"的像素当 mask
|
||
# 默认 "brightness" 保 parity_tests 不变,新工业数据用 "ransac"
|
||
bolt_detect_2d:
|
||
mask_method: "ransac"
|
||
foam_brightness_threshold: 70
|
||
foam_morph_open_kernel: 21
|
||
foam_dilate_px: 0
|
||
bbox_margin_px: 60
|
||
bolt_morph_close_kernel: 15
|
||
bolt_min_area_px: 800
|
||
min_bolts: 1
|
||
max_bolts: 0
|
||
bolt_exclude_dilate_px: 0 # 硬约束:默认 0,详见 CLAUDE.md 隐式决策 #5
|
||
ransac:
|
||
distance_thresh_mm: 8.0 # 点到平面距离 < 此值即视为 inlier(3σ 容忍下,
|
||
# frame 100 residual_std≈2.6 mm)
|
||
max_iterations: 200
|
||
min_inlier_ratio: 0.15 # 兜底:inlier 占比过低视作失败,自动回退
|
||
sample_stride: 4 # xyz_map 下采样步长(每 4×4 像素取 1 个 RANSAC 候选)
|
||
morph_close_kernel_px: 9 # mask 后处理:闭运算填洞 + 最大连通域
|
||
|
||
# ---------- 参考平面 (SVD on foam mask) ----------
|
||
plane:
|
||
max_residual_std_mm: 15.0
|
||
max_normal_to_axis_deg: 60
|
||
outlier_rejection_iterations: 5
|
||
outlier_mad_k: 2.5
|
||
|
||
# ---------- 支撑面几何门 ----------
|
||
# plane fit 后、bolt extract 前执行。把 bolt 的 3D 中心投影到主支撑面
|
||
# inlier OBB, 超出 OBB 超过 margin_mm 的检测会被剔除并打印 WARN。
|
||
# margin_mm 独立于 bolt.expected_diameter_mm, 避免混杂不同尺寸螺杆时
|
||
# 几何门随螺杆规格隐式变宽/变窄。
|
||
support_gate:
|
||
enabled: true
|
||
margin_mm: 10.0
|
||
|
||
# ---------- 螺栓几何先验 ----------
|
||
# 主路径(run_pipeline / c_api)对每颗 bolt 先跑 bbox_projection 得 h_est,
|
||
# 然后 extract 内的 height 过滤改用 max(h_est × 1.3, h_est + 20 mm),
|
||
# validate_measurements 改用 |measured - h_est| < bolt.height_tolerance_mm。
|
||
# 下面的 max_height_mm / extract_height_filter_mm 只剩 fallback 作用 —— 当
|
||
# bbox_projection 失败、h_est 不可得时才走全局上限。
|
||
# 工件外形规格(expected_diameter_mm)仍是真正的先验,保留。
|
||
bolt:
|
||
min_height_mm: 5.0
|
||
max_height_mm: 250.0 # fallback ceiling (used only when h_est is unavailable)
|
||
extract_height_filter_mm: 200.0 # fallback filter (same condition)
|
||
height_tolerance_mm: 60.0 # |measured - h_est| 允许差;触发 validate_measurements 失败
|
||
expected_diameter_mm: 16.0
|
||
min_points_per_bolt: 50
|
||
max_axis_plane_angle_deg: 30
|
||
extract_fallback: "bbox_projection" # 'none' | 'bbox_projection'; 后者用 YOLO bbox + 平面法向反解高度,处理 SGBM 在窄/反光螺杆上失败的情况
|
||
|
||
# ---------- 几何测量 ----------
|
||
measurement:
|
||
top_extraction_method: "percentile_on_axis"
|
||
top_percentile: 0.99
|
||
plane_use_sgbm: true
|
||
# true: 高度 = 螺杆顶点到支撑平面的法向距离; false: 高度 = 顶点到可见底沿拟合轴的长度
|
||
height_from_plane: true
|
||
plane_height_along_axis: true
|
||
plane_anchor_max_foot_gap_std_mm: 20.0
|
||
plane_sgbm_scale: 0.25
|
||
plane_max_samples: 40000
|
||
|
||
# ---------- Diagnostics ----------
|
||
diagnostics:
|
||
enabled: true
|
||
blind_strip_warn_ratio: 0.25
|
||
min_roi_pointcloud_coverage_ratio: 0.001
|
||
|
||
# ---------- YOLO 螺栓检测 ----------
|
||
# 注意 C++ 端走 ONNX:先在 Python 把 best_v4_finetune.pt 导出 .onnx。
|
||
# dilate 量原本写成像素(50/30),跟距离和分辨率耦合。改成毫米后由
|
||
# scene_runtime.cpp 在运行时用 pixels_per_mm(= f / Z_repr)换算成像素,
|
||
# 不同工作距离 / 不同镜头不再需要手调。
|
||
yolo:
|
||
enabled: true
|
||
model_path: "weights/obb_plus_halcon_seg_1024_fp16.rknn"
|
||
backend: "rknn"
|
||
task: "obb"
|
||
imgsz: 1024
|
||
conf: 0.25
|
||
dead_zone_min_valid_pts: 50
|
||
dead_zone_bbox_dilate_mm: 24.0 # = expected_diameter_mm × 1.5; 算 valid_xyz 前把 bbox 膨胀,救窄/反光螺杆
|
||
foam_bbox_dilate_mm: 16.0 # = expected_diameter_mm × 1.0; foam_mask 从 YOLO bbox 减去前用的膨胀量
|
||
|
||
# Experimental: keep sparse-global YOLO bolts only when right YOLO + local LR check pass.
|
||
local_stereo_fallback:
|
||
enabled: true
|
||
min_valid_points: 50
|
||
|
||
# ---------- 评估通过判据 ----------
|
||
evaluation:
|
||
height_max_mm: 2.0
|
||
height_p95_mm: 1.5
|
||
pair_max_mm: 2.0
|
||
pair_p95_mm: 1.5
|
||
repeatability_std_max_mm: 1.0
|
||
matching_max_distance_mm: 50.0
|
||
|
||
# ---------- 流水线行为 ----------
|
||
pipeline:
|
||
fail_fast: true
|
||
resume_from_checkpoint: true
|
||
parallel_frames: false
|
||
save_intermediate: false
|
||
|
||
# ---------- 日志 ----------
|
||
logging:
|
||
level: "INFO"
|
||
log_to_file: true
|
||
log_file: "outputs/logs/pipeline.log"
|
||
|
||
# ---------- 路径 ----------
|
||
# 项目自带数据集在 data/ 下,跟 Python 工程完全脱钩。
|
||
paths:
|
||
calibration_dir: "data/calib"
|
||
test_dir: "E:/01_Projects/01_InProgress/hongchuang_bolt_detect_2026/image/0627-bolt-12mp"
|
||
groundtruth_csv: "data/groundtruth.csv"
|
||
output_dir: "outputs/macro257"
|
||
stereo_params_yaml: "outputs/macro257/stereo_params.yaml"
|