00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "tracks.h"
00021 #include <assert.h>
00022
00023
00024
00025 const tkeypoint &tkeypoint::operator = (const tkeypoint &a)
00026 {
00027 point2d::operator=(a);
00028 frame=0;
00029 track=0;
00030 points_in_frame.prev=0;
00031 points_in_frame.next=0;
00032 matches.prev=0;
00033 matches.next=0;
00034 return *this;
00035 }
00036
00037 void tracks::set_match(tkeypoint *prev, tkeypoint *next) {
00038 assert(prev->matches.next == 0);
00039 assert(next->matches.prev == 0);
00040 assert(next->track==0);
00041
00042 prev->matches.next = next;
00043 next->matches.prev = prev;
00044 if (prev->track) {
00045 next->track = prev->track;
00046 prev->track->keypoints = next;
00047 } else {
00048 ttrack *track = ttrack_factory->create(this);
00049 MLIST_INSERT(all_tracks, track, track_node)
00050 track->keypoints = next;
00051 next->track = track;
00052 prev->track = track;
00053
00054 next->track->point_added(prev);
00055 }
00056 next->track->point_added(next);
00057 }
00058
00059 void tracks::unset_match(tkeypoint *k) {
00060 assert(k->matches.prev != 0);
00061 assert(k->track);
00062
00063 k->track->point_removed(k);
00064
00065 RLIST_RM(&k->track->keypoints, k, matches);
00066
00067 if (k->track->keypoints==0) {
00068 MLIST_RM(&all_tracks, k->track, track_node);
00069 ttrack_factory->destroy(k->track);
00070 }
00071
00072 k->track=0;
00073 }
00074
00075 void tframe::append_to(tracks &t)
00076 {
00077 assert(frames.next ==0 && frames.prev==0);
00078 MLIST_INSERT(t.frames, this, frames);
00079 }
00080
00081 void tkeypoint::set(tframe *f, float u, float v)
00082 {
00083 if (frame) unlink();
00084 frame = f;
00085 this->u=u;
00086 this->v=v;
00087 track=0;
00088 f->points.add_pt(this);
00089 }
00090
00091 void tkeypoint::unlink() {
00092 if (frame) frame->points.rm_pt(this);
00093
00094 if (track) track->point_removed(this);
00095
00096 RLIST_RM((track?&track->keypoints:0), this, matches);
00097 if (track&&track->keypoints==0) {
00098 tracks *db = track->db;
00099 MLIST_RM(&db->all_tracks,track,track_node);
00100 db->ttrack_factory->destroy(track);
00101 }
00102 track=0;
00103 frame=0;
00104 }
00105
00106 tkeypoint::~tkeypoint() {
00107 unlink();
00108 }
00109
00110 int tkeypoint::track_length() {
00111 int i=0;
00112 for(tkeypoint *p=matches.prev; p; p=p->matches.prev) i++;
00113 return i;
00114 }
00115
00116 tracks::tracks(tkeypoint::factory_t *kf, tframe::factory_t *ff, ttrack::factory_t *tf)
00117 : frames(0),all_tracks(0)
00118 {
00119 static tkeypoint::factory_t default_kf;
00120 static tframe::factory_t default_ff;
00121 static ttrack::factory_t default_tf;
00122
00123 keypoint_factory = (kf !=0 ? kf : &default_kf);
00124 tframe_factory = (ff !=0 ? ff : &default_ff);
00125 ttrack_factory = (tf !=0 ? tf : &default_tf);
00126 }
00127
00128 tracks::~tracks() {
00129 while (frames) {
00130 frame_iterator it(frames);
00131 remove_frame(it);
00132 }
00133 }
00134
00135 tracks::frame_iterator tracks::get_nth_frame_it(int n) {
00136 frame_iterator it(this);
00137 for (int i=0; i<n; i++) {
00138 if (!it.end()) ++it;
00139 else return it;
00140 }
00141 return it;
00142 }
00143
00144 tframe *tracks::get_nth_frame(int n) {
00145 frame_iterator it = get_nth_frame_it(n);
00146 return it.frame;
00147 }
00148
00149 void tracks::remove_point_track(tkeypoint *point) {
00150 if (!point) return;
00151
00152 tkeypoint *p=point;
00153 tkeypoint *prevs = point->matches.prev;
00154 while (p) {
00155 tkeypoint *np = p->matches.next;
00156 p->dispose();
00157 p = np;
00158 }
00159 while (prevs) {
00160 tkeypoint *pp = prevs->matches.prev;
00161 prevs->dispose();
00162 prevs = pp;
00163 }
00164 }
00165 void tracks::remove_track_tail(tkeypoint *point) {
00166 tkeypoint *prev = point->matches.prev;
00167 point->dispose();
00168 if (prev) remove_point_track(prev);
00169 }
00170
00171 void tracks::remove_unmatched_tracks(frame_iterator frame_it) {
00172
00173
00174
00175 if (!frame_it.end())
00176 {
00177
00178 bucket2d<tkeypoint>::iterator it(frame_it.frame->points.begin());
00179
00180 while (!it.end()) {
00181 tkeypoint *kpt = it.elem();
00182 ++it;
00183 if (!kpt->matches.next) {
00184 remove_point_track(kpt);
00185 }
00186 }
00187 it=frame_it.frame->points.begin();
00188 }
00189 remove_empty_frames();
00190 }
00191
00192 void tracks::remove_empty_frames() {
00193
00194 frame_iterator it(this);
00195 while (!it.end()) {
00196 frame_iterator next(it);
00197 ++next;
00198 if (it.frame->points.size()==0) {
00199 remove_frame(it);
00200 }
00201 it = next;
00202 }
00203 }
00204
00205 void tracks::remove_frame(frame_iterator &f) {
00206 if (f.end()) return;
00207 remove_frame(f.frame);
00208 f.frame = 0;
00209 }
00210
00211 void tracks::remove_frame(tframe *frame) {
00212
00213 if (frame==0) return;
00214
00215 bucket2d<tkeypoint>::iterator it(frame->points.begin());
00216
00217 while (!it.end()) {
00218 tkeypoint *kpt = it.elem();
00219 ++it;
00220 remove_track_tail(kpt);
00221 }
00222
00223 assert(frame->points.size() == 0);
00224
00225 MLIST_RM(&frames, frame, frames);
00226
00227 tframe_factory->destroy(frame);
00228 }
00229
00230 bool tframe::has_point_in(float u, float v, float r)
00231 {
00232 float r2 = r*r;
00233 for (bucket2d<tkeypoint>::iterator it = points.search(u,v,r);
00234 !it.end(); ++it)
00235 {
00236 float du = u-it.elem()->u;
00237 float dv = v-it.elem()->v;
00238 if (du*du+dv*dv < r2) return true;
00239 }
00240 return false;
00241 }
00242
00243
00244 #if 0
00245 #include <iostream>
00246 void::tracks::print_stats()
00247 {
00248 int i=0;
00249 for (frame_iterator it(this); !it.end(); ++it, ++i) {
00250 std::cout << "Frame " << i << ": " << it.frame->points.size() << " points.\n";
00251 for (keypoint_frame_iterator pit(it.frame->points.begin()); !pit.end(); ++pit) {
00252 std::cout << "\t" << pit.elem() << "(p:" << pit.elem()->matches.prev << ",n:" << pit.elem()->matches.next << ") ";
00253 tkeypoint *k=pit.elem();
00254 while(k->matches.prev) k=k->matches.prev;
00255 while(k) {
00256 std::cout << k << ",";
00257 k = k->matches.next;
00258 }
00259 std::cout << ")\n";
00260 }
00261 }
00262 if (i==0) std::cout << "no frames\n";
00263 }
00264 #endif