21 #ifndef _BOOTSTRAP_PROCEDURE_H
22 #define _BOOTSTRAP_PROCEDURE_H
34 #endif // #ifdef _MULTITHREADING
68 template<
class SourceDatasetType,
class ClassifierType>
75 sz.width = training_set.width;
76 sz.height = training_set.height;
82 #ifdef LIMIT_PER_FRAME
84 std::vector< ImageHandle > image_scales;
85 std::vector< Candidate > candidates;
92 int src_width = img.
width;
93 int src_height = img.height;
94 std::cout <<
"Testing classifier on " << item.
filename <<
" (" << src_width <<
'x' << src_height <<
") with step " << params.
downsampling <<
" [ID:" <<
frameidx <<
"]" << std::endl;
95 std::vector<datasetobject> list = item.
object;
98 bool first_scale =
true;
108 int h_r = ((
int) img.height - (int) sz.height)/params.
downsampling;
110 std::cout <<
"\t" << img.
width <<
'x' << img.height <<
" (" << w_r <<
'x' << h_r <<
")... ";
113 std::vector<Candidate> elements;
115 typename SourceDatasetType::ReturnType Out;
118 if(h_r < 3 || w_r < 3)
120 std::cout <<
"\tWarn: response image too small\n";
125 double* response =
new double[w_r*h_r];
132 training_set.Process(Out, img.
data, img.
width, img.height, img.
stride);
136 typename ClassifierType::OptimizedType _Inst(cl, 0, Out.second);
144 for(
int ii=0; ii<num_thread; ii++)
146 int startH = (ii*h_r)/num_thread;
147 int endH = ((ii+1)*h_r)/num_thread;
151 thread_pool_.
create_thread(sprint::thread_bind(&optimizedWorkerResponse<typename SourceDatasetType::ReturnType, typename ClassifierType::OptimizedType>,response,startH,endH,w_r, sprint::c_ref(_Inst), sprint::c_ref(Out), params.
downsampling ));
165 double dt = t.GetTime();
167 r_min = *std::min_element(response,response+w_r*h_r);
168 r_max = *std::max_element(response,response+w_r*h_r);
170 std::cout <<
"\tr_max " << r_max <<
" | r_min " << r_min;
204 std::vector<Candidate> tmpOut;
208 param.
cl_geom.width = training_set.width;
209 param.
cl_geom.height = training_set.height;
218 std::cout <<
" | detected: "<< tmpOut.size() <<
" in " << dt <<
"s";
234 for(std::vector<Candidate>::const_iterator i = tmpOut.begin(); i != tmpOut.end(); ++i)
236 bool is_overlap =
false;
238 for(std::vector<datasetobject>::const_iterator j = list.begin(); j != list.end(); ++j)
240 if(j->category >= 0 &&
overlap(i->box, j->roi))
249 elements.push_back(*i);
256 #ifndef LIMIT_PER_FRAME
257 std::cout <<
" | " << elements.size() <<
"/" << params.
negative_random_samples <<
" false positives found" << std::endl;
263 std::sort(elements.begin(), elements.end());
267 for(std::vector<Candidate>::const_iterator i = elements.begin(); i != elements.end(); ++i)
269 training_set.ImportImage(img.
crop(i->box),-1);
273 new_pattern += elements.size();
277 std::cout <<
" | " << elements.size() <<
" false positives found" << std::endl;
280 for(std::vector<Candidate>::const_iterator i = elements.begin(); i != elements.end(); ++i)
282 std::pair<float, Image *> d;
283 d.first = i->response;
284 d.second =
new Image;
286 candidates.push_back(d);
297 w_r = (int(src_width/scale) - (int) sz.width) /params.
downsampling;
298 h_r = (int(src_height/scale) - (int) sz.height)/params.
downsampling;
302 if(w_r > 3 && h_r > 3)
307 rsmp.ImportImage(img);
312 out.
alloc( (
int) ((
float)src_width/scale), (
int) ((
float)src_height/scale), 1);
313 rsmp.ExportImage(out);
315 for(
unsigned int i=0; i<list.size(); ++i)
316 { list[i].roi.x0 = floor((
float)item.
object[i].roi.x0 / scale);
317 list[i].roi.y0 = floor((
float)item.
object[i].roi.y0 / scale);
318 list[i].roi.x1 = ceil((
float)item.
object[i].roi.x1 / scale);
319 list[i].roi.y1 = ceil((
float)item.
object[i].roi.y1 / scale);
337 #ifdef LIMIT_PER_FRAME
338 std::cout <<
"\t" << candidates.size() <<
"/" << params.
negative_random_samples <<
" total false positives found" << std::endl;
344 std::sort(candidates.begin(), candidates.end());
348 for(std::vector<std::pair<float, Image *> >::const_iterator i = candidates.begin(); i != candidates.end(); ++i)
351 training_set.ImportImage(*i->second,-1);
357 new_pattern += candidates.size();
359 std::cout <<
"\tFrame processed in " << t0.GetTime() <<
"s. " << n_negatives <<
" total new negatives imported.\n";
367 std::cout <<
"Bootstrap completed. " << new_pattern <<
" added to the negative pool.\n";
369 return new_pattern == 0;
void clone(const ImageHandle &src)
clone an image
Definition: Image.h:104
int frameidx
a counter, used for debug
bool pnm_load(const char *file, Image &out)
bool BootStrapProcedure(SourceDatasetType &training_set, datasetin &in, const ClassifierType &cl, const BootStrapParams ¶ms, int num_thread)
Definition: BootStrapProcedure.h:69
size cl_geom
classifier geometry
Definition: Candidate.h:39
int downsampling
downsampling factor for computing response
Definition: BootStrapProcedure.h:50
parameters used in the NMS step
Definition: Candidate.h:33
a virtual pure pattern list reader
Definition: datasetin.h:56
a structure to hold image data (memory)
Definition: Image.h:74
Implement a local maxima search algorithm.
ImageHandle crop(int x0, int y0, int x1, int y1) const
return a subpart of the image (without copy)
Definition: Image.h:47
void optimizedWorkerResponse(double *r, int startH, int endH, int W, const ClassifierType &cl, const ReturnType &out, int step)
Definition: ResponseUtils.h:59
int step
response step. Multiplication factor to convert from (x,y) to box coordinates
Definition: Candidate.h:37
ClassifierType
Definition: Types.h:31
int negative_random_samples
max number of negative extract per frame or per scale
Definition: BootStrapProcedure.h:46
int category
category
Definition: Candidate.h:41
float scale_factor
scale factor between two images
Definition: BootStrapProcedure.h:44
Parameters for BootStrapProcedure.
Definition: BootStrapProcedure.h:42
double thMin
threshold
Definition: BootStrapProcedure.h:52
Definition: thread_group.h:82
image/size TODO namespace
Definition: Types.h:39
void join_all()
wait all threads terminate
Definition: thread_group.h:114
proposal 1 for thread group
helping method used during resposne computations
long stride
line stride, the delta offset, in bytes, between two different scanline
Definition: Image.h:41
int nms_step
non maxima suppression step
Definition: BootStrapProcedure.h:48
method to create function pointer for thread call
bool create_thread(const sprint::thread_function &p)
create an additional thread
Definition: thread_group.h:102
an item used for positive
Definition: datasetin.h:44
unsigned int width
image geometry
Definition: Image.h:39
std::vector< datasetobject > object
List of object.
Definition: datasetin.h:52
bool overlap(const rect &a, const rect &b)
test if 2 rect are overlapped
virtual class to import images
std::string filename
filename
Definition: datasetin.h:46
Definition: ImageUtils.h:35
unsigned char * data
initial address of the first pixel. It must be cast to correct format (uint8, uint16, rgb, etc etc)
Definition: Image.h:43
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
bool auto_negative
if the rest of the blob can be used as source for negative
Definition: datasetin.h:50
void alloc(unsigned int w, unsigned int h, unsigned int b)
reserve memory for the image
Definition: Image.h:98
float scale
detection scale. Multiplication factor to convert from (x,y) and size to box coordinates ...
Definition: Candidate.h:35