00001 #ifndef QD_ALGO_HPP
00002 #define QD_ALGO_HPP
00003
00004 #include <set>
00005 #include <list>
00006 #include <string>
00007 #include <iomanip>
00008
00009 #include "quasidense/qdMatches.hpp"
00010
00011 #include "quasidense/qdImgRank.hpp"
00012 #include "quasidense/qdImgZncc.hpp"
00013 #include "quasidense/qdImgCensus.hpp"
00014
00015 #include "boost/timer.hpp"
00016
00017 namespace jafar {
00018
00019 namespace quasidense {
00020
00021 void initShifts (int rLocal, pixel* &localShiftIma1, pixel** &localShiftIma2, unsigned int* &nbShift);
00022 void initShiftsWRot (double angle, pixel* &localShiftIma1, pixel** &localShiftIma2, unsigned int* &nbShift);
00023
00024
00025 template <typename imgPair>
00026 void matchesPropagation (imgPair &imagesPair, jafar::image::Image &imaRef,
00027 std::string filematch, double deltaYaw, int rLocal, double initThres,
00028 double propaThres, std::string directory, std::string prefix)
00029 {
00030 JFR_PRECOND(deltaYaw>-M_PI && deltaYaw<=M_PI, "quadisense::qdAlgo::matchesPropagation. deltaYaw must be in ]-PI,PI]");
00031
00032 int cpt, u1, v1, u2, v2;
00033 unsigned int searchAeraSize, *nbShifts;
00034 pixel *localShiftIma1, **localShiftIma2;
00035 double *disparitymap;
00036 boost::timer t1;
00037
00038 std::ostringstream outFilenameStream;
00039
00040
00041
00042
00043 double power=0.75, minnzv = 30, vnorm, maxnzv=255.0;
00044 vnorm = pow(maxnzv,power);
00045
00046 t1.restart();
00047
00048
00049
00050
00051
00052 if (fabs(deltaYaw)<M_PI/18.0)
00053 {
00054 initShifts(rLocal, localShiftIma1, localShiftIma2, nbShifts);
00055 searchAeraSize = (2*rLocal+1)*(2*rLocal+1);
00056 }
00057 else
00058 {
00059 std::cout << " Rotation angle > Threshold : Propagation process adapted to rotation configuration " << std::endl;
00060 std::cout << " (3x3 in ref image to 5x5 in insp image)" << std::endl;
00061 initShiftsWRot(deltaYaw,localShiftIma1,localShiftIma2,nbShifts);
00062 searchAeraSize = 8;
00063 }
00064
00065
00066
00067
00068 unsigned int nbrow = imaRef.height(), nbcol = imaRef.width();
00069
00070 jafar::image::Image exportIma(nbcol,nbrow,IPL_DEPTH_8U,JfrImage_CS_GRAY);
00071 jafar::image::Image warpedIma(nbcol,nbrow,IPL_DEPTH_8U,JfrImage_CS_GRAY);
00072
00073 disparitymap = new double[nbrow*nbcol];
00074 for (v1=0,cpt=0;v1<(int)nbrow;++v1)
00075 for (u1=0;u1<(int)nbcol;++u1,++cpt)
00076 {
00077 disparitymap[cpt] = -1.0;
00078 exportIma.setPixelValue<unsigned char>(0,u1,v1,0);
00079 warpedIma.setPixelValue<unsigned char>(0,u1,v1,0);
00080 }
00081
00082 outFilenameStream << nbrow*nbcol;
00083 unsigned int nbDigits = outFilenameStream.str().size();
00084 outFilenameStream.str("");
00085
00086
00087
00088
00089 std::set<pixelmatch*,greaterSimilScore> Seeds;
00090 std::set<pixelmatch*,greaterSimilScore> Local;
00091 std::list<pixelmatch*> ValidMatches;
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 unsigned int nbInitialSeeds = 0, nbInitialValidSeeds = 0;
00102 std::ifstream matchesfile(filematch.c_str(),std::ios::in);
00103 pixelmatch *onePM;
00104 double similScore;
00105
00106 if (matchesfile.is_open())
00107 {
00108 std::string oneline;
00109 while(!matchesfile.eof())
00110 {
00111 getline(matchesfile,oneline);
00112
00113 if (oneline.size() == 0 || oneline.at(0) == '#')
00114 continue;
00115 ++nbInitialSeeds;
00116
00117 std::istringstream ss(oneline);
00118 ss >> u1 >> v1 >> u2 >> v2 >> similScore;
00119
00120 if (similScore >= initThres)
00121 {
00122 onePM = new pixelmatch(u1,v1,u2,v2,similScore);
00123 Seeds.insert(onePM);
00124 imagesPair.confirmedMatch(u1,v1,u2,v2);
00125 ++nbInitialValidSeeds;
00126 }
00127 }
00128 matchesfile.close();
00129 }
00130 std::cout << " Elapsed time for data formating : " << t1.elapsed() << std::endl;
00131 std::cout << " # ValidInitial Seeds : " << nbInitialValidSeeds << std::endl;
00132
00133
00134
00135
00136
00137 pixel pixTestIma1, pixTestIma2;
00138 std::set<pixelmatch*,greaterSimilScore>::iterator bestSeed = Seeds.begin();
00139 std::set<pixelmatch*,greaterSimilScore>::iterator itOnLocal;
00140 std::list<pixelmatch*>::iterator vmLastEntry;
00141 std::list<pixelmatch*>::iterator itOnPmList;
00142 unsigned int nbiter=0;
00143 double dispa, dispamax = -(double)nbrow*(double)nbcol;
00144 std::ofstream outfile, outfile2;
00145
00146 outFilenameStream.str("");
00147 outFilenameStream << directory << "/" << prefix << "_matchinglist.txt";
00148
00149 outfile.open(outFilenameStream.str().c_str(),std::ios::out);
00150 if (outfile.is_open())
00151 {
00152 t1.restart();
00153 while (!Seeds.empty())
00154 {
00155
00156 ValidMatches.push_back(*bestSeed);
00157 vmLastEntry = --(ValidMatches.end());
00158 Seeds.erase(bestSeed);
00159
00160
00161 pixTestIma1 = (*vmLastEntry)->pix1;
00162 pixTestIma2 = (*vmLastEntry)->pix2;
00163 for (unsigned int cpt1 = 0; cpt1<searchAeraSize ; ++cpt1)
00164 {
00165 u1 = pixTestIma1.u + localShiftIma1[cpt1].u;
00166 v1 = pixTestIma1.v + localShiftIma1[cpt1].v;
00167
00168 if (imagesPair.isPointValidinIma1(u1,v1))
00169 {
00170 for (unsigned int cpt2=0; cpt2<nbShifts[cpt1] ; ++cpt2)
00171 {
00172 u2 = pixTestIma2.u+localShiftIma2[cpt1][cpt2].u;
00173 v2 = pixTestIma2.v+localShiftIma2[cpt1][cpt2].v;
00174
00175 if (imagesPair.isPointValidinIma2(u2,v2))
00176 {
00177 similScore = imagesPair.matchEval(u1,v1,u2,v2);
00178 if (similScore>propaThres)
00179 {
00180 onePM = new pixelmatch(u1,v1,u2,v2,similScore);
00181 Local.insert(onePM);
00182 }
00183 }
00184 }
00185 }
00186 }
00187
00188
00189
00190
00191 if (!Local.empty())
00192 {
00193 itOnLocal = Local.begin();
00194 while (itOnLocal != Local.end())
00195 {
00196 u1 = ((*itOnLocal)->pix1).u;
00197 v1 = ((*itOnLocal)->pix1).v;
00198 u2 = ((*itOnLocal)->pix2).u;
00199 v2 = ((*itOnLocal)->pix2).v;
00200
00201 if (imagesPair.isMatchValid(u1,v1,u2,v2))
00202 {
00203 Seeds.insert(*itOnLocal);
00204 imagesPair.confirmedMatch(u1,v1,u2,v2);
00205 Local.erase(itOnLocal);
00206 }
00207 else
00208 {
00209 free(*itOnLocal);
00210 Local.erase(itOnLocal);
00211 }
00212 ++itOnLocal;
00213 }
00214 }
00215
00216
00217
00218 bestSeed = Seeds.begin();
00219 ++nbiter;
00220 dispa = (*vmLastEntry)->disparity();
00221 dispamax = (dispamax>dispa)?dispamax:dispa;
00222
00223
00224
00225
00226
00227 if (nbiter%10000==0)
00228 {
00229 if (nbiter==10000)
00230 itOnPmList = ValidMatches.begin();
00231 else
00232 ++itOnPmList;
00233
00234 while (itOnPmList != ValidMatches.end())
00235 {
00236 dispa = (*itOnPmList)->disparity();
00237 u1 = ((*itOnPmList)->pix1).u;
00238 v1 = ((*itOnPmList)->pix1).v;
00239 disparitymap[v1*nbcol+u1] = dispa;
00240
00241 dispa = maxnzv*dispa/dispamax;
00242 dispa = minnzv + (maxnzv-minnzv)*pow(dispa,power)/vnorm;
00243 exportIma.setPixelValue<unsigned char>((unsigned char)dispa,u1,v1,0);
00244
00245 u2 = ((*itOnPmList)->pix2).u;
00246 v2 = ((*itOnPmList)->pix2).v;
00247 warpedIma.setPixelValue<unsigned char>(imaRef.getPixelValue<unsigned char>(u1,v1),u2,v2,0);
00248
00249 outfile << u1 << " " << v1 << " " << u2 << " " << v2 << std::endl;
00250
00251 ++itOnPmList;
00252 }
00253 --itOnPmList;
00254
00255 outFilenameStream.str("");
00256 outFilenameStream << directory << "/" << prefix << "dispaMap_after" << std::setfill('0') << std::setw(nbDigits) << nbiter << ".tif";
00257 exportIma.save(outFilenameStream.str().c_str(),"disparityMap");
00258 }
00259 }
00260
00261
00262
00263
00264
00265 ++ itOnPmList;
00266
00267 while (itOnPmList != ValidMatches.end())
00268 {
00269 dispa = (*itOnPmList)->disparity();
00270 u1 = ((*itOnPmList)->pix1).u;
00271 v1 = ((*itOnPmList)->pix1).v;
00272 disparitymap[v1*nbcol+u1] = dispa;
00273
00274 dispa = maxnzv*dispa/dispamax;
00275 dispa = minnzv + (maxnzv-minnzv)*pow(dispa,power)/vnorm;
00276 exportIma.setPixelValue<unsigned char>((unsigned char)dispa,u1,v1,0);
00277
00278 u2 = ((*itOnPmList)->pix2).u;
00279 v2 = ((*itOnPmList)->pix2).v;
00280 warpedIma.setPixelValue<unsigned char>(imaRef.getPixelValue<unsigned char>(u1,v1),u2,v2,0);
00281
00282 outfile << u1 << " " << v1 << " " << u2 << " " << v2 << std::endl;
00283
00284 ++itOnPmList;
00285 }
00286
00287 outFilenameStream.str("");
00288 outFilenameStream << directory << "/" << prefix << "dispaMap_atConvergence_after" << std::setfill('0') << std::setw(nbDigits) << nbiter << ".map";
00289 outfile2.open(outFilenameStream.str().c_str(),std::ios::binary | std::ios::out);
00290 if (outfile.is_open())
00291 {
00292 outfile2.write((char*)&nbcol,sizeof(unsigned int));
00293 outfile2.write((char*)&nbrow,sizeof(unsigned int));
00294 outfile2.write((char*)disparitymap,nbrow*nbcol*sizeof(double));
00295 outfile2.close();
00296 }
00297
00298
00299 outFilenameStream.str("");
00300 outFilenameStream << directory << "/" << prefix << "dispaMap_atConvergence_after" << std::setfill('0') << std::setw(nbDigits) << nbiter << ".tif";
00301 exportIma.save(outFilenameStream.str().c_str(),"disparityMap");
00302
00303 outFilenameStream.str("");
00304 outFilenameStream << directory << "/" << prefix << "Ima1Warped_atConvergence_after" << std::setfill('0') << std::setw(nbDigits) << nbiter << ".tif";
00305 warpedIma.save(outFilenameStream.str().c_str(),"ImaWarped");
00306
00307 outfile.close();
00308 std::cout << " " << nbiter-1 << " iterations in " << t1.elapsed() <<" sec" << std::endl;
00309
00310 }
00311
00312
00313
00314
00315
00316
00317 Seeds.clear();
00318 itOnPmList = ValidMatches.begin();
00319 while (itOnPmList != ValidMatches.end())
00320 {
00321 delete *itOnPmList;
00322 ++itOnPmList;
00323 }
00324 std::cout << " Clear ValidMatches .... OK!" << std::endl;
00325
00326 delete[] nbShifts;
00327 std::cout << " Dynamic variable \"nbshifts\" unallocated " << std::endl;
00328
00329 for (cpt=0;cpt<(int)searchAeraSize;++cpt)
00330 delete[] localShiftIma2[cpt];
00331 std::cout << " Dynamic variable \"localShiftIma2\" unallocated " << std::endl;
00332
00333 delete[] disparitymap;
00334 std::cout << " Dynamic variable \"disparitymap\" unallocated " << std::endl;
00335 };
00336
00337 }
00338
00339 }
00340
00341 #endif