subpixelcorner.cpp
Go to the documentation of this file.
00001 #include <aruco/subpixelcorner.h>
00002 #include <opencv2/imgproc/imgproc.hpp>
00003 using namespace cv;
00004 
00005 namespace aruco{
00006 
00007 SubPixelCorner::SubPixelCorner()
00008 {
00009     _winSize=15;
00010     _apertureSize=3;
00011     _term.maxCount=10;
00012     _term.epsilon=0.1;
00013     _term.type=CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
00014      enable=true;
00015 }
00016 
00017 void SubPixelCorner::checkTerm()
00018 {
00019     switch( _term.type)
00020     {
00021     case CV_TERMCRIT_ITER:
00022         _term.epsilon = 0.f;
00023         _term.maxCount;
00024         break;
00025     case CV_TERMCRIT_EPS:
00026         _term.maxCount=_term.COUNT;
00027         break;
00028     case CV_TERMCRIT_ITER | CV_TERMCRIT_EPS:
00029         break;
00030     default:
00031         _term.maxCount=_term.COUNT;
00032         _term.epsilon=0.1;
00033         _term.type=CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
00034     break;
00035     }
00036 
00037     eps = std::max( _term.epsilon ,0.0);
00038     eps=eps*eps;
00039 
00040     _max_iters= std::max( _term.maxCount, 1 );
00041     int max1=TermCriteria::MAX_ITER;
00042     _max_iters= std::min(_max_iters,max1);
00043 
00044 }
00045 
00046 double SubPixelCorner::pointDist(cv::Point2f estimate_corner,cv::Point2f curr_corner)
00047 {
00048     double dist=((curr_corner.x-estimate_corner.x)*(curr_corner.x-estimate_corner.x))+
00049                         ((curr_corner.y-estimate_corner.y)*(curr_corner.y-estimate_corner.y));
00050     return dist;
00051 }
00052 
00053 
00054 void SubPixelCorner::generateMask()
00055 {
00056 
00057      double coeff = 1. / (_winSize*_winSize);
00058      float * maskX=(float *)calloc(1,(_winSize*sizeof(float)));
00059      float * maskY=(float *)calloc(1,(_winSize*sizeof(float)));
00060      mask.create (_winSize,_winSize,CV_32FC(1));
00061     /* calculate mask */
00062      int k=0;
00063     for( int i = -_winSize/2, k = 0; i <= _winSize/2; i++, k++ )
00064     {
00065         maskX[k] = (float)exp( -i * i * coeff );
00066 
00067     }
00068 
00069         maskY = maskX;
00070 
00071     for( int i = 0; i < _winSize; i++ )
00072     {
00073         float * mask_ptr=mask.ptr <float>(i);
00074         for( int j = 0; j < _winSize; j++ )
00075         {
00076             mask_ptr[j] = maskX[j] * maskY[i];
00077         }
00078     }
00079 
00080 }
00081 
00082 void SubPixelCorner::RefineCorner(cv::Mat image,std::vector <cv::Point2f> &corners)
00083 {
00084 
00085     if(enable==false)
00086         return;
00087     checkTerm();
00088 
00089     generateMask ();
00090     //loop over all the corner points
00091     for(int k=0;k<corners.size ();k++)
00092     {
00093         cv::Point2f curr_corner;
00094         //initial estimate
00095         cv::Point2f estimate_corner=corners[k];
00096 
00097 // cerr << 'SSS" << corners[k].x <<":" << corners[k].y << endl;
00098 
00099         if(estimate_corner.x<0 || estimate_corner.y<0 || estimate_corner.y >image.rows || estimate_corner.y > image.cols)
00100             continue;
00101         int iter=0;
00102         double dist=TermCriteria::EPS;
00103         //loop till termination criteria is met
00104         do
00105        {
00106         iter=iter+1;
00107         curr_corner=estimate_corner;
00108 
00109         /*
00110 Point cx;
00111 cx.x=floor(curr_corner.x);
00112 cx.y=floor(curr_corner.y);
00113 double dx=curr_corner.x-cx.x;
00114 double dy=curr_corner.y-cx.y;
00115 float vIx[2];
00116 float vIy[2];
00117 
00118 vIx[0] = dx;
00119 vIx[1] = 1 - dx;
00120 vIy[0] = dy;
00121 vIy[1] = 1 - dy;
00122 
00123 int x1=std::max((int)(cx.x-_winSize-_apertureSize/2),0);
00124 int y1=std::max((int)(cx.y-_winSize-_apertureSize/2),0);
00125 
00126 xmin = x1<0?0:x1;
00127 xmax = x1+_winSize<image.cols?x1+_winSize:image.cols-1;
00128 ymin = y1<0?0:y1;
00129 ymax = y1+_winSize<image.rows?y1+_winSize:image.rows-1;
00130 
00131 Rect roi=Rect(xmin,ymin,xmax-xmin,ymax-ymin);
00132 */
00133 
00134         Mat local;
00135         cv::getRectSubPix (image,Size(_winSize+2*(_apertureSize/2),_winSize+2*(_apertureSize/2)),curr_corner,local);
00136 
00137 
00138 
00139         cv::Mat Dx,Dy;
00140         //extracing image ROI about the corner point
00141         //Mat local=image(roi);
00142         //computing the gradients over the neighborhood about corner point
00143         cv::Sobel (local,Dx,CV_32FC(1),1,0,_apertureSize,1,0);
00144         cv::Sobel (local,Dy,CV_32FC(1),0,1,_apertureSize,1,0);
00145 
00146         //parameters requried for estimations
00147         double A=0,B=0,C=0,D=0,E=0,F=0;
00148         int lx=0,ly=0;
00149         for(int i=_apertureSize/2;i<=_winSize;i++)
00150         {
00151 
00152             float *dx_ptr=Dx.ptr <float>(i);
00153             float *dy_ptr=Dy.ptr <float>(i);
00154             ly=i-_winSize/2-_apertureSize/2;
00155 
00156             float * mask_ptr=mask.ptr <float>(ly+_winSize/2);
00157 
00158             for(int j=_apertureSize/2;j<=_winSize;j++)
00159             {
00160 
00161                 lx=j-_winSize/2-_apertureSize/2;
00162                 //cerr << lx+_winSize/2 << ":" ;
00163                 double val=mask_ptr[lx+_winSize/2];
00164                 double dxx=dx_ptr[j]*dx_ptr[j]*val;
00165                 double dyy=dy_ptr[j]*dy_ptr[j]*val;
00166                 double dxy=dx_ptr[j]*dy_ptr[j]*val;
00167 
00168                 A=A+dxx;
00169                 B=B+dxy;
00170                 E=E+dyy;
00171                 C=C+dxx*lx+dxy*ly;
00172                 F=F+dxy*lx+dyy*ly;
00173 
00174             }
00175         }
00176 
00177         //computing denominator
00178         double det=(A*E-B*B);
00179         if(fabs( det ) > DBL_EPSILON*DBL_EPSILON)
00180         {
00181          det=1.0/det;
00182         //translating back to original corner and adding new estimates
00183         estimate_corner.x=curr_corner.x+((C*E)-(B*F))*det;
00184         estimate_corner.y=curr_corner.y+((A*F)-(C*D))*det;
00185         }
00186         else
00187         {
00188             estimate_corner.x=curr_corner.x;
00189             estimate_corner.y=curr_corner.y;
00190         }
00191 
00192         dist=pointDist(estimate_corner,curr_corner);
00193 
00194 
00195         }while(iter<_max_iters && dist>eps);
00196 
00197         //double dist=pointDist(corners[k],estimate_corner);
00198         if(fabs(corners[k].x-estimate_corner.x) > _winSize || fabs(corners[k].y-estimate_corner.y)>_winSize)
00199         {
00200             estimate_corner.x=corners[k].x;
00201             estimate_corner.y=corners[k].y;
00202         }
00203         corners[k].x=estimate_corner.x;
00204         corners[k].y=estimate_corner.y;
00205         //cerr << "EEE" << corners[k].x <<":" << corners[k].y << endl;
00206 
00207     }
00208 
00209 }
00210 
00211 }


ar_sys
Author(s): Hamdi Sahloul , Rafael Muñoz Salinas , Bence Magyar
autogenerated on Thu Aug 27 2015 12:23:55