00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __lfeat_boxfilter_h
00022 #define __lfeat_boxfilter_h
00023
00024 #include "MathStuff.h"
00025
00026 namespace lfeat
00027 {
00028
00029 class Image;
00030
00031 class BoxFilter
00032 {
00033 public:
00034 BoxFilter(double iBaseSize, Image& iImage);
00035
00036 void setY(unsigned int y);
00037 double getDxxWithX(unsigned int x) const;
00038 double getDyyWithX(unsigned int x) const;
00039 double getDxyWithX(unsigned int x) const;
00040 double getDetWithX(unsigned int x) const;
00041
00042 bool checkBounds(int x, int y) const;
00043
00044
00045 double** _ii;
00046 unsigned int _im_width;
00047 unsigned int _im_height;
00048
00049 int _basesize;
00050
00051
00052 double _sqCorrectFactor;
00053
00054
00055
00056 int _lxy_d2;
00057
00058
00059 int _lxx_x_mid;
00060 int _lxx_x_right;
00061 int _lxx_y_bottom;
00062
00063
00064
00065 unsigned int _y_minus_lxx_y_bottom;
00066 unsigned int _y_plus_lxx_y_bottom;
00067 unsigned int _y_minus_lxx_x_right;
00068 unsigned int _y_plus_lxx_x_right;
00069 unsigned int _y_minus_lxx_x_mid;
00070 unsigned int _y_plus_lxx_x_mid;
00071 unsigned int _y_minus_lxy_d2;
00072 unsigned int _y_plus_lxy_d2;
00073 unsigned int _y;
00074
00075 };
00076
00077 inline BoxFilter::BoxFilter(double iBaseSize, Image& iImage)
00078 {
00079 _ii = iImage.getIntegralImage();
00080 _im_width = iImage.getWidth();
00081 _im_height = iImage.getHeight();
00082
00083 _basesize = Math::Round(iBaseSize);
00084
00085
00086
00087 double aCorrectFactor = 9.0 / (iBaseSize * iBaseSize);
00088 _sqCorrectFactor = aCorrectFactor * aCorrectFactor;
00089
00090
00091 _lxy_d2 = ((int)(iBaseSize * 3) - 1) / 2 - 1;
00092
00093
00094 _lxx_x_mid = _basesize / 2;
00095 _lxx_x_right = _lxx_x_mid + _basesize;
00096 _lxx_y_bottom = _lxx_x_mid * 2;
00097
00098
00099 }
00100
00101 #define CALC_INTEGRAL_SURFACE(II, STARTX, ENDX, STARTY, ENDY) \
00102 (II[ENDY+1][ENDX+1] + II[STARTY][STARTX] - II[ENDY+1][STARTX] - II[STARTY][ENDX+1])
00103
00104 inline double BoxFilter::getDxxWithX(unsigned int x) const
00105 {
00106 return CALC_INTEGRAL_SURFACE(_ii,x - _lxx_x_right, x + _lxx_x_right, _y_minus_lxx_y_bottom, _y_plus_lxx_y_bottom)
00107 - 3.0 * CALC_INTEGRAL_SURFACE(_ii,x - _lxx_x_mid, x + _lxx_x_mid, _y_minus_lxx_y_bottom, _y_plus_lxx_y_bottom);
00108 }
00109
00110 inline double BoxFilter::getDyyWithX(unsigned int x) const
00111 {
00112
00113
00114 return CALC_INTEGRAL_SURFACE(_ii, x - _lxx_y_bottom, x + _lxx_y_bottom, _y_minus_lxx_x_right, _y_plus_lxx_x_right)
00115 - 3.0 * CALC_INTEGRAL_SURFACE(_ii, x - _lxx_y_bottom, x + _lxx_y_bottom, _y_minus_lxx_x_mid, _y_plus_lxx_x_mid);
00116
00117 }
00118
00119 inline double BoxFilter::getDxyWithX(unsigned int x) const
00120 {
00121
00122
00123 return CALC_INTEGRAL_SURFACE(_ii, x, x + _lxy_d2, _y, _y_plus_lxy_d2)
00124 + CALC_INTEGRAL_SURFACE(_ii, x - _lxy_d2, x, _y_minus_lxy_d2, _y)
00125 - CALC_INTEGRAL_SURFACE(_ii, x, x + _lxy_d2, _y_minus_lxy_d2, _y)
00126 - CALC_INTEGRAL_SURFACE(_ii, x - _lxy_d2, x, _y, _y_plus_lxy_d2);
00127 }
00128
00129 #undef CALC_INTEGRAL_SURFACE
00130
00131 inline double BoxFilter::getDetWithX(unsigned int x) const
00132 {
00133 double aDxy = getDxyWithX(x) * 0.9 * 2 / 3.0;
00134 double aDxx = getDxxWithX(x);
00135 double aDyy = getDyyWithX(x);
00136
00137 return ((aDxx * aDyy) - (aDxy * aDxy)) * _sqCorrectFactor;
00138 }
00139
00140 inline void BoxFilter::setY(unsigned int y)
00141 {
00142 _y_minus_lxx_y_bottom = y - _lxx_y_bottom;
00143 _y_plus_lxx_y_bottom = y + _lxx_y_bottom;
00144 _y_minus_lxx_x_right = y - _lxx_x_right;
00145 _y_plus_lxx_x_right = y + _lxx_x_right;
00146 _y_minus_lxx_x_mid = y - _lxx_x_mid;
00147 _y_plus_lxx_x_mid = y + _lxx_x_mid;
00148 _y_minus_lxy_d2 = y - _lxy_d2;
00149 _y_plus_lxy_d2 = y + _lxy_d2;
00150 _y = y;
00151
00152 }
00153
00154 inline bool BoxFilter::checkBounds(int x, int y) const
00155 {
00156 return ( x > _lxx_x_right && x + _lxx_x_right < (int)_im_width - 1
00157 && y > _lxx_x_right && y + _lxx_x_right < (int)_im_height - 1);
00158 }
00159
00160 }
00161
00162 #endif //__lfeat_boxfilter_h