filters.cpp

来自「显著区域检测。求的图像中感兴趣区域的位置」· C++ 代码 · 共 274 行

CPP
274
字号
/*!@file Filters.cpp various filter functions. */// This file is part of the SaliencyToolbox - Copyright (C) 2006-2007// by Dirk B. Walther and the California Institute of Technology.// See the enclosed LICENSE.TXT document for the license agreement. // More information about this project is available at: // http://www.saliencytoolbox.net#include "mexLog.h"#include "Image.h"#include "Filters.h"#include <algorithm>#include <cmath>#include <limits>// ######################################################################// kernel: 1 5 10 10 5 1Image lowPass6yDecY(const Image& src){  ASSERT(ecxStr);  const int w = src.getWidth(), hs = src.getHeight();  const float ecw = ecx / w;  int hr = hs / 2;  if (hr == 0) hr = 1;    Image result(w,hr);  Image::iterator rptr = result.beginw();  Image::const_iterator sptr = src.begin();    if (hs <= 1)    result = src;  else if (hs == 2)    for (int x = 0; x < w; ++x)      {        // use kernel [1 1]^T / 2        *rptr++ = (sptr[0] + sptr[1]) / 2.0;        sptr += 2;      }  else if (hs == 3)    for (int x = 0; x < w; ++x)      {        // use kernel [1 2 1]^T / 4        *rptr++ = (sptr[0] + sptr[1] * 2.0 + sptr[2]) / 4.0;        sptr += 3;      }  else // general case with hs >= 4    for (int x = 0; x < w; ++x)      {        // top most point - use kernel [10 10 5 1]^T / 26        *rptr++ = ((sptr[0] + sptr[1]) * 10.0 +                     sptr[2] * 5.0 + sptr[3]) / 26.0;        //++sptr;                // general case        int y;        for (y = 0; y < (hs - 5); y += 2)          {            // use kernel [1 5 10 10 5 1]^T / 32            *rptr++ = ((sptr[1] + sptr[4])  *  5.0 +                       (sptr[2] + sptr[3])  * 10.0 +                       (sptr[0] + sptr[5])) / 32.0;            sptr += 2;          }                // find out how to treat the bottom most point        if (y == (hs - 5))          {            // use kernel [1 5 10 10 5]^T / 31             *rptr++ = ((sptr[1] + sptr[4])  *  5.0 +                        (sptr[2] + sptr[3])  * 10.0 +                         sptr[0])            / 31.0;            sptr += 5;          }        else          {            // use kernel [1 5 10 10]^T / 26            *rptr++ = ( sptr[0] + sptr[1]  *  5.0 +                       (sptr[2] + sptr[3]) * 10.0) / 26.0;            sptr += 4;          }        }               return result;      }// ######################################################################// kernel: 1 5 10 10 5 1Image lowPass6xDecX(const Image& src){  ASSERT(ecxStr);  const int ws = src.getWidth(), h = src.getHeight();  const float ecw = ecx / ws;  const int h2 = h * 2, h3 = h * 3, h4 = h * 4, h5 = h * 5;  int wr = ws / 2;  if (wr == 0) wr = 1;    Image result(wr,h);  Image::iterator rptr = result.beginw();  Image::const_iterator sptr = src.begin();  if (ws <= 1)    result = src;  else if (ws == 2)    for (int y = 0; y < h; ++y)      {        // use kernel [1 1] / 2        *rptr++ = (sptr[0] + sptr[h]) / 2.0;        ++sptr;      }  else if (ws == 3)    for (int y = 0; y < h; ++y)      {        // use kernel [1 2 1] / 4        *rptr++ = (sptr[0] + sptr[h] * 2.0 + sptr[h2]) / 4.0;        ++sptr;      }  else // general case for ws >= 4    {      // left most point - use kernel [10 10 5 1] / 26      for (int y = 0; y < h; ++y)        {          *rptr++ = ((sptr[0] + sptr[h]) * 10.0 +                       sptr[h2] * 5.0 + sptr[h3]) / 26.0;          ++sptr;        }      sptr -= h;            // general case      int x;      for (x = 0; x < (ws - 5); x += 2)        {          for (int y = 0; y < h; ++y)            {              // use kernel [1 5 10 10 5 1] / 32              *rptr++ = ((sptr[h]  + sptr[h4])  *  5.0 +                         (sptr[h2] + sptr[h3])  * 10.0 +                         (sptr[0]  + sptr[h5])) / 32.0;              ++sptr;            }          sptr += h;        }              // find out how to treat the right most point      if (x == (ws - 5))        for (int y = 0; y < h; ++y)          {            // use kernel [1 5 10 10 5] / 31            *rptr++ = ((sptr[h]  + sptr[h4])  *  5.0 +                       (sptr[h2] + sptr[h3])  * 10.0 +                        sptr[0]) / 31.0;            ++sptr;          }      else        for (int y = 0; y < h; ++y)          {            // use kernel [1 5 10 10] / 26            *rptr++ = ( sptr[0]  + sptr[h]   * 5.0 +                        (sptr[h2] + sptr[h3]) * 10.0) / 26.0;            ++sptr;          }    }  return result;}// ######################################################################Image conv2PreserveEnergy(const Image& src, const Image& f){  ASSERT(src.isInitialized());  ASSERT(ecxStr);  const int sw = src.getWidth();  const int sh = src.getHeight();  const float ecw = ecx / sw;  Image::const_iterator filter = f.begin();  const int fw = f.getWidth();  const int fh = f.getHeight();  ASSERT((fw & 1) && (fh & 1));  Image result(sw, sh);  Image::const_iterator sptr = src.begin();  Image::iterator rptr = result.beginw();  const int fend = fw * fh - 1;  const int fw2 = (fw - 1) / 2;  const int fh2 = (fh - 1) / 2;  const int sSkip = sh - fh;  for (int rx = 0; rx < sw; ++rx)    {      // Determine if we're safely inside the image in the x-direction:      const bool isXclean = ((rx >= fw2) && (rx <  (sw - fw2)));      for (int ry = 0; ry < sh; ++ry, ++rptr)        {          // Determine if we're safely inside the image in the y-direction:          const bool isYclean = ((ry >= fh2) && (ry <  (sh - fh2)));                    if (isXclean && isYclean)            {              // well inside the image: use straight-forward convolution              float rval = 0.0f;              Image::const_iterator fptr = filter+fend;              Image::const_iterator sptr2 = sptr + sh*(rx-fw2) + ry - fh2;              for (int fx = 0; fx < fw; ++fx)                {                  for (int fy = 0; fy < fh; ++fy)                    rval += (*sptr2++) * (*fptr--);                  sptr2 += sSkip;                }              *rptr = rval;              continue;            }          else            {              // near the border: assume that the value missing pixels              // is equal to the average over the present pixels              // to minimize artifacts at the edge.              float rval = 0.0f;              float sSum = 0.0f;              int sCount = 0;              float fsum_skipped = 0.0f;              for (int fx = 0; fx < fw; ++fx)                {                  const int sx = rx + fx - fw2;                  if (sx >= 0 && sx < sw)                    {                      for (int fy = 0; fy < fh; ++fy)                        {                          const float fil = filter[fend - fx * fh - fy];                          const int sy = ry + fy - fh2;                          if (sy >= 0 && sy < sh)                            {                              // here we have the pixel present:                               // store it and count it to compute the mean                              const float sVal = sptr[sx * sh + sy];                              rval += sVal * fil;                              sSum += sVal;                              ++sCount;                            }                          else                            {                              // this is accumulataing the filter values                               // over missing pixels                              fsum_skipped += fil;                            }                        }                    }                  else                    {                      // this is accumulating the filter values                      // over an entire column of mixxing pixels                      for (int fy = 0; fy < fh; ++fy)                        fsum_skipped += filter[fend - fx * fh - fy];                    }                }              // compute the average over the present pixels              const float sAvg = sSum / sCount;                            // add the that average x accumulated filter values to the result              *rptr = rval + (fsum_skipped * sAvg);            }        }    }  return result;}

⌨️ 快捷键说明

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