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 #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
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
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
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
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
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
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
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
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
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
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
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
00226
00227
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
00250
00251 std::cout<<"Fast Directional Chamfer Matching DOne "<<std::endl;
00252
00253 ISort(distances_, counter, iindices_);
00254
00255
00256
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
00266
00267 matches.push_back(Rect(x,y,detWindWidth, detWindHeight, distances_[i]));
00268
00269
00270 if (imageName_.size() > 0)
00271 {
00272
00273
00274
00275
00276
00277
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
00324
00325
00326
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
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
00360
00361 LFLineSegment dbLine, queryLine;
00362
00363
00364 double ltrans[2];
00365
00366 double factor = 1.0;
00367 double cost;
00368 double minx, miny, maxx, maxy;
00369 double scale;
00370
00371 LFLineSegment line;
00372
00373
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
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
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 }