/* * compute the second order. */ bool harrisCorners::getSecondOrder(channel& gx, channel& gy, channel& fxy) const { const parameters& par = getParameters(); fxy.resize(gx.size(),false,false); gaussKernel2D<float> gk(par.kernelSize,par.variance); convolution filter; convolution::parameters filterPar; filterPar.boundaryType = lti::Constant; filterPar.setKernel(gk); filter.setParameters(filterPar); channel::iterator igx=gx.begin(); channel::iterator igxend=gx.end(); channel::iterator igy=gy.begin(); channel::iterator ifxy=fxy.begin(); float tx, ty; while (igx!=igxend) { tx=(*igx); ty=(*igy); (*igx)=tx*tx; (*igy)=ty*ty; (*ifxy)=tx*ty; ++igx; ++igy; ++ifxy; } return (filter.apply(gx) && filter.apply(gy) && filter.apply(fxy)); }
// split image into float channels bool splitImageToxyY::apply(const image& img, channel& c1, channel& c2, channel& c3) const { point p; // coordinates rgbPixel pix; // single Pixel Element in RGB-values... float Y; // channels float X, XYZ; // help variables // make the channels size of source image... c1.resize(img.rows(),img.columns(),0,false,false); c2.resize(img.rows(),img.columns(),0,false,false); c3.resize(img.rows(),img.columns(),0,false,false); for (p.y=0;p.y<img.rows();p.y++) for (p.x=0;p.x<img.columns();p.x++) { // take pixel at position p pix = img.at(p); // see Gonzales & Woods for explanation of magic numbers X = (((float)(pix.getRed())) *0.412453f + ((float)(pix.getGreen())) *0.357580f + ((float)(pix.getBlue())) *0.180423f)/255.0f; // x Y = (((float)(pix.getRed())) *0.212671f + ((float)(pix.getGreen())) *0.715160f + ((float)(pix.getBlue())) *0.072169f)/255.0f; // y XYZ = (((float)(pix.getRed())) *0.644458f + ((float)(pix.getGreen())) *1.191933f + ((float)(pix.getBlue())) *1.202819f)/255.0f; // Y if (XYZ>0.0f) { c1.at(p) = X/XYZ; // x c2.at(p) = Y/XYZ; // y } else { c1.at(p) = 0; // x c2.at(p) = 0; // y } c3.at(p) = Y; // Y } // loop return true; }
/* * compute cornerness */ bool harrisCorners::getCornerness(const channel& fxx, const channel& fxy, const channel& fyy, const float scale, channel& cornerness, float& maxCornerness) const { // we can assume that all channels are connected, but try it out if not if ((fxx.getMode() != channel::Connected) || (fxy.getMode() != channel::Connected) || (fyy.getMode() != channel::Connected)) { setStatusString("Channels not contigous in getCornerness"); return false; } if (fxx.empty() || fxy.empty() || fyy.empty()) { cornerness.clear(); maxCornerness = 0.0f; return false; } int i; const int end = fxx.rows()*fxx.columns(); const float *const pfxx = &fxx.at(0); const float *const pfxy = &fxy.at(0); const float *const pfyy = &fyy.at(0); cornerness.resize(fxx.size(),0,false,false); float* pcor = &cornerness.at(0); float det,trace,txx,txy,tyy,c; float maxc = 0.0f; for (i=0;i<end;++i) { txx=pfxx[i]; txy=pfxy[i]; tyy=pfyy[i]; det=txx*tyy - txy*txy; trace=txx+tyy; c = det-scale*trace*trace; pcor[i]=c; if (c>maxc) { maxc=c; } } maxCornerness = maxc; return true; }
bool hessianFunctor::classicXY(const channel& src, channel& xy) const { if (src.columns() < 3) { setStatusString("width less than 3"); xy.clear(); return false; } if (src.rows() < 3) { setStatusString("height less than 3"); xy.clear(); return false; } if (src.getMode()!=channel::Connected) { setStatusString("src must be Connected"); xy.clear(); return false; } const int width = src.columns(); const int height = src.rows(); xy.resize(height,width,0.f,false,false); float* fpxy = &xy.at(0,0); const float* fpSrc = &src.at(0,0); const float* rowy; const float* colx; float* pidxy; const int w1 = width-1; const int w2 = width-2; const int last = (height-1)*width; // index of begin of last row const int lastRow = -w1; // offset from actual column pointer to // last row const int nextRow = width+1; // offset from actual column pointer to // next row const int nextRow2 = width+2; // offset from actual column pointer to // next row + 1 // top-left corner fpxy[0]=(fpSrc[0]-fpSrc[1]-fpSrc[width]+fpSrc[nextRow]); // top pidxy = &fpxy[1]; for (colx=&fpSrc[0],rowy=&fpSrc[w1]; colx<rowy; ++colx,++pidxy) { *pidxy=(*colx - colx[2] - colx[width] + colx[nextRow2]); } // top-right corner fpxy[w1]=(fpSrc[w2]-fpSrc[w1]-fpSrc[w2+width]+fpSrc[w1+width]); // main loop (begin at coordinates (1,0) pidxy = &fpxy[width]; const float *const rowEnd = &fpSrc[last]; for (rowy=&fpSrc[width]; rowy<rowEnd; rowy+=width) { // left side *pidxy=(rowy[-width] - rowy[lastRow] - rowy[width] + rowy[nextRow]); ++pidxy; // middle const float *const colEnd = &rowy[w2]; for (colx=rowy; colx<colEnd; ++colx,++pidxy) { *pidxy=(colx[-width] - colx[-w2] - colx[width] + colx[nextRow2]); } // right side *pidxy=(colx[-width] - colx[lastRow] - colx[width] + colx[nextRow]); ++pidxy; } // bottom-left corner fpxy[last]=(fpSrc[last+1]-fpSrc[last]); // bottom pidxy = &fpxy[last+1]; const float *const colEnd = &rowEnd[w2]; for (colx=rowEnd; colx<colEnd; ++colx,++pidxy) { *pidxy=(colx[-width] - colx[-w2] - *colx + colx[2]); } // bottom-right corner fpxy[last+w1]=(fpSrc[last-2]-fpSrc[last-1]-fpSrc[last+w2]+fpSrc[last+w1]); return true; };
// return probability channel bool probabilityMap2D::apply(const channel8& src1, const channel8& src2, channel& dest) const { const parameters& param = getParameters(); point chnl1_size = src1.size(); point chnl2_size = src2.size(); // size of src1 equals src2 ? if ( (chnl1_size.x != chnl2_size.x) || (chnl1_size.y != chnl2_size.y) ) { setStatusString("probabilityMap2D: channels do not match"); return false; } // the color model MUST have 2 dimensions! if (probabilityHistogram.dimensions() == 2) { // resize probability channel dest.resize(src1.size()); ivector theBin(2); // compute first iteration int y; vector<channel8::value_type>::const_iterator srcIterator1, eit1; vector<channel8::value_type>::const_iterator srcIterator2, eit2; vector<channel::value_type>::iterator destIterator; for (y=0;y<src1.rows();++y) { srcIterator1 = src1.getRow(y).begin(); eit1 = src1.getRow(y).end(); srcIterator2 = src2.getRow(y).begin(); eit2 = src2.getRow(y).end(); destIterator = dest.getRow(y).begin(); while (srcIterator1 != eit1) { theBin[0] = lookupTable[0][*srcIterator1]; theBin[1] = lookupTable[1][*srcIterator2]; (*destIterator)=static_cast<float>(probabilityHistogram.at(theBin)); srcIterator1++; srcIterator2++; destIterator++; } } // compute all other iterations if (param.iterations > 1) { int i; if (param.gaussian) { gaussKernel2D<float> gk(param.windowSize,param.variance); convolution convolver; convolution::parameters convParam; convParam.boundaryType = lti::Mirror; convParam.setKernel(gk); convolver.setParameters(convParam); for (i=1;i<param.iterations;++i) { convolver.apply(dest); computeMap(src1,src2,dest); } } else { squareConvolution<float> convolver; squareConvolution<float>::parameters convParam; convParam.boundaryType = lti::Mirror; convParam.initSquare(param.windowSize); convolver.setParameters(convParam); for (i=1;i<param.iterations;++i) { convolver.apply(dest); computeMap(src1,src2,dest); } } } // of (param.iterations > 1) return true; } // of (probabilityHistogram.dimensions() == 2) setStatusString("probabilityMap2D: no models loaded"); return false; }