00001 #ifndef QD_ROTCENSUS_HPP
00002 #define QD_ROTCENSUS_HPP
00003
00004 #include <iostream>
00005 #include <fstream>
00006 #include <sstream>
00007 #include <string>
00008 #include <vector>
00009 #include <bitset>
00010
00011 #include <math.h>
00012
00013 #include "kernel/jafarMacro.hpp"
00014 #include "jmath/jblas.hpp"
00015 #include "image/Image.hpp"
00016 #include "quasidense/qdImgCensus.hpp"
00017 #include "boost/timer.hpp"
00018
00019 namespace jafar {
00020
00021 namespace quasidense {
00022
00031 struct rotDataCensus {
00032
00034
00035 bitset80 *censusData;
00036
00038 unsigned int width;
00039 unsigned int height;
00040 unsigned int widthstep;
00041
00043 boost::numeric::ublas::matrix<bool> vMask;
00044
00045 private :
00046
00047 unsigned int rExclu;
00048
00049 unsigned int estimExcluRadius (double angle);
00050
00051 void censusShiftsGenerator (long int *tab, unsigned int tabSize,
00052 unsigned int indCircQuadrant, unsigned int indRotAngle);
00053
00054
00055 public :
00056
00061 rotDataCensus (jafar::image::Image &img, double angle, double cmThreshold=0.01) :
00062 width(img.width()),
00063 height(img.height()),
00064 widthstep(img.step()),
00065 vMask(img.height(),img.width())
00066 {
00067 JFR_PRECOND(angle>-M_PI && angle<=M_PI, "quadisense::rotDataCensus::rotDataCensus : Constructor waits for angle in ]-PI,PI]");
00068 JFR_PRECOND(img.depth() == IPL_DEPTH_8U , "quasidense::rotDataCensus::rotDataCensus : Constructor don't tolerate float images");
00069
00070 unsigned int pos, posIma;
00071 unsigned int rExclu;
00072 unsigned int nbrow = img.height(), nbcol = img.width();;
00073 double vmax1, vmax2, cstnormal;
00074 double *diffv, *diffh;
00075
00076 diffv = new double [nbrow*nbcol];
00077 diffh = new double [nbrow*nbcol];
00078
00079
00080
00081
00082 censusData = new bitset80[nbrow*widthstep];
00083
00084 unsigned char *rawData = reinterpret_cast<unsigned char*>(img.data());
00085 unsigned char current_gl;
00086 cstnormal = 1.0/255.0;
00087
00088 boost::timer chrono;
00089
00090
00091
00092
00093
00094
00095
00096 if (angle<-13*M_PI/180)
00097 angle += 2.0*M_PI;
00098
00099 unsigned int configBase, configLUT;
00100 double angleRed;
00101
00102 if (angle<77*M_PI/180)
00103 configBase = 0;
00104 else if (angle<167*M_PI/180)
00105 configBase = 1;
00106 else if (angle<257*M_PI/180)
00107 configBase = 2;
00108 else
00109 configBase = 3;
00110
00111 angleRed = angle - configBase*M_PI_2;
00112 rExclu = 3;
00113
00114 if (angleRed<13*M_PI/180)
00115 {
00116 rExclu = 2;
00117 configLUT = 0;
00118 }
00119 else if (angleRed<18*M_PI/180)
00120 {
00121 rExclu = 2;
00122 configLUT = 1;
00123 }
00124 else if (angleRed<25*M_PI/180)
00125 configLUT = 2;
00126 else if (angleRed<35*M_PI/180)
00127 configLUT = 3;
00128 else if (angleRed<40*M_PI/180)
00129 configLUT = 4;
00130 else if (angleRed<50*M_PI/180)
00131 configLUT = 5;
00132 else if (angleRed<55*M_PI/180)
00133 configLUT = 6;
00134 else if (angleRed<66*M_PI/180)
00135 configLUT = 7;
00136 else if (angleRed<73*M_PI/180)
00137 configLUT = 8;
00138 else if (angleRed<77*M_PI/180)
00139 {
00140 rExclu = 2;
00141 configLUT = 9;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 vMask(0,0) = false;
00157 diffv[0] = 0.0;
00158 diffh[0] = 0.0;
00159
00160 pos = nbcol;
00161 for (unsigned int cptr=1; cptr<nbrow ; ++cptr,pos+=nbcol)
00162 {
00163 vMask(cptr,0) = false;
00164 diffv[pos] = cstnormal*fabs((double)rawData[cptr*widthstep]-(double)rawData[(cptr-1)*widthstep]);
00165 diffh[pos] = 0.0;
00166 }
00167
00168 for (unsigned int cptc=1; cptc<nbcol;cptc++)
00169 {
00170 vMask(0,cptc) = false;
00171 diffv[cptc] = 0.0;
00172 diffh[cptc] = cstnormal*fabs((double)rawData[cptc]-(double)rawData[cptc-1]);
00173 }
00174
00175 pos = nbcol;
00176 for (unsigned int cptr = 1; cptr<nbrow; ++cptr)
00177 {
00178 pos++;
00179 posIma = cptr*widthstep;
00180 for (unsigned int cptc = 1; cptc<nbcol; ++cptc, ++pos)
00181 {
00182 vMask(cptr,cptc) = false;
00183 diffv[pos] = cstnormal*fabs((double)rawData[posIma+cptc]-(double)rawData[posIma+cptc-widthstep]);
00184 diffh[pos] = cstnormal*fabs((double)rawData[posIma+cptc]-(double)rawData[posIma+cptc-1]);
00185 }
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 for (unsigned int cptr=2*rExclu;cptr<(nbrow-2*rExclu);++cptr)
00196 {
00197 pos = cptr*nbcol+2*rExclu;
00198 for (unsigned int cptc=2*rExclu;cptc<(nbcol-2*rExclu);++pos,++cptc)
00199 {
00200 vmax1 = (diffv[pos]<diffh[pos])?diffh[pos]:diffv[pos];
00201 vmax2 = (diffv[pos+nbcol]<diffh[pos+1])?diffh[pos+1]:diffv[pos+nbcol];
00202 if ((vmax1>=cmThreshold)||(vmax2>=cmThreshold))
00203 vMask(cptr,cptc) = true;
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 unsigned int N, rCensus = 2;
00216 unsigned int testNumber;
00217 long int *shiftsTabular;
00218
00219 N = (rCensus*2+1);
00220 testNumber = (N*N-1)/2;
00221
00222
00223 shiftsTabular = new long int [testNumber];
00224 censusShiftsGenerator (shiftsTabular, testNumber, configBase, configLUT);
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 unsigned int current_pos, tested_pos, irow, icol;
00237
00238 for (pos=0;pos<widthstep*nbrow;++pos)
00239 censusData[pos].reset();
00240
00241 for (irow = rExclu; irow<(nbrow-rExclu) ; ++irow)
00242 {
00243 pos = irow*widthstep;
00244 for ( icol = rExclu; icol<(nbcol-rExclu) ; ++icol)
00245 {
00246 current_pos = pos+icol;
00247 current_gl = rawData[current_pos];
00248
00249 for (unsigned int cpt_test=0;cpt_test<testNumber;++cpt_test)
00250 {
00251 tested_pos = current_pos+shiftsTabular[cpt_test];
00252 if (current_gl!=rawData[tested_pos])
00253 if (current_gl<rawData[tested_pos])
00254 censusData[current_pos].set(cpt_test,1);
00255 else
00256 censusData[tested_pos].set(N*N-1-cpt_test,1);
00257 }
00258 }
00259 }
00260
00261
00262 std::cout << " Census Transform accomplished in " << chrono.elapsed() << "sec." << std::endl;
00263
00264
00265
00266
00267
00268
00269
00270 delete[] diffv;
00271 delete[] diffh;
00272 delete[] shiftsTabular;
00273
00274 };
00275
00276 ~rotDataCensus(void)
00277 {
00278 delete[] censusData;
00279 };
00280
00281 };
00282
00283
00284
00293 class rotPairCensus {
00294
00295 rotDataCensus img1;
00296
00297 rotDataCensus img2;
00298
00299 public :
00303 rotPairCensus (jafar::image::Image &img1_, jafar::image::Image &img2_, double angle_=0.0, double cmThreshold_=0.01) :
00304 img1(img1_, 0.0, cmThreshold_),
00305 img2(img2_, angle_, cmThreshold_)
00306 { };
00307
00311 bool isPointValidinIma1 (int u, int v);
00312 bool isPointValidinIma2 (int u, int v);
00313
00317 bool isMatchValid (int u1, int v1, int u2, int v2);
00318 bool isMatchValid (int u1, int v1, int u2, int v2, unsigned int radius);
00319
00323 double matchEval (int u1, int v1, int u2, int v2);
00324 double matchEval (int u1, int v1, int u2, int v2, unsigned int radius);
00325
00329 void confirmedMatch (int u1, int v1, int u2, int v2)
00330 {
00331 img1.vMask(v1,u1) = false;
00332 img2.vMask(v2,u2) = false;
00333 };
00334
00335 };
00336
00337
00338 }
00339
00340 }
00341
00342 #endif