#if defined (_MSC_VER) && !defined (_WIN64) #pragma warning(disable:4244) // boost::number_distance::distance() // converts 64 to 32 bits integers #endif #include #include #include #include #include #include #include #include #include typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_3 Point; typedef CGAL::Point_set_3 Point_set; typedef Kernel::Iso_cuboid_3 Iso_cuboid_3; typedef Point_set::Point_map Pmap; typedef Point_set::Property_map Imap; typedef Point_set::Property_map UCmap; namespace Classification = CGAL::Classification; typedef Classification::Label_handle Label_handle; typedef Classification::Feature_handle Feature_handle; typedef Classification::Label_set Label_set; typedef Classification::Feature_set Feature_set; typedef Classification::Point_set_feature_generator Feature_generator; int main (int argc, char** argv) { std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("points_3/b9_training.ply"); std::cerr << "Reading input" << std::endl; std::ifstream in (filename.c_str(), std::ios::binary); Point_set pts; in >> pts; std::optional label_map = pts.property_map ("label"); if (!label_map.has_value()) { std::cerr << "Error: \"label\" property not found in input file." << std::endl; return EXIT_FAILURE; } Feature_set features; std::cerr << "Generating features" << std::endl; CGAL::Real_timer t; t.start(); Feature_generator generator (pts, pts.point_map(), 5); // using 5 scales features.begin_parallel_additions(); generator.generate_point_based_features (features); features.end_parallel_additions(); t.stop(); std::cerr << "Done in " << t.time() << " second(s)" << std::endl; // Add labels Label_set labels; Label_handle ground = labels.add ("ground"); Label_handle vegetation = labels.add ("vegetation"); Label_handle roof = labels.add ("roof"); std::vector label_indices(pts.size(), -1); std::cerr << "Using OpenCV Random Forest Classifier" << std::endl; Classification::OpenCV::Random_forest_classifier classifier (labels, features); std::cerr << "Training" << std::endl; t.reset(); t.start(); classifier.train (pts.range(label_map.value())); t.stop(); std::cerr << "Done in " << t.time() << " second(s)" << std::endl; t.reset(); t.start(); Classification::classify_with_graphcut (pts, pts.point_map(), labels, classifier, generator.neighborhood().k_neighbor_query(12), 0.2f, 1, label_indices); t.stop(); std::cerr << "Classification with graphcut done in " << t.time() << " second(s)" << std::endl; std::cerr << "Precision, recall, F1 scores and IoU:" << std::endl; Classification::Evaluation evaluation (labels, pts.range(label_map.value()), label_indices); for (Label_handle l : labels) { std::cerr << " * " << l->name() << ": " << evaluation.precision(l) << " ; " << evaluation.recall(l) << " ; " << evaluation.f1_score(l) << " ; " << evaluation.intersection_over_union(l) << std::endl; } std::cerr << "Accuracy = " << evaluation.accuracy() << std::endl << "Mean F1 score = " << evaluation.mean_f1_score() << std::endl << "Mean IoU = " << evaluation.mean_intersection_over_union() << std::endl; // Color point set according to class UCmap red = pts.add_property_map("red", 0).first; UCmap green = pts.add_property_map("green", 0).first; UCmap blue = pts.add_property_map("blue", 0).first; for (std::size_t i = 0; i < label_indices.size(); ++ i) { label_map.value()[i] = label_indices[i]; // update label map with computed classification Label_handle label = labels[label_indices[i]]; const CGAL::IO::Color& color = label->color(); red[i] = color.red(); green[i] = color.green(); blue[i] = color.blue(); } // Write result std::ofstream f ("classification_opencv_random_forest.ply"); f.precision(18); f << pts; std::cerr << "All done" << std::endl; return EXIT_SUCCESS; }