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