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/qvdefaultgui.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 #define QVIMAGE_ITERATOR_WRITE(TYPE, IMAGE, ITERATOR) {} \
00040 TYPE * __qv_image_iterator_##ITERATOR##__ = IMAGE.getWriteData(); \
00041 const uInt __qv_iterator_col_inc_##ITERATOR##__ = IMAGE.getChannels(); \
00042 const uInt __qv_iterator_row_inc_##ITERATOR##__ = IMAGE.getStep()/sizeof(TYPE); \
00043 const uInt __qv_iterator_new_line_inc_##ITERATOR##__ = __qv_iterator_row_inc_##ITERATOR##__ - IMAGE.getCols();
00044
00045 #define QVIMAGE_ITERATOR_READ(TYPE, IMAGE, ITERATOR) \
00046 const TYPE * __qv_image_iterator_##ITERATOR##__ = IMAGE.getReadData(); \
00047 const uInt __qv_iterator_col_inc_##ITERATOR##__ = IMAGE.getChannels(); \
00048 const uInt __qv_iterator_row_inc_##ITERATOR##__ = IMAGE.getStep()/sizeof(TYPE); \
00049 const uInt __qv_iterator_new_line_inc_##ITERATOR##__ = __qv_iterator_row_inc_##ITERATOR##__ - IMAGE.getCols();
00050
00051
00052 QList<QPoint> MaxIPPRel( QVImage<sFloat> &image1, QVImage<sFloat> &image2, QVImage<sFloat> &image3, float threshold)
00053 {
00054
00055 QList<QPoint> listMax;
00056 float max1, min1, aux; int xmax, ymax;
00057 float max2, min2;
00058 float max3, min3;
00059 float max, min;
00060 QRect image1ROI=image1.getROI();
00061 QRect image2ROI=image2.getROI();
00062 QRect image3ROI=image3.getROI();
00063
00064 int rows=image3.getRows(), cols=image3.getCols();
00065 QVImage<sFloat> imageMax1(cols,rows), imageMax2(cols,rows), imageMax3(cols,rows);
00066 int beginx=image3.getROI().x(), beginy=image3.getROI().y();
00067 int endx=image3.getROI().width()+beginx, endy=image3.getROI().height()+beginy;
00068 imageMax1.setMarginROI(beginx);
00069 imageMax2.setMarginROI(beginx);
00070 imageMax3.setMarginROI(beginx);
00071
00072 image1.setMarginROI(beginx);
00073 imageMax1.setMarginROI(beginx);
00074 FilterMax(image1,imageMax1,3,3,QPoint(beginx+1,beginy+1));
00075 image2.setMarginROI(beginx);
00076 imageMax2.setMarginROI(beginx);
00077 FilterMax(image2,imageMax2,3,3,QPoint(beginx+1,beginy+1));
00078 imageMax3.setMarginROI(beginx);
00079 FilterMax(image3,imageMax3,3,3,QPoint(beginx+1,beginy+1));
00080
00081
00082 image1.setROI(image1ROI);
00083 image2.setROI(image2ROI);
00084 image3.setROI(image3ROI);
00085
00086
00087
00088
00089 QVIMAGE_INIT_READ(sFloat,imageMax1);
00090 QVIMAGE_INIT_WRITE(sFloat,imageMax2);
00091 QVIMAGE_INIT_READ(sFloat,imageMax3);
00092 QVIMAGE_INIT_READ(sFloat,image2);
00093
00094 QMap<sFloat,QPoint> listMap;
00095 sFloat faux;
00096 for(int row=beginy; row<endy; ++row)
00097 { for(int col=beginx; col<endx; ++col)
00098 { faux = QVIMAGE_PIXEL(imageMax2,col,row,0);
00099 if ((faux == QVIMAGE_PIXEL(image2,col,row,0)) && (faux > QVIMAGE_PIXEL(imageMax1,col,row,0)) && (faux > QVIMAGE_PIXEL(imageMax3,col,row,0)))
00100 { listMap.insertMulti(faux,QPoint(col,row));
00101 }
00102 }
00103 }
00104 QList<QPoint> valuesList = listMap.values();
00105 QList<QPoint> listFiltered;
00106 int miThreshold = threshold * valuesList.size();
00107 for(int i=valuesList.size()-miThreshold; i<valuesList.size(); ++i)
00108 listFiltered.append(valuesList[i]);
00109 return(listFiltered);
00110 }
00111
00112
00114
00116 #define QVIMAGE_ITERATOR_INIT2(TYPE, IMAGE) {} \
00117 const uInt __qv_iterator_col_inc_##IMAGE##__ = IMAGE.getChannels(); \
00118 const uInt __qv_iterator_row_inc_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00119 const uInt __qv_iterator_new_line_inc_##IMAGE##__ = __qv_iterator_row_inc_##IMAGE##__ - IMAGE.getCols();
00120
00121 #define QVIMAGE_ITERATOR_ROW_INCREMENT(IMAGE) ( __qv_iterator_row_inc_##IMAGE##__ )
00122 #define QVIMAGE_ITERATOR_COL_INCREMENT(IMAGE) ( __qv_iterator_col_inc_##IMAGE##__ )
00123 #define QVIMAGE_ITERATOR_NEW_LINE_INCREMENT(IMAGE) ( __qv_iterator_new_line_inc_##IMAGE##__ )
00124
00125 QList<QPoint> MaxIPPAbs( QVImage<sFloat> &image1, QVImage<sFloat> &image2, QVImage<sFloat> &image3, float threshold)
00126 {
00127
00128 QList<QPoint> listMax;
00129 float max1, min1, aux; int xmax, ymax;
00130 float max2, min2;
00131 float max3, min3;
00132 float max, min;
00133 QRect image1ROI=image1.getROI();
00134 QRect image2ROI=image2.getROI();
00135 QRect image3ROI=image3.getROI();
00136
00137 int rows=image3.getRows(), cols=image3.getCols();
00138 QVImage<sFloat> imageMax1(cols,rows), imageMax2(cols,rows), imageMax3(cols,rows);
00139 int beginx=image3.getROI().x(), beginy=image3.getROI().y();
00140 int endx=image3.getROI().width()+beginx, endy=image3.getROI().height()+beginy;
00141 imageMax1.setMarginROI(beginx);
00142 imageMax2.setMarginROI(beginx);
00143 imageMax3.setMarginROI(beginx);
00144
00145 image1.setMarginROI(beginx);
00146 imageMax1.setMarginROI(beginx);
00147 FilterMax(image1,imageMax1,3,3,QPoint(beginx+1,beginy+1));
00148 image2.setMarginROI(beginx);
00149 imageMax2.setMarginROI(beginx);
00150 FilterMax(image2,imageMax2,3,3,QPoint(beginx+1,beginy+1));
00151 imageMax3.setMarginROI(beginx);
00152 FilterMax(image3,imageMax3,3,3,QPoint(beginx+1,beginy+1));
00153
00154
00155 image1.setROI(image1ROI);
00156 image2.setROI(image2ROI);
00157 image3.setROI(image3ROI);
00158
00159
00160
00161
00162 QVIMAGE_INIT_READ(sFloat,imageMax1);
00163 QVIMAGE_INIT_WRITE(sFloat,imageMax2);
00164 QVIMAGE_INIT_READ(sFloat,imageMax3);
00165 QVIMAGE_INIT_READ(sFloat,image2);
00166
00167
00168
00169
00170
00171
00172 const sFloat *imageMax1Ptr = &imageMax1(beginx, beginy);
00173 const sFloat *imageMax2Ptr = &imageMax2(beginx, beginy);
00174 const sFloat *imageMax3Ptr = &imageMax3(beginx, beginy);
00175 const sFloat *image2Ptr = &image2(beginx, beginy);
00176
00177 QList<QPoint> listFiltered;
00178 sFloat faux;
00179 for(int row=beginy; row<endy; ++row, imageMax1Ptr = &QVIMAGE_PIXEL(imageMax1,0,row,0), imageMax2Ptr = &QVIMAGE_PIXEL(imageMax2,0,row,0),
00180 imageMax3Ptr = &QVIMAGE_PIXEL(imageMax3,0,row,0), image2Ptr = &QVIMAGE_PIXEL(image2,0,row,0) )
00181 { for(int col=beginx; col<endx; ++col, ++imageMax1Ptr, ++imageMax2Ptr, ++imageMax3Ptr, ++image2Ptr)
00182 { faux = *imageMax2Ptr;
00183 if ((faux > threshold) && (faux == *image2Ptr) && (faux > *imageMax1Ptr) && (faux > *imageMax3Ptr))
00184 { listFiltered.append(QPoint(col,row));
00185 }
00186 }
00187 }
00188 return(listFiltered);
00189 }
00190
00191
00192 void detHessianRowsNaive1(const QVImage<sInt> &integralImage, QVImage<sFloat> &hessian, int octave, int scale)
00193 {
00194 const int cols = integralImage.getROI().width(), rows = integralImage.getROI().height();
00195 const int sizeMask=9 + 6*octave + scale*(6 << octave);
00196 const int step= 1;
00197 const int colsHessian = cols/step, rowsHessian = rows/step;
00198 const int marginHessian = ((sizeMask)/2)/step+1;
00199 const int marginImage = sizeMask/2;
00200 const int w = 5 + 4*octave + scale*(4 << octave);
00201 const int h = 3 + 2*octave + scale*(2 << octave);
00202 const int margin = 2 + 1*octave + scale*(1<<octave);
00203 const int marginDxy = 1 + 1*octave + scale*(1<<octave);
00204 const int wDxy = 3 + 2*octave + scale*(2 << octave);
00205 const int hDxy = 3 + 2*octave + scale*(2 << octave);
00206 const int beginxDxx=0, beginyDxx=margin;
00207 const int beginxDyy=margin, beginyDyy=0;
00208 const int beginxDxy=marginDxy, beginyDxy=marginDxy;
00209 register sFloat Dxx, Dyy, Dxy;
00210 const float division = 1.0/(sizeMask*sizeMask*sizeMask*sizeMask);
00211
00212
00213 QVIMAGE_INIT_WRITE(sFloat,hessian);
00214
00215 QVIMAGE_ITERATOR_READ(sInt, integralImage, itIntegral);
00216 __qv_image_iterator_itIntegral__ += integralImage.getROI().y()*__qv_iterator_row_inc_itIntegral__+integralImage.getROI().x();
00217
00218
00219 const sInt *itaDyy, *itcDyy, *iteDyy, *itgDyy, *itbDyy, *itdDyy, *itfDyy, *ithDyy;
00220 const sInt *itaDxx, *itcDxx, *iteDxx, *itgDxx, *itbDxx, *itdDxx, *itfDxx, *ithDxx;
00221 const sInt *itaDxy, *itbDxy, *itcDxy, *itdDxy, *iteDxy, *itfDxy, *itgDxy, *ithDxy;
00222 const sInt *itiDxy, *itjDxy, *itkDxy, *itlDxy, *itmDxy, *itnDxy, *itoDxy, *itpDxy;
00223 const sInt *itbeginaDyy, *itbegincDyy, *itbegineDyy, *itbegingDyy, *itbeginbDyy, *itbegindDyy, *itbeginfDyy, *itbeginhDyy;
00224 const sInt *itbeginaDxx, *itbegincDxx, *itbegineDxx, *itbegingDxx, *itbeginbDxx, *itbegindDxx, *itbeginfDxx, *itbeginhDxx;
00225 const sInt *itbeginaDxy, *itbeginbDxy, *itbegincDxy, *itbegindDxy, *itbegineDxy, *itbeginfDxy, *itbegingDxy, *itbeginhDxy;
00226 const sInt *itbeginiDxy, *itbeginjDxy, *itbeginkDxy, *itbeginlDxy, *itbeginmDxy, *itbeginnDxy, *itbeginoDxy, *itbeginpDxy;
00227
00228 const sInt *punteroComienzoDyy=__qv_image_iterator_itIntegral__+beginxDyy;
00229 const sInt *punteroComienzoDxx=__qv_image_iterator_itIntegral__+beginyDxx*__qv_iterator_row_inc_itIntegral__;
00230 const sInt *punteroComienzoDxy=__qv_image_iterator_itIntegral__+beginyDxy*__qv_iterator_row_inc_itIntegral__+beginxDxy;
00231
00232 itbeginaDyy = punteroComienzoDyy;
00233 itbeginbDyy = punteroComienzoDyy + w;
00234 itbegincDyy = punteroComienzoDyy+h*__qv_iterator_row_inc_itIntegral__;
00235 itbegindDyy = punteroComienzoDyy+h*__qv_iterator_row_inc_itIntegral__+w;
00236 itbegineDyy = punteroComienzoDyy+2*h*__qv_iterator_row_inc_itIntegral__;
00237 itbeginfDyy = punteroComienzoDyy+2*h*__qv_iterator_row_inc_itIntegral__+w;
00238 itbegingDyy = punteroComienzoDyy+3*h*__qv_iterator_row_inc_itIntegral__;
00239 itbeginhDyy = punteroComienzoDyy+3*h*__qv_iterator_row_inc_itIntegral__+w;
00240
00241 itbeginaDxx = punteroComienzoDxx;
00242 itbeginbDxx = punteroComienzoDxx + h;
00243 itbegincDxx = punteroComienzoDxx+ 2*h;
00244 itbegindDxx = punteroComienzoDxx+ 3*h;
00245 itbegineDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__;
00246 itbeginfDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__+h;
00247 itbegingDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__+2*h;
00248 itbeginhDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__+3*h;
00249
00250 itbeginaDxy = punteroComienzoDxy;
00251 itbeginbDxy = punteroComienzoDxy + wDxy;
00252 itbegincDxy = punteroComienzoDxy+ wDxy+1;
00253 itbegindDxy = punteroComienzoDxy+ 2*wDxy+1;
00254 itbegineDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__;
00255 itbeginfDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__+wDxy;
00256 itbegingDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__+wDxy+1;
00257 itbeginhDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__+2*wDxy+1;
00258 itbeginiDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__;
00259 itbeginjDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy;
00260 itbeginkDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy+1;
00261 itbeginlDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__+2*wDxy+1;
00262 itbeginmDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__;
00263 itbeginnDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy;
00264 itbeginoDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy+1;
00265 itbeginpDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__+2*wDxy+1;
00266
00267 for(int row=0,rowh=marginHessian; row<rows-sizeMask;
00268 row++, ++rowh,
00269 itbeginaDyy+=__qv_iterator_row_inc_itIntegral__, itbeginbDyy+=__qv_iterator_row_inc_itIntegral__, itbegincDyy+=__qv_iterator_row_inc_itIntegral__, itbegindDyy+=__qv_iterator_row_inc_itIntegral__, itbegineDyy+=__qv_iterator_row_inc_itIntegral__, itbeginfDyy+=__qv_iterator_row_inc_itIntegral__, itbegingDyy+=__qv_iterator_row_inc_itIntegral__, itbeginhDyy+=__qv_iterator_row_inc_itIntegral__,
00270
00271 itbeginaDxx+=__qv_iterator_row_inc_itIntegral__, itbeginbDxx+=__qv_iterator_row_inc_itIntegral__, itbegincDxx+=__qv_iterator_row_inc_itIntegral__, itbegindDxx+=__qv_iterator_row_inc_itIntegral__, itbegineDxx+=__qv_iterator_row_inc_itIntegral__, itbeginfDxx+=__qv_iterator_row_inc_itIntegral__, itbegingDxx+=__qv_iterator_row_inc_itIntegral__, itbeginhDxx+=__qv_iterator_row_inc_itIntegral__,
00272
00273 itbeginaDxy+=__qv_iterator_row_inc_itIntegral__, itbeginbDxy+=__qv_iterator_row_inc_itIntegral__, itbegincDxy+=__qv_iterator_row_inc_itIntegral__, itbegindDxy+=__qv_iterator_row_inc_itIntegral__, itbegineDxy+=__qv_iterator_row_inc_itIntegral__, itbeginfDxy+=__qv_iterator_row_inc_itIntegral__, itbegingDxy+=__qv_iterator_row_inc_itIntegral__, itbeginhDxy+=__qv_iterator_row_inc_itIntegral__,
00274 itbeginiDxy+=__qv_iterator_row_inc_itIntegral__, itbeginjDxy+=__qv_iterator_row_inc_itIntegral__, itbeginkDxy+=__qv_iterator_row_inc_itIntegral__, itbeginlDxy+=__qv_iterator_row_inc_itIntegral__, itbeginmDxy+=__qv_iterator_row_inc_itIntegral__, itbeginnDxy+=__qv_iterator_row_inc_itIntegral__, itbeginoDxy+=__qv_iterator_row_inc_itIntegral__, itbeginpDxy+=__qv_iterator_row_inc_itIntegral__
00275 )
00276 {
00277 itaDyy = itbeginaDyy; itbDyy = itbeginbDyy; itcDyy = itbegincDyy; itdDyy = itbegindDyy;
00278 iteDyy = itbegineDyy; itfDyy = itbeginfDyy; itgDyy = itbegingDyy; ithDyy = itbeginhDyy;
00279
00280 itaDxx = itbeginaDxx; itbDxx = itbeginbDxx; itcDxx = itbegincDxx; itdDxx = itbegindDxx;
00281 iteDxx = itbegineDxx; itfDxx = itbeginfDxx; itgDxx = itbegingDxx; ithDxx = itbeginhDxx;
00282
00283 itaDxy = itbeginaDxy; itbDxy = itbeginbDxy; itcDxy = itbegincDxy; itdDxy = itbegindDxy;
00284 iteDxy = itbegineDxy; itfDxy = itbeginfDxy; itgDxy = itbegingDxy; ithDxy = itbeginhDxy;
00285 itiDxy = itbeginiDxy; itjDxy = itbeginjDxy; itkDxy = itbeginkDxy; itlDxy = itbeginlDxy;
00286 itmDxy = itbeginmDxy; itnDxy = itbeginnDxy; itoDxy = itbeginoDxy; itpDxy = itbeginpDxy;
00287
00288 for(int col=0,colh=marginHessian; col<cols-sizeMask;
00289 col++, ++colh,
00290 itaDyy+=step, itbDyy+=step, itcDyy+=step, itdDyy+=step, iteDyy+=step, itfDyy+=step, itgDyy+=step, ithDyy+=step,
00291 itaDxx+=step, itbDxx+=step, itcDxx+=step, itdDxx+=step, iteDxx+=step, itfDxx+=step, itgDxx+=step, ithDxx+=step,
00292 itaDxy+=step, itbDxy+=step, itcDxy+=step, itdDxy+=step, iteDxy+=step, itfDxy+=step, itgDxy+=step, ithDxy+=step,
00293 itiDxy+=step, itjDxy+=step, itkDxy+=step, itlDxy+=step, itmDxy+=step, itnDxy+=step, itoDxy+=step, itpDxy+=step)
00294 { sInt Dyy, Dxx, Dxy;
00295 sFloat det;
00296 Dyy=(((*itaDyy)-(*itbDyy)+(*ithDyy)-(*itgDyy)+3*((*itdDyy)+(*iteDyy)-(*itcDyy)-(*itfDyy))));
00297 Dxx=((*itaDxx)+(*ithDxx)-(*itdDxx)-(*iteDxx)+3*((*itfDxx)+(*itcDxx)-(*itbDxx)-(*itgDxx)));
00298 Dxy=(((*itaDxy)-(*itbDxy)-(*iteDxy)+(*itfDxy))+((*itkDxy)-(*itlDxy)-(*itoDxy)+(*itpDxy))-((*itcDxy)-(*itdDxy)-(*itgDxy)+(*ithDxy))-((*itiDxy)-(*itjDxy)-(*itmDxy)+(*itnDxy)));
00299
00300 det = ( Dxx * Dyy -0.81*Dxy*Dxy );
00301 det = (det < 0.0) ? 0.0 : det*division;
00302 QVIMAGE_PIXEL(hessian,colh,rowh,0) = det;
00303
00304 }
00305 }
00306
00307 }
00308
00309
00310 void detHessianRowsNaive(const QVImage<sInt> &integralImage, QVImage<sFloat> &hessian, int octave, int scale)
00311 {
00312 const int cols = integralImage.getROI().width(), rows = integralImage.getROI().height();
00313 const int sizeMask=9 + 6*octave + scale*(6 << octave);
00314 const int step= 1 << octave;
00315 const int colsHessian = cols/step, rowsHessian = rows/step;
00316 const int marginHessian = ((sizeMask)/2)/step;
00317 const int marginImage = sizeMask/2+step/2;
00318 const int w = 5 + 4*octave + scale*(4 << octave);
00319 const int h = 3 + 2*octave + scale*(2 << octave);
00320 const int margin = 2 + 1*octave + scale*(1<<octave);
00321 const int marginDxy = 1 + 1*octave + scale*(1<<octave);
00322 const int wDxy = 3 + 2*octave + scale*(2 << octave);
00323 const int hDxy = 3 + 2*octave + scale*(2 << octave);
00324 const int beginxDxx=0, beginyDxx=margin;
00325 const int beginxDyy=margin, beginyDyy=0;
00326 const int beginxDxy=marginDxy, beginyDxy=marginDxy;
00327 register sFloat Dxx, Dyy, Dxy;
00328 const float division = 1.0/(sizeMask*sizeMask*sizeMask*sizeMask);
00329
00330
00331 QVIMAGE_INIT_WRITE(sFloat,hessian);
00332
00333 QVIMAGE_ITERATOR_READ(sInt, integralImage, itIntegral);
00334 __qv_image_iterator_itIntegral__ += integralImage.getROI().y()*__qv_iterator_row_inc_itIntegral__+integralImage.getROI().x();
00335
00336
00337 const sInt *itaDyy, *itcDyy, *iteDyy, *itgDyy, *itbDyy, *itdDyy, *itfDyy, *ithDyy;
00338 const sInt *itaDxx, *itcDxx, *iteDxx, *itgDxx, *itbDxx, *itdDxx, *itfDxx, *ithDxx;
00339 const sInt *itaDxy, *itbDxy, *itcDxy, *itdDxy, *iteDxy, *itfDxy, *itgDxy, *ithDxy;
00340 const sInt *itiDxy, *itjDxy, *itkDxy, *itlDxy, *itmDxy, *itnDxy, *itoDxy, *itpDxy;
00341 const sInt *itbeginaDyy, *itbegincDyy, *itbegineDyy, *itbegingDyy, *itbeginbDyy, *itbegindDyy, *itbeginfDyy, *itbeginhDyy;
00342 const sInt *itbeginaDxx, *itbegincDxx, *itbegineDxx, *itbegingDxx, *itbeginbDxx, *itbegindDxx, *itbeginfDxx, *itbeginhDxx;
00343 const sInt *itbeginaDxy, *itbeginbDxy, *itbegincDxy, *itbegindDxy, *itbegineDxy, *itbeginfDxy, *itbegingDxy, *itbeginhDxy;
00344 const sInt *itbeginiDxy, *itbeginjDxy, *itbeginkDxy, *itbeginlDxy, *itbeginmDxy, *itbeginnDxy, *itbeginoDxy, *itbeginpDxy;
00345
00346 const sInt *punteroComienzoDyy=__qv_image_iterator_itIntegral__+beginxDyy;
00347 const sInt *punteroComienzoDxx=__qv_image_iterator_itIntegral__+beginyDxx*__qv_iterator_row_inc_itIntegral__;
00348 const sInt *punteroComienzoDxy=__qv_image_iterator_itIntegral__+beginyDxy*__qv_iterator_row_inc_itIntegral__+beginxDxy;
00349
00350 itbeginaDyy = punteroComienzoDyy;
00351 itbeginbDyy = punteroComienzoDyy + w;
00352 itbegincDyy = punteroComienzoDyy+h*__qv_iterator_row_inc_itIntegral__;
00353 itbegindDyy = punteroComienzoDyy+h*__qv_iterator_row_inc_itIntegral__+w;
00354 itbegineDyy = punteroComienzoDyy+2*h*__qv_iterator_row_inc_itIntegral__;
00355 itbeginfDyy = punteroComienzoDyy+2*h*__qv_iterator_row_inc_itIntegral__+w;
00356 itbegingDyy = punteroComienzoDyy+3*h*__qv_iterator_row_inc_itIntegral__;
00357 itbeginhDyy = punteroComienzoDyy+3*h*__qv_iterator_row_inc_itIntegral__+w;
00358
00359 itbeginaDxx = punteroComienzoDxx;
00360 itbeginbDxx = punteroComienzoDxx + h;
00361 itbegincDxx = punteroComienzoDxx+ 2*h;
00362 itbegindDxx = punteroComienzoDxx+ 3*h;
00363 itbegineDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__;
00364 itbeginfDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__+h;
00365 itbegingDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__+2*h;
00366 itbeginhDxx = punteroComienzoDxx+w*__qv_iterator_row_inc_itIntegral__+3*h;
00367
00368 itbeginaDxy = punteroComienzoDxy;
00369 itbeginbDxy = punteroComienzoDxy + wDxy;
00370 itbegincDxy = punteroComienzoDxy+ wDxy+1;
00371 itbegindDxy = punteroComienzoDxy+ 2*wDxy+1;
00372 itbegineDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__;
00373 itbeginfDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__+wDxy;
00374 itbegingDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__+wDxy+1;
00375 itbeginhDxy = punteroComienzoDxy+wDxy*__qv_iterator_row_inc_itIntegral__+2*wDxy+1;
00376 itbeginiDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__;
00377 itbeginjDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy;
00378 itbeginkDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy+1;
00379 itbeginlDxy = punteroComienzoDxy+(wDxy+1)*__qv_iterator_row_inc_itIntegral__+2*wDxy+1;
00380 itbeginmDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__;
00381 itbeginnDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy;
00382 itbeginoDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__+wDxy+1;
00383 itbeginpDxy = punteroComienzoDxy+(2*wDxy+1)*__qv_iterator_row_inc_itIntegral__+2*wDxy+1;
00384
00385 const int incRowStep=step*__qv_iterator_row_inc_itIntegral__;
00386 const float norm_Dxy=0.81/(wDxy*wDxy*hDxy*hDxy);
00387 const float norm_Dxx=1.0/(w*w*h*h);
00388 for(int row=0,rowh=marginHessian; row<rows-sizeMask;
00389 row+=step, ++rowh,
00390 itbeginaDyy+=incRowStep, itbeginbDyy+=incRowStep, itbegincDyy+=incRowStep, itbegindDyy+=incRowStep, itbegineDyy+=incRowStep,
00391 itbeginfDyy+=incRowStep, itbegingDyy+=incRowStep, itbeginhDyy+=incRowStep,
00392 itbeginaDxx+=incRowStep, itbeginbDxx+=incRowStep, itbegincDxx+=incRowStep, itbegindDxx+=incRowStep, itbegineDxx+=incRowStep,
00393 itbeginfDxx+=incRowStep, itbegingDxx+=incRowStep, itbeginhDxx+=incRowStep,
00394
00395 itbeginaDxy+=incRowStep, itbeginbDxy+=incRowStep, itbegincDxy+=incRowStep, itbegindDxy+=incRowStep, itbegineDxy+=incRowStep,
00396 itbeginfDxy+=incRowStep, itbegingDxy+=incRowStep, itbeginhDxy+=incRowStep,
00397 itbeginiDxy+=incRowStep, itbeginjDxy+=incRowStep, itbeginkDxy+=incRowStep, itbeginlDxy+=incRowStep, itbeginmDxy+=incRowStep,
00398 itbeginnDxy+=incRowStep, itbeginoDxy+=incRowStep, itbeginpDxy+=incRowStep
00399 )
00400 {
00401 itaDyy = itbeginaDyy; itbDyy = itbeginbDyy; itcDyy = itbegincDyy; itdDyy = itbegindDyy;
00402 iteDyy = itbegineDyy; itfDyy = itbeginfDyy; itgDyy = itbegingDyy; ithDyy = itbeginhDyy;
00403
00404 itaDxx = itbeginaDxx; itbDxx = itbeginbDxx; itcDxx = itbegincDxx; itdDxx = itbegindDxx;
00405 iteDxx = itbegineDxx; itfDxx = itbeginfDxx; itgDxx = itbegingDxx; ithDxx = itbeginhDxx;
00406
00407 itaDxy = itbeginaDxy; itbDxy = itbeginbDxy; itcDxy = itbegincDxy; itdDxy = itbegindDxy;
00408 iteDxy = itbegineDxy; itfDxy = itbeginfDxy; itgDxy = itbegingDxy; ithDxy = itbeginhDxy;
00409 itiDxy = itbeginiDxy; itjDxy = itbeginjDxy; itkDxy = itbeginkDxy; itlDxy = itbeginlDxy;
00410 itmDxy = itbeginmDxy; itnDxy = itbeginnDxy; itoDxy = itbeginoDxy; itpDxy = itbeginpDxy;
00411
00412 for(int col=0,colh=marginHessian; col<cols-sizeMask;
00413 col+=step, ++colh,
00414 itaDyy+=step, itbDyy+=step, itcDyy+=step, itdDyy+=step, iteDyy+=step, itfDyy+=step, itgDyy+=step, ithDyy+=step,
00415 itaDxx+=step, itbDxx+=step, itcDxx+=step, itdDxx+=step, iteDxx+=step, itfDxx+=step, itgDxx+=step, ithDxx+=step,
00416 itaDxy+=step, itbDxy+=step, itcDxy+=step, itdDxy+=step, iteDxy+=step, itfDxy+=step, itgDxy+=step, ithDxy+=step,
00417 itiDxy+=step, itjDxy+=step, itkDxy+=step, itlDxy+=step, itmDxy+=step, itnDxy+=step, itoDxy+=step, itpDxy+=step)
00418 { sInt Dyy, Dxx, Dxy;
00419 sFloat det;
00420 Dyy=(((*itaDyy)-(*itbDyy)+(*ithDyy)-(*itgDyy)+3*((*itdDyy)+(*iteDyy)-(*itcDyy)-(*itfDyy))));
00421 Dxx=((*itaDxx)+(*ithDxx)-(*itdDxx)-(*iteDxx)+3*((*itfDxx)+(*itcDxx)-(*itbDxx)-(*itgDxx)));
00422 Dxy=(((*itaDxy)-(*itbDxy)-(*iteDxy)+(*itfDxy))+((*itkDxy)-(*itlDxy)-(*itoDxy)+(*itpDxy))-((*itcDxy)-(*itdDxy)-(*itgDxy)+(*ithDxy))-((*itiDxy)-(*itjDxy)-(*itmDxy)+(*itnDxy)));
00423
00424 det = ( Dxx * Dyy * norm_Dxx - Dxy*Dxy*norm_Dxy );
00425 det = (det < 0.0) ? 0.0 : det;
00426 QVIMAGE_PIXEL(hessian,colh,rowh,0) = det;
00427
00428 }
00429 }
00430
00431 }
00432
00433
00434 QList<QVPolyline> addBlobs(QList<QVPolyline> listBlobs, QList<QPoint> listPoints, int octave, int scale)
00435 { const int radius=4+3*octave+scale*(3<<octave);
00436 const int sizeMask=9 + 6*octave + scale*(6 << octave);
00437 const int step= 1 << octave;
00438
00439 for(QList<QPoint>::const_iterator i=listPoints.constBegin(); i!=listPoints.constEnd(); ++i)
00440 listBlobs.append(QVPolyline::ellipse(10,i->x()*step,i->y()*step,radius,radius,0));
00441 return(listBlobs);
00442 }
00443
00444
00445 QList<QVPolyline> getBlobsRowsNaive(QVImage<sInt> &integralInt, float THRESHOLD)
00446 { int cols=integralInt.getCols(), rows=integralInt.getRows();
00447 QVImage<sFloat> approxHessian0[4]={QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows),
00448 QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows)};
00449 QVImage<sFloat> approxHessian1[4]={QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2),
00450 QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2)};
00451 QVImage<sFloat> approxHessian2[4]={QVImage<sFloat>(cols/4,rows/4),QVImage<sFloat>(cols/4,rows/4),
00452 QVImage<sFloat>(cols/4,rows/4),QVImage<sFloat>(cols/4,rows/4)};
00453 QList<QVPolyline> listBlobs;
00454
00455 int oct=0;
00456 for(int sca=0; sca<4; ++sca)
00457 detHessianRowsNaive(integralInt,approxHessian0[sca],oct,sca);
00458 listBlobs=addBlobs(listBlobs,MaxIPPRel(approxHessian0[0],approxHessian0[1],approxHessian0[2], THRESHOLD),oct,1);
00459 listBlobs=addBlobs(listBlobs,MaxIPPRel(approxHessian0[1],approxHessian0[2],approxHessian0[3], THRESHOLD),oct,2);
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 return(listBlobs);
00479 }
00480
00481
00482 class MyWorker: public QVWorker
00483 {
00484 public:
00485 MyWorker(QString name): QVWorker(name)
00486 {
00487 addProperty<double>("Threshold", inputFlag, 100.0, "Threshold",1.0,10000.0);
00488 addProperty< QVImage<uChar> >("Input image", inputFlag|outputFlag);
00489 addProperty< QVImage<uChar> >("Output image 1", outputFlag);
00490 addProperty< QVImage<sFloat> >("Output image 2", outputFlag);
00491 addProperty< QVImage<sFloat> >("Output image 3", outputFlag);
00492 addProperty< QVImage<sFloat> >("Output image 4", outputFlag);
00493 addProperty< QVImage<sFloat> >("Output image 5", outputFlag);
00494 addProperty< QVImage<sFloat> >("Output image 6", outputFlag);
00495 addProperty< QList<QVPolyline> >("BlobsMax1",outputFlag);
00496
00497 }
00498
00499 void iterate()
00500 {
00501 sFloat THRESHOLD = getPropertyValue<sFloat>("Threshold");
00502 QVImage<uChar> input0 = getPropertyValue< QVImage<uChar> >("Input image");
00503 uInt rows = input0.getRows()*2, cols = input0.getCols()*2;
00504
00505 QVImage<uChar> input(cols, rows);
00506 Resize(input0, input,IPPI_INTER_NN);
00507 timeFlag("double size");
00508 QVImage<uChar> imageGaussian(cols,rows);
00509
00510 FilterGauss(input,imageGaussian,3,QPoint(1,1));
00511 QVImage<sInt> integralInt(cols,rows);
00512 integralInt.setROI(1,1,cols-2,rows-2);
00513 Integral(imageGaussian,integralInt,0,QPoint(1,1));
00514
00515 timeFlag("integral");
00516
00517
00518
00519 QList<QVPolyline> listBlobs;
00520
00521
00522 QVImage<sFloat> approxHessian0[4]={QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows),
00523 QVImage<sFloat>(cols,rows),QVImage<sFloat>(cols,rows)};
00524 QVImage<sFloat> approxHessian1[4]={QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2),
00525 QVImage<sFloat>(cols/2,rows/2),QVImage<sFloat>(cols/2,rows/2)};
00526 QVImage<sFloat> approxHessian2[4]={QVImage<sFloat>(cols/4,rows/4),QVImage<sFloat>(cols/4,rows/4),
00527 QVImage<sFloat>(cols/4,rows/4),QVImage<sFloat>(cols/4,rows/4)};
00528
00529
00530
00531
00532
00533
00534
00535
00536 int oct=0;
00537
00538
00539 timeFlag("a cero");
00540 Set(approxHessian0[0],0.0);
00541 Set(approxHessian0[1],0.0);
00542 Set(approxHessian0[2],0.0);
00543 Set(approxHessian0[3],0.0);
00544
00545 for(int sca=0; sca<4; ++sca)
00546 detHessianRowsNaive(integralInt,approxHessian0[sca],oct,sca);
00547 timeFlag("nuevo oct0");
00548
00549 listBlobs=addBlobs(listBlobs,MaxIPPAbs(approxHessian0[0],approxHessian0[1],approxHessian0[2], THRESHOLD),oct,1);
00550 listBlobs=addBlobs(listBlobs,MaxIPPAbs(approxHessian0[1],approxHessian0[2],approxHessian0[3], THRESHOLD),oct,2);
00551
00552 timeFlag("lista de blobs oct0");
00553
00554 oct=1;
00555 Set(approxHessian1[0],0.0);
00556 Set(approxHessian1[1],0.0);
00557 Set(approxHessian1[2],0.0);
00558 Set(approxHessian1[3],0.0);
00559 timeFlag("a cero1");
00560
00561 Resize(approxHessian0[1], approxHessian1[0],IPPI_INTER_NN);
00562 detHessianRowsNaive(integralInt,approxHessian1[1],oct,1);
00563 detHessianRowsNaive(integralInt,approxHessian1[2],oct,2);
00564 detHessianRowsNaive(integralInt,approxHessian1[3],oct,3);
00565 timeFlag("nuevo oct1");
00566 listBlobs=addBlobs(listBlobs,MaxIPPAbs(approxHessian1[0],approxHessian1[1],approxHessian1[2], THRESHOLD),oct,1);
00567 listBlobs=addBlobs(listBlobs,MaxIPPAbs(approxHessian1[1],approxHessian1[2],approxHessian1[3], THRESHOLD),oct,2);
00568 timeFlag("lista de blobs oct1");
00569
00570
00571 oct=2;
00572 Set(approxHessian2[0],0.0);
00573 Set(approxHessian2[1],0.0);
00574 Set(approxHessian2[2],0.0);
00575 Set(approxHessian2[3],0.0);
00576 timeFlag("a cero2");
00577
00578 Resize(approxHessian1[1], approxHessian2[0],IPPI_INTER_NN);
00579 detHessianRowsNaive(integralInt,approxHessian2[1],oct,1);
00580 detHessianRowsNaive(integralInt,approxHessian2[2],oct,2);
00581 detHessianRowsNaive(integralInt,approxHessian2[3],oct,3);
00582 timeFlag("nuevo oct2");
00583
00584 listBlobs=addBlobs(listBlobs,MaxIPPAbs(approxHessian2[0],approxHessian2[1],approxHessian2[2], THRESHOLD),oct,1);
00585 listBlobs=addBlobs(listBlobs,MaxIPPAbs(approxHessian2[1],approxHessian2[2],approxHessian2[3], THRESHOLD),oct,2);
00586 timeFlag("lista de blobs oct2");
00587
00588
00589
00590 setPropertyValue< QVImage<uChar> >("Output image 1", imageGaussian);
00591 setPropertyValue< QList<QVPolyline > >("BlobsMax1",listBlobs);
00592 setPropertyValue< QVImage<sFloat> >("Output image 2", approxHessian1[0]);
00593 setPropertyValue< QVImage<sFloat> >("Output image 3", approxHessian1[1]);
00594 setPropertyValue< QVImage<sFloat> >("Output image 4", approxHessian1[2]);
00595 setPropertyValue< QVImage<sFloat> >("Output image 5", approxHessian1[3]);
00596
00597
00598
00599 timeFlag("shows");
00600
00601 }
00602 };
00603
00604 int main(int argc, char *argv[])
00605 { ippSetNumThreads(1);
00606 QVApplication app(argc, argv,
00607 "Example program for QVision library. It is an implementation of the SURF algorithm."
00608 );
00609
00610 QVMPlayerCamera camera1("Video 1");
00611 MyWorker worker("Surf Worker");
00612
00613 camera1.link(&worker,"Input image");
00614
00615 QVDefaultGUI interface;
00616
00617
00618 QVImageCanvas imageCanvas1("Output image 1");
00619 imageCanvas1.linkProperty(worker,"Output image 1");
00620 imageCanvas1.linkProperty(worker,"BlobsMax1", Qt::green);
00621 QVImageCanvas imageCanvas2("Output image 2");
00622 imageCanvas2.linkProperty(worker,"Output image 2");
00623 QVImageCanvas imageCanvas3("Output image 3");
00624 imageCanvas3.linkProperty(worker,"Output image 3");
00625 QVImageCanvas imageCanvas4("Output image 4");
00626 imageCanvas4.linkProperty(worker,"Output image 4");
00627 QVImageCanvas imageCanvas5("Output image 5");
00628 imageCanvas5.linkProperty(worker,"Output image 5");
00629
00630
00631
00632
00633
00634
00635 return app.exec();
00636 }
00637
00638 #endif