22 #ifndef _CLASSIFIER_DETECTOR_HELPER_H
23 #define _CLASSIFIER_DETECTOR_HELPER_H
48 template<
class _Instance,
class _DataType>
49 void inner_compute_response(
const _Instance * inst,
const _DataType * data,
double * response,
int stride,
rect roi)
51 for(
int j=roi.y0; j<roi.y1; j++)
52 for(
int i=roi.x0; i<roi.x1; i++)
53 response[i+j*stride]= (*inst)(getData1(data->first,data->second,i,j),getData2(data->first,data->second));
59 template<
class _Instance,
class _DataType>
60 void inner_compute_masked_response(
const _Instance * inst,
const _DataType * data,
double * response,
int stride,
int y0,
int y1,
const std::pair<int, int> *roi)
62 for(
int j=y0; j<y1; j++)
63 for(
int i=roi[j].first; i<roi[j].second; i++)
64 response[i+j*stride]= (*inst)(getData1(data->first,data->second,i,j),getData2(data->first,data->second));
70 template<
class _Instance,
class _DataType>
71 void inner_compute_masked_response(
const _Instance * inst,
const _DataType * data,
double * response,
int stride,
const unsigned char *mask,
rect roi)
74 for(
int j=roi.y0; j<roi.y1; j++)
75 for(
int i=roi.x0; i<roi.x1; i++)
77 response[i+j*stride]= (*inst)(getData1(data->first,data->second,i,j),getData2(data->first,data->second));
79 response[i+j*stride]= -1.0;
83 template<
class _Preprocessor,
class _Instance>
89 typedef typename _Preprocessor::ReturnType data_type;
99 Statistic timer_preprocess, timer_total, timer_response, timer_nms;
101 Statistic timer_preprocess_scale[MAX_SCALES];
102 Statistic timer_response_scale[MAX_SCALES];
113 std::cout <<
"Timing Debug:\n";
114 std::cout <<
"Total Total: " << timer_total << std::endl;
116 std::cout <<
"Total Preprocess: " << timer_preprocess << std::endl;
117 for(
int i =0; i<MAX_SCALES; ++i)
119 if(timer_preprocess_scale[i])
120 std::cout <<
"Scale " << i <<
" preprocess: " << timer_preprocess_scale[i] << std::endl;
121 if(timer_response_scale[i])
122 std::cout <<
"Scale " << i <<
" response: " << timer_response_scale[i] << std::endl;
123 if(timer_nms_scale[i])
124 std::cout <<
"Scale " << i <<
" nms: " << timer_nms_scale[i] << std::endl;
158 void prepare_mask(
int cl_index,
float s,
unsigned char *mask,
unsigned int r_width,
unsigned int r_height,
int cl_width,
int cl_height,
rect & roi)
160 std::vector<std::pair<int,int> > searchRanges;
161 std::vector<rect> rois;
162 this->
get_ranges(searchRanges, rois, cl_index, s);
175 int n = std::min<int>(r_height, searchRanges.size()-cl_height);
180 for(
int i = 0; i<n; ++i)
184 if(searchRanges[i+cl_height].first <= cl_width && searchRanges[i+cl_height].second >= cl_width)
186 if(roi.y0 > i) roi.y0 = i;
187 if(roi.y1 < i) roi.y1 = i;
189 memset(mask + i * r_width, 255, r_width);
192 memset(mask + i * r_width, 0, r_width);
198 memset(mask, 0, r_width * r_height);
204 else if(searchRanges.empty())
206 memset(mask, 0, r_width * r_height);
208 for(
unsigned int i = 0; i<rois.size(); ++i)
217 if(cur.x0 < 0) cur.x0 = 0;
218 if(cur.y0 < 0) cur.y0 = 0;
219 if(cur.x1 > (
int) r_width) cur.x1 = r_width;
220 if(cur.y1 > (
int) r_height) cur.y1 = r_height;
223 if(roi.x0 > cur.x0) roi.x0 = cur.x0;
224 if(roi.x1 < cur.x1) roi.x1 = cur.x1;
225 if(roi.y0 > cur.y0) roi.y0 = cur.y0;
226 if(roi.y1 < cur.y1) roi.y1 = cur.y1;
229 for(
int j = cur.y0; j<cur.y1; ++j)
230 memset(mask + j * r_width + cur.x0, 255, cur.width() );
236 int n = std::min<int>(r_height, searchRanges.size()-cl_height);
239 memset(mask, 0, r_width * r_height);
241 for( std::vector<rect>::const_iterator i = rois.begin(); i != rois.end(); ++i)
250 if(cur.x0 < 0) cur.x0 = 0;
251 if(cur.y0 < 0) cur.y0 = 0;
252 if(cur.x1 > (
int) r_width) cur.x1 = r_width;
253 if(cur.y1 > n) cur.y1 = n;
256 if(roi.x0 > cur.x0) roi.x0 = cur.x0;
257 if(roi.x1 < cur.x1) roi.x1 = cur.x1;
258 if(roi.y0 > cur.y0) roi.y0 = cur.y0;
259 if(roi.y1 < cur.y1) roi.y1 = cur.y1;
262 for(
int j = cur.y0; j<cur.y1; ++j)
264 if(searchRanges[j+cl_height].first < cl_width && searchRanges[j+cl_height].second > cl_width)
266 memset(mask + j * r_width + cur.x0, 255, cur.width() );
276 void get_ranges(std::vector<std::pair<int,int> > & searchRanges, std::vector<rect> & roi,
int n,
float s)
const
280 const std::vector<std::pair<int,int> > & src =
m_clsparams[n].m_srcSearchRanges;
281 unsigned int h = src.size()/s;
282 searchRanges.resize(h);
285 for(
unsigned int i=0; i<h; ++i)
288 unsigned int ij = (
unsigned int) j;
289 float dj = j - (float) ij;
291 searchRanges[i].first = ((ij+1 < src.size()) ? (src[ij].first * (1.0f - dj) + src[ij+1].first * dj) : src[ij].first)/s;
292 searchRanges[i].second = ((ij+1 < src.size()) ? (src[ij].second * (1.0f - dj) + src[ij+1].second * dj) : src[ij].second)/s;
297 const std::vector<rect> & src =
m_clsparams[n].m_searchRoi;
298 roi.resize(src.size());
300 for(
unsigned int i=0; i<src.size(); ++i)
302 roi[i].x0 = (src[i].x0 / s)+0.5f;
303 roi[i].x1 = (src[i].x1 / s)+0.5f;
304 roi[i].y0 = (src[i].y0 / s)+0.5f;
305 roi[i].y1 = (src[i].y1 / s)+0.5f;
324 static void compute_response(
const _Instance & inst,
const data_type & data,
double * response,
int stride,
const rect & roi,
int nThread)
330 for(
int i =0; i<nThread; ++i)
335 ir.y0 = roi.y0 + (i * roi.height())/nThread;
336 ir.y1 = roi.y0 + ((i+1) * roi.height())/nThread;
337 thread_pool_.
create_thread(sprint::thread_bind(&inner_compute_response<_Instance, data_type>, &inst, &data, response, stride, ir));
343 inner_compute_response(&inst, &data, response, stride, roi);
347 static void compute_masked_response(
const _Instance & inst,
const data_type & data,
double * response,
int stride,
const rect & roi,
const unsigned char *mask,
int nThread)
354 for(
int i =0; i<nThread; ++i)
359 ir.y0 = roi.y0 + (i * roi.height())/nThread;
360 ir.y1 = roi.y0 + ((i+1) * roi.height())/nThread;
361 thread_pool_.
create_thread(sprint::thread_bind(&inner_compute_masked_response<_Instance, data_type>, &inst, &data, response, stride, mask, ir));
367 inner_compute_masked_response(&inst, &data, response, stride, mask, roi);
454 timer_preprocess.Start();
459 preprocess_images.resize(m_params.
nScales);
462 this->timer_parallel_ichn.Start();
464 for(
int scale=0; scale<m_params.
nScales; scale++)
474 timer_preprocess.Stop();
482 timer_preprocess.Start();
486 preprocess_images.resize(m_params.
nScales * k_max);
489 this->timer_parallel_ichn.Start();
490 for(
int scale=0; scale<m_params.
nScales; scale++)
500 timer_preprocess.Stop();
505 static void dump_response_image(
const T *src,
unsigned int w,
unsigned int h,
const char *filename)
510 std::cout <<
"Dump " << w <<
'x'<< h <<
':';
511 for(
int i=0; i<w*h; ++i)
513 if (src[i] > max) max = src[i];
514 if (src[i] < min) min = src[i];
516 std::cout <<
"min: " << min <<
"max: " << max << std::endl;
518 if(-min > max) max = -min;
520 for(
int i=0; i<w*h; ++i)
521 out.data[i] = 128 + ((src[i] * T(128)) / max);
527 template <
class _Instance,
class _Preprocessor>
some common method that can be used to inner detector
Definition: ClassifierDetectorHelper.h:84
a structure to hold image data (memory)
Definition: Image.h:74
void prepare_mask(int cl_index, float s, unsigned char *mask, unsigned int r_width, unsigned int r_height, int cl_width, int cl_height, rect &roi)
Definition: ClassifierDetectorHelper.h:158
bool pnm_write(const ImageHandle &in, const char *file)
Over-Classifier params.
Definition: ObjectDetector.h:68
void setClassifierParams(int index, const ObjectDetectorParams ¶ms)
set per-classifier params
Definition: ClassifierDetectorHelper.h:138
Cross Platform High Performance timer.
Definition: ClassifierDetectorHelper.h:528
int nScales
Number of Scales per Octave.
Definition: ObjectDetector.h:72
Definition: thread_group.h:82
static void compute_response(const _Instance &inst, const data_type &data, double *response, int stride, const rect &roi, int nThread)
Definition: ClassifierDetectorHelper.h:324
image/size TODO namespace
Definition: Types.h:39
void join_all()
wait all threads terminate
Definition: thread_group.h:114
const ObjectDetectorParams & getClassifierParams(int index)
get per-classifier params
Definition: ClassifierDetectorHelper.h:144
bool require_a_mask(int n) const
Definition: ClassifierDetectorHelper.h:150
std::vector< _Instance > m_classifs
a vector of classifier instance
Definition: ClassifierDetectorHelper.h:92
Compute timing statistics.
Definition: timer.h:105
bool create_thread(const sprint::thread_function &p)
create an additional thread
Definition: thread_group.h:102
std::vector< ObjectDetectorParams > m_clsparams
per classifier params
Definition: ClassifierDetectorHelper.h:94
Definition: ObjectDetector.h:42
a rectangle structure
Definition: Types.h:55
void precompute_scales_octaves(std::vector< data_type > &preprocess_images, double scale_factor, int k_max)
calcola sia le scale che le ottave
Definition: ClassifierDetectorHelper.h:479
void get_ranges(std::vector< std::pair< int, int > > &searchRanges, std::vector< rect > &roi, int n, float s) const
convert the internal ranges of the classifier of index n
Definition: ClassifierDetectorHelper.h:276
void precompute_scales(std::vector< data_type > &preprocess_images, double scale_factor)
compute scaled preprocessor, without using m_img resampler!
Definition: ClassifierDetectorHelper.h:451
int octave_mode
use octave or linear search mode (deprecated)
Definition: ObjectDetector.h:70