BoxFilter.h

Go to the documentation of this file.
00001 /*
00002 * Copyright (C) 2007-2008 Anael Orlinski
00003 *
00004 * This file is part of Panomatic.
00005 *
00006 * Panomatic is free software; you can redistribute it and/or modify
00007 * it under the terms of the GNU General Public License as published by
00008 * the Free Software Foundation; either version 2 of the License, or
00009 * (at your option) any later version.
00010 *
00011 * Panomatic is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU General Public License
00017 * along with Panomatic; if not, write to the Free Software
00018 * <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #ifndef __lfeat_boxfilter_h
00022 #define __lfeat_boxfilter_h
00023 
00024 #include "MathStuff.h"
00025 #include "hugin_math/hugin_math.h"
00026 
00027 namespace lfeat
00028 {
00029 
00030 class Image;
00031 
00032 class BoxFilter
00033 {
00034 public:
00035     BoxFilter(double iBaseSize, Image& iImage);
00036 
00037     void                                setY(unsigned int y);
00038     double getDxxWithX(unsigned int x) const;
00039     double getDyyWithX(unsigned int x) const;
00040     double getDxyWithX(unsigned int x) const;
00041     double getDetWithX(unsigned int x) const;
00042 
00043     bool checkBounds(int x, int y) const;
00044 
00045     // orig image info
00046     double**    _ii;
00047     unsigned int        _im_width;
00048     unsigned int        _im_height;
00049 
00050     int _basesize;
00051 
00052     // precomp values for det
00053     double _sqCorrectFactor;
00054 
00055 
00056     // the relative values of rectangle position for the first derivatives on x
00057     int _lxy_d2;
00058 
00059     // new ones
00060     int _lxx_x_mid;
00061     int _lxx_x_right;
00062     int _lxx_y_bottom;
00063 
00064     // stored Y
00065 
00066     unsigned int _y_minus_lxx_y_bottom;
00067     unsigned int _y_plus_lxx_y_bottom;
00068     unsigned int _y_minus_lxx_x_right;
00069     unsigned int _y_plus_lxx_x_right;
00070     unsigned int _y_minus_lxx_x_mid;
00071     unsigned int _y_plus_lxx_x_mid;
00072     unsigned int _y_minus_lxy_d2;
00073     unsigned int _y_plus_lxy_d2;
00074     unsigned int _y;
00075 
00076 };
00077 
00078 inline BoxFilter::BoxFilter(double iBaseSize, Image& iImage)
00079 {
00080     _ii = iImage.getIntegralImage();
00081     _im_width = iImage.getWidth();
00082     _im_height = iImage.getHeight();
00083 
00084     _basesize = hugin_utils::roundi(iBaseSize); // convert to integer
00085 
00086 
00087     // precomputed values for det
00088     double aCorrectFactor = 9.0 / (iBaseSize * iBaseSize);
00089     _sqCorrectFactor = aCorrectFactor * aCorrectFactor;
00090 
00091     // the values for lxy are all positive. will negate in the getDxy
00092     _lxy_d2 = ((int)(iBaseSize * 3) - 1) / 2 - 1;
00093 
00094     // new ones
00095     _lxx_x_mid = _basesize / 2;
00096     _lxx_x_right = _lxx_x_mid + _basesize;
00097     _lxx_y_bottom = _lxx_x_mid * 2;
00098     setY(0);
00099 
00100 }
00101 
00102 #define CALC_INTEGRAL_SURFACE(II, STARTX, ENDX, STARTY, ENDY) \
00103     (II[ENDY+1][ENDX+1] + II[STARTY][STARTX] - II[ENDY+1][STARTX] - II[STARTY][ENDX+1])
00104 
00105 inline double BoxFilter::getDxxWithX(unsigned int x) const
00106 {
00107     return      CALC_INTEGRAL_SURFACE(_ii,x - _lxx_x_right,     x + _lxx_x_right, _y_minus_lxx_y_bottom, _y_plus_lxx_y_bottom)
00108             - 3.0 * CALC_INTEGRAL_SURFACE(_ii,x - _lxx_x_mid,   x + _lxx_x_mid,   _y_minus_lxx_y_bottom, _y_plus_lxx_y_bottom);
00109 }
00110 
00111 inline double BoxFilter::getDyyWithX(unsigned int x) const
00112 {
00113     // calculates the Lyy convolution a point x,y with filter base size, using integral image
00114     // use the values of Lxx, but rotate them.
00115     return      CALC_INTEGRAL_SURFACE(_ii,              x - _lxx_y_bottom,              x + _lxx_y_bottom, _y_minus_lxx_x_right, _y_plus_lxx_x_right)
00116             -  3.0 * CALC_INTEGRAL_SURFACE(_ii, x - _lxx_y_bottom,              x + _lxx_y_bottom, _y_minus_lxx_x_mid, _y_plus_lxx_x_mid);
00117 
00118 }
00119 
00120 inline double BoxFilter::getDxyWithX(unsigned int x) const
00121 {
00122     // calculates the Lxy convolution a point x,y with filter base size, using integral image
00123 
00124     return      CALC_INTEGRAL_SURFACE(_ii,              x,                                              x + _lxy_d2, _y,                        _y_plus_lxy_d2)
00125             +   CALC_INTEGRAL_SURFACE(_ii,              x - _lxy_d2,                    x, _y_minus_lxy_d2,                     _y)
00126             -   CALC_INTEGRAL_SURFACE(_ii,              x,                                              x + _lxy_d2, _y_minus_lxy_d2,                   _y)
00127             -   CALC_INTEGRAL_SURFACE(_ii,              x - _lxy_d2,                    x, _y,                  _y_plus_lxy_d2);
00128 }
00129 
00130 #undef CALC_INTEGRAL_SURFACE
00131 
00132 inline double BoxFilter::getDetWithX(unsigned int x) const
00133 {
00134     double aDxy = getDxyWithX(x) * 0.9 * 2 / 3.0;
00135     double aDxx = getDxxWithX(x);
00136     double aDyy = getDyyWithX(x);
00137 
00138     return  ((aDxx * aDyy) - (aDxy * aDxy)) * _sqCorrectFactor;
00139 }
00140 
00141 inline void     BoxFilter::setY(unsigned int y)
00142 {
00143     _y_minus_lxx_y_bottom = y - _lxx_y_bottom;
00144     _y_plus_lxx_y_bottom = y + _lxx_y_bottom;
00145     _y_minus_lxx_x_right = y - _lxx_x_right;
00146     _y_plus_lxx_x_right = y + _lxx_x_right;
00147     _y_minus_lxx_x_mid = y - _lxx_x_mid;
00148     _y_plus_lxx_x_mid = y + _lxx_x_mid;
00149     _y_minus_lxy_d2 = y - _lxy_d2;
00150     _y_plus_lxy_d2 = y + _lxy_d2;
00151     _y = y;
00152 
00153 }
00154 
00155 inline bool BoxFilter::checkBounds(int x, int y) const
00156 {
00157     return (    x > _lxx_x_right && x + _lxx_x_right < (int)_im_width - 1
00158                 &&      y > _lxx_x_right && y + _lxx_x_right < (int)_im_height - 1);
00159 }
00160 
00161 } // namespace lfeat
00162 
00163 #endif //__lfeat_boxfilter_h

Generated on 26 Jun 2016 for Hugintrunk by  doxygen 1.4.7