WoodAlgo/Algo/DetectHole/include/HoleDetectionParams.h

216 lines
8.6 KiB
C
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.

#ifndef HOLE_DETECTION_PARAMS_H
#define HOLE_DETECTION_PARAMS_H
#include <cmath>
#include "VZNL_Types.h" // 使用 VZNL_Types.h 中定义的类型
/**
* @brief RANSAC平面分割参数
*/
struct RansacPlaneSegmentationParams {
float distanceThreshold; // 点到平面距离阈值 (mm), 建议 0.5-2.0
int maxIterations; // RANSAC最大迭代次数, 建议 100-1000
int minPlanePoints; // 最小平面点数, 建议 50-200
int maxPlanes; // 最大提取平面数量, 建议 3-10
float growthZThreshold; // 区域生长时相邻点Z差阈值 (mm), 建议 0.5-2.0
float minPlaneRatio; // 平面最小点数占比 (相对最大平面), 建议 0.05-0.2
float maxNormalAngleDeg; // 平面法向量与Z轴最大夹角 (度), 超过则直接丢弃; <=0 表示不过滤
float maxDistFromPlane; // 点到平面的最大允许距离;超出则从 pointIndices 中移除;<=0 表示不过滤
RansacPlaneSegmentationParams()
: distanceThreshold(0.5f)
, maxIterations(500)
, minPlanePoints(100)
, maxPlanes(5)
, growthZThreshold(1.0f)
, minPlaneRatio(0.1f)
, maxNormalAngleDeg(30.0f)
, maxDistFromPlane(1.f)
{
}
};
/**
* @brief 孔洞检测算法的检测参数
*/
struct SHoleDetectionParams {
// 凹坑检测参数
float angleThresholdPos; // 正角度阈值单位默认值50.0
float angleThresholdNeg; // 负角度阈值,单位:度(默认值:-50.0
float angleSearchDistance; // Method1 前后搜索距离 A单位mm
float minPitDepth; // 最小凹坑深度单位mm默认值1.0
// 椭圆拟合参数
float minRadius; // 最小孔洞半径单位mm默认值2.0
float maxRadius; // 最大孔洞半径单位mm默认值50.0
// 平面拟合参数
int expansionSize1; // 第一圈扩展大小默认值5
int expansionSize2; // 第二圈扩展大小默认值10
// V 型检测参数
int minVTransitionPoints; // V 型端点之间的最小有效过渡点数默认值1
float jumpThresholdResidual; // 相邻有效点的残差跳变阈值,<=0 表示自适应
float gapJumpThresholdResidual; // 跨无效点间隙的残差跳变阈值,<=0 表示自适应
int maxGapPointsInLine; // 允许跨越的最大无效点数
float minFeatureSpan; // 特征点对最小弧长跨度mm
int residualSmoothWindow; // 残差平滑窗口(奇数,建议 3~7
float slopeAngleThreshold; // 坡度补充判断阈值单位默认值3.0
// 当曲率角未超过 angleThreshold 时,若前后参考点间的
// 净 Z 坡度角超过此阈值,则将该点判定为下降或上升趋势。
// 设置为 0 可禁用坡度补充判断。
float edgeBoundaryFilterDist; // 边缘过滤距离单位mm默认值0.0,即不过滤)
// pair 中任意端点到首/尾有效线(行扫描取 y列扫描取 x
// 的距离小于此值时,该 pair 将被剔除。
// 构造函数,设置默认值
SHoleDetectionParams()
: angleThresholdPos(50.0f)
, angleThresholdNeg(-50.0f)
, angleSearchDistance(2.0f)
, minPitDepth(1.0f)
, minRadius(2.0f)
, maxRadius(50.0f)
, expansionSize1(5)
, expansionSize2(10)
, minVTransitionPoints(1)
, jumpThresholdResidual(0.0f)
, gapJumpThresholdResidual(0.0f)
, maxGapPointsInLine(12)
, minFeatureSpan(2.0f)
, residualSmoothWindow(5)
, slopeAngleThreshold(3.0f)
, edgeBoundaryFilterDist(0.0f)
{}
};
/**
* @brief 孔洞过滤参数
*/
struct SHoleFilterParams {
// 质量阈值过滤
float maxEccentricity; // 最大离心率默认值0.99995,标准公式 e=sqrt(1-(b/a)^2)
// 形状过滤(拟合前)
float minAngularCoverage; // 最小角度覆盖范围单位默认值10.0
// 用于过滤非闭合边界。设置为 0 可禁用。
float maxRadiusFitRatio; // 最大半径拟合比率 radiusVariance / radius默认值1.0
// 衡量边界点与圆的拟合程度。设置为 1.0 可禁用。
float minQualityScore; // 最小整体质量分数默认值0.0
// 形状指标的加权组合。设置为 0 可禁用。
// 平面一致性过滤(投影前)
float maxPlaneResidual; // 最大点到平面残差单位mm默认值10.0
// 用于拒绝非平面簇,例如悬崖、台阶边缘。
float maxAngularGap; // 最大角度间隙单位默认值90.0
// 用于拒绝 L 型或非闭合边界。
float minInlierRatio; // 圆拟合的最小内点比率默认值0.0
// 表示落在拟合圆容差范围内的点所占比例。
// 深度验证
float minHoleDepth; // 圆孔内部最大 Z 与参考平面 Z 的最小差值单位mm默认值2.5
// 若差值小于此阈值则认为是假孔,返回失败。<=0 表示不过滤。
// 构造函数,设置默认值
SHoleFilterParams()
: maxEccentricity(0.99995f)
, minAngularCoverage(10.f)
, maxRadiusFitRatio(1.f)
, minQualityScore(0.f)
, maxPlaneResidual(10.0f)
, maxAngularGap(90.0f)
, minInlierRatio(0.f)
, minHoleDepth(2.5f)
{}
};
/**
* @brief 单个孔洞检测结果
*
* 注意SVzNL3DPointF 和 SVzNL2DPointF 在 VZNL_Types.h 中定义。
*/
struct SHoleResult {
SVzNL3DPointF center; // 孔洞中心点 (x, y, z)
SVzNL3DPointF normal; // 拟合平面法向量(单位长度)
float radius; // 孔洞半径单位mm
float depth; // 凹坑深度单位mm
float eccentricity; // 离心率0 表示完美圆形)
float radiusVariance; // 半径离散度单位mm
float angularSpan; // 角度覆盖范围,单位:度
float qualityScore; // 质量分数0~1越高越好
SHoleResult()
: center()
, normal()
, radius(0.0f)
, depth(0.0f)
, eccentricity(0.0f)
, radiusVariance(0.0f)
, angularSpan(0.0f)
, qualityScore(0.0f)
{}
};
/**
* @brief 多孔洞检测结果
*
* @note 内存管理holes 数组不会自动释放。
* 调用者必须调用 FreeMultiHoleResult() 或手动 delete[] holes。
*/
struct SMultiHoleResult {
int holeCount; // 检测到的孔洞数量
SHoleResult* holes; // 孔洞结果数组(调用者必须释放)
int totalCandidates; // 过滤前的候选孔洞总数
int filteredCount; // 被过滤掉的孔洞数量
SMultiHoleResult()
: holeCount(0)
, holes(nullptr)
, totalCandidates(0)
, filteredCount(0)
{}
};
/**
* @brief 释放 DetectMultipleHoles 分配的内存
*
* @param [in,out] result 要释放的结果结构
*/
inline void FreeMultiHoleResult(SMultiHoleResult* result) {
if (result != nullptr && result->holes != nullptr) {
delete[] result->holes;
result->holes = nullptr;
result->holeCount = 0;
}
}
/**
* @brief 线段端点对结果
*
* 表示在线扫描中检测到的一段特征,包含起点和终点。
* 可用于描述凹坑边界、空洞间隙等一维特征。
*/
struct SSegmentPair {
SVzNLPointXYZ startPoint; // 线段起点
SVzNLPointXYZ endPoint; // 线段终点
int startRow; // 起点行索引
int startCol; // 起点列索引
int endRow; // 终点行索引
int endCol; // 终点列索引
float depth; // 起点和终点之间的深度差
SSegmentPair()
: startPoint()
, endPoint()
, startRow(0)
, startCol(0)
, endRow(0)
, endCol(0)
, depth(0.0f)
{}
};
#endif // HOLE_DETECTION_PARAMS_H