GrabBag/AppAlgo/holeDetection/include/PlaneSegmentation.h

286 lines
9.2 KiB
C
Raw Normal View History

2026-03-25 11:07:14 +08:00
#ifndef PLANE_SEGMENTATION_H
#define PLANE_SEGMENTATION_H
#include "../include/VZNL_Types.h"
#include "ErrorCodes.h"
#include <vector>
/**
* @brief Z值直方图峰值信息
*/
struct ZHistogramPeak {
float zValue; // 峰值对应的Z坐标
int pointCount; // 该峰值区域的点数
float zMin; // 峰值区域的Z最小值
float zMax; // 峰值区域的Z最大值
std::vector<int> pointIndices; // 属于该平面的点索引
};
/**
* @brief Z值直方图平面分割参数
*/
struct ZHistogramSegmentationParams {
float binSize; // 直方图bin大小 (mm), 建议 1.0-5.0
int minPeakPoints; // 最小峰值点数, 建议 50-100
float minPeakRatio; // 最小峰值点数占比, 建议 0.03 (3%)
float peakMergeThreshold; // 峰值合并阈值 (mm), 建议 5.0-10.0
int smoothingWindow; // 平滑窗口大小, 建议 3-5
};
/**
* @brief 使Z值直方图分割平面
*
* :
* 1. Z值范围
* 2. bin的点数
* 3.
* 4.
* 5.
* 6.
*
*
* - O(n)
* -
* -
*
*
* - Z值会分散
* - Z方向分层明显的平面
*
* @param points
* @param pointCount
* @param params
* @param outPeaks Z值排序
* @param errCode
* @return
*/
int SegmentPlanesByZHistogram(
const SVzNLPointXYZ* points,
int pointCount,
const ZHistogramSegmentationParams& params,
std::vector<ZHistogramPeak>& outPeaks,
int* errCode
);
/**
* @brief
*
*
* 1. Z直方图粗分割
* 2. Z层XY平面上再做一次分层
* 3.
*
* @param points
* @param pointCount
* @param params
* @param outPeaks
* @param errCode
* @return
*/
int SegmentTiltedPlanesByHistogram(
const SVzNLPointXYZ* points,
int pointCount,
const ZHistogramSegmentationParams& params,
std::vector<ZHistogramPeak>& outPeaks,
int* errCode
);
/**
* @brief Z值波动统计信息
*/
struct ZFluctuationStats {
float meanZ; // Z值均值
float stdDevZ; // Z值标准差去除离群点后
float minZ; // Z值最小值去除离群点后
float maxZ; // Z值最大值去除离群点后
float rangeZ; // Z值范围maxZ - minZ
int validPointCount; // 有效点数(去除离群点后)
int outlierCount; // 离群点数量
float outlierRatio; // 离群点占比
float medianZ; // Z值中位数
float iqrZ; // 四分位距IQR
};
/**
* @brief Z值波动分析参数
*/
struct ZFluctuationParams {
enum OutlierMethod {
SIGMA_3, // 3-sigma规则适合正态分布
IQR, // 四分位距方法(更鲁棒,推荐)
PERCENTILE // 百分位数方法
};
OutlierMethod method; // 离群点检测方法
float sigmaMultiplier; // sigma倍数默认3.0
float iqrMultiplier; // IQR倍数默认1.5
float percentileLow; // 下百分位数默认5.0 (5%)
float percentileHigh; // 上百分位数默认95.0 (95%)
// 默认构造函数
ZFluctuationParams()
: method(IQR)
, sigmaMultiplier(3.0f)
, iqrMultiplier(1.5f)
, percentileLow(5.0f)
, percentileHigh(95.0f)
{}
};
/**
* @brief Z值波动统计
*
*
* 1. Z值
* 2.
* - 3-sigma: 3
* - IQR: [Q1-1.5*IQR, Q3+1.5*IQR]
* - Percentile:
* 3.
*
* 使
* -
* -
* -
*
*
* ```cpp
* ZFluctuationParams params;
* params.method = ZFluctuationParams::IQR; // 使用IQR方法推荐
*
* ZFluctuationStats stats;
* int errCode = 0;
* ComputeZFluctuation(points, pointCount, params, &stats, &errCode);
*
* std::cout << "Z波动: " << stats.stdDevZ << " mm" << std::endl;
* std::cout << "Z范围: " << stats.rangeZ << " mm" << std::endl;
* std::cout << "离群点: " << stats.outlierCount << " ("
* << stats.outlierRatio * 100 << "%)" << std::endl;
* ```
*
* @param points
* @param pointCount
* @param params
* @param outStats
* @param errCode
* @return HD_SUCCESS
*/
int ComputeZFluctuation(
const SVzNLPointXYZ* points,
int pointCount,
const ZFluctuationParams& params,
ZFluctuationStats* outStats,
int* errCode
);
/**
* @brief 使Z值波动
*
* 使IQR方法自动去除离群点
*
* @param points
* @param pointCount
* @param outStats
* @param errCode
* @return HD_SUCCESS
*/
int ComputeZFluctuation(
const SVzNLPointXYZ* points,
int pointCount,
ZFluctuationStats* outStats,
int* errCode
);
/**
* @brief
*/
struct PointSpacingStats {
// 主要结果:取两个方向的最大值
float typicalSpacing; // 典型间距(行内和列内中位数的最大值,推荐使用)
// 分方向统计
float rowSpacing; // 行内平均间距同一激光线上相邻点YZ平面距离
float colSpacing; // 列内平均间距相邻激光线间XZ平面距离
float rowSpacingMedian; // 行内间距中位数(更鲁棒)
float colSpacingMedian; // 列内间距中位数(更鲁棒)
float rowSpacingStdDev; // 行内间距标准差
float colSpacingStdDev; // 列内间距标准差
int rowSampleCount; // 行内采样数量
int colSampleCount; // 列内采样数量
float rowSpacingMin; // 行内最小间距
float rowSpacingMax; // 行内最大间距
float colSpacingMin; // 列内最小间距
float colSpacingMax; // 列内最大间距
};
/**
* @brief
*
*
* 1.
* - 线使YZ平面距离 sqrt((y2-y1)² + (z2-z1)²)
* - 线使XZ平面距离 sqrt((x2-x1)² + (z2-z1)²)
* 2. (0,0,0)
* 3.
* 4. 使IQR方法去除噪点
* 5.
*
* 使
* - /
* -
* -
* -
*
*
* - 使YZ平面线沿Y方向扫描Z是深度
* - 使XZ平面线X方向分布Z是深度
* - (0,0,0)
* - 使
*
*
* ```cpp
* PointSpacingStats stats;
* int errCode = 0;
* ComputePointSpacing(points, rows, cols, &stats, &errCode);
*
* std::cout << "行内间距: " << stats.rowSpacingMedian << " mm" << std::endl;
* std::cout << "列内间距: " << stats.colSpacingMedian << " mm" << std::endl;
* ```
*
* @param points
* @param rows 线
* @param cols 线
* @param outStats
* @param errCode
* @return HD_SUCCESS
*/
int ComputePointSpacing(
const SVzNLPointXYZ* points,
int rows,
int cols,
PointSpacingStats* outStats,
int* errCode
);
struct RowZDiffFluctuationStats {
float meanAbsDz; // |dz| 均值(去除异常值后)
float medianAbsDz; // |dz| 中位数(去除异常值后)
float stdDevAbsDz; // |dz| 标准差作为Z波动值
float minAbsDz; // |dz| 最小值(去除异常值后)
float maxAbsDz; // |dz| 最大值(去除异常值后)
float rangeAbsDz; // |dz| 波动范围maxAbsDz - minAbsDz
int sampleCount; // 有效样本数(去除异常值后)
int outlierCount; // 被剔除的异常样本数
float outlierRatio; // 异常样本占比outlierCount / 原始样本数)
};
int ComputeRowZDiffFluctuation(
const SVzNLPointXYZ* points,
int rows,
int cols,
RowZDiffFluctuationStats* outStats,
int* errCode
);
#endif // PLANE_SEGMENTATION_H