提交空行问题
This commit is contained in:
parent
f95e3dc753
commit
25101160c2
@ -597,7 +597,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Set up detection parameters (using defaults from constructor)
|
||||
SHoleDetectionParams detectionParams;
|
||||
detectionParams.minRadius = 0.5f;
|
||||
detectionParams.minRadius = 1.5f;
|
||||
SHoleFilterParams filterParams;
|
||||
std::cout << "=== Hole Detection Visualization Demo ===" << std::endl;
|
||||
|
||||
|
||||
@ -973,6 +973,8 @@ int SegmentPlanesByRansac(
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int kMaxGrowthBridgeGap = 3; // BFS生长时允许跨越的最大空行/空列数
|
||||
|
||||
while (!bfsQueue.empty()) {
|
||||
int curIdx = bfsQueue.front();
|
||||
bfsQueue.pop();
|
||||
@ -980,32 +982,36 @@ int SegmentPlanesByRansac(
|
||||
int curRow = curIdx / cols;
|
||||
int curCol = curIdx % cols;
|
||||
|
||||
// 遍历4-连通邻居
|
||||
// 遍历4-连通邻居,允许跨越少量无效点(空行/空列)
|
||||
for (int d = 0; d < 4; d++) {
|
||||
int nr = curRow + dr[d];
|
||||
int nc = curCol + dc[d];
|
||||
for (int step = 1; step <= kMaxGrowthBridgeGap + 1; step++) {
|
||||
int nr = curRow + dr[d] * step;
|
||||
int nc = curCol + dc[d] * step;
|
||||
|
||||
if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) continue;
|
||||
if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) break;
|
||||
|
||||
int nIdx = nr * cols + nc;
|
||||
if (used[nIdx] || inPlane[nIdx]) continue;
|
||||
if (!IsValidPoint(points[nIdx])) continue;
|
||||
int nIdx = nr * cols + nc;
|
||||
if (used[nIdx] || inPlane[nIdx]) break;
|
||||
if (!IsValidPoint(points[nIdx])) continue; // 空点,继续向前探测
|
||||
|
||||
// 局部Z差检查:防止跨越单步噪点
|
||||
float zDiff = std::abs(points[nIdx].z - points[curIdx].z);
|
||||
if (zDiff > params.growthZThreshold) continue;
|
||||
// 找到有效点,执行原有的生长条件检查
|
||||
// 局部Z差检查:防止跨越单步噪点
|
||||
float zDiff = std::abs(points[nIdx].z - points[curIdx].z);
|
||||
if (zDiff > params.growthZThreshold) break;
|
||||
|
||||
// 全局点到平面距离检查:防止BFS在渐变区域内漂移到不同表面。
|
||||
// 仅靠局部Z差无法阻止逐步穿越台阶(每步小但累积大),
|
||||
// 全局距离能确保生长点始终贴近当前RANSAC平面。
|
||||
float planeDist = std::abs(
|
||||
bestA * points[nIdx].x + bestB * points[nIdx].y +
|
||||
bestC * points[nIdx].z + bestD
|
||||
);
|
||||
if (planeDist > params.distanceThreshold * 2.0f) continue;
|
||||
// 全局点到平面距离检查:防止BFS在渐变区域内漂移到不同表面。
|
||||
// 仅靠局部Z差无法阻止逐步穿越台阶(每步小但累积大),
|
||||
// 全局距离能确保生长点始终贴近当前RANSAC平面。
|
||||
float planeDist = std::abs(
|
||||
bestA * points[nIdx].x + bestB * points[nIdx].y +
|
||||
bestC * points[nIdx].z + bestD
|
||||
);
|
||||
if (planeDist > params.distanceThreshold * 2.0f) break;
|
||||
|
||||
inPlane[nIdx] = true;
|
||||
bfsQueue.push(nIdx);
|
||||
inPlane[nIdx] = true;
|
||||
bfsQueue.push(nIdx);
|
||||
break; // 成功连接,不再继续探测
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1156,8 +1162,10 @@ int SegmentPlanesByRansac(
|
||||
}
|
||||
|
||||
// ===== 后处理:对每个平面做连通域标注,将每个连通域拆分为独立平面 =====
|
||||
// 允许跨越少量空行/空列(无效数据行)进行连通,避免因单行数据缺失导致同一平面被拆分
|
||||
{
|
||||
std::vector<PlaneSegment> splitPlanes;
|
||||
constexpr int kMaxBridgeGap = 3; // 允许跨越的最大空行/空列数
|
||||
|
||||
for (size_t pi = 0; pi < outPlanes.size(); pi++) {
|
||||
const PlaneSegment& plane = outPlanes[pi];
|
||||
@ -1168,7 +1176,7 @@ int SegmentPlanesByRansac(
|
||||
mask[idx] = true;
|
||||
}
|
||||
|
||||
// BFS 连通域标注 (4-连通)
|
||||
// BFS 连通域标注 (4-连通,允许跨越空行/空列)
|
||||
std::vector<int> label(pointCount, -1);
|
||||
std::vector<std::vector<int>> components;
|
||||
|
||||
@ -1190,13 +1198,21 @@ int SegmentPlanesByRansac(
|
||||
int cc = cur % cols;
|
||||
|
||||
for (int d = 0; d < 4; d++) {
|
||||
int nr = cr + dr[d];
|
||||
int nc = cc + dc[d];
|
||||
if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) continue;
|
||||
int nIdx = nr * cols + nc;
|
||||
if (!mask[nIdx] || label[nIdx] >= 0) continue;
|
||||
label[nIdx] = compId;
|
||||
q.push(nIdx);
|
||||
// 沿当前方向尝试跨越空行/空列
|
||||
for (int step = 1; step <= kMaxBridgeGap + 1; step++) {
|
||||
int nr = cr + dr[d] * step;
|
||||
int nc = cc + dc[d] * step;
|
||||
if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) break;
|
||||
int nIdx = nr * cols + nc;
|
||||
if (label[nIdx] >= 0) break; // 已标注,无需继续
|
||||
if (mask[nIdx]) {
|
||||
// 找到属于同一平面的点,建立连接
|
||||
label[nIdx] = compId;
|
||||
q.push(nIdx);
|
||||
break;
|
||||
}
|
||||
// mask[nIdx] == false: 空点,继续向前探测
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user