00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021 #include <highgui.h>
00022 #include <fstream>
00023
00024 #include "vobj_tracker_view.h"
00025 #include <QDir>
00026 #include <QInputDialog>
00027 #include <map>
00028 #include <polyora/timer.h>
00029 #include <math.h>
00030 #include <QTextEdit>
00031
00032 #ifndef M_2PI
00033 #define M_2PI 6.283185307179586476925286766559f
00034 #endif
00035 #ifndef M_PI
00036 #define M_PI 3.141592653589793238462643383279f
00037 #endif
00038
00039 using namespace std;
00040
00041 const int fps_stat_bin_size=20;
00042
00043 void gl_hash_mark(unsigned code, float x, float y, float orient=0, float r = 5);
00044
00045
00046 using namespace std;
00047 vobj_tracker_view::vobj_tracker_view(QWidget *parent, const char *name, VideoSource *vs)
00048 : GLBox(parent, name), vs(vs), database(id_cluster_collection::QUERY_IDF_NORMALIZED)
00049 {
00050 timer=startTimer(0);
00051 filter = false;
00052 record=false;
00053 record_movie=false;
00054 viewScores=false;
00055 learning = true;
00056
00057 tree_fn = 0;
00058 clusters_fn = "clusters.bin";
00059 descriptors_fn = "descriptors.dat";
00060 visual_db_fn = "visual.db";
00061
00062 help_window=0;
00063
00064
00065
00066 nb_missing_frames=0;
00067 auto_index = false;
00068
00069 nbLev = 10;
00070 tracker=0;
00071 frameCnt=0;
00072 frameno=0;
00073 threshold = .06;
00074 im=im2=0;
00075
00076 draw_flags = DRAW_COLOR | DRAW_INSTANCE;
00077
00078 int w,h;
00079 if (vs) {
00080 int w,h;
00081 vs->getSize(w,h);
00082
00083 resize(w,h);
00084
00085 while ((h/(1<<nbLev)) < 16) {
00086 nbLev--;
00087 }
00088 std::cout << "Video source: " << w << "x"<<h<<", working with " << nbLev << " levels.\n";
00089
00090 im = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 3);
00091 im2 = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 3);
00092 vs->getFrame(im);
00093 vs->start();
00094 setImage(im);
00095 }
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 vobj_tracker_view::~vobj_tracker_view() {
00108
00109 if (im) cvReleaseImage(&im);
00110 if (im2) cvReleaseImage(&im2);
00111 if (vs) delete vs;
00112 if (tracker) delete tracker;
00113 if (help_window) delete help_window;
00114 }
00115
00116 void vobj_tracker_view::timerEvent(QTimerEvent *) {
00117
00118
00119 if (im==0) return;
00120 createTracker();
00121
00122 TaskTimer::pushTask("main loop");
00123
00124 makeCurrent();
00125
00126 float fps=0;
00127 int ms = qtime.elapsed();
00128 if (frameCnt>0 && ms > 500) {
00129 ms = qtime.restart();
00130 fps = 1000.0f*frameCnt / ms;
00131 frameCnt=0;
00132 char str[512];
00133 sprintf(str,"Visual Object Tracker, Julien Pilet, %3.1f fps", fps);
00134 setWindowTitle(str);
00135 }
00136
00137 static int n=0;
00138 if (vs) {
00139 int w,h;
00140 vs->getSize(w,h);
00141 int lastId = vs->getId();
00142
00143
00144 TaskTimer::pushTask("Fetch frame");
00145 swap(im,im2);
00146 vs->getFrame(im);
00147
00148 if (lastId > vs->getId()) {
00149
00150 summary();
00151 close();
00152 return;
00153 }
00154
00155 frameCnt++;
00156 IplImage *frame = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 1);
00157 cvCvtColor(im,frame,CV_BGR2GRAY);
00158
00159 TaskTimer::popTask();
00160
00161 makeCurrent();
00162
00163 QTime frame_processing;
00164 frame_processing.restart();
00165 float frame_processing_time=0;
00166
00167 TaskTimer::pushTask("Process frame");
00168 vobj_frame *pframe = static_cast<vobj_frame *>(tracker->process_frame_pipeline(frame));
00169
00170 if (pframe)
00171 setImage(pframe->pyr->images[0]);
00172
00173
00174 tracker->remove_unmatched_tracks(tracker->get_nth_frame(2));
00175 tracks::frame_iterator it = tracker->get_nth_frame_it(512);
00176 tracker->remove_frame(it);
00177
00178 frame_processing_time = frame_processing.elapsed();
00179 if (pframe) update_fps_stat(frame_processing_time, pframe);
00180
00181 if (record) {
00182 char fn[256];
00183 sprintf(fn,"out/frame%04d.bmp", n++);
00184 renderAndSave(fn, im->width, im->height);
00185
00186 }
00187
00188 TaskTimer::popTask();
00189
00190 update();
00191
00192 if (record_movie) {
00193 char fn[256];
00194 sprintf(fn,"out/frame%04d.bmp", frameno++);
00195 renderAndSave(fn,0,0);
00196 }
00197
00198 }
00199 TaskTimer::popTask();
00200 }
00201
00202 void vobj_tracker_view::update_fps_stat(float fr_ms, pyr_frame *pframe)
00203 {
00204 unsigned hbin = pframe->points.size() / fps_stat_bin_size;
00205 fps_stat_map::iterator it(fps_stat.find(hbin));
00206 if (it != fps_stat.end()) {
00207 it->second.first = (it->second.second*it->second.first + fr_ms) / (it->second.second+1);
00208 it->second.second++;
00209 } else {
00210 fps_stat[hbin] = pair<double,unsigned>(fr_ms,1);
00211 }
00212 }
00213
00214
00215 void vobj_tracker_view::saveCurrentFrame(const char *filename)
00216 {
00217 cvSaveImage(filename, image);
00218 }
00219
00220 static inline bool toggle(unsigned &flags, unsigned bit) { return flags = flags ^ bit; }
00221
00222 static const char *help =
00223 "Key mapping:\n"
00224 "--- Database editing ---\n"
00225 "h - add current view as a new planar object\n"
00226 "backspace - delete visible object(s) from DB\n"
00227 "i - toggle incremental learning\n"
00228 "\n--- Video/Processing control ---\n"
00229 "tab - pause/resume video input\n"
00230 "space - pause/resume processing\n"
00231 "\n--- Display ---\n"
00232 "f: toggle fullscreen display\n"
00233 "1: Display key points\n"
00234 "2: Display tracks\n"
00235 "3: Show matched points\n"
00236 "4: Show augmented reality result\n"
00237 "g: toggle augmented reality display\n"
00238 "c: toggles gray/color display\n"
00239 "d: toggles image darkening for better constrast\n"
00240 "m: show/hide matches\n"
00241 "\n--- Miscellaneous ---\n"
00242 "s: save a screen shot as 'shot0000.png'\n"
00243 "q: quit the program\n"
00244 "z: reset view\n";
00245
00246 void vobj_tracker_view::show_help()
00247 {
00248 if (help_window==0) {
00249 QMessageBox *box = new QMessageBox(QMessageBox::NoIcon,
00250 "Visual Object Tracker Help", help,
00251 QMessageBox::Ok, this,
00252 Qt::Dialog);
00253 box->resize(100,600);
00254 help_window = box;
00255 }
00256 help_window->show();
00257 help_window->raise();
00258 help_window->activateWindow();
00259 }
00260
00261 void vobj_tracker_view::keyPressEvent(QKeyEvent *k)
00262 {
00263 static int n=0;
00264 char fn[256];
00265 vobj_frame *frame = (vobj_frame *) tracker->get_nth_frame(0);
00266
00267 switch (k->key()) {
00268 case Qt::Key_1: draw_flags = DRAW_COLOR|DRAW_TRACKS; break;
00269 case Qt::Key_2: draw_flags = DRAW_COLOR|DRAW_KEYPOINTS|DRAW_DARK; break;
00270 case Qt::Key_3: draw_flags = DRAW_COLOR|DRAW_MATCHES|DRAW_DARK; break;
00271 case Qt::Key_4: draw_flags = DRAW_COLOR|DRAW_INSTANCE; break;
00272 case Qt::Key_C: toggle(draw_flags, DRAW_COLOR); break;
00273 case Qt::Key_D: toggle(draw_flags, DRAW_DARK); break;
00274
00275 case Qt::Key_S: sprintf(fn,"shot%04d.png", n++); renderAndSave(fn, im->width*2, im->height); break;
00276 case Qt::Key_Tab: if (vs->isPlaying()) vs->stop(); else vs->start(); break;
00277 case Qt::Key_R: record = !record; break;
00278 case Qt::Key_I: tracker->use_incremental_learning = !tracker->use_incremental_learning; break;
00279 case Qt::Key_Backspace: tracker->remove_visible_objects_from_db(frame); break;
00280
00281
00282
00283
00284
00285
00286
00287 case Qt::Key_G: toggle(draw_flags, DRAW_INSTANCE); break;
00288 case Qt::Key_F: if (isFullScreen()) showNormal(); else showFullScreen(); break;
00289
00290 case Qt::Key_M: if(k->modifiers() & Qt::ShiftModifier) {
00291 record_movie = !record_movie;
00292 } else {
00293 toggle(draw_flags, DRAW_MATCHES);
00294 }
00295
00296
00297
00298
00299
00300
00301 break;
00302
00303
00304
00305
00306
00307
00308
00309 case Qt::Key_Space: if (timer) {killTimer(timer); timer=0; }
00310 else { timer = startTimer(0); } break;
00311 case Qt::Key_Q: summary(); close(); break;
00312 case Qt::Key_Escape: selected_kpt=0; break;
00313
00314
00315 case Qt::Key_H: add_current_frame_to_db("Interactive, homography checking", visual_object::VERIFY_HOMOGRAPHY); break;
00316 case Qt::Key_Plus: threshold += .005; cout << "T=" << threshold << endl; break;
00317 case Qt::Key_Minus: threshold -= .005; cout << "T=" << threshold << endl; break;
00318 case Qt::Key_Z: zoom(1,1); translate(0,0); resize(frame->pyr->images[0]->width, frame->pyr->images[0]->height); break;
00319 default: if ((k->key()>= Qt::Key_F1 && k->key()<=Qt::Key_F12) || k->text().size() > 0)
00320 show_help();
00321 }
00322 update();
00323 }
00324
00325
00326
00327 void vobj_tracker_view::add_current_frame_to_db(const char *name, int flags)
00328 {
00329 pyr_frame *frame = (pyr_frame *)tracker->get_nth_frame(0);
00330
00331 cout << "Adding object " << name << endl;
00332 visual_object *obj = database.create_object(name, flags);
00333 obj->add_frame(frame);
00334 obj->prepare();
00335 database.add_to_index(obj);
00336 add_frame_time.restart();
00337 }
00338
00339 bool vobj_tracker_view::selectKeypoint(QMouseEvent *event)
00340 {
00341 point2d c;
00342 screenToImageCoord(event->x(), event->y(), &c.u, &c.v);
00343
00344 pyr_frame *frame = (pyr_frame *) tracker->get_nth_frame(0);
00345
00346 bucket2d<tkeypoint>::iterator it = frame->points.search(c.u,c.v,5);
00347 if (it.end()) return false;
00348
00349 float dist = c.dist(*it.elem());
00350 bucket2d<tkeypoint>::iterator best = it;
00351 for(++it; !it.end(); ++it) {
00352 float d= c.dist(*it.elem());
00353 if (d<dist) {
00354 dist = d;
00355 best = it;
00356 }
00357 }
00358 selected_kpt = (pyr_keypoint *) best.elem();
00359 show_track(selected_kpt);
00360
00361 return true;
00362 }
00363
00364 void vobj_tracker_view::mouseDoubleClickEvent ( QMouseEvent * ) {
00365 selected_kpt=0;
00366 update();
00367 }
00368
00369 void vobj_tracker_view::mousePressEvent ( QMouseEvent * event )
00370 {
00371 switch (event->button()) {
00372 case Qt::LeftButton:
00373 if (!selected_kpt) {
00374 selectKeypoint(event);
00375 }
00376 break;
00377 default:
00378 break;
00379 }
00380 GLBox::mousePressEvent(event);
00381 update();
00382 }
00383
00384 void vobj_tracker_view::mouseReleaseEvent ( QMouseEvent * event )
00385 {
00386 GLBox::mouseReleaseEvent(event);
00387 }
00388
00389 void draw_keypoint(pyr_keypoint *k) {
00390 float x = k->u;
00391 float y = k->v;
00392 float angle = k->descriptor.orientation;
00393 float len=5 + (2 << k->scale);
00394 float dx = len * cosf(angle);
00395 float dy = len * sinf(angle);
00396
00397 if (k->cid) {
00398 gl_hash_mark(k->cid, k->u, k->v, k->descriptor.orientation, len);
00399 } else {
00400 glBegin(GL_LINES);
00401 glVertex2f(x,y);
00402 glVertex2f(x+dx,y+dy);
00403 glVertex2f(x-dy/4,y+dx/4);
00404 glVertex2f(x+dy/4,y-dx/4);
00405 glEnd();
00406 }
00407 }
00408
00409 void vobj_tracker_view::createTracker()
00410 {
00411 if (tracker==0) {
00412 if (im==0) return;
00413
00414
00415 makeCurrent();
00416 cout << "Loading object db..." << flush;
00417 database.open(visual_db_fn);
00418 cout << "done.\n";
00419 tracker = new vobj_tracker(im->width,im->height,nbLev, (int)(16), &database, true);
00420 tracker->use_incremental_learning = learning;
00421
00422 if (tree_fn) {
00423
00424 if (tracker->load_tree(tree_fn)) {
00425 cout << tree_fn << ": tree has " << tracker->tree->count_leafs() << " leafs.\n";
00426 if (tracker->load_clusters(clusters_fn))
00427 cout << clusters_fn << ": clusters loaded.\n";
00428 }
00429 } else {
00430
00431 cout << "Loading tree from db..." << flush;
00432 if (tracker->load_tree(database.get_sqlite3_db())) {
00433 cout << "done, loaded " << tracker->tree->count_leafs() << " leafs.\n";
00434 } else {
00435 cout << "failed\n";
00436 }
00437 cout << "Loading clusters from db..." << flush;
00438 if (tracker->load_clusters(database.get_sqlite3_db())) {
00439 cout << "done.\n";
00440 } else {
00441 cout << "failed.\n";
00442 }
00443 }
00444 cout << "Ready. Press F1 for help.\n";
00445 }
00446 }
00447
00448 static void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v )
00449 {
00450 int i;
00451 float f, p, q, t;
00452
00453 if( s == 0 ) {
00454
00455 *r = *g = *b = v;
00456 return;
00457 }
00458
00459 h /= 60;
00460 i = floor( h );
00461 f = h - i;
00462 p = v * ( 1 - s );
00463 q = v * ( 1 - s * f );
00464 t = v * ( 1 - s * ( 1 - f ) );
00465
00466 switch( i ) {
00467 case 0: *r = v; *g = t; *b = p; break;
00468 case 1: *r = q; *g = v; *b = p; break;
00469 case 2: *r = p; *g = v; *b = t; break;
00470 case 3: *r = p; *g = q; *b = v; break;
00471 case 4: *r = t; *g = p; *b = v; break;
00472 default:
00473 *r = v; *g = p; *b = q; break;
00474 }
00475 }
00476
00477 static void gl_hash_color(unsigned key)
00478 {
00479 float c[3];
00480 HSVtoRGB(c,c+1,c+2, fmod((float)key, 360), 1, 1);
00481 glColor3fv(c);
00482 }
00483
00484 void gl_hash_mark(unsigned code, float x, float y, float orient, float r)
00485 {
00486
00487
00488 unsigned char c = (code^(code>>8)^(code>>16)^(code>>24))&0xff;
00489 int n = 4 + (c&0x7);
00490 float f = 1.5f + ((c>>3)&0x3)/2.0f;
00491
00492 float step_angle = M_PI*2.0f/n;
00493 float angle=orient;
00494
00495 glBegin(GL_LINE_STRIP);
00496
00497 for (int i=0; i<n; i++) {
00498
00499 float r2 = (i&1 ? r*f : r);
00500 float sin = sinf(angle);
00501 float cos = cosf(angle);
00502 angle+=step_angle;
00503
00504 glVertex2f(x+r2*cos,y+r2*sin);
00505 }
00506 float sin = sinf(angle);
00507 float cos = cosf(angle);
00508 glVertex2f(x+r*cos,y+r*sin);
00509
00510 glEnd();
00511 }
00512
00513 void vobj_tracker_view::draw_selected_track()
00514 {
00515 if (!selected_kpt) return;
00516
00517
00518 tracks::keypoint_match_iterator it(selected_kpt);
00519 while (it.elem()->matches.next) ++it;
00520 tracks::keypoint_match_iterator first(it);
00521
00522 pyr_frame *frame = (pyr_frame *) tracker->get_nth_frame(0);
00523
00524 if (it.elem()->frame != frame) {
00525 glColor4f(1,0,0,1);
00526 selected_kpt=0;
00527 } else {
00528 glColor4f(0,1,0,1);
00529 }
00530
00531 for (it=first; !it.end(); --it) {
00532 pyr_keypoint *p = (pyr_keypoint *)it.elem();
00533 draw_keypoint(p);
00534 }
00535
00536 float r = 16;
00537 point2d pos(0,image->height);
00538 for (it=first; !it.end(); --it) {
00539 #ifndef WITH_SURF
00540 pyr_keypoint *k = (pyr_keypoint *) it.elem();
00541
00542 if (k->node) {
00543 CvMat mat; cvInitMatHeader(&mat, patch_tagger::patch_size, patch_tagger::patch_size, CV_32FC1,
00544 k->node->mean.mean);
00545 point2d pos_down(pos.u, pos.v+r);
00546 draw_icon(&pos_down, &mat, r, r, image->width, 0, r);
00547 }
00548 draw_icon(&pos, &k->descriptor.rotated, r, r, image->width, 0, r);
00549 #endif
00550 }
00551 glPopMatrix();
00552 glPopMatrix();
00553 }
00554
00555 void vobj_tracker_view::draw_icon(point2d *c, CvArr *image, float w, float h, float max_width, int margin_x, int margin_y)
00556 {
00557 if (!image) return;
00558
00559 if (icon_texture_available.begin() == icon_texture_available.end()) {
00560 IplTexture t;
00561 icon_texture_available.push_back(t);
00562 }
00563 icon_texture_used.splice(icon_texture_used.begin(), icon_texture_available, icon_texture_available.begin());
00564 IplTexture &t(icon_texture_used.front());
00565 CvMat m;
00566 t.setImage( cvGetMat(image, &m));
00567 glColor4f(1,1,1,1);
00568 t.drawQuad(c->u, c->v, w, h);
00569 c->u += w + margin_x;
00570 if (c->u>=max_width) {
00571 c->u = 0;
00572 c->v += h + margin_y;
00573 }
00574 }
00575
00576 void vobj_tracker_view::draw_all_tracks(pyr_frame *frame)
00577 {
00578 glColor4f(0,1,0,1);
00579
00580 for (tracks::keypoint_frame_iterator it(frame->points.begin()); !it.end(); ++it) {
00581 pyr_keypoint *k = (pyr_keypoint *) it.elem();
00582
00583 if (k->track_is_longer(2)) {
00584 glBegin(GL_LINE_STRIP);
00585
00586 int n=0;
00587
00588
00589 for (tracks::keypoint_match_iterator it(k); !it.end(); --it) {
00590 pyr_keypoint *p = (pyr_keypoint *)it.elem();
00591
00592 float alpha = 1.0f-(n++)/256.0f;
00593 glColor4f(0,1,0,alpha);
00594 glVertex2f(p->u, p->v);
00595 }
00596 glEnd();
00597 }
00598 }
00599 }
00600
00601 void vobj_tracker_view::draw_keypoints(pyr_frame *frame)
00602 {
00603 for (tracks::keypoint_frame_iterator it(frame->points.begin()); !it.end(); ++it) {
00604 pyr_keypoint *k = (pyr_keypoint *) it.elem();
00605
00606
00607
00608 glColor4f(0,1,0,.5);
00609 draw_keypoint(k);
00610
00611 }
00612 }
00613
00614 void vobj_tracker_view::draw_entry_image(visual_object *entry)
00615 {
00616 if (!entry) return;
00617
00618 IplImage *entry_image = database.get_image(entry->representative_image);
00619 entry_tex.setImage(entry_image);
00620
00621 if (entry_image)
00622 entry_tex.drawQuad(entry_image->width,0);
00623 }
00624
00625 void vobj_tracker_view::draw_matches(vobj_frame *frame)
00626 {
00627 for (tracks::keypoint_frame_iterator it(frame->points.begin()); !it.end(); ++it) {
00628 vobj_keypoint *k = (vobj_keypoint *) it.elem();
00629
00630
00631
00632 if (k->vobj) {
00633 vobj_keypoint *prevk = k->prev_match_vobj();
00634 if (prevk && prevk->vobj == k->vobj)
00635 glColor4f(0,1,0,1);
00636 else
00637 glColor4f(1,0,0,1);
00638 gl_hash_mark((int)(((long)k->vobj)&0xFFFFFFFF), k->u, k->v, k->descriptor.orientation, 3);
00639 }
00640
00641 }
00642 }
00643
00644 static void setupHomography(const float H[3][3])
00645 {
00646 float m[4][4];
00647
00648
00649 m[0][0]=H[0][0]; m[1][0]=H[0][1]; m[2][0]=0; m[3][0]=H[0][2];
00650 m[0][1]=H[1][0]; m[1][1]=H[1][1]; m[2][1]=0; m[3][1]=H[1][2];
00651 m[0][2]=0; m[1][2]=0; m[2][2]=1; m[3][2]=0;
00652 m[0][3]=H[2][0]; m[1][3]=H[2][1]; m[2][3]=0; m[3][3]=H[2][2];
00653
00654 glMultMatrixf(&m[0][0]);
00655
00656 }
00657
00658 GLuint vobj_tracker_view::get_texture_for_obj(visual_object *obj)
00659 {
00660 GLuint texture=0;
00661 static QStringList textures;
00662
00663 if (textures.size()==0) {
00664 QDir texdir("textures");
00665 QStringList filters;
00666 filters << "*.dds";
00667 texdir.setNameFilters(filters);
00668 textures = texdir.entryList();
00669 cout << "Found " << textures.size() << " dds files.\n";
00670 }
00671
00672 if (textures.size()>0) {
00673 unsigned long id = obj->get_id();
00674 unsigned long texno = id % textures.size();
00675
00676 texture = bindTexture("textures/"+textures[texno]);
00677 }
00678 return texture;
00679 }
00680
00681 void vobj_tracker_view::homography_augment(visual_object *obj, float H[3][3])
00682 {
00683 glMatrixMode(GL_MODELVIEW);
00684 glPushMatrix();
00685 setupHomography(H);
00686
00687 const int n=9;
00688 const int skip=2;
00689 float dx = image->width/n;
00690 float dy = image->height/n;
00691
00692 GLuint texture=get_texture_for_obj(obj);
00693 glEnable(GL_BLEND);
00694 if (texture) {
00695 glEnable(GL_TEXTURE_2D);
00696 glBindTexture(GL_TEXTURE_2D, texture);
00697 glColor4f(1,1,1,1);
00698 glBegin(GL_QUADS);
00699 glTexCoord2f(0,0);
00700 glVertex2f(skip*dx, skip*dy);
00701 glTexCoord2f(1,0);
00702 glVertex2f((n-skip)*dx, skip*dy);
00703 glTexCoord2f(1,1);
00704 glVertex2f((n-skip)*dx, (n-skip)*dy);
00705 glTexCoord2f(0,1);
00706 glVertex2f(skip*dx, (n-skip)*dy);
00707 glEnd();
00708 glDisable(GL_TEXTURE_2D);
00709 } else {
00710 glEnable(GL_LINE_SMOOTH);
00711 glColor4f(1,1,1,1);
00712 glBegin(GL_LINES);
00713 for (int i=skip; i<=(n-skip); i++) {
00714 glVertex2f(i*dx, skip*dy);
00715 glVertex2f(i*dx, (n-skip)*dy);
00716 glVertex2f(skip*dx, i*dy);
00717 glVertex2f((n-skip)*dx, i*dy);
00718 }
00719 glEnd();
00720 }
00721
00722 glPopMatrix();
00723 }
00724
00725 void vobj_tracker_view::draw_instances(vobj_frame *frame)
00726 {
00727 for (vobj_instance_vector::iterator it(frame->visible_objects.begin());
00728 it != frame->visible_objects.end(); ++it)
00729 {
00730 if (it->object->get_flags() & visual_object::VERIFY_HOMOGRAPHY) {
00731 homography_augment(it->object, it->transform);
00732 }
00733 }
00734 }
00735
00736 void vobj_tracker_view::paintGL()
00737 {
00738 TaskTimer::pushTask("Display");
00739
00740 #ifdef WITH_SIFTGPU
00741 glDisable(GL_TEXTURE_RECTANGLE_ARB);
00742 #endif
00743 icon_texture_available.splice(icon_texture_available.begin(), icon_texture_used);
00744
00745 glDisable(GL_DEPTH_TEST);
00746 resizeGL(width(),height());
00747
00748 if (draw_flags & DRAW_DARK) glColor4f(.5,.5,.5,1);
00749 else glColor4f(1,1,1,1);
00750
00751 if (draw_flags & DRAW_COLOR)
00752 setImage(im2);
00753
00754 GLBox::paintGL();
00755
00756 if (tracker==0) {
00757 TaskTimer::popTask();
00758 return;
00759 }
00760
00761 int t = add_frame_time.elapsed();
00762 if (t>0 && t< 1200) {
00763 GLuint tex = bindTexture("add_frame.dds");
00764 if (tex) {
00765 glColor4f(1,1,1,1);
00766 glEnable(GL_BLEND);
00767 glEnable(GL_TEXTURE_2D);
00768 glBindTexture(GL_TEXTURE_2D, tex);
00769 glBegin(GL_QUADS);
00770 glTexCoord2f(0,0);
00771 glVertex2f(10,10);
00772 glTexCoord2f(1,0);
00773 glVertex2f(256,10);
00774 glTexCoord2f(1,1);
00775 glVertex2f(256,64);
00776 glTexCoord2f(0,1);
00777 glVertex2f(10,64);
00778 glEnd();
00779 }
00780 }
00781
00782 vobj_frame *frame = (vobj_frame *) tracker->get_nth_frame(0);
00783 if (!frame) {
00784 TaskTimer::popTask();
00785 return;
00786 }
00787
00788 glEnable(GL_BLEND);
00789 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00790
00791 setAxisUp(false);
00792 setImageSpace();
00793
00794
00795 if (draw_flags & DRAW_MATCHES)
00796 draw_matches(frame);
00797
00798 if (draw_flags & DRAW_INSTANCE)
00799 draw_instances(frame);
00800
00801 if (draw_flags & DRAW_KEYPOINTS)
00802 draw_keypoints(frame);
00803
00804 if (draw_flags & DRAW_TRACKS)
00805 draw_all_tracks(frame);
00806
00807 glDisable(GL_BLEND);
00808 glEnable(GL_DEPTH_TEST);
00809 #ifdef WITH_SIFTGPU
00810 glEnable(GL_TEXTURE_RECTANGLE_ARB);
00811 #endif
00812 TaskTimer::popTask();
00813 }
00814
00815 void vobj_tracker_view::show_track(pyr_keypoint *k)
00816 {
00817
00818 std::map<unsigned, unsigned> map, cmap;
00819 int track_len= 0;
00820 if (k->track) track_len = k->track->length;
00821 cout << "Track has " << track_len << " frames:\n";
00822 for (tracks::keypoint_match_iterator it(k); !it.end(); --it) {
00823 pyr_keypoint *p = (pyr_keypoint *)it.elem();
00824 cout << " " << p->id << ":" << p->cid << "("<<p->cscore<<")";
00825
00826 std::map<unsigned, unsigned>::iterator id_it = map.find(p->id);
00827 if (id_it == map.end()) map[p->id] = 1;
00828 else id_it->second++;
00829
00830 id_it = cmap.find(p->cid);
00831 if (id_it == cmap.end()) cmap[p->cid] = 1;
00832 else id_it->second++;
00833
00834 }
00835 cout << endl << "ID histogram:\n";
00836
00837 for (std::map<unsigned,unsigned>::iterator id_it = map.begin();
00838 id_it != map.end(); ++id_it)
00839 {
00840 cout << " id:" << id_it->first << " on " << id_it->second << " frames.\n";
00841 }
00842 if (k->track) {
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 float d;
00853 pyr_track *track = (pyr_track *) k->track;
00854 if (tracker->id_clusters) {
00855 id_cluster *c = tracker->id_clusters->get_best_cluster(&track->id_histo.query_cluster, &d);
00856 cout << "Best cluster: " << c->id << " score= " << d << endl;
00857 }
00858 } else {
00859 cout << "pointer to track is 0\n";
00860 }
00861
00862 for (std::map<unsigned,unsigned>::iterator id_it = cmap.begin();
00863 id_it != cmap.end(); ++id_it)
00864 {
00865 cout << " cid:" << id_it->first << " on " << id_it->second << " frames.\n";
00866 }
00867
00868
00869 }
00870
00871 void vobj_tracker_view::show_tracks()
00872 {
00873 int t=1;
00874 pyr_frame *frame = (pyr_frame *) tracker->get_nth_frame(0);
00875
00876 std::map<unsigned, unsigned> full_map;
00877
00878 for (tracks::keypoint_frame_iterator it(frame->points.begin()); !it.end(); ++it) {
00879 pyr_keypoint *k = (pyr_keypoint *) it.elem();
00880
00881 if (k->track_is_longer(10)) {
00882
00883
00884 std::map<unsigned, unsigned> map;
00885 int track_len=0;
00886 for (tracks::keypoint_match_iterator it(k); !it.end(); --it) {
00887 pyr_keypoint *p = (pyr_keypoint *)it.elem();
00888 std::map<unsigned, unsigned>::iterator id_it = map.find(p->id);
00889 if (id_it == map.end())
00890 map[p->id] = 1;
00891 else
00892 id_it->second++;
00893
00894 track_len++;
00895 }
00896 cout << "Track " << t++ << " " << track_len << " frames:\n";
00897 for (std::map<unsigned,unsigned>::iterator id_it = map.begin();
00898 id_it != map.end(); ++id_it)
00899 {
00900 cout << " id:" << id_it->first << " on " << id_it->second << " frames.\n";
00901 std::map<unsigned, unsigned>::iterator f_it = full_map.find(id_it->first);
00902 if (f_it == full_map.end())
00903 full_map[id_it->first] = id_it->second;
00904 else
00905 f_it->second += id_it->second;
00906
00907 }
00908 }
00909 }
00910
00911 cout << "total, " << full_map.size() << " different ids detected:\n";
00912 for (std::map<unsigned,unsigned>::iterator id_it = full_map.begin();
00913 id_it != full_map.end(); ++id_it)
00914 {
00915 cout << " id:" << id_it->first << " on " << id_it->second << " frames.\n";
00916 }
00917 }
00918
00919 void vobj_tracker_view::summary()
00920 {
00921
00922 TaskTimer::printStats();
00923
00924 cout <<"FPS vs number of features:\n";
00925 for (fps_stat_map::iterator it(fps_stat.begin()); it!=fps_stat.end(); ++it)
00926 {
00927 cout << it->first*fps_stat_bin_size << ".." << ((1+it->first)*fps_stat_bin_size)-1 << ": "
00928 << it->second.first << " ms (count=" << it->second.second << ")\n";
00929 }
00930 cout << endl;
00931
00932
00933 }
00934
00935