From fb53e932dc89b710e9b2192dacac10f1010bb18b Mon Sep 17 00:00:00 2001 From: MaJunwei Date: Tue, 31 Mar 2026 20:18:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=96=9C=E9=9D=A2=E8=A7=92?= =?UTF-8?q?=E5=BA=A6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../visualization_demo/VisualizationDemo.cpp | 12 ++++++----- Algo/DetectHole/src/HoleDetectionBoundary.cpp | 21 ++++++++++++++----- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Algo/DetectHole/examples/visualization_demo/VisualizationDemo.cpp b/Algo/DetectHole/examples/visualization_demo/VisualizationDemo.cpp index 0e8c8f9..022565c 100644 --- a/Algo/DetectHole/examples/visualization_demo/VisualizationDemo.cpp +++ b/Algo/DetectHole/examples/visualization_demo/VisualizationDemo.cpp @@ -477,14 +477,14 @@ int ProcessSingleFile(const std::string& inputFile, callbackData.showLines = showLines; SHoleDetectionDebugCallbacks debugCallbacks; - debugCallbacks.onBoundaryDetected = OnBoundaryDetected; - debugCallbacks.onClustersFound = OnClustersFound; - debugCallbacks.onExpandedRegion = OnExpandedRegion; + debugCallbacks.onBoundaryDetected = nullptr;//OnBoundaryDetected; + debugCallbacks.onClustersFound = nullptr;//OnClustersFound; + debugCallbacks.onExpandedRegion = nullptr;//OnExpandedRegion; debugCallbacks.onHoleFitted = nullptr;// OnHoleFitted; debugCallbacks.onSegmentPairsDetected = OnSegmentPairsDetected; debugCallbacks.onLineAngleProfileDetected = nullptr;// OnLineAngleProfileDetected; - debugCallbacks.onPlanesSegmented = nullptr;// OnPlanesSegmented; - debugCallbacks.onMaskedPointsReady = OnMaskedPointsReady; + debugCallbacks.onPlanesSegmented = OnPlanesSegmented; + debugCallbacks.onMaskedPointsReady = nullptr;// OnMaskedPointsReady; debugCallbacks.userData = &callbackData; SMultiHoleResult result; @@ -586,6 +586,8 @@ int main(int argc, char* argv[]) { // Set up detection parameters (using defaults from constructor) SHoleDetectionParams detectionParams; detectionParams.minRadius = 0.5f; + detectionParams.angleThresholdPos = 50; + detectionParams.angleThresholdNeg = -50; SHoleFilterParams filterParams; std::cout << "=== Hole Detection Visualization Demo ===" << std::endl; diff --git a/Algo/DetectHole/src/HoleDetectionBoundary.cpp b/Algo/DetectHole/src/HoleDetectionBoundary.cpp index d48c7ff..dda0f83 100644 --- a/Algo/DetectHole/src/HoleDetectionBoundary.cpp +++ b/Algo/DetectHole/src/HoleDetectionBoundary.cpp @@ -124,11 +124,22 @@ void EvaluateLine( pts[i].hasAngle = true; - // 坡度方向:从 backRef 到 fwdRef 的整体倾斜角 - // 正角度 = 上升坡,负角度 = 下降坡,近零 = 平坦 - float slopeCoord = std::abs(fwdCoord - backCoord); - float slopeZ = backMeanZ - fwdMeanZ; // 相机坐标系: z增大=远离相机=下降 - float slopeAngleDeg = std::atan2(slopeZ, slopeCoord) * (180.0f / kPi); + // 两线夹角:line1(backRef→cur) 延长后 与 line2(cur→fwdRef) 的有符号夹角 + // 与旧方案(backRef→fwdRef 整体坡度角)的本质区别: + // 均匀倾斜面(无弯折)→ 0°;只有在 pts[i] 处发生方向变化时才得到非零角。 + // 正角度 = 向相机弯折(上升),负角度 = 远离相机弯折(下降进坑) + float curCoord = getCoord(cur); + float v1_coord = curCoord - backCoord; // backRef → cur(水平分量) + float v1_z = cur.z - backMeanZ; // backRef → cur(z 分量) + float v2_coord = fwdCoord - curCoord; // cur → fwdRef(水平分量) + float v2_z = fwdMeanZ - cur.z; // cur → fwdRef(z 分量) + + // 2D 叉积(z 分量)和点积,用于计算有符号夹角 + float cross2d = v1_coord * v2_z - v1_z * v2_coord; + float dot2d = v1_coord * v2_coord + v1_z * v2_z; + // 消除扫描方向(正向/反向)对叉积符号的影响 + float scanDirSign = ((v1_coord + v2_coord) >= 0.0f) ? 1.0f : -1.0f; + float slopeAngleDeg = std::atan2(-cross2d * scanDirSign, dot2d) * (180.0f / kPi); pts[i].signedAngleDeg = slopeAngleDeg;