TuttleOFX  1
math.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_MATH_HPP_
00002 #define _TERRY_MATH_HPP_
00003 
00004 #include "basic_colors.hpp"
00005 
00006 namespace terry {
00007 
00008 /**
00009  * @brief Compute min & max value from a view
00010  *
00011  * @param[in]   view     Source view
00012  * @param[out]  max      maximum image value
00013  * @param[out]  min      minimum image value
00014  *
00015  */
00016 template <typename View, typename T>
00017 void maxmin( const View& view, T& max, T& min )
00018 {
00019         using namespace boost::gil;
00020         typedef typename View::x_iterator iterator;
00021         typedef typename channel_type<View>::type dPix_t;
00022         const int nc = view.num_channels();
00023         int w        = view.width();
00024         int h        = view.height();
00025         max = min = view( 0, 0 )[0];
00026         for( int y = 0; y < h; ++y )
00027         {
00028                 iterator view_it = view.row_begin( y );
00029                 for( int x = 0; x < w; ++x )
00030                 {
00031                         for( int c = 0; c < nc; c++ )
00032                         {
00033                                 const dPix_t val = ( *view_it )[c];
00034                                 if( val > max )
00035                                 {
00036                                         max = val;
00037                                 }
00038                                 else if( val < min )
00039                                 {
00040                                         min = val;
00041                                 }
00042                         }
00043                         ++view_it;
00044                 }
00045         }
00046 }
00047 
00048 /**
00049  * @brief Normalize a view (using contrast streching)
00050  *
00051  * @param[in, out]  dst     Source and destination view
00052  * @param[in]       a       lower limit
00053  * @param[in]       b       upper limit
00054  * @return Return the normalized image
00055  */
00056 template <class S_VIEW, class D_VIEW, typename T>
00057 D_VIEW& normalize( const S_VIEW& src, D_VIEW& dst, const T a, const T b )
00058 {
00059         using namespace boost::gil;
00060         typedef typename S_VIEW::x_iterator sIterator;
00061         typedef typename D_VIEW::x_iterator dIterator;
00062         typedef typename channel_type<D_VIEW>::type dPix_t;
00063         dPix_t m, M;
00064         maxmin( dst, M, m );
00065         const float fm = m, fM = M;
00066         int w          = dst.width();
00067         int h          = dst.height();
00068 
00069         if( m == M )
00070         {
00071                 fill_black( dst );
00072         }
00073         else if( m != a || M != b )
00074         {
00075                 int nc = dst.num_channels();
00076                 for( int y = 0; y < h; ++y )
00077                 {
00078                         sIterator src_it = src.row_begin( y );
00079                         dIterator dst_it = dst.row_begin( y );
00080                         for( int x = 0; x < w; ++x )
00081                         {
00082                                 for( int c = 0; c < nc; c++ )
00083                                 {
00084                                         ( *dst_it )[c] = (dPix_t)( ( ( *src_it )[c] - fm ) / ( fM - fm ) * ( b - a ) + a );
00085                                 }
00086                                 ++dst_it;
00087                                 ++src_it;
00088                         }
00089                 }
00090         }
00091         return dst;
00092 }
00093 
00094 template <class S_VIEW, class D_VIEW, typename T>
00095 D_VIEW& multiply( const S_VIEW& src, D_VIEW& dst, const T factor )
00096 {
00097         using namespace boost::gil;
00098         typedef typename S_VIEW::x_iterator sIterator;
00099         typedef typename D_VIEW::x_iterator dIterator;
00100         typedef typename channel_type<D_VIEW>::type dPix_t;
00101 
00102         const int nc = src.num_channels();
00103         const int w  = src.width();
00104         const int h  = src.height();
00105         int x, y, c;
00106         for( y = 0; y < h; y++ )
00107         {
00108                 sIterator src_it = src.row_begin( y );
00109                 dIterator dst_it = dst.row_begin( y );
00110                 for( x = 0; x < w; x++ )
00111                 {
00112                         for( c = 0; c < nc; c++ )
00113                         {
00114                                 ( *dst_it )[c] = (dPix_t)( ( *src_it )[c] * factor );
00115                         }
00116                         ++src_it;
00117                         ++dst_it;
00118                 }
00119         }
00120         return dst;
00121 }
00122 
00123 }
00124 
00125 #endif
00126