filterbank.cc

来自「用于计算矩阵的特征值,及矩阵的其他运算.可以用与稀疏矩阵」· CC 代码 · 共 589 行 · 第 1/2 页

CC
589
字号
  float  FilterBank::getSigmaY (int index) const  {    assert (index >= 0 && index < m_nfilters);    return m_sigmasY(index);  }  float  FilterBank::getOrient (int index) const  {    assert (index >= 0 && index < m_nfilters);    return m_orients(index);  }  int FilterBank::getNscales () const  {    return m_nscales;  }                                                                                                         int FilterBank::getNorient () const  {    return m_norient;  }                                                                                                         int FilterBank::getIndexElong (int scale, int orient, int evenodd) const  {    return calcIndexElong(m_nscales, m_norient, scale, orient, evenodd);  }                                                                                                         int FilterBank::getIndexCenter (int scale) const  {    return calcIndexCenter(m_nscales, m_norient, scale);  }  int FilterBank::calcNumFilters (const int nscales, const int norient)  {    return nscales * (2 * norient + 1);  }  int FilterBank::calcIndexElong (const int nscales, const int norient,                              const int scale, const int orient,                              const int evenodd)  {    assert (scale >= 0 && scale < nscales);    assert (orient >= 0 && orient < norient);    assert (evenodd == 0 || evenodd == 1);    return scale * (2 * norient + 1) + 2 * orient + evenodd;  }  int FilterBank::calcIndexCenter (const int nscales, const int norient,                               const int scale)  {    assert (scale >= 0 && scale < nscales);    return scale * (2 * norient + 1) + 2 * norient;  }  ////////////////////////////////////////////////////////////////////////////////////////////////  //  //run the filterbank on an image and return  //an array of images containing numFilters elements.  //  void FilterBank::filter (const Util::Image& im, Util::ImageStack& filtered) const  {    filtered.resize(m_nfilters,im.size(0),im.size(1));    filtered.init(0);    Util::Image f;    Util::Message::startBlock(m_nfilters,"filtering",1);    for (int i = 0; i < m_nfilters; i++)    {      Util::Message::stepBlock(1);      getFiltered(im,getFilter(i),f);      assert(f.size(0) == filtered.size(1));      assert(f.size(1) == filtered.size(2));      for (int x = 0; x < f.size(0); x++)      {        for (int y = 0; y < f.size(1); y++)        {          filtered(i,x,y) = f(x,y);        }       }    }    Util::Message::endBlock(1);  }  // given a set of quadrature pair images, returns   // half as many new images which give the orientation  // energy at each point  void FilterBank::orientationEnergy (const Util::ImageStack& filtered, Util::ImageStack& energy) const  {    int width = filtered.size(1);    int height = filtered.size(2);    energy.resize(m_nscales*m_norient,width,height);    for (int scale = 0; scale < m_nscales; scale++)    {      for (int orient = 0; orient < m_norient; orient++)      {        for (int x = 0; x < width; x++)        {          for (int y = 0; y < height; y++)          {            const float e1 = filtered(getIndexElong (scale, orient,0), x, y);            const float e2 = filtered(getIndexElong (scale, orient,1), x, y);            energy(scale*m_norient + orient,x,y) = sqrt(e1*e1 + e2*e2);          }        }      }    }  }  ////////////////////////////////////////////////////////////////////////////////////////////////  //  // create a 2D gaussian kernel with sigmaX and sigmaY where  //  orient - the orientation in radians.  //  deriv - 2 or 0 depending on whether we want an edge filter  //          or just a gaussian bump  //  hilbert - whether to take the hilbert transform in the Y direction  //    void FilterBank::createGaussianKernel (const float sigmaX, const float sigmaY,                                    const float support, const float orient,                                    const int deriv, const bool hilbert,                                     Util::Image& kernelImage)  {      assert (deriv >= 0 && deriv <= 2);      //make an odd size kernel      int kernelSize = (int) rint (2.0 * support * Util::max (sigmaX, sigmaY));      kernelSize = kernelSize + (1 - (kernelSize % 2));      assert ((kernelSize % 2) == 1);      int halfSize = (kernelSize - 1) / 2;      //create a grayscale image      kernelImage.resize(kernelSize, kernelSize);      //compute the kernel value along the x and y directions at a fine      //resolution      int maxSize = 2 * kernelSize;      int zoom = 64;      int nsamples = zoom * maxSize + 1;      int halfnsamples = zoom * maxSize / 2;      Util::Array1D<float> xval(nsamples);      Util::Array1D<float> yval(nsamples);      for (int y = -halfnsamples; y <= halfnsamples; y++)      {        const float sigmaYsqr = (sigmaY * sigmaY);        const float sigmaXsqr = (sigmaX * sigmaX);        const float u = (((float) y) / ((float) zoom));        xval(y + halfnsamples) = exp (-u * u / (2 * sigmaXsqr));        if (deriv == 0)        {            yval(y + halfnsamples) = exp (-u * u / (2 * sigmaYsqr));        }        else if (deriv == 1)        {            yval(y + halfnsamples) = exp (-u * u / (2 * sigmaYsqr)) * (-u / sigmaYsqr);        }        else if (deriv == 2)        {            yval(y + halfnsamples) = exp (-u * u / (2 * sigmaYsqr)) * ((u * u / sigmaYsqr) - 1);        }      }      //take the hilbert transform in the Y direction if necessary      if (hilbert == true)      {        computeHilbert (yval);      }      //now create the filter by averaging values out of the sampled      //kernels.      for (int x = -halfSize; x <= halfSize; x++)      {        for (int y = -halfSize; y <= halfSize; y++)        {          float u = x * cos(orient) + y * sin(orient);          float v = x * sin(orient) - y * cos(orient);          // compute the x value          int u1 = (int) rint (((u - 0.5) * zoom) + halfnsamples);          int u2 = (int) rint (((u + 0.5) * zoom) + halfnsamples);          u1 = Util::max (u1, 0);          u2 = Util::min (u2, nsamples - 1);          assert (u2 >= u1);          float xvalue = 0;          for (int i = u1; i <= u2; i++)          {              xvalue += xval(i);          }          xvalue /= (u2 - u1 + 1);          // compute the y value          int v1 = (int) rint (((v - 0.5) * zoom) + halfnsamples);          int v2 = (int) rint (((v + 0.5) * zoom) + halfnsamples);          v1 = Util::max (v1, 0);          v2 = Util::min (v2, nsamples - 1);          assert (v2 >= v1);          float yvalue = 0;          for (int i = v1; i <= v2; i++)          {              yvalue += yval(i);          }          yvalue /= (v2 - v1 + 1);          float val = xvalue * yvalue;          kernelImage(x + halfSize, y + halfSize) = val;        }      }      //make it zero mean if it's a derivative of a gaussian      if (deriv != 0)      {        makeZeroMean(kernelImage);      }      //make sure the filter has unit L1 norm       makeL1Normalized(kernelImage);  }  /////////////////////////////////////////////////////////////////////////////////////////////////////  //  // paste kernel into a bigger image  //  static void drawFilter(const Util::Image& filt, int cx, int cy, Util::Image& im)  {    int iwidth = im.size(0);    int iheight = im.size(1);    int w = filt.size(0);    int h = filt.size(1);    // (i,j) are coorindates local to the filter    for (int i = 0; i < w; i++)    {      for (int j = 0; j < h; j++)      {        // (x,y) are image coordinates for (i,j)        int x = cx + i - w / 2;        int y = cy + j - h / 2;        assert (x >= 0 && x < iwidth);        assert (y >= 0 && y < iheight);        im(x,y) = filt(i,j);      }    }  }  //  // create a nice image of the filterbank for presentation or debugging  //  void FilterBank::getFilterBankImage (Util::Image& fbim) const  {      // figure out the max filter dimensions      int maxd = 0;      for (int i = 0; i < m_nfilters; i++)      {        maxd = Util::max (maxd,getFilter(i).size(0));        maxd = Util::max (maxd,getFilter(i).size(1));      }      maxd++;      // allocate an image large enough to hold images of all the filters      int nscales = getNscales ();      int norient = getNorient ();      int iheight = maxd * nscales;      int iwidth = maxd * (2 * norient + 1);      fbim.resize(iwidth,iheight);      fbim.init(0);      // write the filters into the big image      // (cx,cy) give the image coordinates for the center of      // the this filter      for (int scale = 0; scale < nscales; scale++)      {        // lay out filters for this scale like this: eoeoeoeoeoeoc        for (int orient = 0; orient < norient; orient++)        {          for (int evenodd = 0; evenodd < 2; evenodd++)          {            int cx = (2 * orient + evenodd) * maxd + maxd / 2;            int cy = scale * maxd + maxd / 2;            const Util::Image filt = getFilter(getIndexElong (scale, orient, evenodd));            drawFilter (filt, cx, cy, fbim);          }        }        int cx = 2 * norient * maxd + maxd / 2;        int cy = scale * maxd + maxd / 2;        const Util::Image filt = getFilter(getIndexCenter (scale));        drawFilter (filt, cx, cy, fbim);      }  }} //namespace Group

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?