244 lines
8.3 KiB
YAML
Raw Normal View History

2026-06-26 17:55:15 +08:00
# ============================================================
2026-07-11 15:47:32 +08:00
# 双目相机螺栓测量系统配置文件 (C++ port)
#
# 这是 Python 项目 e:/02_Modules/StereoVisionBoltMeasurement/config.yaml
# 的镜像。两者必须保持参数一致——任何一边改值,另一边同步。
# 数据路径用 Python 项目的绝对路径(见 paths 段末尾)。
2026-06-26 17:55:15 +08:00
# ============================================================
2026-07-11 15:47:32 +08:00
# ---------- 工作距离 ----------
# 从标定推导视差范围,替代 SGBM 固定 [288,1024]。
# z_min=1200 → disp_max≈1089覆盖近处螺杆(disp~1060)。
2026-07-01 18:16:18 +08:00
working_distance:
z_min_mm: 900
z_max_mm: 4000
2026-07-11 15:47:32 +08:00
# ---------- 图像基本参数 ----------
2026-06-26 17:55:15 +08:00
image:
width: 4096
height: 3000
channels: 1
expected_dtype: "uint8"
allowed_extensions: [".tiff", ".tif", ".bmp", ".png"]
2026-07-11 15:47:32 +08:00
# ---------- 图像输入自检 ----------
2026-06-26 17:55:15 +08:00
image_validation:
min_max_value: 10
max_saturation_ratio: 0.20
2026-07-11 15:47:32 +08:00
# ---------- ChArUco 标定板参数 ----------
2026-06-26 17:55:15 +08:00
charuco:
rows: 9
cols: 9
square_length_mm: 50.0
marker_length_mm: 37.0
2026-07-11 15:47:32 +08:00
dict_id: 11 # DICT_6X6_1000
2026-06-26 17:55:15 +08:00
min_corners_per_image: 30
2026-07-11 15:47:32 +08:00
# ---------- 标定模块参数 ----------
2026-06-26 17:55:15 +08:00
calibration:
source: "xml"
2026-07-01 18:16:18 +08:00
xml_path: "calib/stereo_calib.xml"
2026-06-26 17:55:15 +08:00
min_image_pairs: 15
max_skip_ratio: 0.30
2026-07-01 18:16:18 +08:00
max_single_rms: 0.40
2026-06-26 17:55:15 +08:00
max_stereo_rms: 0.80
expected_baseline_range: [80, 600]
use_fix_intrinsic: true
2026-07-11 15:47:32 +08:00
# ---------- 校正模块参数 ----------
# alpha=1.0 是硬约束,详见 CLAUDE.md 隐式决策 #1。
2026-06-26 17:55:15 +08:00
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
2026-07-11 15:47:32 +08:00
# ---------- SGBM 立体匹配参数 ----------
# min_disparity / num_disparities 依赖 f_rect·B如标定改了必须重算。
# 当前值假设 f_rect≈3190, B≈235mmalpha=1.0 下)。
2026-06-26 17:55:15 +08:00
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"
2026-07-11 15:47:32 +08:00
# ---------- WLS 滤波 ----------
2026-06-26 17:55:15 +08:00
wls:
lambda_value: 8000.0
sigma_color: 1.5
2026-07-11 15:47:32 +08:00
# ---------- 视差自检 ----------
2026-06-26 17:55:15 +08:00
disparity_validation:
min_valid_pixel_ratio: 0.10
min_disparity_range: 50
max_nan_ratio: 0.90
2026-07-11 15:47:32 +08:00
# ---------- 点云参数 ----------
# 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.
2026-06-26 17:55:15 +08:00
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
2026-07-11 15:47:32 +08:00
# ---------- 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"
2026-06-26 17:55:15 +08:00
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
2026-07-11 15:47:32 +08:00
bolt_exclude_dilate_px: 0 # 硬约束:默认 0详见 CLAUDE.md 隐式决策 #5
2026-06-26 17:55:15 +08:00
ransac:
2026-07-11 15:47:32 +08:00
distance_thresh_mm: 8.0 # 点到平面距离 < 此值即视为 inlier(3σ 容忍下,
# frame 100 residual_std≈2.6 mm)
2026-06-26 17:55:15 +08:00
max_iterations: 200
2026-07-11 15:47:32 +08:00
min_inlier_ratio: 0.15 # 兜底inlier 占比过低视作失败,自动回退
sample_stride: 4 # xyz_map 下采样步长(每 4×4 像素取 1 个 RANSAC 候选)
morph_close_kernel_px: 9 # mask 后处理:闭运算填洞 + 最大连通域
2026-06-26 17:55:15 +08:00
2026-07-11 15:47:32 +08:00
# ---------- 参考平面 (SVD on foam mask) ----------
2026-06-26 17:55:15 +08:00
plane:
max_residual_std_mm: 15.0
max_normal_to_axis_deg: 60
outlier_rejection_iterations: 5
outlier_mad_k: 2.5
2026-07-11 15:47:32 +08:00
# ---------- 支撑面几何门 ----------
# plane fit 后、bolt extract 前执行。把 bolt 的 3D 中心投影到主支撑面
# inlier OBB, 超出 OBB 超过 margin_mm 的检测会被剔除并打印 WARN。
# margin_mm 独立于 bolt.expected_diameter_mm, 避免混杂不同尺寸螺杆时
# 几何门随螺杆规格隐式变宽/变窄。
2026-06-26 17:55:15 +08:00
support_gate:
enabled: true
margin_mm: 10.0
2026-07-11 15:47:32 +08:00
# ---------- 螺栓几何先验 ----------
# 主路径(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)仍是真正的先验,保留。
2026-06-26 17:55:15 +08:00
bolt:
min_height_mm: 5.0
2026-07-11 15:47:32 +08:00
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 失败
2026-06-26 17:55:15 +08:00
expected_diameter_mm: 16.0
min_points_per_bolt: 50
max_axis_plane_angle_deg: 30
2026-07-11 15:47:32 +08:00
extract_fallback: "bbox_projection" # 'none' | 'bbox_projection'; 后者用 YOLO bbox + 平面法向反解高度,处理 SGBM 在窄/反光螺杆上失败的情况
2026-06-26 17:55:15 +08:00
2026-07-11 15:47:32 +08:00
# ---------- 几何测量 ----------
2026-06-26 17:55:15 +08:00
measurement:
top_extraction_method: "percentile_on_axis"
top_percentile: 0.99
2026-07-01 18:16:18 +08:00
plane_use_sgbm: true
2026-07-15 10:35:58 +08:00
# 主线定义:螺杆顶点沿拟合轴线到支撑平面的交点距离。
2026-07-11 15:47:32 +08:00
height_from_plane: true
plane_height_along_axis: true
plane_anchor_max_foot_gap_std_mm: 20.0
plane_sgbm_scale: 0.25
2026-07-01 18:16:18 +08:00
plane_max_samples: 40000
2026-06-26 17:55:15 +08:00
2026-07-11 15:47:32 +08:00
# ---------- Diagnostics ----------
2026-06-26 17:55:15 +08:00
diagnostics:
enabled: true
blind_strip_warn_ratio: 0.25
min_roi_pointcloud_coverage_ratio: 0.001
2026-07-11 15:47:32 +08:00
# ---------- YOLO 螺栓检测 ----------
# 注意 C++ 端走 ONNX先在 Python 把 best_v4_finetune.pt 导出 .onnx。
# dilate 量原本写成像素(50/30),跟距离和分辨率耦合。改成毫米后由
# scene_runtime.cpp 在运行时用 pixels_per_mm(= f / Z_repr)换算成像素,
# 不同工作距离 / 不同镜头不再需要手调。
2026-06-26 17:55:15 +08:00
yolo:
enabled: true
2026-07-11 15:47:32 +08:00
model_path: "weights/obb.rknn"
2026-06-26 17:55:15 +08:00
backend: "rknn"
2026-07-03 14:19:06 +08:00
task: "obb"
2026-07-01 18:16:18 +08:00
imgsz: 1024
2026-07-15 10:35:58 +08:00
conf: 0.50
2026-06-26 17:55:15 +08:00
dead_zone_min_valid_pts: 50
2026-07-11 15:47:32 +08:00
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.
2026-06-26 17:55:15 +08:00
local_stereo_fallback:
enabled: true
min_valid_points: 50
2026-07-11 15:47:32 +08:00
# ---------- 评估通过判据 ----------
2026-06-26 17:55:15 +08:00
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
2026-07-11 15:47:32 +08:00
# ---------- 流水线行为 ----------
2026-06-26 17:55:15 +08:00
pipeline:
fail_fast: true
resume_from_checkpoint: true
parallel_frames: false
save_intermediate: false
2026-07-11 15:47:32 +08:00
# ---------- 日志 ----------
2026-06-26 17:55:15 +08:00
logging:
level: "INFO"
log_to_file: true
log_file: "outputs/logs/pipeline.log"
2026-07-11 15:47:32 +08:00
# ---------- 路径 ----------
# 项目自带数据集在 data/ 下,跟 Python 工程完全脱钩。
2026-06-26 17:55:15 +08:00
paths:
2026-07-11 15:47:32 +08:00
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"