IM: im_math.h Source File

IM - Imaging Libray

im_math.h

Go to the documentation of this file.
00001 /** \file
00002  * \brief Math Utilities
00003  *
00004  * See Copyright Notice in im_lib.h
00005  * $Id: Exp $
00006  */
00007 
00008 #ifndef __IM_MATH_H
00009 #define __IM_MATH_H
00010 
00011 #include <math.h>
00012 #include "im_util.h"
00013 
00014 #ifdef IM_DEFMATHFLOAT
00015 inline float acosf(float _X) {return ((float)acos((double)_X)); }
00016 inline float asinf(float _X) {return ((float)asin((double)_X)); }
00017 inline float atanf(float _X) {return ((float)atan((double)_X)); }
00018 inline float atan2f(float _X, float _Y) {return ((float)atan2((double)_X, (double)_Y)); }
00019 inline float ceilf(float _X) {return ((float)ceil((double)_X)); }
00020 inline float cosf(float _X)  {return ((float)cos((double)_X)); }
00021 inline float coshf(float _X) {return ((float)cosh((double)_X)); }
00022 inline float expf(float _X) {return ((float)exp((double)_X)); }
00023 inline float fabsf(float _X) {return ((float)fabs((double)_X)); }
00024 inline float floorf(float _X) {return ((float)floor((double)_X)); }
00025 inline float fmodf(float _X, float _Y) {return ((float)fmod((double)_X, (double)_Y)); }
00026 inline float logf(float _X) {return ((float)log((double)_X)); }
00027 inline float log10f(float _X) {return ((float)log10((double)_X)); }
00028 inline float powf(float _X, float _Y) {return ((float)pow((double)_X, (double)_Y)); }
00029 inline float sinf(float _X) {return ((float)sin((double)_X)); }
00030 inline float sinhf(float _X) {return ((float)sinh((double)_X)); }
00031 inline float sqrtf(float _X) {return ((float)sqrt((double)_X)); }
00032 inline float tanf(float _X) {return ((float)tan((double)_X)); }
00033 inline float tanhf(float _X) {return ((float)tanh((double)_X)); }
00034 #endif
00035 
00036 /** \defgroup math Math Utilities
00037  * \par
00038  * See \ref im_color.h
00039  * \ingroup util */
00040 
00041 
00042 /** Does Zero Order Decimation (Mean).
00043  * \ingroup math */
00044 template <class T, class TU>
00045 inline T imZeroOrderDecimation(int width, int height, T *map, float xl, float yl, float box_width, float box_height, TU Dummy)
00046 {
00047   int x0,x1,y0,y1;
00048   (void)Dummy;
00049 
00050   x0 = (int)floor(xl - box_width/2.0 - 0.5) + 1;
00051   y0 = (int)floor(yl - box_height/2.0 - 0.5) + 1;
00052   x1 = (int)floor(xl + box_width/2.0 - 0.5);
00053   y1 = (int)floor(yl + box_height/2.0 - 0.5);
00054 
00055   if (x0 == x1) x1++;
00056   if (y0 == y1) y1++;
00057 
00058   x0 = x0<0? 0: x0>width-1? width-1: x0;
00059   y0 = y0<0? 0: y0>height-1? height-1: y0;
00060   x1 = x1<0? 0: x1>width-1? width-1: x1;
00061   y1 = y1<0? 0: y1>height-1? height-1: y1;
00062 
00063   TU Value;
00064   int Count = 0;
00065 
00066   Value = 0;
00067 
00068   for (int y = y0; y <= y1; y++)
00069   {
00070     for (int x = x0; x <= x1; x++)
00071     {
00072       Value += map[y*width+x];
00073       Count++;
00074     }
00075   }
00076 
00077   if (Count == 0)
00078   {
00079     Value = 0;
00080     return (T)Value;
00081   }
00082 
00083   return (T)(Value/(float)Count);
00084 }
00085 
00086 /** Does Bilinear Decimation.
00087  * \ingroup math */
00088 template <class T, class TU>
00089 inline T imBilinearDecimation(int width, int height, T *map, float xl, float yl, float box_width, float box_height, TU Dummy)
00090 {
00091   int x0,x1,y0,y1;
00092   (void)Dummy;
00093 
00094   x0 = (int)floor(xl - box_width/2.0 - 0.5) + 1;
00095   y0 = (int)floor(yl - box_height/2.0 - 0.5) + 1;
00096   x1 = (int)floor(xl + box_width/2.0 - 0.5);
00097   y1 = (int)floor(yl + box_height/2.0 - 0.5);
00098 
00099   if (x0 == x1) x1++;
00100   if (y0 == y1) y1++;
00101 
00102   x0 = x0<0? 0: x0>width-1? width-1: x0;
00103   y0 = y0<0? 0: y0>height-1? height-1: y0;
00104   x1 = x1<0? 0: x1>width-1? width-1: x1;
00105   y1 = y1<0? 0: y1>height-1? height-1: y1;
00106 
00107   TU Value, LineValue;
00108   float LineNorm, Norm, dxr, dyr;
00109 
00110   Value = 0;
00111   Norm = 0;
00112 
00113   for (int y = y0; y <= y1; y++)
00114   {
00115     dyr = yl - (y+0.5f);
00116     if (dyr < 0) dyr *= -1;
00117 
00118     LineValue = 0;
00119     LineNorm = 0;
00120 
00121     for (int x = x0; x <= x1; x++)
00122     {
00123       dxr = xl - (x+0.5f);
00124       if (dxr < 0) dxr *= -1;
00125 
00126       LineValue += map[y*width+x] * dxr;
00127       LineNorm += dxr;
00128     }
00129 
00130     Value += LineValue * dyr;
00131     Norm += dyr * LineNorm;
00132   }
00133 
00134   if (Norm == 0)
00135   {
00136     Value = 0;
00137     return (T)Value;
00138   }
00139 
00140   return (T)(Value/Norm);
00141 }
00142 
00143 /** Does Zero Order Interpolation (Nearest Neighborhood).
00144  * \ingroup math */
00145 template <class T>
00146 inline T imZeroOrderInterpolation(int width, int height, T *map, float xl, float yl)
00147 {
00148   int x0 = (int)(xl-0.5f);
00149   int y0 = (int)(yl-0.5f);
00150   x0 = x0<0? 0: x0>width-1? width-1: x0;
00151   y0 = y0<0? 0: y0>height-1? height-1: y0;
00152   return map[y0*width + x0];
00153 }
00154 
00155 /** Does Bilinear Interpolation.
00156  * \ingroup math */
00157 template <class T>
00158 inline T imBilinearInterpolation(int width, int height, T *map, float xl, float yl)
00159 {
00160   int x0 = (int)(xl-0.5f);
00161   int y0 = (int)(yl-0.5f);
00162   int x1 = x0+1;
00163   int y1 = y0+1;
00164 
00165   float t = xl - (x0+0.5f);
00166   float u = yl - (y0+0.5f);
00167 
00168   x0 = x0<0? 0: x0>width-1? width-1: x0;
00169   y0 = y0<0? 0: y0>height-1? height-1: y0;
00170   x1 = x1<0? 0: x1>width-1? width-1: x1;
00171   y1 = y1<0? 0: y1>height-1? height-1: y1;
00172 
00173   T fll = map[y0*width + x0];
00174   T fhl = map[y0*width + x1];
00175   T flh = map[y1*width + x0];
00176   T fhh = map[y1*width + x1];
00177 
00178   return (T)((fhh - flh - fhl + fll) * u * t +
00179                          (fhl - fll) * t +
00180                          (flh - fll) * u +
00181                                 fll);
00182 }
00183 
00184 /** Does Bicubic Interpolation.
00185  * \ingroup math */
00186 template <class T, class TU>
00187 inline T imBicubicInterpolation(int width, int height, T *map, float xl, float yl, TU Dummy)
00188 {
00189   (void)Dummy;
00190 
00191   int x0 = (int)(xl-0.5f);
00192   int y0 = (int)(yl-0.5f);
00193   int x1 = x0-1; 
00194   int x2 = x0+2;
00195   int y1 = y0-1; 
00196   int y2 = y0+2;
00197 
00198   float t = xl - (x0+0.5f);
00199   float u = yl - (y0+0.5f);
00200 
00201   x1 = x1<0? 0: x1>width-1? width-1: x1;
00202   y1 = y1<0? 0: y1>height-1? height-1: y1;
00203   x2 = x2<0? 0: x2>width-1? width-1: x2;
00204   y2 = y2<0? 0: y2>height-1? height-1: y2;
00205 
00206   float CX[4], CY[4];
00207 
00208   // Optimize calculations
00209   {
00210     float x, x2, x3;
00211 
00212 #define C0 (-x3 + 2.0f*x2 - x)
00213 #define C1 ( x3 - 2.0f*x2 + 1.0f)
00214 #define C2 (-x3 + x2 + x)
00215 #define C3 ( x3 - x2)
00216 
00217     x = t;
00218     x2 = x*x; x3 = x2*x;
00219     CX[0] = C0; CX[1] = C1; CX[2] = C2; CX[3] = C3;
00220 
00221     x = u;
00222     x2 = x*x; x3 = x2*x;
00223     CY[0] = C0; CY[1] = C1; CY[2] = C2; CY[3] = C3;
00224   }
00225 
00226 #undef C0
00227 #undef C1
00228 #undef C2
00229 #undef C3
00230 
00231   TU LineValue, Value;
00232   float LineNorm, Norm;
00233 
00234   Value = 0;
00235   Norm = 0;
00236 
00237   for (int y = y1; y <= y2; y++)
00238   {
00239     LineValue = 0;
00240     LineNorm = 0;
00241 
00242     for (int x = x1; x <= x2; x++)
00243     {
00244       LineValue += map[y*width+x] * CX[x-x1];
00245       LineNorm += CX[x-x1];
00246     }
00247 
00248     Value += LineValue * CY[y-y1];
00249     Norm += CY[y-y1] * LineNorm;
00250   }
00251 
00252   if (Norm == 0)
00253   {
00254     Value = 0;
00255     return (T)Value;
00256   }
00257 
00258   Value = (Value/Norm);
00259 
00260   int size = sizeof(T); 
00261   if (size == 1)
00262     return (T)(Value<=0? 0: Value<=255? Value: 255);
00263   else
00264     return (T)(Value);
00265 }
00266 
00267 /** Calculates minimum and maximum values.
00268  * \ingroup math */
00269 template <class T> 
00270 inline void imMinMax(const T *map, int count, T& min, T& max)
00271 {
00272   min = *map++;
00273   max = min;
00274   for (int i = 1; i < count; i++)
00275   {
00276     T value = *map++;
00277 
00278     if (value > max)
00279       max = value;
00280     else if (value < min)
00281       min = value;
00282   }
00283 }
00284 
00285 #endif