File: example_opencv_random_forest.cpp

package info (click to toggle)
cgal 6.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 141,840 kB
  • sloc: cpp: 797,081; ansic: 203,398; sh: 490; python: 411; makefile: 286; javascript: 174
file content (136 lines) | stat: -rw-r--r-- 4,558 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#if defined (_MSC_VER) && !defined (_WIN64)
#pragma warning(disable:4244) // boost::number_distance::distance()
                              // converts 64 to 32 bits integers
#endif

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Classification.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>

#include <CGAL/Real_timer.h>

typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Point_set_3<Point> Point_set;
typedef Kernel::Iso_cuboid_3 Iso_cuboid_3;

typedef Point_set::Point_map Pmap;
typedef Point_set::Property_map<int> Imap;
typedef Point_set::Property_map<unsigned char> 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<Kernel, Point_set, Pmap>    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<Imap> label_map = pts.property_map<int> ("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<int> 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<CGAL::Parallel_if_available_tag>
    (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<unsigned char>("red", 0).first;
  UCmap green = pts.add_property_map<unsigned char>("green", 0).first;
  UCmap blue = pts.add_property_map<unsigned char>("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;
}