| 155 | |
| 156 | template <typename PointT> |
| 157 | void discern_ground(const pcl::PointCloud<PointT> &src, |
| 158 | pcl::PointCloud<PointT> &ground, |
| 159 | pcl::PointCloud<PointT> &non_ground) { |
| 160 | // Ensure that PointT is PointT because this function only works in the |
| 161 | // SemanticKITTI |
| 162 | if (!std::is_same<PointT, PointXYZILID>::value) { |
| 163 | throw invalid_argument( |
| 164 | "This function only supports `PointT`. Not " |
| 165 | "implemented for this point type."); |
| 166 | } |
| 167 | |
| 168 | ground.clear(); |
| 169 | non_ground.clear(); |
| 170 | std::vector<int>::iterator iter; |
| 171 | for (auto const &pt : src.points) { |
| 172 | if (pt.label == UNLABELED || pt.label == OUTLIER) continue; |
| 173 | iter = std::find(ground_classes.begin(), ground_classes.end(), pt.label); |
| 174 | if (iter != ground_classes.end()) { // corresponding class is in ground classes |
| 175 | if (pt.label == VEGETATION) { |
| 176 | if (pt.z < VEGETATION_THR) { |
| 177 | ground.push_back(pt); |
| 178 | } else { |
| 179 | non_ground.push_back(pt); |
| 180 | } |
| 181 | } else { |
| 182 | ground.push_back(pt); |
| 183 | } |
| 184 | } else { |
| 185 | non_ground.push_back(pt); |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | template <typename PointT> |
| 191 | void calculate_precision_recall(const pcl::PointCloud<PointT> &pc_curr, |
no test coverage detected