2026-07-15 10:35:58 +08:00

244 lines
8.3 KiB
YAML
Raw 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.

# ============================================================
# 双目相机螺栓测量系统配置文件 (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.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≈235mmalpha=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
# 主线定义:螺杆顶点沿拟合轴线到支撑平面的交点距离。
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.rknn"
backend: "rknn"
task: "obb"
imgsz: 1024
conf: 0.50
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"