c++实现基于kd树的3d点云半径滤波 不使用pcl库
c++实现基于kd树的3d点云半径滤波 不使用pcl库
可优化的地方挺多的 是不使用kd树的运算时间的大约四分之一
1 #include <iostream> 2 #include <fstream> 3 #include <vector> 4 #include <cmath> 5 #include <algorithm> 6 #include <chrono> 7 8 struct Point3D 9 { 10 float x, y, z; 11 }; 12 13 struct TreeNode 14 { 15 Point3D point; 16 int split_dim; 17 TreeNode* left_child; 18 TreeNode* right_child; 19 TreeNode(const Point3D& p) : point(p), split_dim(0), left_child(nullptr), right_child(nullptr) {} 20 }; 21 22 bool compare_x(const Point3D& p1, const Point3D& p2) 23 { 24 return p1.x < p2.x; 25 } 26 27 bool compare_y(const Point3D& p1, const Point3D& p2) 28 { 29 return p1.y < p2.y; 30 } 31 32 bool compare_z(const Point3D& p1, const Point3D& p2) 33 { 34 return p1.z < p2.z; 35 } 36 37 float distance(const Point3D& p1, const Point3D& p2) 38 { 39 return std::sqrt(std::pow(p1.x - p2.x, 2) + std::pow(p1.y - p2.y, 2) + std::pow(p1.z - p2.z, 2)); 40 } 41 42 void build_kd_tree(TreeNode*& node, std::vector<Point3D>& pointclouds, int start_index, int end_index, int depth) 43 { 44 if (start_index > end_index) { 45 node = nullptr; 46 return; 47 } 48 int middle_index = start_index + (end_index - start_index) / 2; 49 if (depth % 3 == 0) { 50 std::sort(pointclouds.begin() + start_index, pointclouds.begin() + end_index + 1, compare_x); 51 } 52 else if (depth % 3 == 1) { 53 std::sort(pointclouds.begin() + start_index, pointclouds.begin() + end_index + 1, compare_y); 54 } 55 else { 56 std::sort(pointclouds.begin() + start_index, pointclouds.begin() + end_index + 1, compare_z); 57 } 58 node = new TreeNode(pointclouds[middle_index]); 59 node->split_dim = depth % 3; 60 build_kd_tree(node->left_child, pointclouds, start_index, middle_index - 1, depth + 1); 61 build_kd_tree(node->right_child, pointclouds, middle_index + 1, end_index, depth + 1); 62 } 63 64 void search_knn(TreeNode* node, const Point3D& p, float radius, int k, std::vector<int>& indices, std::vector<float>& distances) 65 { 66 if (node == nullptr) { 67 return; 68 } 69 float dist = distance(node->point, p); 70 if (dist <= radius) { 71 indices.push_back(indices.size()); 72 distances.push_back(dist); 73 } 74 if (indices.size() < k || dist < distances[indices.size() - 1]) { 75 if (node->split_dim == 0) { 76 if (p.x < node->point.x) { 77 search_knn(node->left_child, p, radius, k, indices, distances); 78 search_knn(node->right_child, p, radius, k, indices, distances); 79 } 80 else { 81 search_knn(node->right_child, p, radius, k, indices, distances); 82 search_knn(node->left_child, p, radius, k, indices, distances); 83 } 84 } 85 else if (node->split_dim == 1) { 86 if (p.y < node->point.y) { 87 search_knn(node->left_child, p, radius, k, indices, distances); 88 search_knn(node->right_child, p, radius, k, indices, distances); 89 } 90 else { 91 search_knn(node->right_child, p, radius, k, indices, distances); 92 search_knn(node->left_child, p, radius, k, indices, distances); 93 } 94 } 95 else { 96 if (p.z < node->point.z) { 97 search_knn(node->left_child, p, radius, k, indices, distances); 98 search_knn(node->right_child, p, radius, k, indices, distances); 99 } 100 else { 101 search_knn(node->right_child, p, radius, k, indices, distances); 102 search_knn(node->left_child, p, radius, k, indices, distances); 103 } 104 } 105 106 } 107 } 108 109 int main() 110 { 111 // 获取当前系统时间点 112 auto start_time = std::chrono::high_resolution_clock::now(); 113 114 float radius = 0.25f; 115 int k = 10; 116 117 // 读取点云数据 118 std::vector<Point3D> pointclouds; 119 std::ifstream infile(".txt"); 120 if (!infile) { 121 std::cerr << "Failed to open file: filtered_points5.txt" << std::endl; 122 return -1; 123 } 124 Point3D p; 125 while (infile >> p.x >> p.y >> p.z) { 126 pointclouds.emplace_back(p); 127 } 128 129 // 构建kd树 130 TreeNode* root = nullptr; 131 build_kd_tree(root, pointclouds, 0, pointclouds.size() - 1, 0); 132 133 // 搜索邻域点 134 std::vector<Point3D> filtered_cloud; 135 for (int i = 0; i < pointclouds.size(); i++) { 136 std::vector<int> indices; 137 std::vector<float> distances; 138 search_knn(root, pointclouds[i], radius, k, indices, distances); 139 if (indices.size() >= k) { 140 filtered_cloud.emplace_back(pointclouds[i]); 141 } 142 } 143 144 std::ofstream outFile(".txt"); 145 for (int i = 0; i < filtered_cloud.size(); ++i) 146 { 147 outFile << filtered_cloud[i].x << " " << filtered_cloud[i].y << " " << filtered_cloud[i].z << std::endl; 148 } 149 150 outFile.close(); 151 152 auto end_time = std::chrono::high_resolution_clock::now(); 153 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time); 154 std::cout << "Execution time: " << duration.count() << " microseconds" << std::endl; 155 156 return 0; 157 }

浙公网安备 33010602011771号