GrabBag/AppAlgo/holeDetection/include/HoleDetectionParams.h

176 lines
6.2 KiB
C
Raw Normal View History

2026-03-11 23:40:06 +08:00
#ifndef HOLE_DETECTION_PARAMS_H
#define HOLE_DETECTION_PARAMS_H
#include <cmath>
#include "../include/VZNL_Types.h" // 使用 VZNL_Types.h 中的类型
2026-03-11 23:40:06 +08:00
/**
* @brief
2026-03-11 23:40:06 +08:00
*/
enum ESortMode {
keSortMode_None = 0, // 不排序
keSortMode_ByRadius = 1, // 按半径排序(最大的在前)
keSortMode_ByDepth = 2, // 按深度排序(最深的在前)
keSortMode_ByQuality = 3 // 按质量分数排序(最高的在前)
2026-03-11 23:40:06 +08:00
};
/**
* @brief
2026-03-11 23:40:06 +08:00
*/
struct SHoleDetectionParams {
// 凹坑检测参数
int neighborCount; // 线连接的相邻点数默认值3
float angleThresholdPos; // 正角度阈值单位默认值10.0
float angleThresholdNeg; // 负角度阈值,单位:度(默认值:-10.0
float minPitDepth; // 最小凹坑深度单位mm默认值1.0
// 椭圆拟合参数
float minRadius; // 最小孔洞半径单位mm默认值2.0
float maxRadius; // 最大孔洞半径单位mm默认值50.0
// 平面拟合参数
int expansionSize1; // 第一环扩展大小单位mm默认值5
int expansionSize2; // 第二环扩展大小单位mm默认值10
// V型检测参数
int minVTransitionPoints; // V型端点之间的最小有效过渡点数默认值1
// 构造函数,设置默认值
2026-03-11 23:40:06 +08:00
SHoleDetectionParams()
: neighborCount(3)
, angleThresholdPos(10.0f)
, angleThresholdNeg(-10.0f)
, minPitDepth(1.0f)
, minRadius(2.0f)
2026-03-11 23:40:06 +08:00
, maxRadius(50.0f)
, expansionSize1(5)
, expansionSize2(10)
, minVTransitionPoints(1)
{}
};
/**
* @brief
2026-03-11 23:40:06 +08:00
*/
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
// 在拟合椭圆容差范围内的点的比例。
// 构造函数,设置默认值
2026-03-11 23:40:06 +08:00
SHoleFilterParams()
: maxEccentricity(0.99995f)
2026-03-11 23:40:06 +08:00
, minAngularCoverage(10.f)
, maxRadiusFitRatio(1.f)
, minQualityScore(0.f)
2026-03-11 23:40:06 +08:00
, maxPlaneResidual(10.0f)
, maxAngularGap(90.0f)
, minInlierRatio(0.f)
2026-03-11 23:40:06 +08:00
{}
};
/**
* @brief
2026-03-11 23:40:06 +08:00
*
* SVzNL3DPointF SVzNL2DPointF VZNL_Types.h
2026-03-11 23:40:06 +08:00
*/
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越高越好
2026-03-11 23:40:06 +08:00
SHoleResult()
: center()
, normal()
, radius(0.0f)
, depth(0.0f)
, eccentricity(0.0f)
, radiusVariance(0.0f)
, angularSpan(0.0f)
, qualityScore(0.0f)
{}
};
/**
* @brief
2026-03-11 23:40:06 +08:00
*
* @note holes
* FreeMultiHoleResult() delete[] holes
2026-03-11 23:40:06 +08:00
*/
struct SMultiHoleResult {
int holeCount; // 检测到的孔洞数量
SHoleResult* holes; // 孔洞结果数组(调用者必须释放)
int totalCandidates; // 过滤前的候选孔洞总数
int filteredCount; // 被过滤掉的孔洞数量
2026-03-11 23:40:06 +08:00
SMultiHoleResult()
: holeCount(0)
, holes(nullptr)
, totalCandidates(0)
, filteredCount(0)
{}
};
/**
* @brief DetectMultipleHoles
2026-03-11 23:40:06 +08:00
*
* @param [in,out] result
2026-03-11 23:40:06 +08:00
*/
inline void FreeMultiHoleResult(SMultiHoleResult* result) {
if (result != nullptr && result->holes != nullptr) {
delete[] result->holes;
result->holes = nullptr;
result->holeCount = 0;
}
}
/**
* @brief 线
*
* 线线
* "PeakValley"线
* /
*/
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)
{}
};
2026-03-11 23:40:06 +08:00
#endif // HOLE_DETECTION_PARAMS_H