LMLineMatcher.cpp

00001 /*
00002 Copyright 2010, Ming-Yu Liu
00003 
00004 All Rights Reserved 
00005 
00006 Permission to use, copy, modify, and distribute this software and 
00007 its documentation for any non-commercial purpose is hereby granted 
00008 without fee, provided that the above copyright notice appear in 
00009 all copies and that both that copyright notice and this permission 
00010 notice appear in supporting documentation, and that the name of 
00011 the author not be used in advertising or publicity pertaining to 
00012 distribution of the software without specific, written prior 
00013 permission. 
00014 
00015 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
00016 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
00017 ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 
00018 ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
00019 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
00020 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 
00021 OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
00022 */
00023 
00024 
00025 
00026 #include "LMLineMatcher.h"
00027 
00028 
00029 LMLineMatcher::LMLineMatcher()
00030 {
00031         dbImages_ = NULL;
00032         distances_ = new double[5000000];
00033         indices_ = new int[5000000];
00034         xIndices_ = new int[5000000];
00035         yIndices_ = new int[5000000];
00036         sIndices_ = new double[5000000];
00037         dIndices_ = new double[5000000];
00038         iindices_ = new int[5000000];
00039         wIndices_ = new int[5000000];
00040         hIndices_ = new int[5000000];
00041 };
00042 
00043 LMLineMatcher::~LMLineMatcher()
00044 {
00045         SafeRelease();
00046 };
00047 
00048 void LMLineMatcher::SafeRelease()
00049 {
00050         delete []       distances_;
00051         delete []       indices_;
00052         delete []       xIndices_;
00053         delete []       yIndices_;
00054         delete []       dIndices_;
00055         delete []       iindices_;
00056         delete []       sIndices_;
00057         delete []       wIndices_;
00058         delete []       hIndices_;
00059 
00060         if (dbImages_)
00061                 delete[] dbImages_;
00062         dbImages_ = NULL;
00063 
00064 };
00065 
00066 void LMLineMatcher::Configure(const char *fileName)
00067 {
00068 
00069         for(int i=0;i<50;i++)
00070                 cout<<"*";
00071         cout<<endl;
00072 
00073         cout<<" LMLineMatching"<<endl;
00074 
00075         for(int i=0;i<50;i++)
00076                 cout<<"*";
00077         cout<<endl;
00078 
00079 
00080         char str[256];
00081         FILE *fp=NULL;
00082         fp = fopen(fileName,"rt");
00083         if(fp==NULL)
00084         {
00085                 cerr<<"[ERROR] Cannot read file "<<fileName<<"\n!!!";
00086                 exit(0);
00087         }
00088         cout<<"Load Configuration from "<<fileName<<endl;
00089         
00090   int ret=0;
00091         // nDirections
00092         ret=fscanf(fp,"%s\n",str);
00093         cout<<str<<" = ";
00094         ret=fscanf(fp,"%s\n",str);
00095         nDirections_ = atoi(str);
00096         cout<<nDirections_<<endl;
00097 
00098         // direction cost
00099         ret=fscanf(fp,"%s\n",str);
00100         cout<<str<<" = ";
00101         ret=fscanf(fp,"%s\n",str);
00102         directionCost_ = (float)atof(str);
00103         cout<<directionCost_<<endl;
00104 
00105         // maximum cost
00106         ret=fscanf(fp,"%s\n",str);
00107         cout<<str<<" = ";
00108         ret=fscanf(fp,"%s\n",str);
00109         maxCost_ = atof(str);
00110         cout<<maxCost_<<endl;
00111 
00112         // matching Scale
00113         ret=fscanf(fp,"%s\n",str);
00114         cout<<str<<" = ";
00115         ret=fscanf(fp,"%s\n",str);
00116         scale_ = atof(str);
00117         cout<<scale_<<endl;
00118 
00119 
00120         // db Scale
00121         ret=fscanf(fp,"%s\n",str);
00122         cout<<str<<" = ";
00123         ret=fscanf(fp,"%s\n",str);
00124         db_scale_ = atof(str);
00125         cout<<db_scale_<<endl;
00126 
00127         // Base Search Scale
00128         ret=fscanf(fp,"%s\n",str);
00129         cout<<str<<" = ";
00130         ret=fscanf(fp,"%s\n",str);
00131         baseSearchScale_ = atof(str);
00132         cout<<baseSearchScale_<<endl;
00133 
00134         // Min Search Scale
00135         ret=fscanf(fp,"%s\n",str);
00136         cout<<str<<" = ";
00137         ret=fscanf(fp,"%s\n",str);
00138         minSearchScale_ = atof(str);
00139         cout<<minSearchScale_<<endl;
00140 
00141         // Max Search Scale
00142         ret=fscanf(fp,"%s\n",str);
00143         cout<<str<<" = ";
00144         ret=fscanf(fp,"%s\n",str);
00145         maxSearchScale_ = atof(str);
00146         cout<<maxSearchScale_<<endl;
00147 
00148 
00149         // Search Step Size
00150         ret=fscanf(fp,"%s\n",str);
00151         cout<<str<<" = ";
00152         ret=fscanf(fp,"%s\n",str);
00153         searchStepSize_ = atoi(str);
00154         cout<<searchStepSize_<<endl;
00155 
00156         // Search Boundary Size
00157         ret=fscanf(fp,"%s\n",str);
00158         cout<<str<<" = ";
00159         ret=fscanf(fp,"%s\n",str);
00160         searchBoundarySize_ = atoi(str);
00161         cout<<searchBoundarySize_<<endl;
00162 
00163         // Min Cost Ratio
00164         ret=fscanf(fp,"%s\n",str);
00165         cout<<str<<" = ";
00166         ret=fscanf(fp,"%s\n",str);
00167         minCostRatio_ = atof(str);
00168         cout<<minCostRatio_<<endl;
00169 
00170 
00171         fclose(fp);
00172         cout<<endl<<endl;
00173 }
00174 
00175 
00176 void LMLineMatcher::Init(const char* fileName,double db_scale)
00177 {
00178         char imageName[512];
00179 
00180         db_scale_ = db_scale;
00181         
00182         FILE* fin=NULL;
00183 
00184         fin = fopen(fileName, "r");
00185         if(fileName==NULL)
00186         {
00187                 cerr<<"[ERROR] Cannot read file "<<fileName<<"\n!!!";
00188                 exit(0);
00189         }
00190   int ret = 0;
00191         ret=fscanf(fin, "%d", &ndbImages_);
00192         dbImages_ = new EIEdgeImage [ndbImages_];
00193 
00194         std::cout<<"Num. templates = "<<ndbImages_<<std::endl;
00195 
00196         for (int i=0;i<ndbImages_ ;i++)
00197         {
00198                 ret=fscanf(fin, "%s\n", (char*)imageName);
00199                 dbImages_[i].SetNumDirections(nDirections_);
00200                 dbImages_[i].Read(imageName);           
00201                 dbImages_[i].Scale(scale_*db_scale_);
00202         }
00203 
00204         fclose(fin);
00205 }
00206 
00207 
00208 void LMLineMatcher::computeIDT3(int width, int height, int nLines, LFLineSegment* linesSegment)
00209 {
00210 
00211         queryImage_.SetNumDirections(nDirections_);
00212         queryImage_.Read(width, height, nLines, linesSegment);
00213         queryImage_.Scale(scale_);
00214         queryDistanceImage_.Configure(directionCost_,maxCost_);
00215         queryDistanceImage_.SetImage(queryImage_);
00216 
00217         std::cout<<"IDT3 Computation done " << std::endl;
00218 
00219 }
00220 
00221 
00222 
00223 std::vector<LMLineMatcher::Rect> LMLineMatcher::Match(int width, int height, int nLines, LFLineSegment* linesSegment)
00224 {
00225         //LARGE_INTEGER t1, t2, f;
00226         //QueryPerformanceFrequency(&f);
00227         //QueryPerformanceCounter(&t1);
00228 
00229 
00230 
00231         queryImage_.SetNumDirections(nDirections_);
00232         queryImage_.Read(width, height, nLines, linesSegment);
00233         queryImage_.Scale(scale_);
00234         queryDistanceImage_.Configure(directionCost_,maxCost_);
00235         queryDistanceImage_.SetImage(queryImage_);
00236 
00237         std::cout<<"IDT3 Computation done " << std::endl;
00238 
00239 
00240         double minCost = 1e+10;
00241         int counter = 0;
00242         for (int i=0 ; i<ndbImages_ ; i++)
00243         {               
00244                 MatchBruteForce(dbImages_[i], i, iindices_,
00245         indices_, xIndices_, yIndices_, dIndices_, sIndices_, distances_,
00246         counter, minCost);              
00247         }
00248 
00249         //QueryPerformanceCounter(&t2);
00250         //std::cout<<"Fast Directional Chamfer Matching Time "<<setiosflags(ios::fixed)<<setprecision(6)<<(t2.QuadPart - t1.QuadPart)/(1.0*f.QuadPart)<<std::endl;      
00251         std::cout<<"Fast Directional Chamfer Matching DOne "<<std::endl;        
00252 
00253         ISort(distances_, counter, iindices_);
00254 
00255 
00256         // Display best matcher in edge map
00257   std::vector<Rect> matches;
00258   for(int i=0; i<counter; i++)
00259   {
00260     int x = (int)ceil(xIndices_[iindices_[i]]/scale_-0.5);
00261     int y = (int)ceil(yIndices_[iindices_[i]]/scale_-0.5);
00262     double scale = sIndices_[iindices_[i]];
00263     int detWindWidth= (int)(dbImages_[indices_[iindices_[i]]].width_*scale/scale_);
00264     int detWindHeight= (int)(dbImages_[indices_[iindices_[i]]].height_*scale/scale_);
00265     //printf("MATCH: %i %f %i %i %i %i\n", i, distances_[i], 
00266     //    x, y, detWindWidth, detWindHeight);
00267     matches.push_back(Rect(x,y,detWindWidth, detWindHeight, distances_[i]));
00268 
00269 
00270     if (imageName_.size() > 0)
00271     {
00272       //IplImage *debugImage = cvLoadImage(imageName_.c_str(),1);
00273       //DrawDetWind(debugImage,x,y,detWindWidth,detWindHeight);
00274       //cvNamedWindow("output",0);
00275       //cvShowImage("output",debugImage);
00276       //cvWaitKey(0);
00277       //cvReleaseImage(&debugImage);
00278     }
00279   }
00280   return matches;
00281 }
00282 
00283 void LMLineMatcher::DrawMatchTemplate(IplImage *image,EIEdgeImage &ei,int x,int y,double scale,CvScalar scalar,int thickness)
00284 {
00285         EIEdgeImage tdbImage;
00286         tdbImage = ei;
00287         tdbImage.Scale(scale);
00288         LFLineSegment line;
00289         double ltrans[2];
00290         ltrans[0] = 1.0*x;
00291         ltrans[1] = 1.0*y;
00292         for (int k=0 ; k<tdbImage.nLines_ ; k++)
00293         {
00294                 line = tdbImage.lines_[k];
00295                 line.Translate(ltrans); 
00296                 cvLine(image,cvPoint((int)line.sx_,(int)line.sy_),cvPoint((int)line.ex_,(int)line.ey_),scalar,thickness);
00297         }
00298 }
00299 
00300 void LMLineMatcher::DrawDetWind(IplImage *image,int x,int y,int detWindWidth,int detWindHeight,CvScalar scalar,int thickness)
00301 {
00302         cvLine(image,cvPoint( x,y),cvPoint( x+detWindWidth,y),scalar,thickness);
00303         cvLine(image,cvPoint( x+detWindWidth,y),cvPoint( x+detWindWidth, y+detWindHeight),scalar,thickness);
00304         cvLine(image,cvPoint( x+detWindWidth,y+detWindHeight),cvPoint( x, y+detWindHeight),scalar,thickness);
00305         cvLine(image,cvPoint( x, y+detWindHeight),cvPoint( x, y),scalar,thickness);
00306 
00307 }
00308 
00309 
00310 
00311 double LMLineMatcher::getCost(EIEdgeImage& tdbImage, double ltrans[2], double factor, int& count)
00312 {
00313 
00314         LFLineSegment line;
00315         double minCost = 1e+10;
00316   
00317   double cost = 0;                              
00318   for (int k=0 ; k<tdbImage.nLines_ ; k++)
00319   {
00320     line = tdbImage.lines_[k];
00321     line.Translate(ltrans);     
00322 
00323     //printf("Count: %f %f %i %i %i %i\n",
00324     //    ltrans[0], ltrans[1],
00325     //    (int)line.sx_, (int) line.sy_,
00326     //    (int)line.ex_,(int) line.ey_);
00327 
00328 
00329     int ccount = 0;
00330     double sum = queryDistanceImage_.idtImages_[tdbImage.directionIndices_[k]].Sum((int)line.sx_,(int) line.sy_,(int) line.ex_,(int) line.ey_, ccount);
00331     count += ccount;
00332 
00333     //printf("Done\n");
00334     cost+=sum*factor;
00335     if (cost > minCost*minCostRatio_)
00336     {
00337       cost = 1e+10;
00338       break;
00339     }
00340   }
00341 
00342   return cost;
00343 }
00344 
00345 double LMLineMatcher::getCost(int directionIdx, int sx, int sy, int ex, int ey, int count) const
00346 {
00347   return queryDistanceImage_.idtImages_[directionIdx].Sum(sx,sy,ex,ey,count);
00348 }
00349 
00350 double LMLineMatcher::MatchBruteForce(EIEdgeImage& dbImage,
00351     int index, int* iindices,
00352     int* indices, int* xIndex, int* yIndex,
00353     double* dIndex, double* sIndex,
00354     double* distances, int& counter, double& minCost)
00355 {
00356         
00357         int count =0;
00358         int i = 0;
00359         //int k;
00360 
00361         LFLineSegment dbLine, queryLine;
00362         
00363 
00364         double ltrans[2];
00365         
00366         double factor = 1.0;
00367         double cost; //, sum;
00368         double minx, miny, maxx, maxy;
00369         double scale;
00370 
00371         LFLineSegment line;
00372         
00373         //int currentcount;
00374 
00375         for(double s = minSearchScale_  ; s< maxSearchScale_ ; s++)     
00376         {               
00377                 scale = pow(baseSearchScale_,s);
00378     printf("Scale %f\n", scale);
00379                 EIEdgeImage tdbImage;
00380                 tdbImage = dbImage;
00381                 tdbImage.Scale(scale);
00382                 factor = 1.0/dbImage.Length();
00383                 tdbImage.Boundary(minx, miny, maxx, maxy);
00384                 tdbImage.SetDirectionIndices();
00385 
00386     printf("W %i H %i\n", queryImage_.width_, queryImage_.height_);
00387                 for (int x=-(int)minx ; x<queryImage_.width_-(int)minx ; x += searchStepSize_)
00388                 {
00389                         for (int y=-(int)miny; y<queryImage_.height_-(int)miny; y += searchStepSize_)
00390                         {
00391                 
00392                                 ltrans[0] = (double)x;
00393                                 ltrans[1] = (double)y;                          
00394                                 cost = 0;                               
00395 
00396                                 if (minx + ltrans[0] <=searchBoundarySize_ ||
00397             minx + ltrans[0] >=queryImage_.width_-searchBoundarySize_ || 
00398             maxx + ltrans[0] <=searchBoundarySize_ ||
00399             maxx + ltrans[0] >=queryImage_.width_-searchBoundarySize_ ||
00400             miny + ltrans[1] <=searchBoundarySize_ ||
00401             miny + ltrans[1] >=queryImage_.height_-searchBoundarySize_ || 
00402             maxy + ltrans[1] <=searchBoundarySize_ ||
00403             maxy + ltrans[1] >=queryImage_.height_-searchBoundarySize_ )
00404                                 {
00405                                         cost = 1e+10;
00406                                         continue;
00407                                 }
00408                                 else
00409                                 {
00410                                         count++;
00411 
00412           int ccount;
00413           cost = getCost(tdbImage, ltrans, factor, ccount);
00414                                         //for (k=0 ; k<tdbImage.nLines_ ; k++)
00415                                         //{
00416                                         //      line = tdbImage.lines_[k];
00417                                         //      line.Translate(ltrans); 
00418 
00419                                         //      sum = queryDistanceImage_.idtImages_[tdbImage.directionIndices_[k]].Sum((int)line.sx_,(int) line.sy_,(int) line.ex_,(int) line.ey_, currentcount);
00420                 
00421                                         //      cost+=sum*factor;
00422                                         //      if (cost > minCost*minCostRatio_)
00423                                         //      {
00424                                         //              cost = 1e+10;
00425                                         //              break;
00426                                         //      }
00427                                         //}
00428                                 }
00429 
00430 
00431                                 if (cost<minCost*minCostRatio_)
00432                                 {
00433                                         xIndex[counter] = (int)ltrans[0];
00434                                         yIndex[counter] = (int)ltrans[1];
00435                                         dIndex[counter] = (i*M_PI)/nDirections_;
00436                                         sIndex[counter] = scale;
00437                                         distances[counter] = cost;
00438                                         iindices[counter] = counter;
00439                                         indices[counter++] = index;
00440 
00441                                         if (cost<minCost)
00442                                                 minCost = cost;
00443 
00444                                 }
00445 
00446 
00447                         }
00448                 }
00449                 
00450         }
00451         return minCost;
00452 }
00453 
00454 
00455 void LMLineMatcher::ISort(double* ra, int nVec, int* ira)
00456 {
00457    unsigned long n, l, ir, i, j;
00458    n = nVec;
00459    double rra;
00460    int irra;
00461    
00462    if (n<2)
00463       return;
00464    l = (n>>1)+1;
00465    ir = n;
00466    for (;;)
00467    {
00468       if (l>1)
00469       {
00470          irra = ira[(--l)-1];
00471          rra = ra[l-1];
00472       }
00473       else
00474       {
00475          irra = ira[ir-1];
00476          rra = ra[ir-1];
00477 
00478          ira[ir-1] = ira[1-1];
00479          ra[ir-1] = ra[1-1];
00480 
00481          if (--ir==1)
00482          {
00483             ira[1-1] = irra;
00484             ra[1-1] = rra;
00485             break;
00486          }
00487       }
00488       i = l;
00489       j = l+l;
00490       while (j<=ir)
00491       {
00492          if (j<ir && ra[j-1]<ra[j+1-1])
00493             j++;
00494          if (rra<ra[j-1])
00495          {
00496             ira[i-1] = ira[j-1];
00497             ra[i-1] = ra[j-1];
00498 
00499             i = j;
00500             j <<= 1;
00501          }
00502          else
00503             j = ir+1;
00504       }
00505       ira[i-1] = irra;
00506       ra[i-1] = rra;
00507    }
00508 
00509 }
Generated on Sun May 8 08:41:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3