00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <fvutils/colormap/bayes/bayes_generator.h>
00026 #include <fvutils/statistical/histogram_file.h>
00027 #include <fvutils/statistical/histogram_block.h>
00028
00029 #include <fvutils/color/yuv.h>
00030 #include <fvutils/statistical/histogram.h>
00031 #include <fvutils/colormap/yuvcm.h>
00032 #include <fvutils/colormap/bayes/bayes_histos_to_lut.h>
00033 #include <core/exception.h>
00034
00035 #include <cmath>
00036
00037 using namespace std;
00038 using namespace fawkes;
00039
00040 namespace firevision {
00041 #if 0
00042 }
00043 #endif
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 BayesColormapGenerator::BayesColormapGenerator(unsigned int lut_depth, hint_t fg_object, unsigned int lut_width, unsigned int lut_height)
00058 {
00059 this->lut_width = lut_width;
00060 this->lut_height = lut_height;
00061 this->lut_depth = lut_depth;
00062
00063 set_fg_object(fg_object);
00064
00065 histos.clear();
00066 fg_histos.clear();
00067 bg_histos.clear();
00068
00069 image_width = image_height = 0;
00070 selection_mask = 0;
00071
00072 bhtl = new BayesHistosToLut(histos, lut_depth, fg_object, lut_width, lut_height);
00073 cm = bhtl->get_colormap();
00074 }
00075
00076
00077
00078 BayesColormapGenerator::~BayesColormapGenerator()
00079 {
00080 for (histo_it = fg_histos.begin(); histo_it != fg_histos.end(); ++histo_it) {
00081 delete histo_it->second;
00082 }
00083
00084 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00085 delete histo_it->second;
00086 }
00087
00088 for (histo_it = histos.begin(); histo_it != histos.end(); ++histo_it) {
00089 delete histo_it->second;
00090 }
00091
00092 delete[] selection_mask;
00093 }
00094
00095
00096
00097
00098
00099 void
00100 BayesColormapGenerator::set_fg_object(hint_t object)
00101 {
00102 if (H_UNKNOWN == object)
00103 { return; }
00104
00105 if ( fg_histos.find(object) == fg_histos.end() ) {
00106 fg_histos[object] = new Histogram(lut_width, lut_height, lut_depth);
00107 bg_histos[object] = new Histogram(lut_width, lut_height, lut_depth, 2);
00108 histos[object] = new Histogram(lut_width, lut_height, lut_depth);
00109 }
00110
00111 fg_object = object;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120 void
00121 BayesColormapGenerator::set_buffer(unsigned char *buffer,
00122 unsigned int width, unsigned int height)
00123 {
00124 this->buffer = buffer;
00125 image_width = width;
00126 image_height = height;
00127
00128 selection_mask = new bool[image_width * image_height];
00129
00130 for (unsigned int i = 0; i < image_width * image_height; ++i) {
00131 selection_mask[i] = false;
00132 }
00133
00134 norm_size = image_width * image_height;
00135 }
00136
00137
00138
00139
00140
00141 YuvColormap *
00142 BayesColormapGenerator::get_current()
00143 {
00144 return cm;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 bool
00154 BayesColormapGenerator::is_in_region(unsigned int x, unsigned int y)
00155 {
00156 return selection_mask[image_width * y + x];
00157 }
00158
00159
00160
00161
00162
00163 void
00164 BayesColormapGenerator::set_selection(vector< rectangle_t > region)
00165 {
00166 this->region = region;
00167
00168 for (unsigned int i = 0; i < image_width * image_height; ++i) {
00169 selection_mask[i] = false;
00170 }
00171
00172 vector<rectangle_t>::iterator it;
00173
00174
00175 for (it = region.begin(); it != region.end(); it++) {
00176 for (unsigned int w = 0; w < (*it).extent.w; ++w) {
00177 for (unsigned int h = 0; h < (*it).extent.h; ++h) {
00178 unsigned int x = (*it).start.x + w;
00179 unsigned int y = (*it).start.y + h;
00180
00181 selection_mask[image_width * y + x] = true;
00182 }
00183 }
00184 }
00185 }
00186
00187
00188
00189
00190
00191
00192 void
00193 BayesColormapGenerator::set_min_probability(float min_prob)
00194 {
00195 bhtl->setMinProbability( min_prob );
00196 }
00197
00198
00199
00200 void
00201 BayesColormapGenerator::consider()
00202 {
00203
00204 if (region.size() == 0) {
00205 cout << "Region empty, cannot consider" << endl;
00206 return;
00207 }
00208
00209 for (histo_it = fg_histos.begin(); histo_it != fg_histos.end(); ++histo_it) {
00210 (*histo_it).second->reset_undo();
00211 }
00212
00213 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00214 (*histo_it).second->reset_undo();
00215 }
00216
00217 unsigned int y;
00218 unsigned int u;
00219 unsigned int v;
00220
00221 for (unsigned int w = 0; w < image_width; ++w) {
00222 for (unsigned int h = 0; h < image_height; ++h) {
00223
00224 y = YUV422_PLANAR_Y_AT(buffer, image_width, w, h);
00225 u = YUV422_PLANAR_U_AT(buffer, image_width, image_height, w, h);
00226 v = YUV422_PLANAR_V_AT(buffer, image_width, image_height, w, h);
00227
00228 unsigned int y_index = (unsigned int)( y / 256.0f * float(lut_depth) );
00229 unsigned int u_index = (unsigned int)( u / 256.0f * float(lut_width) );
00230 unsigned int v_index = (unsigned int)( v / 256.0f * float(lut_height) );
00231
00232 if ( is_in_region(w, h) ) {
00233 fg_histos[fg_object]->inc_value(u_index, v_index, y_index );
00234 } else {
00235 bg_histos[fg_object]->inc_value(u_index, v_index, y_index );
00236 }
00237 }
00238 cout << "." << flush;
00239 }
00240 cout << endl;
00241 }
00242
00243
00244
00245 void
00246 BayesColormapGenerator::calc()
00247 {
00248 normalize_histos();
00249 bhtl->calculateLutValues( false );
00250 }
00251
00252
00253
00254 void
00255 BayesColormapGenerator::undo()
00256 {
00257 for (histo_it = fg_histos.begin(); histo_it != fg_histos.end(); ++histo_it) {
00258 (*histo_it).second->undo();
00259 }
00260
00261 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00262 (*histo_it).second->undo();
00263 }
00264
00265 for (histo_it = histos.begin(); histo_it != histos.end(); ++histo_it) {
00266 (*histo_it).second->undo();
00267 }
00268 }
00269
00270
00271
00272 void
00273 BayesColormapGenerator::reset()
00274 {
00275 for (histo_it = histos.begin(); histo_it != histos.end(); ++histo_it) {
00276 (*histo_it).second->reset();
00277 }
00278
00279 for (histo_it = fg_histos.begin(); histo_it != fg_histos.end(); ++histo_it) {
00280 (*histo_it).second->reset();
00281 }
00282
00283 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00284 (*histo_it).second->reset();
00285 }
00286
00287 cm->reset();
00288
00289 for (unsigned int i = 0; i < image_width * image_height; ++i) {
00290 selection_mask[i] = false;
00291 }
00292 }
00293
00294
00295
00296 void
00297 BayesColormapGenerator::reset_undo()
00298 {
00299 for (histo_it = histos.begin(); histo_it != histos.end(); ++histo_it) {
00300 (*histo_it).second->reset_undo();
00301 }
00302
00303 for (histo_it = fg_histos.begin(); histo_it != fg_histos.end(); ++histo_it) {
00304 (*histo_it).second->reset_undo();
00305 }
00306
00307 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00308 (*histo_it).second->reset_undo();
00309 }
00310 }
00311
00312
00313
00314
00315
00316 bool
00317 BayesColormapGenerator::has_histograms()
00318 {
00319 return true;
00320 }
00321
00322
00323
00324
00325
00326 std::map< hint_t, Histogram * > *
00327 BayesColormapGenerator::get_histograms()
00328 {
00329 return &histos;
00330 }
00331
00332
00333
00334
00335
00336 void
00337 BayesColormapGenerator::load_histograms(const char *filename)
00338 {
00339 HistogramFile histogram_file;
00340 histogram_file.set_owns_blocks(false);
00341 histogram_file.read(filename);
00342
00343 HistogramFile::HistogramBlockList histogram_list = histogram_file.histogram_blocks();
00344 HistogramFile::HistogramBlockList::iterator lit;
00345
00346 for (histo_it = fg_histos.begin(); histo_it != fg_histos.end(); ++histo_it) {
00347 delete histo_it->second;
00348 }
00349 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00350 delete histo_it->second;
00351 }
00352 for (histo_it = histos.begin(); histo_it != histos.end(); ++histo_it) {
00353 delete histo_it->second;
00354 }
00355 fg_histos.clear();
00356 bg_histos.clear();
00357 histos.clear();
00358
00359
00360 HistogramBlock* bg_histogram_block = NULL;
00361 for (lit = histogram_list.begin(); lit != histogram_list.end(); ++lit)
00362 {
00363 if ( (*lit)->object_type() == H_BACKGROUND )
00364 {
00365 bg_histogram_block = *lit;
00366 lut_width = bg_histogram_block->width();
00367 lut_height = bg_histogram_block->height();
00368 lut_depth = bg_histogram_block->depth();
00369
00370 break;
00371 }
00372 }
00373
00374 if ( !bg_histogram_block )
00375 {
00376 throw fawkes::Exception("Histograms file does not contain a background histogram");
00377 }
00378
00379
00380 norm_size = 0;
00381 for (lit = histogram_list.begin(); lit != histogram_list.end(); ++lit)
00382 {
00383 hint_t cur_object = (*lit)->object_type();
00384
00385 if (cur_object == H_BACKGROUND)
00386 { continue; }
00387
00388 fg_histos[cur_object] = new Histogram(*lit);
00389 bg_histos[cur_object] = new Histogram(bg_histogram_block);
00390
00391 norm_size += fg_histos[cur_object]->get_sum();
00392 }
00393
00394 norm_size += bg_histos.begin()->second->get_sum();
00395
00396
00397 HistogramMap::iterator hit;
00398 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00399 hint_t cur_object = histo_it->first;
00400
00401 for (hit = fg_histos.begin(); hit != fg_histos.end(); ++hit) {
00402 if (cur_object == hit->first)
00403 { continue; }
00404
00405 for (unsigned int x = 0; x < lut_width; ++x) {
00406 for (unsigned int y = 0; y < lut_height; ++y) {
00407 for (unsigned int z = 0; z < lut_depth; ++z) {
00408 unsigned int val = hit->second->get_value(x, y, z);
00409 histo_it->second->add(x, y, z, val);
00410 }
00411 }
00412 }
00413 }
00414 }
00415
00416
00417 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++histo_it) {
00418 hint_t cur_object = histo_it->first;
00419 float factor = ( norm_size - fg_histos[cur_object]->get_sum() ) / float( histo_it->second->get_sum() );
00420
00421 if (factor == 1.0)
00422 { continue; }
00423
00424 for (unsigned int x = 0; x < lut_width; ++x) {
00425 for (unsigned int y = 0; y < lut_height; ++y) {
00426 for (unsigned int z = 0; z < lut_depth; ++z) {
00427 unsigned int cur_val = histo_it->second->get_value(x, y, z);
00428 unsigned int new_val = (unsigned int) rint(factor * cur_val);
00429 histo_it->second->set_value(x, y, z, new_val);
00430 }
00431 }
00432 }
00433 }
00434
00435 delete bhtl;
00436 bhtl = new BayesHistosToLut(histos, lut_depth, H_UNKNOWN, lut_width, lut_height);
00437 cm = bhtl->get_colormap();
00438
00439
00440 calc();
00441 }
00442
00443
00444
00445
00446
00447 void
00448 BayesColormapGenerator::save_histograms(const char *filename)
00449 {
00450 HistogramFile histogram_file;
00451 histogram_file.set_owns_blocks(false);
00452 HistogramBlock *histogram_block;
00453
00454 normalize_histos();
00455
00456 for (histo_it = histos.begin(); histo_it != histos.end(); ++histo_it)
00457 {
00458 histogram_block = histo_it->second->get_histogram_block();
00459 histogram_block->set_object_type( histo_it->first );
00460 histogram_file.add_histogram_block(histogram_block);
00461 }
00462
00463 histogram_file.write(filename);
00464 }
00465
00466
00467
00468 void
00469 BayesColormapGenerator::normalize_histos()
00470 {
00471 for (histo_it = histos.begin(); histo_it != histos.end(); ++histo_it) {
00472 delete histo_it->second;
00473 }
00474 histos.clear();
00475
00476 unsigned int fg_size = 0;
00477 unsigned int hval;
00478 float norm_factor;
00479
00480
00481 for (histo_it = fg_histos.begin(); histo_it != fg_histos.end(); ++histo_it)
00482 {
00483 hint_t cur_object = histo_it->first;
00484
00485 if ( bg_histos.find(cur_object) == bg_histos.end() ) {
00486 throw fawkes::Exception("Corresponding background histogram is missing");
00487 }
00488
00489 Histogram *fg = fg_histos[cur_object];
00490 Histogram *bg = bg_histos[cur_object];
00491
00492 unsigned int fg_sum = fg->get_sum();
00493 unsigned int bg_sum = bg->get_sum();
00494
00495 if ( (fg_sum + bg_sum) == 0 )
00496 { continue; }
00497
00498 Histogram *h = new Histogram(lut_width, lut_height, lut_depth);
00499 histos[cur_object] = h;
00500
00501 norm_factor = norm_size / float(fg_sum + bg_sum);
00502
00503 for (unsigned int x = 0; x < lut_width; ++x) {
00504 for (unsigned int y = 0; y < lut_height; ++y) {
00505 for (unsigned int z = 0; z < lut_depth; ++z) {
00506 hval = (unsigned int) rint(float(fg->get_value(x, y, z)) * norm_factor);
00507 h->set_value(x, y, z, hval);
00508 }
00509 }
00510 }
00511
00512 fg_size += h->get_sum();
00513 }
00514
00515
00516 Histogram *bh = new Histogram(lut_width, lut_height, lut_depth);
00517 histos[H_BACKGROUND] = bh;
00518 for (histo_it = bg_histos.begin(); histo_it != bg_histos.end(); ++ histo_it)
00519 {
00520 hint_t cur_object = histo_it->first;
00521
00522 Histogram *fg = fg_histos[cur_object];
00523 Histogram *bg = bg_histos[cur_object];
00524
00525 unsigned int fg_sum = fg->get_sum();
00526 unsigned int bg_sum = bg->get_sum();
00527
00528 if ( (fg_sum + bg_sum) == 0 )
00529 { continue; }
00530
00531 norm_factor = norm_size / float(fg_sum + bg_sum);
00532
00533 for (unsigned int x = 0; x < lut_width; ++x) {
00534 for (unsigned int y = 0; y < lut_height; ++y) {
00535 for (unsigned int z = 0; z < lut_depth; ++z) {
00536
00537 hval = (unsigned int) rint( float(bg->get_value(x, y, z)) * norm_factor);
00538 bh->add(x, y, z, hval);
00539
00540
00541 std::map< hint_t, Histogram * >::iterator hit;
00542 for (hit = histos.begin(); hit != histos.end(); ++hit) {
00543 if (hit->first == cur_object || hit->first == H_BACKGROUND)
00544 { continue; }
00545
00546 hval = hit->second->get_value(x, y, z);
00547 bh->sub(x, y, z, hval);
00548 }
00549 }
00550 }
00551 }
00552 }
00553
00554
00555 norm_factor = (norm_size - fg_size) / float( bh->get_sum() );
00556
00557 for (unsigned int x = 0; x < lut_width; ++x) {
00558 for (unsigned int y = 0; y < lut_height; ++y) {
00559 for (unsigned int z = 0; z < lut_depth; ++z) {
00560 hval = (unsigned int) rint( float(bh->get_value(x, y, z)) * norm_factor );
00561 bh->set_value(x, y, z, hval);
00562 }
00563 }
00564 }
00565 }
00566
00567 }