WoodAlgo/Algo/DetectBarIntersection/include/BarIntersectionParams.h

110 lines
3.4 KiB
C
Raw Normal View History

2026-04-09 23:39:51 +08:00
#ifndef BAR_INTERSECTION_PARAMS_H
2026-04-08 19:45:15 +08:00
#define BAR_INTERSECTION_PARAMS_H
#include "VZNL_Types.h"
#include <vector>
/**
2026-04-09 23:39:51 +08:00
* @brief RANSAC
2026-04-08 19:45:15 +08:00
*/
struct SPlaneSegmentationParams {
2026-04-09 23:39:51 +08:00
float distanceThreshold; // 点到平面距离阈值 (mm)
int maxIterations; // RANSAC 最大迭代次数
int minPlanePoints; // 最小平面点数
float minPlaneRatio; // 平面最小点数占比
float heightThreshold; // 高于平面的最小高度,用于过滤平面点 (mm)
2026-04-08 19:45:15 +08:00
SPlaneSegmentationParams()
: distanceThreshold(1.0f)
, maxIterations(500)
, minPlanePoints(1000)
, minPlaneRatio(0.05f)
, heightThreshold(10.0f)
{}
};
/**
2026-04-09 23:39:51 +08:00
* @brief
2026-04-08 19:45:15 +08:00
*/
struct SGrowthParams {
2026-04-09 23:39:51 +08:00
float thresholdX; // 跨行合并阈值:相邻行 segment 质心 x 的最大允许差 (mm)
float thresholdY; // 行内分段阈值:同行相邻点 y 的最大允许差 (mm)
float thresholdZ; // 行内分段阈值:同行相邻点 z 的最大允许差 (mm)
int minClusterSize; // 最小簇点数
2026-04-10 00:18:05 +08:00
float angleSearchDistance;
int residualSmoothWindow;
2026-04-08 19:45:15 +08:00
float maxAxisDeviationFromXYDeg; // Max allowed axis deviation from the XY plane (deg)
float maxPerpendicularDeviationDeg; // Max deviation from 90 deg for centroid-connection test
int minContinuousValidPointCount; // Min consecutive valid points kept on each laser line after plane filtering; <=1 disables
float maxContinuousPointZTolerance; // Max z difference between adjacent points inside one valid run (mm)
2026-04-11 23:24:16 +08:00
float minBarDiameter;
float maxBarDiameter;
2026-04-08 19:45:15 +08:00
SGrowthParams()
: thresholdX(5.0f)
, thresholdY(5.0f)
, thresholdZ(5.0f)
, minClusterSize(20)
2026-04-10 00:18:05 +08:00
, angleSearchDistance(2.f)
, residualSmoothWindow(5)
2026-04-08 19:45:15 +08:00
, maxAxisDeviationFromXYDeg(50.0f)
, maxPerpendicularDeviationDeg(50.0f)
, minContinuousValidPointCount(0)
, maxContinuousPointZTolerance(5.0f)
2026-04-11 23:24:16 +08:00
, minBarDiameter(10.0f)
, maxBarDiameter(30.0f)
2026-04-08 19:45:15 +08:00
{}
};
/**
2026-04-09 23:39:51 +08:00
* @brief
2026-04-08 19:45:15 +08:00
*/
struct SGrowthCluster {
2026-04-09 23:39:51 +08:00
std::vector<int> pointIndices; // 簇内点在原始 rows*cols 网格中的线性索引
SVzNL3DPointF centroid; // 簇质心
SVzNL3DPointF minBound; // 包围盒最小角
SVzNL3DPointF maxBound; // 包围盒最大角
2026-04-08 19:45:15 +08:00
int pointCount;
SGrowthCluster()
: centroid(), minBound(), maxBound(), pointCount(0)
{}
};
/**
2026-04-09 23:39:51 +08:00
* @brief
2026-04-08 19:45:15 +08:00
*/
struct SBarIntersectionResult {
2026-04-09 23:39:51 +08:00
// 平面信息
SVzNL3DPointF planeNormal; // 平面法向量
float planeD; // 平面方程 ax+by+cz+d=0 中的 d
2026-04-08 19:45:15 +08:00
2026-04-09 23:39:51 +08:00
// 簇(原始坐标系)
2026-04-08 19:45:15 +08:00
int clusterCount;
SGrowthCluster* clusters;
2026-04-09 23:39:51 +08:00
// 最优簇索引(-1表示无有效簇
2026-04-08 19:45:15 +08:00
int bestClusterIndex;
2026-04-09 23:39:51 +08:00
// 最优簇的过滤后点云(对齐坐标系,用于可视化)
2026-04-08 19:45:15 +08:00
std::vector<SVzNLPointXYZ> bestClusterPoints;
SBarIntersectionResult()
: planeNormal(), planeD(0.0f)
, clusterCount(0), clusters(nullptr)
, bestClusterIndex(-1)
{}
};
/**
2026-04-09 23:39:51 +08:00
* @brief
2026-04-08 19:45:15 +08:00
*/
inline void FreeBarIntersectionResult(SBarIntersectionResult* result) {
if (result) {
if (result->clusters) { delete[] result->clusters; result->clusters = nullptr; }
result->clusterCount = 0;
}
}
#endif // BAR_INTERSECTION_PARAMS_H