00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <iostream>
00026 #include <QDebug>
00027 #include <QVector>
00028 #include <QMap>
00029
00030 #include <qvcore/qvapplication.h>
00031 #include <qvcameras/qvmplayercamera.h>
00032 #include <qvgui/qvgui.h>
00033 #include <qvip/qvipp/qvipp.h>
00034 #include <qvip/qvpolyline.h>
00035 #include <qvdta/qvdta.h>
00036
00037 #ifndef DOXYGEN_IGNORE_THIS
00038
00039
00040 class PointPlusValue
00041 { QPoint point;
00042 float value;
00043
00044 public:
00045 PointPlusValue() : point(0,0), value(0.0) {}
00046 PointPlusValue(int x, int y, float v): point(x,y), value(v) {}
00047 QPoint getPoint() {return point;}
00048 float getValue() {return value;}
00049 bool operator<(const PointPlusValue &ppv) const { return (value < ppv.value);}
00050 };
00051
00052
00053 inline sFloat rectArea(const QVImage<sFloat> &integralImage, int x0, int y0, int x1, int y1)
00054 {
00055
00056
00057
00058 QVIMAGE_INIT_READ(sFloat,integralImage);
00059 return(QVIMAGE_PIXEL(integralImage,x1,y1,0)
00060 -QVIMAGE_PIXEL(integralImage,x1,y0,0)
00061 -QVIMAGE_PIXEL(integralImage,x0,y1,0)
00062 +QVIMAGE_PIXEL(integralImage,x0,y0,0));
00063 }
00064
00065
00066 void ApplyDyyIPP(QVImage<sFloat> &integral, QVImage<sFloat> &imageDyy, int octave, int scale)
00067 {
00068 int rows=integral.getRows(), cols=integral.getCols();
00069 QVImage<sFloat> aux(cols,rows),auxab(cols,rows),auxde(cols,rows),auxcf(cols,rows),
00070 auxdecf(cols,rows),auxdecf3(cols,rows), auxhg(cols,rows),
00071 auxabhg(cols,rows), auxabcdefgh(cols,rows);
00072 aux=integral;
00073
00074
00075
00076
00077 const int incMargin = 1, incWidth=4, incHeight=2;
00078 const int margin=2 + incMargin*octave + scale*(incMargin<<octave);
00079 const int width = 5 + incWidth*octave + scale*(incWidth << octave);
00080 const int height = 3 + incHeight*octave + scale*(incHeight << octave);
00081 const int destx= 4 + (incMargin+incHeight)*octave + scale*((incMargin+incHeight)<<octave);
00082
00083 integral.setROI(margin,0,cols-(width+margin),rows-destx);
00084 aux.setROI(width+margin,0,cols-(width+margin),rows-destx);
00085 Sub(aux,integral,auxab,QPoint(destx,destx));
00086 auxab.setAnchor(0,0);
00087
00088 integral.setROI(width+margin,height,cols-(width+margin),rows-2*height);
00089 aux.setROI(margin,2*height,cols-(width+margin),rows-2*height);
00090 Add(integral,aux,auxde,QPoint(destx,destx));
00091 auxde.setAnchor(0,0);
00092
00093 integral.setROI(margin,height,cols-(margin+width),rows-2*height);
00094 aux.setROI(margin+width,2*height,cols-(margin+width),rows-2*height);
00095 Add(integral,aux,auxcf,QPoint(destx,destx));
00096 auxcf.setAnchor(0,0);
00097
00098 auxde.setROI(destx,destx,cols-destx,rows-destx);
00099 auxcf.setROI(destx,destx,cols-destx,rows-destx);
00100 Sub(auxcf,auxde,auxdecf,QPoint(destx,destx));
00101 auxdecf.setAnchor(0,0);
00102
00103 MulC(auxdecf,auxdecf3,3.0,QPoint(destx,destx));
00104 auxdecf3.setAnchor(0,0);
00105
00106 integral.setROI(margin+width,3*height,cols-(margin+width),rows-3*height);
00107 aux.setROI(margin,3*height,cols-(margin+width),rows-3*height);
00108 auxhg.setAnchor(0,0);
00109 Sub(aux,integral,auxhg,QPoint(destx,destx));
00110
00111 auxab.setROI(destx,destx,cols-destx,rows-destx);
00112 auxhg.setROI(destx,destx,cols-destx,rows-destx);
00113 auxabhg.setAnchor(0,0);
00114 Add(auxab,auxhg,auxabhg,QPoint(destx,destx));
00115
00116 auxabhg.setROI(destx,destx,cols-destx,rows-destx);
00117 auxdecf3.setROI(destx,destx,cols-destx,rows-destx);
00118
00119 Add(auxabhg,auxdecf3,auxabcdefgh,QPoint(destx,destx));
00120
00121 MulC(auxabcdefgh,imageDyy,1.0/(width*height),QPoint(destx,destx));
00122
00123 imageDyy.setROI(0,0,cols,rows); imageDyy.setAnchor(0,0);
00124
00125
00126 }
00127
00128 void ApplyDxxIPP(QVImage<sFloat> &integral, QVImage<sFloat> &imageDxx, int octave, int scale)
00129 {
00130 int rows=integral.getRows(), cols=integral.getCols();
00131 QVImage<sFloat> aux(cols,rows),auxab(cols,rows),auxde(cols,rows),auxcf(cols,rows),
00132 auxdecf(cols,rows),auxdecf3(cols,rows), auxhg(cols,rows),
00133 auxabhg(cols,rows), auxabcdefgh(cols,rows);
00134 aux=integral;
00135
00136
00137
00138
00139 const int incMargin = 1, incWidth=4, incHeight=2;
00140 const int margin=2 + incMargin*octave + scale*(incMargin<<octave);
00141 const int width = 5 + incWidth*octave + scale*(incWidth << octave);
00142 const int height = 3 + incHeight*octave + scale*(incHeight << octave);
00143 const int destx= 4 + (incMargin+incHeight)*octave + scale*((incMargin+incHeight)<<octave);
00144
00145 integral.setROI(0,margin,cols-destx,rows-(margin+width));
00146 aux.setROI(0,margin+width,cols-destx,rows-(margin+width));
00147 Sub(aux,integral,auxab,QPoint(destx,destx));
00148 auxab.setAnchor(0,0);
00149
00150 integral.setROI(height,margin+width,cols-2*height,rows-(margin+width));
00151 aux.setROI(2*height,margin,cols-2*height,rows-(margin+width));
00152 Add(integral,aux,auxde,QPoint(destx,destx));
00153 auxde.setAnchor(0,0);
00154
00155 integral.setROI(height,margin,cols-2*height,rows-(margin+width));
00156 aux.setROI(2*height,margin+width,cols-2*height,rows-(margin+width));
00157 Add(integral,aux,auxcf,QPoint(destx,destx));
00158 auxcf.setAnchor(0,0);
00159
00160 auxde.setROI(destx,destx,cols-destx,rows-destx);
00161 auxcf.setROI(destx,destx,cols-destx,rows-destx);
00162 Sub(auxcf,auxde,auxdecf,QPoint(destx,destx));
00163 auxdecf.setAnchor(0,0);
00164
00165 MulC(auxdecf,auxdecf3,3.0,QPoint(destx,destx));
00166 auxdecf3.setAnchor(0,0);
00167
00168 integral.setROI(3*height,(margin+width),cols-3*height,rows-(margin+width));
00169 aux.setROI(3*height,margin,cols-3*height,rows-(margin+width));
00170 auxhg.setAnchor(0,0);
00171 Sub(aux,integral,auxhg,QPoint(destx,destx));
00172
00173 auxab.setROI(destx,destx,cols-destx,rows-destx);
00174 auxhg.setROI(destx,destx,cols-destx,rows-destx);
00175 auxabhg.setAnchor(0,0);
00176 Add(auxab,auxhg,auxabhg,QPoint(destx,destx));
00177
00178 auxabhg.setROI(destx,destx,cols-destx,rows-destx);
00179 auxdecf3.setROI(destx,destx,cols-destx,rows-destx);
00180 auxabcdefgh.setAnchor(destx,destx);
00181 Add(auxabhg,auxdecf3,auxabcdefgh,QPoint(destx,destx));
00182
00183 MulC(auxabcdefgh,imageDxx,1.0/(width*height),QPoint(destx,destx));
00184
00185 imageDxx.setROI(0,0,cols,rows); imageDxx.setAnchor(0,0);
00186
00187 }
00188
00189 void ApplyDxyIPP(QVImage<sFloat> &integral, QVImage<sFloat> &imageDxy, int octave, int scale)
00190 {
00191 int rows=integral.getRows(), cols=integral.getCols();
00192 QVImage<sFloat> aux(cols,rows),auxab(cols,rows),auxde(cols,rows),auxcf(cols,rows),
00193 auxdecf(cols,rows),auxdecf3(cols,rows), auxhg(cols,rows),
00194 auxabhg(cols,rows), auxabcdefgh(cols,rows), auxijkl(cols,rows), auxmnop(cols,rows), diag1(cols,rows), diag2(cols,rows);
00195 aux=integral;
00196
00197
00198
00199
00200 const int incMargin = 1, incWidth=2, incHeight=2;
00201 const int margin=1 + incMargin*octave + scale*(incMargin<<octave);
00202 const int interMargin = 1;
00203 const int width = 3 + incWidth*octave + scale*(incWidth << octave);
00204 const int height = 3 + incHeight*octave + scale*(incHeight << octave);
00205 const int destx= 4 + (incMargin+incHeight)*octave + scale*((incMargin+incHeight)<<octave);
00206 const int totalwidth=margin+width+interMargin+width+margin;
00207
00208 integral.setROI(margin,margin,cols-destx,rows-destx);
00209 aux.setROI(destx,destx,cols-destx,rows-destx);
00210 Add(aux,integral,auxab,QPoint(destx,destx));
00211 auxab.setAnchor(0,0);
00212
00213 integral.setROI(destx,margin,cols-destx,rows-destx);
00214 aux.setROI(margin,destx,cols-destx,rows-destx);
00215 Add(integral,aux,auxde,QPoint(destx,destx));
00216 auxde.setAnchor(0,0);
00217
00218 auxde.setROI(destx,destx,cols-destx,rows-destx);
00219 auxab.setROI(destx,destx,cols-destx,rows-destx);
00220 Sub(auxde,auxab,auxdecf,QPoint(destx,destx));
00221 auxdecf.setAnchor(0,0);
00222
00223 integral.setROI(margin+width+interMargin,margin,cols-(totalwidth-margin),rows-destx);
00224 aux.setROI(totalwidth-margin,destx,cols-(totalwidth-margin),rows-destx);
00225 Add(aux,integral,auxab,QPoint(destx,destx));
00226 auxab.setAnchor(0,0);
00227
00228 integral.setROI((totalwidth-margin),margin,cols-(totalwidth-margin),rows-destx);
00229 aux.setROI(margin+width+interMargin,destx,cols-(totalwidth-margin),rows-destx);
00230 Add(integral,aux,auxde,QPoint(destx,destx));
00231 auxde.setAnchor(0,0);
00232
00233 auxde.setROI(destx,destx,cols-destx,rows-destx);
00234 auxab.setROI(destx,destx,cols-destx,rows-destx);
00235 Sub(auxde,auxab,auxabhg,QPoint(destx,destx));
00236 auxabhg.setAnchor(0,0);
00237
00238 integral.setROI(margin,(margin+width+interMargin),cols-destx,rows-(totalwidth-margin));
00239 aux.setROI(destx,(totalwidth-margin),cols-destx,rows-(totalwidth-margin));
00240 Add(aux,integral,auxab,QPoint(destx,destx));
00241 auxab.setAnchor(0,0);
00242
00243 integral.setROI(margin,(totalwidth-margin),cols-destx,rows-(totalwidth-margin));
00244 aux.setROI(destx,(margin+width+interMargin),cols-destx,rows-(totalwidth-margin));
00245 Add(integral,aux,auxde,QPoint(destx,destx));
00246 auxde.setAnchor(0,0);
00247
00248 auxde.setROI(destx,destx,cols-destx,rows-destx);
00249 auxab.setROI(destx,destx,cols-destx,rows-destx);
00250 Sub(auxde,auxab,auxijkl,QPoint(destx,destx));
00251 auxijkl.setAnchor(0,0);
00252
00253 integral.setROI((margin+width+interMargin),(margin+width+interMargin),cols-(totalwidth-margin),rows-(totalwidth-margin));
00254 aux.setROI((totalwidth-margin),(totalwidth-margin),cols-(totalwidth-margin),rows-(totalwidth-margin));
00255 Add(aux,integral,auxab,QPoint(destx,destx));
00256 auxab.setAnchor(0,0);
00257
00258 integral.setROI((totalwidth-margin),(margin+width+interMargin),cols-(totalwidth-margin),rows-(totalwidth-margin));
00259 aux.setROI((margin+width+interMargin),(totalwidth-margin),cols-(totalwidth-margin),rows-(totalwidth-margin));
00260 Add(integral,aux,auxde,QPoint(destx,destx));
00261 auxde.setAnchor(0,0);
00262
00263 auxde.setROI(destx,destx,cols-destx,rows-destx);
00264 auxab.setROI(destx,destx,cols-destx,rows-destx);
00265 Sub(auxde,auxab,auxmnop,QPoint(destx,destx));
00266 auxmnop.setAnchor(0,0);
00267
00268 auxdecf.setROI(destx,destx,cols-destx,rows-destx);
00269 auxmnop.setROI(destx,destx,cols-destx,rows-destx);
00270 Add(auxdecf,auxmnop,diag1,QPoint(destx,destx));
00271
00272 auxijkl.setROI(destx,destx,cols-destx,rows-destx);
00273 auxabhg.setROI(destx,destx,cols-destx,rows-destx);
00274 Add(auxijkl,auxabhg,diag2,QPoint(destx,destx));
00275
00276 diag1.setROI(destx,destx,cols-destx,rows-destx);
00277 diag2.setROI(destx,destx,cols-destx,rows-destx);
00278 Sub(diag2,diag1,auxabcdefgh,QPoint(destx,destx));
00279
00280 MulC(auxabcdefgh,imageDxy,1.0/(width*height),QPoint(destx,destx));
00281 }
00282
00283 void detHessianIPP(QVImage<sFloat> &integral, QVImage<sFloat> &detHessian, int octave, int scale)
00284 {
00285
00286
00287
00288
00289
00290
00291 int rows=integral.getRows(), cols=integral.getCols();
00292 QVImage<sFloat> imageDxx(cols,rows), imageDyy(cols,rows), imageDxy(cols,rows), squared(cols,rows),multiplied(cols,rows), squared81(cols,rows);
00293
00294 const int incCenter = 3;
00295 const int destx= 4 + (incCenter)*octave + scale*(incCenter<<octave);
00296 const float MINVAL = 0.0;
00297
00298 ApplyDxxIPP(integral,imageDxx,octave,scale);
00299 ApplyDyyIPP(integral,imageDyy,octave,scale);
00300 ApplyDxyIPP(integral,imageDxy,octave,scale);
00301
00302 imageDxx.setMarginROI(destx);
00303 imageDyy.setMarginROI(destx);
00304 imageDxy.setMarginROI(destx);
00305
00306 Sqr(imageDxy,squared,QPoint(destx,destx));
00307 MulC(squared,squared81,0.81,QPoint(destx,destx));
00308
00309 Mul(imageDxx,imageDyy,multiplied,QPoint(destx,destx));
00310
00311 squared81.setMarginROI(destx);
00312 multiplied.setMarginROI(destx);
00313 Sub(squared81,multiplied,detHessian,QPoint(destx,destx));
00314 detHessian.setMarginROI(destx);
00315 Threshold_Val(detHessian,MINVAL,0.0,ippCmpLess);
00316
00317 detHessian.setAnchor(0,0);
00318 detHessian.setMarginROI(destx);
00319
00320
00321 }
00322
00323 QList<QPoint> MaxIPP( QVImage<sFloat> &image1, QVImage<sFloat> &image2, QVImage<sFloat> &image3, float percentage, int threshold)
00324 {
00325
00326 QList<QPoint> listMax;
00327 float max1, min1, aux; int xmax, ymax;
00328 float max2, min2;
00329 float max3, min3;
00330 float max, min;
00331 QRect image1ROI=image1.getROI();
00332 QRect image2ROI=image2.getROI();
00333 QRect image3ROI=image3.getROI();
00334
00335 int rows=image3.getRows(), cols=image3.getCols();
00336 QVImage<sFloat> imageMax1(cols,rows), imageMax2(cols,rows), imageMax3(cols,rows);
00337 int beginx=image3.getROI().x(), beginy=image3.getROI().y();
00338 int endx=image3.getROI().width()+beginx, endy=image3.getROI().height()+beginy;
00339 imageMax1.setMarginROI(beginx);
00340 imageMax2.setMarginROI(beginx);
00341 imageMax3.setMarginROI(beginx);
00342
00343 image1.setMarginROI(beginx);
00344 imageMax1.setMarginROI(beginx);
00345 FilterMax(image1,imageMax1,3,3,QPoint(beginx+1,beginy+1));
00346 image2.setMarginROI(beginx);
00347 imageMax2.setMarginROI(beginx);
00348 FilterMax(image2,imageMax2,3,3,QPoint(beginx+1,beginy+1));
00349 imageMax3.setMarginROI(beginx);
00350 FilterMax(image3,imageMax3,3,3,QPoint(beginx+1,beginy+1));
00351
00352
00353 image1.setROI(image1ROI);
00354 image2.setROI(image2ROI);
00355 image3.setROI(image3ROI);
00356
00357
00358
00359
00360 QVIMAGE_INIT_READ(sFloat,imageMax1);
00361 QVIMAGE_INIT_WRITE(sFloat,imageMax2);
00362 QVIMAGE_INIT_READ(sFloat,imageMax3);
00363 QVIMAGE_INIT_READ(sFloat,image2);
00364
00365 QMap<sFloat,QPoint> listMap;
00366 sFloat faux, fmaxvalue=-1e30, fminvalue=1e30;
00367 for(int i=beginx; i<endx; ++i)
00368 { for(int j=beginy; j<endy; ++j)
00369 { faux = QVIMAGE_PIXEL(imageMax2,i,j,0);
00370 if ((faux > threshold) && (faux == QVIMAGE_PIXEL(image2,i,j,0)) && (faux > QVIMAGE_PIXEL(imageMax1,i,j,0)) && (faux > QVIMAGE_PIXEL(imageMax3,i,j,0)))
00371 { listMap.insertMulti(faux,QPoint(i,j));
00372 }
00373 }
00374 }
00375 QList<QPoint> valuesList = listMap.values();
00376 QList<QPoint> listFiltered;
00377 int miPercentage= percentage * valuesList.size();
00378 for(int i=valuesList.size()-miPercentage; i<valuesList.size(); ++i)
00379 listFiltered.append(valuesList[i]);
00380 return(listFiltered);
00381 }
00382
00383
00384
00385 float applyDxx(const QVImage<sFloat> &integralImage, int x, int y, int octave, int scale)
00386 {
00387
00388
00389 int w = 5 + 4*octave + scale*(4 << octave);
00390 int h = 3 + 2*octave + scale*(2 << octave);
00391
00392 float a,b,c,d,e,f,g,hh;
00393 QVIMAGE_INIT_READ(sFloat,integralImage);
00394 a = QVIMAGE_PIXEL(integralImage,x-h/2-h, y-w/2,0);
00395 b = QVIMAGE_PIXEL(integralImage,x-h/2, y-w/2,0);
00396 c = QVIMAGE_PIXEL(integralImage,x+h/2+1, y-w/2,0);
00397 d = QVIMAGE_PIXEL(integralImage,x+h+h/2+1, y-w/2,0);
00398 e = QVIMAGE_PIXEL(integralImage,x-h/2-h, y+w/2+1,0);
00399 f = QVIMAGE_PIXEL(integralImage,x-h/2, y+w/2+1,0);
00400 g = QVIMAGE_PIXEL(integralImage,x+h/2+1,y+w/2+1,0);
00401 hh = QVIMAGE_PIXEL(integralImage,x+h/2+h+1,y+w/2+1,0);
00402
00403 return((a+hh-d-e+3*(f+c-b-g))/(w*h));
00404 }
00405
00406 float applyDyy(const QVImage<sFloat> &integralImage, int x, int y, int octave, int scale)
00407 {
00408
00409
00410 int w = 5 + 4*octave + scale*(4 << octave);
00411 int h = 3 + 2*octave + scale*(2 << octave);
00412 float a,b,c,d,e,f,g,hh;
00413 QVIMAGE_INIT_READ(sFloat,integralImage);
00414 a = QVIMAGE_PIXEL(integralImage,x-w/2,y-h-h/2,0);
00415 c = QVIMAGE_PIXEL(integralImage,x-w/2,y-h/2,0);
00416 e = QVIMAGE_PIXEL(integralImage,x-w/2,y+h/2+1,0);
00417 g = QVIMAGE_PIXEL(integralImage,x-w/2,y+h+h/2+1,0);
00418 b = QVIMAGE_PIXEL(integralImage,x+w/2+1,y-h-h/2,0);
00419 d = QVIMAGE_PIXEL(integralImage,x+w/2+1,y-h/2,0);
00420 f = QVIMAGE_PIXEL(integralImage,x+w/2+1,y+h/2+1,0);
00421 hh = QVIMAGE_PIXEL(integralImage,x+w/2+1,y+h+h/2+1,0);
00422
00423 return((a-b+hh-g+3*(d+e-c-f))/(w*h));
00424
00425 }
00426
00427 float applyDxy(const QVImage<sFloat> &integralImage, int x, int y, int octave, int scale)
00428 {
00429
00430
00431 int w = 3 + 2*octave + scale*(2 << octave);
00432 int h = 3 + 2*octave + scale*(2 << octave);
00433 float a,b,c,d,e,f,g,hh,i,j,k,l,m,n,o,p;
00434 QVIMAGE_INIT_READ(sFloat,integralImage);
00435 a = QVIMAGE_PIXEL(integralImage,x-w,y-h,0);
00436 c = QVIMAGE_PIXEL(integralImage,x-w,y,0);
00437 i = QVIMAGE_PIXEL(integralImage,x-w,y+1,0);
00438 k = QVIMAGE_PIXEL(integralImage,x-w,y+h+1,0);
00439 b = QVIMAGE_PIXEL(integralImage,x,y-h,0);
00440 d = QVIMAGE_PIXEL(integralImage,x,y,0);
00441 j = QVIMAGE_PIXEL(integralImage,x,y+1,0);
00442 l = QVIMAGE_PIXEL(integralImage,x,y+h+1,0);
00443 e = QVIMAGE_PIXEL(integralImage,x+1,y-h,0);
00444 g = QVIMAGE_PIXEL(integralImage,x+1,y,0);
00445 m = QVIMAGE_PIXEL(integralImage,x+1,y+1,0);
00446 o = QVIMAGE_PIXEL(integralImage,x+1,y+h+1,0);
00447 f = QVIMAGE_PIXEL(integralImage,x+w+1,y-h,0);
00448 hh = QVIMAGE_PIXEL(integralImage,x+w+1,y,0);
00449 n = QVIMAGE_PIXEL(integralImage,x+w+1,y+1,0);
00450 p = QVIMAGE_PIXEL(integralImage,x+w+1,y+h+1,0);
00451
00452 return(((a+d-b-c)+(m+p-n-o)-(e+hh-f-g)-(i+l-j-k))/(w*h));
00453 }
00454
00455
00456 void detHessianColumns(const QVImage<sFloat> &integralImage, QVImage<sFloat> &hessian, int octave, int scale)
00457 {
00458 sFloat det;
00459 int cols = integralImage.getCols(), rows = integralImage.getRows();
00460 int sizeMask=9 + 6*octave + scale*(6 << octave);
00461 int step= 1 << octave;
00462 int colsHessian = cols/step, rowsHessian = rows/step;
00463 int marginHessian = ((sizeMask)/2)/step+1;
00464 int marginImage = marginHessian*step;
00465 int w = 5 + 4*octave + scale*(4 << octave);
00466 int h = 3 + 2*octave + scale*(2 << octave);
00467 int margin = 2 + 1*octave + scale*(1<<octave);
00468 int marginDxy = 1 + 1*octave + scale*(1<<octave);
00469 int wDxy = 3 + 2*octave + scale*(2 << octave);
00470 int hDxy = 3 + 2*octave + scale*(2 << octave);
00471 int beginxDxx=0, beginyDxx=margin;
00472 int beginxDyy=margin, beginyDyy=0;
00473 int beginxDxy=marginDxy, beginyDxy=marginDxy;
00474 int xDyy,yDyy,xDxx,yDxx,xDxy,yDxy;
00475 sFloat aDxx,bDxx,cDxx,dDxx,eDxx,fDxx,gDxx,hDxx;
00476 sFloat aDyy,bDyy,cDyy,dDyy,eDyy,fDyy,gDyy,hDyy;
00477 sFloat aDxy,bDxy,cDxy,dDxy,eDxy,fDxy,gDxy,HDxy,iDxy,jDxy,kDxy,lDxy,mDxy,nDxy,oDxy,pDxy;
00478 sFloat Dxx, Dyy, Dxy;
00479 QVImage<sFloat> imageDxx(cols,rows), imageDyy(cols,rows), imageDxy(cols,rows);
00480 QVImage<sFloat> imageDet(cols,rows);
00481
00482
00483 QVIMAGE_INIT_READ(sFloat,integralImage);
00484
00485
00486 QVIMAGE_INIT_WRITE(sFloat,imageDyy);
00487 for(xDyy=beginxDyy; xDyy<cols-sizeMask; ++xDyy)
00488 {
00489 for(int offset=0; offset < h; ++offset)
00490 {
00491 yDyy=beginyDyy+offset;
00492
00493 aDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy,0);
00494 bDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy,0);
00495 cDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy+h,0);
00496 dDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy+h,0);
00497 eDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy+2*h,0);
00498 fDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy+2*h,0);
00499
00500 for(int yDyy=beginyDyy+offset; yDyy<rows-sizeMask; yDyy += h )
00501 {
00502 gDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy+2*h+h,0);
00503 hDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy+2*h+h,0);
00504
00505 Dyy = ((aDyy-bDyy+hDyy-gDyy+3*(dDyy+eDyy-cDyy-fDyy))/(w*h));
00506 aDyy = cDyy;
00507 bDyy = dDyy;
00508 cDyy = eDyy;
00509 dDyy = fDyy;
00510 eDyy = gDyy;
00511 fDyy = hDyy;
00512
00513 QVIMAGE_PIXEL(imageDyy,xDyy+w/2,yDyy+h+h/2,0) = Dyy;
00514 }
00515 }
00516 }
00517
00518
00519
00520 QVIMAGE_INIT_WRITE(sFloat,imageDxx);
00521 for(xDxx=beginxDxx; xDxx<cols-sizeMask; ++xDxx)
00522 {
00523 for(int offset=0; offset < w; ++offset)
00524 {
00525 yDxx=beginyDxx+offset;
00526
00527 aDxx = QVIMAGE_PIXEL(integralImage,xDxx,yDxx,0);
00528 bDxx = QVIMAGE_PIXEL(integralImage,xDxx+h,yDxx,0);
00529 cDxx = QVIMAGE_PIXEL(integralImage,xDxx+2*h,yDxx,0);
00530 dDxx = QVIMAGE_PIXEL(integralImage,xDxx+3*h,yDxx,0);
00531
00532 for(int yDxx=beginyDxx+offset; yDxx<rows-sizeMask; yDxx += w )
00533 {
00534 eDxx = QVIMAGE_PIXEL(integralImage,xDxx,yDxx+w,0);
00535 fDxx = QVIMAGE_PIXEL(integralImage,xDxx+h,yDxx+w,0);
00536 gDxx = QVIMAGE_PIXEL(integralImage,xDxx+2*h,yDxx+w,0);
00537 hDxx = QVIMAGE_PIXEL(integralImage,xDxx+3*h,yDxx+w,0);
00538 Dxx = ((aDxx+hDxx-dDxx-eDxx+3*(fDxx+cDxx-bDxx-gDxx))/(w*h));
00539
00540 aDxx=eDxx;
00541 bDxx=fDxx;
00542 cDxx=gDxx;
00543 dDxx=hDxx;
00544
00545 QVIMAGE_PIXEL(imageDxx,xDxx+h+h/2,yDxx+w/2,0) = Dxx;
00546
00547 }
00548 }
00549 }
00550
00551
00552
00553 QVIMAGE_INIT_WRITE(sFloat,imageDxy);
00554 for(xDxy=beginxDxy; xDxy<cols-sizeMask; ++xDxy)
00555 {
00556 for(int offset=0; offset < hDxy+1; ++offset)
00557 {
00558 yDxy=beginyDxy+offset;
00559
00560 aDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy,0);
00561 bDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy,0);
00562 cDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy,0);
00563 dDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy,0);
00564 eDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy+wDxy,0);
00565 fDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy+wDxy,0);
00566 gDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy+wDxy,0);
00567 HDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy+wDxy,0);
00568
00569 for(int yDxy=beginyDxy+offset; yDxy<rows-sizeMask; yDxy += hDxy+1 )
00570 {
00571 iDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy+wDxy+1,0);
00572 jDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy+wDxy+1,0);
00573 kDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy+wDxy+1,0);
00574 lDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy+wDxy+1,0);
00575 mDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy+2*wDxy+1,0);
00576 nDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy+2*wDxy+1,0);
00577 oDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy+2*wDxy+1,0);
00578 pDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy+2*wDxy+1,0);
00579
00580 Dxy = (((aDxy-bDxy-eDxy+fDxy)+(kDxy-lDxy-oDxy+pDxy)-(cDxy-dDxy-gDxy+HDxy)-(iDxy-jDxy-mDxy+nDxy))/(wDxy*hDxy));
00581 aDxy=iDxy;
00582 bDxy=jDxy;
00583 cDxy=kDxy;
00584 dDxy=lDxy;
00585 eDxy=mDxy;
00586 fDxy=nDxy;
00587 gDxy=oDxy;
00588 HDxy=pDxy;
00589
00590 QVIMAGE_PIXEL(imageDxy,xDxy+wDxy,yDxy+wDxy,0) = Dxy;
00591 }
00592 }
00593 }
00594
00595 QVIMAGE_INIT_WRITE(sFloat,hessian);
00596
00597
00598 for(int j=marginImage,jh=marginHessian; j<rows-marginImage;j+=step,++jh)
00599 for(int i=marginImage,ih=marginHessian; i<cols-marginImage;i+=step,++ih)
00600 { const register float Dxy_apply=QVIMAGE_PIXEL(imageDxy,i,j,0);
00601 det = ( QVIMAGE_PIXEL(imageDxx,i,j,0)
00602 *
00603 QVIMAGE_PIXEL(imageDyy,i,j,0)
00604 -0.81*Dxy_apply*Dxy_apply
00605 );
00606 det = (det < 0.0) ? 0.0 : det;
00607 QVIMAGE_PIXEL(hessian,ih,jh,0) = det;
00608 }
00609
00610 hessian.setMarginROI(marginHessian);
00611 integralImage.setMarginROI(marginImage);
00612
00613 }
00614
00615
00616
00617 void detHessianFewColumns(const QVImage<sFloat> &integralImage, QVImage<sFloat> &hessian, int octave, int scale)
00618 {
00619 sFloat det;
00620 int cols = integralImage.getCols(), rows = integralImage.getRows();
00621 int sizeMask=9 + 6*octave + scale*(6 << octave);
00622 int step= 1 << octave;
00623 int colsHessian = cols/step, rowsHessian = rows/step;
00624 int marginHessian = ((sizeMask)/2)/step+1;
00625 int marginImage = marginHessian*step;
00626 int w = 5 + 4*octave + scale*(4 << octave);
00627 int h = 3 + 2*octave + scale*(2 << octave);
00628 int margin = 2 + 1*octave + scale*(1<<octave);
00629 int marginDxy = 1 + 1*octave + scale*(1<<octave);
00630 int wDxy = 3 + 2*octave + scale*(2 << octave);
00631 int hDxy = 3 + 2*octave + scale*(2 << octave);
00632 int beginxDxx=0, beginyDxx=margin;
00633 int beginxDyy=margin, beginyDyy=0;
00634 int beginxDxy=marginDxy, beginyDxy=marginDxy;
00635 int xDyy,yDyy,xDxx,yDxx,xDxy,yDxy;
00636 sFloat aDxx,bDxx,cDxx,dDxx,eDxx,fDxx,gDxx,hDxx;
00637 sFloat aDyy,bDyy,cDyy,dDyy,eDyy,fDyy,gDyy,hDyy;
00638 sFloat aDxy,bDxy,cDxy,dDxy,eDxy,fDxy,gDxy,HDxy,iDxy,jDxy,kDxy,lDxy,mDxy,nDxy,oDxy,pDxy;
00639 sFloat Dxx, Dyy, Dxy;
00640 QVImage<sFloat> imageDxx(cols,rows), imageDyy(cols,rows), imageDxy(cols,rows);
00641 QVImage<sFloat> imageDet(cols,rows);
00642 int numRowsPerIteration=rows;
00643 int limitNumRowsPerIteration;
00644
00645
00646 QVIMAGE_INIT_READ(sFloat,integralImage);
00647
00648
00649 QVIMAGE_INIT_WRITE(sFloat,imageDyy);
00650 for(int y=beginyDyy; y<rows-sizeMask; y += numRowsPerIteration)
00651 { limitNumRowsPerIteration = ((y+numRowsPerIteration) < (cols-sizeMask)) ? numRowsPerIteration : ((y+numRowsPerIteration) - (cols-sizeMask));
00652 for(xDyy=beginxDyy; xDyy<cols-sizeMask; ++xDyy)
00653 {
00654 for(int offset=0; offset < h; ++offset)
00655 {
00656 yDyy=y+offset;
00657
00658 aDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy,0);
00659 bDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy,0);
00660 cDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy+h,0);
00661 dDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy+h,0);
00662 eDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy+2*h,0);
00663 fDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy+2*h,0);
00664
00665 for(;yDyy < y+limitNumRowsPerIteration; yDyy += h )
00666 {
00667 gDyy = QVIMAGE_PIXEL(integralImage,xDyy,yDyy+2*h+h,0);
00668 hDyy = QVIMAGE_PIXEL(integralImage,xDyy+w,yDyy+2*h+h,0);
00669
00670 Dyy = ((aDyy-bDyy+hDyy-gDyy+3*(dDyy+eDyy-cDyy-fDyy))/(w*h));
00671 aDyy = cDyy;
00672 bDyy = dDyy;
00673 cDyy = eDyy;
00674 dDyy = fDyy;
00675 eDyy = gDyy;
00676 fDyy = hDyy;
00677
00678 QVIMAGE_PIXEL(imageDyy,xDyy+w/2,yDyy+h+h/2,0) = Dyy;
00679 }
00680 }
00681 }
00682 }
00683
00684
00685 QVIMAGE_INIT_WRITE(sFloat,imageDxx);
00686 for(int y=beginyDxx; y<rows-sizeMask; y += numRowsPerIteration)
00687 { limitNumRowsPerIteration = ((y+numRowsPerIteration) < (cols-sizeMask)) ? numRowsPerIteration : ((y+numRowsPerIteration) - (cols-sizeMask));
00688 for(xDxx=beginxDxx; xDxx<cols-sizeMask; ++xDxx)
00689 {
00690 for(int offset=0; offset < w; ++offset)
00691 {
00692 yDxx=y+offset;
00693
00694 aDxx = QVIMAGE_PIXEL(integralImage,xDxx,yDxx,0);
00695 bDxx = QVIMAGE_PIXEL(integralImage,xDxx+h,yDxx,0);
00696 cDxx = QVIMAGE_PIXEL(integralImage,xDxx+2*h,yDxx,0);
00697 dDxx = QVIMAGE_PIXEL(integralImage,xDxx+3*h,yDxx,0);
00698
00699 for(; yDxx<y+limitNumRowsPerIteration; yDxx += w )
00700 {
00701 eDxx = QVIMAGE_PIXEL(integralImage,xDxx,yDxx+w,0);
00702 fDxx = QVIMAGE_PIXEL(integralImage,xDxx+h,yDxx+w,0);
00703 gDxx = QVIMAGE_PIXEL(integralImage,xDxx+2*h,yDxx+w,0);
00704 hDxx = QVIMAGE_PIXEL(integralImage,xDxx+3*h,yDxx+w,0);
00705 Dxx = ((aDxx+hDxx-dDxx-eDxx+3*(fDxx+cDxx-bDxx-gDxx))/(w*h));
00706
00707 aDxx=eDxx;
00708 bDxx=fDxx;
00709 cDxx=gDxx;
00710 dDxx=hDxx;
00711
00712 QVIMAGE_PIXEL(imageDxx,xDxx+h+h/2,yDxx+w/2,0) = Dxx;
00713
00714 }
00715 }
00716 }
00717 }
00718
00719
00720 QVIMAGE_INIT_WRITE(sFloat,imageDxy);
00721
00722 for(int y=beginyDxx; y<rows-sizeMask; y += numRowsPerIteration)
00723 { limitNumRowsPerIteration = ((y+numRowsPerIteration) < (cols-sizeMask)) ? numRowsPerIteration : ((y+numRowsPerIteration) - (cols-sizeMask));
00724 for(xDxy=beginxDxy; xDxy<cols-sizeMask; ++xDxy)
00725 {
00726 for(int offset=0; offset < hDxy+1; ++offset)
00727 {
00728 yDxy=y+offset;
00729
00730 aDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy,0);
00731 bDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy,0);
00732 cDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy,0);
00733 dDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy,0);
00734 eDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy+wDxy,0);
00735 fDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy+wDxy,0);
00736 gDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy+wDxy,0);
00737 HDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy+wDxy,0);
00738
00739 for(; yDxy<y+limitNumRowsPerIteration; yDxy += hDxy+1 )
00740 {
00741 iDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy+wDxy+1,0);
00742 jDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy+wDxy+1,0);
00743 kDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy+wDxy+1,0);
00744 lDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy+wDxy+1,0);
00745 mDxy = QVIMAGE_PIXEL(integralImage,xDxy,yDxy+2*wDxy+1,0);
00746 nDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy,yDxy+2*wDxy+1,0);
00747 oDxy = QVIMAGE_PIXEL(integralImage,xDxy+wDxy+1,yDxy+2*wDxy+1,0);
00748 pDxy = QVIMAGE_PIXEL(integralImage,xDxy+2*wDxy+1,yDxy+2*wDxy+1,0);
00749
00750 Dxy = (((aDxy-bDxy-eDxy+fDxy)+(kDxy-lDxy-oDxy+pDxy)-(cDxy-dDxy-gDxy+HDxy)-(iDxy-jDxy-mDxy+nDxy))/(wDxy*hDxy));
00751 aDxy=iDxy;
00752 bDxy=jDxy;
00753 cDxy=kDxy;
00754 dDxy=lDxy;
00755 eDxy=mDxy;
00756 fDxy=nDxy;
00757 gDxy=oDxy;
00758 HDxy=pDxy;
00759
00760 QVIMAGE_PIXEL(imageDxy,xDxy+wDxy,yDxy+wDxy,0) = Dxy;
00761 }
00762 }
00763 }
00764 }
00765
00766 QVIMAGE_INIT_WRITE(sFloat,hessian);
00767
00768
00769 for(int j=marginImage,jh=marginHessian; j<rows-marginImage;j+=step,++jh)
00770 for(int i=marginImage,ih=marginHessian; i<cols-marginImage;i+=step,++ih)
00771 { const register float Dxy_apply=QVIMAGE_PIXEL(imageDxy,i,j,0);
00772 det = ( QVIMAGE_PIXEL(imageDxx,i,j,0)
00773 *
00774 QVIMAGE_PIXEL(imageDyy,i,j,0)
00775 -0.81*Dxy_apply*Dxy_apply
00776 );
00777 det = (det < 0.0) ? 0.0 : det;
00778 QVIMAGE_PIXEL(hessian,ih,jh,0) = det;
00779 }
00780
00781 hessian.setMarginROI(marginHessian);
00782 integralImage.setMarginROI(marginImage);
00783
00784 }
00785
00786
00787 void detHessianRowsColumns(const QVImage<sFloat> &integralImage, QVImage<sFloat> &hessian, int octave, int scale)
00788 {
00789
00790
00791 int cols = integralImage.getCols(), rows = integralImage.getRows();
00792 int sizeMask=9 + 6*octave + scale*(6 << octave);
00793 int step= 1 << octave;
00794 int marginHessian = ((sizeMask)/2)/step+1;
00795 int marginImage = marginHessian*step;
00796 int w = 5 + 4*octave + scale*(4 << octave);
00797 int h = 3 + 2*octave + scale*(2 << octave);
00798 int margin = 2 + 1*octave + scale*(1<<octave);
00799 int marginDxy = 1 + 1*octave + scale*(1<<octave);
00800 int beginxDxx=0, beginyDxx=margin;
00801 int beginxDyy=margin, beginyDyy=0;
00802 int beginxDxy=marginDxy, beginyDxy=marginDxy;
00803 int blockJump=1;
00804 int xDyy,yDyy,xDxx,yDxx,xDxy,yDxy;
00805 sFloat aDyy[blockJump],bDyy[blockJump],cDyy[blockJump],dDyy[blockJump],eDyy[blockJump],fDyy[blockJump],gDyy[blockJump],hDyy[blockJump];
00806 sFloat *blocksDyy[8]={aDyy,bDyy,cDyy,dDyy,eDyy,fDyy,gDyy,hDyy};
00807 QVImage<sFloat> imageDxx(cols,rows), imageDyy(cols,rows), imageDxy(cols,rows);
00808 QVImage<sFloat> imageDet(cols,rows);
00809 sFloat *t1, *t2;
00810
00811
00812 QVIMAGE_INIT_READ(sFloat,integralImage);
00813
00814 QVIMAGE_INIT_WRITE(sFloat,imageDyy);
00815
00816 for(xDyy=beginxDyy; xDyy<cols-sizeMask; xDyy += blockJump)
00817 {
00818 int limit=((xDyy+blockJump) < (cols-sizeMask)) ? blockJump : ((xDyy+blockJump) - (cols-sizeMask));
00819 for(int offsety=0; offsety < h; ++offsety)
00820 {
00821 yDyy=beginyDyy+offsety;
00822
00823
00824
00825 for(int offsetx=0; offsetx < limit; ++offsetx)
00826 {
00827 blocksDyy[0][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy,yDyy,0);
00828 blocksDyy[1][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy+w,yDyy,0);
00829 blocksDyy[2][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy,yDyy+h,0);
00830 blocksDyy[3][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy+w,yDyy+h,0);
00831 blocksDyy[4][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy,yDyy+2*h,0);
00832 blocksDyy[5][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy+w,yDyy+2*h,0);
00833 }
00834 for(int yDyy=beginyDyy+offsety; yDyy<rows-sizeMask; yDyy += h )
00835 {
00836 for(int offsetx=0; offsetx < limit; ++offsetx)
00837 {
00838 blocksDyy[6][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy,yDyy+2*h+h,0);
00839 blocksDyy[7][offsetx] = QVIMAGE_PIXEL(integralImage,offsetx+xDyy+w,yDyy+2*h+h,0);
00840 }
00841 for(int k=0; k<limit; ++k)
00842 QVIMAGE_PIXEL(imageDyy,k+xDyy+w/2,yDyy+h+h/2,0) = ((blocksDyy[0][k]-blocksDyy[1][k]+blocksDyy[7][k]-blocksDyy[6][k]+3*(blocksDyy[3][k]+blocksDyy[4][k]-blocksDyy[2][k]-blocksDyy[5][k]))/(w*h));
00843
00844
00845 t1=blocksDyy[0]; t2=blocksDyy[1];
00846 blocksDyy[0]=blocksDyy[2];
00847 blocksDyy[1]=blocksDyy[3];
00848 blocksDyy[2]=blocksDyy[4];
00849 blocksDyy[3]=blocksDyy[5];
00850 blocksDyy[4]=blocksDyy[6];
00851 blocksDyy[5]=blocksDyy[7];
00852 blocksDyy[6]=t1;
00853 blocksDyy[7]=t2;
00854
00855 }
00856
00857 }
00858 }
00859
00860 hessian = imageDyy;
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953 hessian.setMarginROI(marginHessian);
00954 integralImage.setMarginROI(marginImage);
00955
00956 }
00957
00958
00959 void detHessian(const QVImage<sFloat> &integral, QVImage<sFloat> &hessian, int octave, int scale)
00960 {
00961 QVIMAGE_INIT_WRITE(sFloat,hessian);
00962 sFloat det;
00963 int cols = integral.getCols(), rows = integral.getRows();
00964 int sizeMask=9 + 6*octave + scale*(6 << octave);
00965 int step= 1 << octave;
00966 int colsHessian = cols/step, rowsHessian = rows/step;
00967 int marginHessian = ((sizeMask)/2)/step+1;
00968 int marginImage = marginHessian*step;
00969 for(int j=marginImage,jh=marginHessian; j<rows-marginImage;j+=step,++jh)
00970 for(int i=marginImage,ih=marginHessian; i<cols-marginImage;i+=step,++ih)
00971 { const float Dxy_apply=applyDxy(integral,i,j,octave,scale);
00972 det = ( applyDxx(integral,i,j,octave,scale)
00973 *
00974 applyDyy(integral,i,j,octave,scale)
00975 -0.81*Dxy_apply*Dxy_apply
00976 );
00977 det = (det < 0.0) ? 0.0 : det;
00978 QVIMAGE_PIXEL(hessian,ih,jh,0) = det;
00979 }
00980 hessian.setMarginROI(marginHessian);
00981 integral.setMarginROI(marginImage);
00982 }
00983
00984
00985 QList<QVPolyline> addBlobsIPP(QList<QVPolyline> listBlobs, QList<QPoint> listPoints, int octave, int scale)
00986 { int radius=4+3*octave+scale*(3<<octave);
00987 for(QList<QPoint>::const_iterator i=listPoints.constBegin(); i!=listPoints.constEnd(); ++i)
00988 listBlobs.append(QVPolyline::ellipse(10,i->x(),i->y(),radius,radius,0));
00989 return(listBlobs);
00990 }
00991
00992 QList<QVPolyline> addBlobs(QList<QVPolyline> listBlobs, QList<QPoint> listPoints, int octave, int scale)
00993 { int radius=4+3*octave+scale*(3<<octave);
00994 int sizeMask=9 + 6*octave + scale*(6 << octave);
00995 int step= 1 << octave;
00996
00997 for(QList<QPoint>::const_iterator i=listPoints.constBegin(); i!=listPoints.constEnd(); ++i)
00998 listBlobs.append(QVPolyline::ellipse(10,i->x()*step,i->y()*step,radius,radius,0));
00999 return(listBlobs);
01000 }
01001
01002
01003 QList<QVPolyline> getBlobsIPP(QVImage<sFloat> &integralFloat, float percentage, float THRESHOLD)
01004 { int cols=integralFloat.getCols(), rows=integralFloat.getRows();
01005 QVImage<sFloat> approxHessian[4]={QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows),
01006 QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows)};
01007 QList<QVPolyline> listBlobs;
01008
01009
01010 for(int sca=0; sca<4; ++sca)
01011 detHessianIPP(integralFloat,approxHessian[sca],0,sca);
01012 listBlobs=addBlobsIPP(listBlobs,MaxIPP(approxHessian[0],approxHessian[1],approxHessian[2], percentage,THRESHOLD),0,1);
01013 listBlobs=addBlobsIPP(listBlobs,MaxIPP(approxHessian[1],approxHessian[2],approxHessian[3], percentage,THRESHOLD),0,2);
01014
01015
01016 for(int oct=1; oct<3; ++oct)
01017 { approxHessian[0]=approxHessian[1];
01018 for(int sca=1; sca<4; ++sca)
01019 detHessianIPP(integralFloat,approxHessian[sca],oct,sca);
01020 listBlobs=addBlobsIPP(listBlobs,MaxIPP(approxHessian[0],approxHessian[1],approxHessian[2], percentage,THRESHOLD),oct,1);
01021 listBlobs=addBlobsIPP(listBlobs,MaxIPP(approxHessian[1],approxHessian[2],approxHessian[3], percentage,THRESHOLD),oct,2);
01022 }
01023
01024 return(listBlobs);
01025 }
01026
01027 QList<QVPolyline> getBlobs(QVImage<sFloat> &integralFloat, float percentage, float THRESHOLD)
01028 { int cols=integralFloat.getCols(), rows=integralFloat.getRows();
01029 QVImage<sFloat> approxHessian0[4]={QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows),
01030 QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows)};
01031 QVImage<sFloat> approxHessian1[4]={QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2),
01032 QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2)};
01033 QVImage<sFloat> approxHessian2[4]={QVImage<sFloat>(cols/4,rows/4),QVImage<sFloat>(cols/4,rows/4),
01034 QVImage<sFloat>(cols/4,rows/4),QVImage<sFloat>(cols/4,rows/4)};
01035 QList<QVPolyline> listBlobs;
01036
01037 int oct=0;
01038 for(int sca=0; sca<4; ++sca)
01039 detHessian(integralFloat,approxHessian0[sca],oct,sca);
01040 listBlobs=addBlobs(listBlobs,MaxIPP(approxHessian0[0],approxHessian0[1],approxHessian0[2], percentage,THRESHOLD),oct,1);
01041 listBlobs=addBlobs(listBlobs,MaxIPP(approxHessian0[1],approxHessian0[2],approxHessian0[3], percentage,THRESHOLD),oct,2);
01042
01043 oct=1;
01044 Resize(approxHessian0[1], approxHessian1[0],IPPI_INTER_NN);
01045 detHessian(integralFloat,approxHessian1[1],oct,1);
01046 detHessian(integralFloat,approxHessian1[2],oct,2);
01047 detHessian(integralFloat,approxHessian1[3],oct,3);
01048 listBlobs=addBlobs(listBlobs,MaxIPP(approxHessian1[0],approxHessian1[1],approxHessian1[2],percentage, THRESHOLD),oct,1);
01049 listBlobs=addBlobs(listBlobs,MaxIPP(approxHessian1[1],approxHessian1[2],approxHessian1[3], percentage,THRESHOLD),oct,2);
01050
01051 oct=2;
01052 Resize(approxHessian1[1], approxHessian2[0],IPPI_INTER_NN);
01053 detHessian(integralFloat,approxHessian2[1],oct,1);
01054 detHessian(integralFloat,approxHessian2[2],oct,2);
01055 detHessian(integralFloat,approxHessian2[3],oct,3);
01056 listBlobs=addBlobs(listBlobs,MaxIPP(approxHessian2[0],approxHessian2[1],approxHessian2[2], percentage,THRESHOLD),oct,1);
01057 listBlobs=addBlobs(listBlobs,MaxIPP(approxHessian2[1],approxHessian2[2],approxHessian2[3], percentage,THRESHOLD),oct,2);
01058
01059
01060 return(listBlobs);
01061 }
01062
01063
01064
01065 class MyWorker: public QVWorker
01066 {
01067 public:
01068 MyWorker(QString name): QVWorker(name)
01069 {
01070 addProperty("Octave", inputFlag, 0, "octave ", 0, 3);
01071 addProperty<int>("Threshold", inputFlag, 600, "Threshold",0,10000);
01072 addProperty<float>("Percentage",inputFlag,1.0,"Percentage",0.01,1.0);
01073
01074 addProperty< QVImage<uChar> >("Input image", inputFlag|outputFlag);
01075 addProperty< QVImage<uChar> >("Output image 1", outputFlag);
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 addProperty< QList<QVPolyline> >("BlobsMax1",outputFlag);
01087
01088
01089 }
01090
01091 void iterate()
01092 {
01093
01094 int octave=getPropertyValue<int>("Octave");
01095 sInt THRESHOLD = getPropertyValue<sInt>("Threshold");
01096 sFloat percentage = getPropertyValue<sFloat>("Percentage");
01097 QVImage<uChar> input0 = getPropertyValue< QVImage<uChar> >("Input image");
01098 uInt rows = input0.getRows()*2, cols = input0.getCols()*2;
01099
01100 QVImage<uChar> input(cols, rows);
01101 Resize(input0, input,IPPI_INTER_NN);
01102
01103 timeFlag("double size");
01104
01105 QVImage<sFloat> imageGaussian(cols,rows);
01106 FilterGauss(input,imageGaussian,3);
01107
01108 ++cols; ++rows;
01109 QVImage<sFloat> integralFloat(cols,rows);
01110 Integral(imageGaussian,integralFloat,0);
01111
01112 QVImage<sFloat> Dyy1(cols,rows);
01113 QVImage<sFloat> Dyy2(cols,rows);
01114
01115 timeFlag("gaussian");
01116
01117
01118
01119 QList<QVPolyline> listBlobs1;
01120
01121 { int cols=integralFloat.getCols(), rows=integralFloat.getRows();
01122 QVImage<sFloat> approxHessian0[4]={QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows),
01123 QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows)};
01124 QVImage<sFloat> approxHessian1[4]={QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2),
01125 QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2)};
01126
01127
01128 for(int sca=0; sca<4; ++sca)
01129 detHessianColumns(integralFloat,approxHessian0[sca],0,sca);
01130
01131 listBlobs1=addBlobs(listBlobs1,MaxIPP(approxHessian0[0],approxHessian0[1],approxHessian0[2], percentage, THRESHOLD),0,1);
01132 listBlobs1=addBlobs(listBlobs1,MaxIPP(approxHessian0[1],approxHessian0[2],approxHessian0[3], percentage, THRESHOLD),0,2);
01133 timeFlag("columnas primera octava");
01134
01135 for(int oct=1; oct<2; ++oct)
01136 { Resize(approxHessian0[1], approxHessian1[0],IPPI_INTER_NN);
01137
01138 detHessianColumns(integralFloat,approxHessian1[1],oct,1);
01139 detHessianColumns(integralFloat,approxHessian1[2],oct,2);
01140 detHessianColumns(integralFloat,approxHessian1[3],oct,3);
01141 listBlobs1=addBlobs(listBlobs1,MaxIPP(approxHessian1[0],approxHessian1[1],approxHessian1[2], percentage, THRESHOLD),oct,1);
01142 listBlobs1=addBlobs(listBlobs1,MaxIPP(approxHessian1[1],approxHessian1[2],approxHessian1[3], percentage,THRESHOLD),oct,2);
01143 }
01144
01145 }
01146 timeFlag("columnas");
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 setPropertyValue< QVImage<uChar> >("Output image 1", imageGaussian);
01214
01215
01216
01217
01218
01219
01220
01221
01222 setPropertyValue< QList<QVPolyline > >("BlobsMax1",listBlobs1);
01223
01224
01225
01226
01227
01228 timeFlag("shows");
01229
01230 }
01231 };
01232
01233 int main(int argc, char *argv[])
01234 {
01235 QVApplication app(argc, argv,
01236 "Example program for QVision library. It is an implementation of the SURF algorithm."
01237 );
01238
01239 QVMPlayerCamera camera1("Video 1");
01240 MyWorker worker("Surf Worker");
01241
01242 camera1.link(&worker,"Input image");
01243
01244 QVGUI interface;
01245
01246
01247 QVImageCanvas imageCanvas("Output image 1");
01248 imageCanvas.linkProperty(worker,"Output image 1");
01249
01250
01251 imageCanvas.linkProperty(worker,"BlobsMax1", Qt::green);
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291 return app.exec();
01292 }
01293
01294 #endif