bool hessianFunctor::apply(const channel& src,
                             channel& xx, channel& xy, channel& yy) const {

    bool rc = true;

    const parameters& param = getParameters();
    
    switch (param.kernelType) {
      
      case parameters::Classic:
        //call specialized member functions
        return classicHessian(src,xx,xy,yy);
        break;

      case parameters::Hessian:
        //call spezialized member function for XY
        rc = rc && convXX.apply(src,xx);
        rc = rc && classicXY(src,xy);
        rc = rc && convYY.apply(src,yy);
        break;

      default:
        // not nice but faster than putting all possibilities
        // after all this has been checked in setParameters()
        rc = rc && convXX.apply(src,xx);
        rc = rc && convXY.apply(src,xy);
        rc = rc && convYY.apply(src,yy);
        break;
    }

    if (!rc) {
      xx.clear();
      xy.clear();
      yy.clear();
      appendStatusString(convXX);
      appendStatusString(convXY);
      appendStatusString(convYY);
    }

    return rc;

  };
 bool cwagmSegmentationEvaluation::segment(const image& img,
                                           const imatrix& prevMask,
                                           imatrix& mask,
                                           channel& certainty) {
   ivector sizes;
   if (!segmenter.apply(img,mask,sizes)) {
     _lti_debug("Error in segmenter: " << segmenter.getStatusString() <<
                std::endl);
     setStatusString(segmenter.getStatusString());
     return false;
   }
   certainty.clear(); // no certainty computation in this kind of functors.
   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;
  }
  /*
   * operates on a copy of the given %parameters.
   * @param src channel with the source data.
   * @param dest list of corners
   * @return true if apply successful or false otherwise.
   */
  bool harrisCorners::apply(const channel& src,
                            channel& cornerness,
                            float& maxCornerness) const {
    const parameters& param = getParameters();

    channel gx,gy,fxy,d;

    if (!gradient.apply(src,gx,gy)) {
      appendStatusString(gradient);
      cornerness.clear();
      maxCornerness = 0.0f;
      return false;
    }
    getSecondOrder(gx,gy,fxy);
    return getCornerness(gx,fxy,gy,param.scale,cornerness,maxCornerness);
  };
  // On copy apply for type channel!
  bool harrisCorners::apply(const channel& src,channel& dest) const {
    const parameters& param = getParameters();

    channel gx,gy,fxy,tmp;
    float maxCornerness;

    pointList cornerMax;

    if (!gradient.apply(src,gx,gy)) {
      appendStatusString(gradient);
      dest.clear();
      return false;
    }
    getSecondOrder(gx,gy,fxy);
    getCornerness(gx,fxy,gy,param.scale,tmp,maxCornerness);
    findCornerMaxima(tmp,dest,cornerMax);

    return true;
  };
  /*
   * find corners with maximal cornerness
   */
  bool harrisCorners::findCornerMaxima(const channel& cornerness,
                                             channel& cornersOnly,
                                             pointList& cornerMax) const {
    if (cornerness.empty()) {
      cornersOnly.clear();
      cornerMax.clear();
      return true;
    }

    const parameters& par = getParameters();

    const float corner = par.cornerValue/255.0f;
    const float noCorner = par.noCornerValue/255.0f;

    localMaxima<float> lmax;
    localMaxima<float>::parameters lmaxPar(par.localMaximaParameters);
    lmaxPar.noMaxValue = noCorner;
    lmaxPar.maxNumber = par.maximumCorners;
    lmax.setParameters(lmaxPar);

    if (lmax.apply(cornerness,cornersOnly,cornerMax)) {
      pointList::iterator it;
      int i;
      for (it=cornerMax.begin(),i=0;
           (it!=cornerMax.end());
           ++it) {
        cornersOnly.at(*it) = corner;
      }

      for (;it!=cornerMax.end();++it) {
        cornersOnly.at(*it) = noCorner;
      }

      return true;
    }
    return false;
  }
  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;
  };