X-Boost  2.3.8
IntegralImage.h
1 /* XBoost: Ada-Boost and Friends on Haar/ICF/HOG Features, Library and ToolBox
2  *
3  * Copyright (c) 2008-2014 Paolo Medici <medici@ce.unipr.it>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #ifndef _INTEGRALIMAGE_DETECTOR_H
22 #define _INTEGRALIMAGE_DETECTOR_H
23 
24 #include "ClassifierDetectorHelper.h"
25 #include <factory/ObjectDetector.h>
26 #include <cmath>
27 
29 #ifndef WIN32
30 template<>
31 #endif
32 template <class _Instance>
33 struct ClassifierDetectHelper<IntegralImagePreprocessor, _Instance>: public ObjectDetectorWrapperBase<IntegralImagePreprocessor, _Instance> {
34 private:
35 
36  typedef typename IntegralImagePreprocessor::ReturnType data_type;
37 
41  unsigned int m_width, m_height;
42 
43  // no-thread safe octave
44 // int nOctave;
45 private:
46 
47  void ImportImage(const ImageHandle & src)
48  {
49  m_width = src.width;
50  m_height = src.height;
51  m_img.Build(src);
52  }
53  // esegue il classificatore a una determinata scala
54  void scale_object_detector(std::vector<Candidate> * out, double s)
55  {
56  data_type data;
57  detail::CandidateParam nms_params;
58  double *response = new double[this->m_width * this->m_height];
59 
60  bool have_to_release;
62 
63  // size of resampled image
64  int width = this->m_width / s;
65  int height = this->m_height / s;
66 
67  // create resampled channel image
68  if(width == (int) this->m_width && height == (int) this->m_height)
69  {
71  have_to_release = false;
72  }
73  else
74  {
75 
76  Resample(m_img, resampled, rect(0,0,this->m_width,this->m_height), width, height);
77  IntegralImagePreprocessor::Process(data, resampled);
78  have_to_release = true;
79  }
80 
81  // estimate maximum octave
82  int nOctave = 1;
83 
84  for(unsigned int n=0; n<this->m_classifs.size(); ++n)
85  {
86  int cl_width = this->m_clsparams[n].sz.width;
87  int cl_height = this->m_clsparams[n].sz.height;
88 
89  int nOctave_test = ( (int)log2(std::min(width/cl_width, height/cl_height)) ) + 1; // rounded
90  if(nOctave_test > nOctave)
91  nOctave = nOctave_test;
92  }
93 
94  // for each octave
95  for(int o=0; o<nOctave; ++o)
96  {
97  // for each classifier
98  for(unsigned int n=0; n<this->m_classifs.size(); ++n)
99  {
100  // compute classifier geometry at this octave and prepare the response image
101  int cl_width = this->m_clsparams[n].sz.width * (1<<o);
102  int cl_height = this->m_clsparams[n].sz.height * (1<<o);
103 
104  // the effective downsampling is a mix between user downsampling and octave
105  int r_step = this->m_clsparams[n].downsampling * (1<<o);
106 
107  // geometry of the response image
108  int r_width = (width - cl_width) / r_step;
109  int r_height = (height - cl_height) / r_step;
110 
111  if(this->m_clsparams[n].enabled && r_width > 3 && r_height > 3)
112  {
113  // allocate an optimized version of _Instance
114  _Instance rInst(this->m_classifs[n], (1<<o), 0, width);
115 
116  unsigned int step = std::min(cl_width, cl_height)/(2 * r_step); // max 50% occlusion
117 
118  if(step==0)
119  step = 1;
120 
121  if(this->require_a_mask(n))
122  {
123  unsigned char *mask = new unsigned char [r_width * r_height];
124  rect roi;
125  // scale (s) and cl_width and cl_height according to octave
126  this->prepare_mask(n, s, mask, r_width, r_height, cl_width, cl_height, roi);
127  ObjectDetectorWrapperBase<IntegralImagePreprocessor, _Instance>::compute_masked_response(rInst, data, response, r_width, roi, mask, this->m_params.concurrent_jobs);
128  delete [] mask;
129  }
130  else
131  {
132 
133  // proces only inside ROI
134  rect roi;
135  roi.x0 = 0;
136  roi.y0 = 0;
137  roi.x1 = r_width;
138  roi.y1 = r_height;
139 
140  // compute response
141  // ObjectDetectorWrapperBase<IntegralImagePreprocessor, _Instance>::compute_response(this->m_classifs[0], data, response, r_width, roi, 8);
142  ObjectDetectorWrapperBase<IntegralImagePreprocessor, _Instance>::compute_response(rInst, data, response, r_width, roi, this->m_params.concurrent_jobs);
143  }
144 
145  nms_params.scale = s;
146  nms_params.step = r_step;
147  nms_params.category = this->m_clsparams[n].category;
148  nms_params.cl_geom.width = cl_width;
149  nms_params.cl_geom.height = cl_height;
150 
151 // {
152 // char buffer[512];
153 // static int count = 0;
154 // sprintf(buffer, "/tmp/response-%06u.pgm", count);
155 // count++;
156 // ObjectDetectorWrapperBase<IntegralImagePreprocessor, _Instance>::dump_response_image(response, r_width, r_height, buffer);
157 // }
158 
159  // extract candidates
160  NonMaximaSuppression(response, *out, step, r_width, r_width, r_height, this->m_clsparams[0].th, nms_params, 1);
161 
162  }
163 
164  }
165 
166  // s *= 2.0; // next octave does not change scale, but only classifier size
167  }
168 
169  if(have_to_release)
170  data.first.release();
171 
172  delete [] response;
173  }
174 public:
175 
176  // bridge for preprocessor
178 
179 
180  // detect implementa le 3 varianti
181  void detect(std::vector<Candidate>& out, const ImageHandle & src) {
182 
183 #ifdef DEBUG_TIMING
184  this->timer_total.Start();
185 #endif
186 
187  data_type data_store;
188 
189 // std::cout << "Max octave:" << nOctave << std::endl;
190 
191  // scale factor
192  double scale_factor = (this->m_params.octave_mode) ? ( exp( log(2.0) / this->m_params.nScales) ) : (1.0 / this->m_params.nScales);
193 
194  std::vector< std::vector<Candidate > > tmp_out;
195 
196  // import image in the helper
197  this->ImportImage(src);
198 
199  tmp_out.resize( this->m_params.nScales );
200 
201  double s = 1.0;
202  /*
203  sprint::thread_group thread_pool_;
204  // TODO: use concurrency value!
205  // ogni thread gestisce una scala
206  for(int scale=0; scale<this->m_params.nScales; scale++)
207  {
208  thread_pool_.create_thread(sprint::thread_bind(&ClassifierDetectHelper<IntegralImagePreprocessor, _Instance>::scale_object_detector,this, &tmp_out[scale], s));
209  if(!this->m_params.octave_mode)
210  s+=scale_factor;
211  else
212  s*=scale_factor;
213  }
214  */
215  for(int scale=0; scale<this->m_params.nScales; scale++)
216  {
217  scale_object_detector(&out, s);
218  if(!this->m_params.octave_mode)
219  s+=scale_factor;
220  else
221  s*=scale_factor;
222  }
223 #ifdef DEBUG_TIMING
224  this->timer_total.Stop();
225 #endif
226  }
227 };
228 
229 
230 #endif
Definition: IntegralImagePreprocessors.h:36
some common method that can be used to inner detector
Definition: ClassifierDetectorHelper.h:84
size cl_geom
classifier geometry
Definition: Candidate.h:39
parameters used in the NMS step
Definition: Candidate.h:33
Definition: Image.h:35
int step
response step. Multiplication factor to convert from (x,y) to box coordinates
Definition: Candidate.h:37
int category
category
Definition: Candidate.h:41
Definition: ClassifierDetectorHelper.h:528
static void compute_response(const _Instance &inst, const data_type &data, double *response, int stride, const rect &roi, int nThread)
Definition: ClassifierDetectorHelper.h:324
static bool Process(std::pair< IntegralImageData, IntegralImageParams > &out, const T *image, unsigned int width, unsigned int height, long stride)
the operator used to convert an image to an integral image
Definition: IntegralImagePreprocessors.h:102
void Resample(ImageHandle &out, const ImageHandle &in, const rect &area)
Crop and Resample an Image using IntegralImage algorithm.
virtual classes to work on classifier. ObjectDetector exploits all the performance of classifier...
unsigned int width
image geometry
Definition: Image.h:39
a rectangle structure
Definition: Types.h:55
std::pair< DataType, ParamType > ReturnType
Data provided by this preprocessor.
Definition: IntegralImagePreprocessors.h:46
void NonMaximaSuppression(const D *src, FeatureListType &maxima, unsigned int n, long stride, unsigned int width, unsigned int height, D threshold, Param param, int nThreads=sprint::thread::hardware_concurrency())
Definition: NonMaximaSuppression.h:167
float scale
detection scale. Multiplication factor to convert from (x,y) and size to box coordinates ...
Definition: Candidate.h:35