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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "RCBot/SceneRec.H"
00038 #include "Component/OptionManager.H"
00039 #include "Image/CutPaste.H"
00040 #include <cstdio>
00041
00042 #define DEBUG
00043 #ifdef DEBUG
00044
00045 #include "GUI/XWinManaged.H"
00046 #include "Image/DrawOps.H"
00047 XWinManaged xwin(Dims(320,240), -1, -1, "SceneRec");
00048
00049 #endif
00050
00051
00052
00053 void *SceneRecWorkTh(void *c)
00054 {
00055 SceneRec *d = (SceneRec*)c;
00056 d->computeLocation();
00057 return NULL;
00058 }
00059
00060
00061 SceneRec::SceneRec(OptionManager& mgr, const std::string& descrName,
00062 const std::string& tagName):
00063 ModelComponent(mgr, descrName, tagName)
00064 { }
00065
00066
00067 void SceneRec::start1()
00068 {
00069 pthread_mutex_init(&jobLock, NULL);
00070 pthread_mutex_init(&locLock, NULL);
00071 pthread_mutex_init(&vdbLock, NULL);
00072 pthread_cond_init(&jobCond, NULL);
00073
00074 currentLeg = 0;
00075 jobDone = true;
00076
00077 currentLegVdb = NULL;
00078 nextLegVdb = NULL;
00079 loadVisualDB(currentLeg);
00080
00081
00082 worker = new pthread_t[1];
00083 pthread_create(&worker[0], NULL, SceneRecWorkTh, (void *)this);
00084 usleep(100000);
00085 }
00086
00087
00088 void SceneRec::stop2()
00089 {
00090 delete [] worker;
00091 }
00092
00093
00094 SceneRec::~SceneRec()
00095 { }
00096
00097
00098 void SceneRec::newInput(const Image< PixRGB<byte> > img)
00099 {
00100 pthread_mutex_lock(&jobLock);
00101 workImg = img;
00102 jobDone = false;
00103 pthread_mutex_unlock(&jobLock);
00104
00105
00106 pthread_cond_broadcast(&jobCond);
00107 }
00108
00109
00110 bool SceneRec::outputReady()
00111 {
00112 bool ret = false;
00113
00114 pthread_mutex_lock(&jobLock);
00115 if (jobDone) ret = true;
00116 pthread_mutex_unlock(&jobLock);
00117
00118 return ret;
00119 }
00120
00121
00122 short SceneRec::getLandmarkLoc(Point2D<int> &loc)
00123 {
00124 pthread_mutex_lock(&locLock);
00125 loc = landmarkLoc;
00126 pthread_mutex_unlock(&locLock);
00127
00128 return currentLeg;
00129 }
00130
00131
00132 void SceneRec::trainFeature(Image<PixRGB<byte> > &img, Point2D<int> loc,
00133 Dims window, short leg)
00134 {
00135 int width = img.getWidth();
00136 int height = img.getHeight();
00137 winsize = window;
00138
00139 try {
00140 LDEBUG("Training loc (%i,%i) Win(%i,%i) leg=%i currentLeg=%i",
00141 loc.i, loc.j, window.w(), window.h(), leg, currentLeg);
00142
00143
00144 if (currentLeg != leg){
00145 pthread_mutex_lock(&vdbLock);
00146 loadVisualDB(leg);
00147 pthread_mutex_unlock(&vdbLock);
00148 }
00149
00150 char name[255]; char fileName[255];
00151 sprintf(name, "Loc%i_%i", objNum, currentLeg);
00152 sprintf(fileName, "Loc%i_%i.png", objNum, currentLeg);
00153
00154
00155 Point2D<int> topLeft(loc.i-((window.w()-1)/2), loc.j-((window.h()-1)/2));
00156
00157
00158 if (topLeft.i < 0 ) topLeft.i = 0;
00159 if (topLeft.i > width - window.w()) topLeft.i = width - window.w();
00160
00161 if (topLeft.j < 0 ) topLeft.j = 0;
00162 if (topLeft.j > height - window.h()) topLeft.j = height - window.h();
00163
00164 Image<PixRGB<byte> > templLoc = crop(img,topLeft, window);
00165 rutz::shared_ptr<VisualObject> voTempl(new VisualObject(name,fileName, templLoc));
00166
00167 LINFO("Saving %s to %s", name, fileName);
00168 pthread_mutex_lock(&vdbLock);
00169 currentLegVdb->addObject(voTempl);
00170 sprintf(fileName, "path%i.vdb", currentLeg);
00171 currentLegVdb->saveTo(fileName);
00172 pthread_mutex_unlock(&vdbLock);
00173 objNum++;
00174
00175 } catch(...) {
00176 LDEBUG("Error in training");
00177 pthread_mutex_unlock(&vdbLock);
00178 }
00179 }
00180
00181
00182 void SceneRec::computeLocation()
00183 {
00184 while (true){
00185
00186 pthread_mutex_lock(&jobLock);
00187 pthread_cond_wait(&jobCond, &jobLock);
00188
00189
00190 Image<PixRGB<byte> > img = workImg;
00191 pthread_mutex_unlock(&jobLock);
00192
00193 LDEBUG("Got a location to recognize, currentLeg = %i", currentLeg);
00194 pthread_mutex_lock(&locLock);
00195 landmarkLoc.i = -1; landmarkLoc.j = -1;
00196 pthread_mutex_unlock(&locLock);
00197
00198 try {
00199 std::vector< rutz::shared_ptr<VisualObjectMatch> > matches;
00200 unsigned int nmatch = 0;
00201 if (img.initialized()){
00202 rutz::shared_ptr<VisualObject> voimg(new VisualObject("PIC", "PIC", img));
00203
00204 float scale; Point2D<int> loc; bool landmarkFound = false;
00205
00206
00207 if (nextLegVdb->numObjects()) {
00208 pthread_mutex_lock(&vdbLock);
00209 nmatch = nextLegVdb->getObjectMatches(voimg, matches,
00210 VOMA_KDTREEBBF);
00211 pthread_mutex_unlock(&vdbLock);
00212
00213 getLandmarkInfo(scale, loc, nmatch, matches, img);
00214 LINFO("Next DB: Found landmark at (%i,%i), scale = %f", loc.i, loc.j, scale);
00215 if (nmatch > 0 && scale > 0.75) {
00216 loadVisualDB(currentLeg+1);
00217 landmarkFound = true;
00218 }
00219 }
00220
00221
00222 if (!landmarkFound){
00223 if (currentLegVdb->numObjects()) {
00224 pthread_mutex_lock(&vdbLock);
00225 nmatch = currentLegVdb->getObjectMatches(voimg, matches,
00226 VOMA_KDTREEBBF);
00227 pthread_mutex_unlock(&vdbLock);
00228
00229 getLandmarkInfo(scale, loc, nmatch, matches, img);
00230 LINFO("Curr DB: Found landmark at (%i,%i), scale = %f", loc.i, loc.j, scale);
00231 if (nmatch > 0){
00232 landmarkFound = true;
00233 }
00234 }
00235 }
00236
00237 if (landmarkFound) {
00238 pthread_mutex_lock(&locLock);
00239 landmarkLoc = loc;
00240 pthread_mutex_unlock(&locLock);
00241 }
00242 }
00243
00244 } catch (...){
00245 LDEBUG("Got an error " );
00246 pthread_mutex_unlock(&vdbLock);
00247 pthread_mutex_unlock(&locLock);
00248 }
00249
00250
00251 pthread_mutex_lock(&jobLock);
00252 jobDone = true;
00253 pthread_mutex_unlock(&jobLock);
00254 }
00255 }
00256
00257
00258 void SceneRec::getLandmarkInfo(float &scale, Point2D<int> &loc,
00259 unsigned int nmatch,
00260 std::vector< rutz::shared_ptr<VisualObjectMatch> > &matches,
00261 Image<PixRGB<byte> > &img)
00262 {
00263 LDEBUG("Found %i currentLeg %i\n", nmatch, currentLeg);
00264 if (nmatch > 0 )
00265 {
00266
00267 for(unsigned int i = 0; i < 1; i++)
00268 {
00269 rutz::shared_ptr<VisualObjectMatch> vom = matches[i];
00270 rutz::shared_ptr<VisualObject> obj = vom->getVoTest();
00271
00272
00273 const char *nameNum = obj->getName().c_str();
00274 int objNum = atoi(nameNum+3);
00275
00276 LDEBUG("### Object match with '%s' score=%f Number %i",
00277 obj->getName().c_str(), vom->getScore(), objNum);
00278 Point2D<int> tl, tr, br, bl;
00279 vom->getTransfTestOutline(tl, tr, br, bl);
00280
00281
00282 Point2D<int> landmarkCenter( tl.i + ((br.i - tl.i)/2),
00283 tl.j + ((br.j - tl.j)/2));
00284 loc = landmarkCenter;
00285
00286 #ifdef DEBUG
00287 drawLine(img, tl, tr, PixRGB<byte>(255, 0, 0));
00288 drawLine(img, tr, br, PixRGB<byte>(255, 0, 0));
00289 drawLine(img, br, bl, PixRGB<byte>(255, 0, 0));
00290 drawLine(img, bl, tl, PixRGB<byte>(255, 0, 0));
00291 drawDisk(img, Point2D<int>(landmarkCenter),
00292 4, PixRGB<byte>(255, 0, 0));
00293 xwin.drawImage(img);
00294 #endif
00295
00296 float size = (br.i - tl.i)*(br.j - tl.j);
00297 LINFO("Size: %i %i %f", br.i - tl.i, br.j - tl.j, size);
00298
00299 scale = size / (winsize.w()*winsize.h());
00300 }
00301 } else {
00302 scale = 0;
00303 loc.i = -1; loc.j = -1;
00304 }
00305 }
00306
00307
00308 void SceneRec::loadVisualDB(short leg)
00309 {
00310 char fileName[255];
00311
00312
00313 if (currentLegVdb) {
00314 if (currentLegVdb->numObjects()){
00315 sprintf(fileName, "path%i.vdb", currentLeg);
00316 currentLegVdb->saveTo(fileName);
00317 }
00318 delete currentLegVdb;
00319 }
00320
00321 if (nextLegVdb){
00322 if (nextLegVdb->numObjects()){
00323 sprintf(fileName, "path%i.vdb", currentLeg+1);
00324 nextLegVdb->saveTo(fileName);
00325 }
00326 delete nextLegVdb;
00327 }
00328
00329
00330 sprintf(fileName, "path%i.vdb", leg);
00331 currentLegVdb = new VisualObjectDB();
00332 currentLegVdb->loadFrom(fileName);
00333 objNum = currentLegVdb->numObjects();
00334 LINFO("Load current=%i(%i) next=%i", leg, objNum, leg+1);
00335
00336 sprintf(fileName, "path%i.vdb", leg+1);
00337 nextLegVdb = new VisualObjectDB();
00338 nextLegVdb->loadFrom(fileName);
00339
00340 currentLeg = leg;
00341 }
00342
00343
00344
00345
00346
00347