LArOpenCV  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
ImageClusterManager.cxx
Go to the documentation of this file.
1 #ifndef __IMAGECLUSTERMANAGER_CXX__
2 #define __IMAGECLUSTERMANAGER_CXX__
3 
4 #include <opencv2/imgproc/imgproc.hpp>
5 #include "ImageClusterManager.h"
6 #include "Core/larbys.h"
7 #include "ImageClusterFactory.h"
8 namespace larcv {
9 
11  : laropencv_base(name)
12  , _name(name)
13  , _configured(false)
14  , _profile(true)
15  {
16  LARCV_DEBUG((*this)) << "start" << std::endl;
17  Reset();
18  LARCV_DEBUG((*this)) << "end" << std::endl;
19  }
20 
22  {
23  LARCV_DEBUG((*this)) << "start" << std::endl;
24  _configured = false;
25  _alg_v.clear();
26  _clusters_v.clear();
28  _process_time=0;
29  LARCV_DEBUG((*this)) << "end" << std::endl;
30  }
31 
33  {
34  if(id >= _alg_v.size()) throw larbys("Invalid algorithm ID requested...");
35  return _alg_v[id];
36  }
37 
38  ImageClusterBase* ImageClusterManager::GetAlg(const std::string name) const
39  {
40  return GetAlg(GetAlgID(name));
41  }
42 
43  AlgorithmID_t ImageClusterManager::GetAlgID(const std::string name) const
44  {
45  auto iter = _alg_m.find(name);
46  if(iter == _alg_m.end()) return kINVALID_ALGO_ID;
47  return (*iter).second;
48  }
49 
50  /*
51  AlgorithmID_t ImageClusterManager::AddAlg(ImageClusterBase* alg)
52  {
53  if(!alg) throw larbys("Cannot add nullptr!");
54  if(_configured) throw larbys("Cannot add algo after configured! (call Reset())");
55  _alg_v.push_back(alg);
56  return (_alg_v.size() - 1);
57  }
58  */
59 
60  void ImageClusterManager::Configure(const ::fcllite::PSet& main_cfg)
61  {
62  LARCV_DEBUG((*this)) << "start" << std::endl;
63  _profile = main_cfg.get<bool>("Profile");
64 
65  this->set_verbosity((msg::Level_t)(main_cfg.get<unsigned short>("Verbosity",(unsigned short)(this->logger().level()))));
66 
67  std::vector<std::string> instance_type_v = main_cfg.get<std::vector<std::string> >("AlgoType");
68  std::vector<std::string> instance_name_v = main_cfg.get<std::vector<std::string> >("AlgoName");
69 
70  if(instance_type_v.size() != instance_name_v.size()) {
71  LARCV_CRITICAL((*this)) << "AlgoType and AlgoName config parameters have different length! "
72  << "(" << instance_type_v.size() << " vs. " << instance_name_v.size() << ")" << std::endl;
73  throw larbys();
74  }
75 
76  _alg_v.clear();
77  _alg_m.clear();
78  for(size_t i=0; i<instance_type_v.size(); ++i) {
79  auto const& name = instance_name_v[i];
80  auto const& type = instance_type_v[i];
81  if(_alg_m.find(name) != _alg_m.end()) {
82  LARCV_CRITICAL((*this)) << "Duplicate algorithm name found!" << std::endl;
83  throw larbys("Duplicate algorithm name found!");
84  }
85 
86  _alg_m[name] = _alg_v.size();
87  _alg_v.push_back(ImageClusterFactory::get().create(type,name));
88  }
89 
90  for(auto& ptr : _alg_v) {
91  ptr->Profile(_profile);
92  ptr->set_verbosity(this->logger().level());
93  ptr->Configure(main_cfg.get_pset(ptr->Name()));
94  }
95  _configured=true;
96  LARCV_DEBUG((*this)) << "end" << std::endl;
97  }
98 
100  {
101 
102  std::cout << " ================== " << Name() << " Profile Report ==================" << std::endl
103  << " # Process call = " << _process_count << " ... Total time = " << _process_time << " [s]" << std::endl;
104  for(auto const& ptr : _alg_v) {
105  std::cout << Form(" \033[93m%-20s\033[00m ... # call %-5zu ... total time %g [s] ... average time %g [s/process]",
106  ptr->Name().c_str(), ptr->ProcessCount(), ptr->ProcessTime(), ptr->ProcessTime() / (double)(ptr->ProcessCount()))
107  << std::endl;
108  }
109 
110  }
111 
112  void ImageClusterManager::Process(const ::cv::Mat& img, const ImageMeta& meta)
113  {
114  LARCV_DEBUG((*this)) << "start" << std::endl;
115 
116  if(!_configured) throw larbys("Must Configure() before Process()!");
117 
118  if(meta.num_pixel_row()!=img.rows)
119  throw larbys("Provided metadata has incorrect # horizontal pixels w.r.t. image!");
120 
121  if(meta.num_pixel_column()!=img.cols)
122  throw larbys("Provided metadata has incorrect # vertical pixels w.r.t. image!");
123 
124  _watch.Start();
125 
126  _orig_meta = meta;
127  _meta_v.clear();
128  _clusters_v.clear();
129  _clusters_v.reserve(_alg_v.size());
130  _meta_v.reserve(_alg_v.size());
131 
132  for(auto& alg_ptr : _alg_v) {
133 
134  if(!alg_ptr) throw larbys("Invalid algorithm pointer!");
135 
136  if(alg_ptr == _alg_v.front()) {
137 
138  ContourArray_t clusters;
139  _meta_v.push_back(_orig_meta);
140  _clusters_v.emplace_back(alg_ptr->Process(clusters,img,_meta_v.back()));
141 
142  }else{
143 
144  auto const& clusters = _clusters_v.back();
145  _meta_v.push_back(_orig_meta);
146  _clusters_v.emplace_back(alg_ptr->Process(clusters,img,_meta_v.back()));
147 
148  }
149  // Sanity check on meta data
150  auto const& result_meta = _meta_v.back();
151  if(result_meta.height() > _orig_meta.height()) {
152  std::cerr << "Return meta data by " << alg_ptr->Name() << " exceeds original image height!" << std::endl;
153  throw larbys();
154  }
155  if(result_meta.width() > _orig_meta.width()) {
156  std::cerr << "Return meta data by " << alg_ptr->Name() << " exceeds original image width!" << std::endl;
157  throw larbys();
158  }
159 
160  }
161 
163  ++_process_count;
164  LARCV_DEBUG((*this)) << "end" << std::endl;
165  }
166 
168  {
169  if(alg_id < _meta_v.size()) return _meta_v[alg_id];
170  if(alg_id >= _meta_v.size()) throw larbys("Invalid algorithm ID requested");
171  throw larbys("Execution of an algorithm not yet done!");
172  }
173 
174  const Contour_t& ImageClusterManager::Cluster(const ClusterID_t cluster_id, const AlgorithmID_t alg_id) const
175  {
176  auto const& clusters = Clusters(alg_id);
177  if(cluster_id >= clusters.size()) throw larbys("Invalid cluster ID requested");
178  return clusters[cluster_id];
179  }
180 
182  {
183  if(alg_id < _clusters_v.size()) return _clusters_v[alg_id];
184  if(alg_id == kINVALID_ALGO_ID && _clusters_v.size()) return _clusters_v.back();
185  throw larbys("Execution of an algorithm not yet done!");
186  }
187 
188  ClusterID_t ImageClusterManager::ClusterID(const double x, const double y, AlgorithmID_t alg_id) const
189  {
190 
192 
193  if(_clusters_v.empty()) return result;
194 
195  if(alg_id == kINVALID_ALGO_ID) alg_id = _clusters_v.size() - 1;
196 
197  auto const& clusters = _clusters_v[alg_id];
198 
199  auto const& meta = _meta_v[alg_id];
200 
201  auto const& origin = meta.origin();
202 
203  if(x < origin.x || x > (origin.x + meta.width())) return result;
204 
205  if(y < origin.y || x > (origin.y + meta.height())) return result;
206 
207  //std::cout<<"Inspecting a point "<<x<<" : "<<y<<" ... ";
208 
209  auto pt = ::cv::Point2d((x-origin.x)/meta.pixel_width(),(y-origin.y)/meta.pixel_height());
210 
211  //std::cout<<pt.x<<" : "<<pt.y<<std::endl;
212 
213  for(size_t id=0; id<clusters.size(); ++id) {
214 
215  auto const& c = clusters[id];
216 
217  double inside = ::cv::pointPolygonTest(c,pt,false);
218 
219  if(inside < 0) continue;
220 
221  result = id;
222 
223  break;
224  }
225 
226  return result;
227  }
228 }
229 #endif