TuttleOFX  1
rgb_algorithms.hpp
Go to the documentation of this file.
00001 #ifndef RGB_ALGORITHMS_HPP
00002 #define RGB_ALGORITHMS_HPP
00003 
00004 #include <boost/gil/gil_all.hpp>
00005 
00006 namespace boost { namespace gil {
00007 namespace toolbox {
00008 
00009 struct calc_negative
00010 {
00011    template < typename DST_CHANNEL
00012             , typename SRC_CHANNEL
00013             > void operator()( DST_CHANNEL& dst 
00014                              , SRC_CHANNEL& src ) const
00015    {
00016       SRC_CHANNEL max = channel_traits< SRC_CHANNEL >::max_value();
00017 
00018       dst = max - src;
00019    }
00020 
00021    template < typename CHANNEL
00022             > void operator()( CHANNEL& c ) const
00023    {
00024       CHANNEL max = channel_traits< CHANNEL >::max_value();
00025 
00026       c = max - c;
00027    }
00028 };
00029 
00030 template< typename RGB_VIEW >
00031 void negative( const RGB_VIEW& view )
00032 {
00033    typedef typename channel_type< RGB_VIEW >::type channel_t;
00034    channel_t max = channel_traits<channel_t>::max_value();
00035 
00036    for( int y=0; y < view.height(); ++y )
00037    {
00038       typename RGB_VIEW::x_iterator it = view.row_begin( y );
00039 
00040       for( int x = 0; x < view.width(); ++x )
00041       {
00042          static_for_each( it[x], calc_negative() );
00043       }
00044    }
00045 }
00046 
00047 template< typename RGB_VIEW >
00048 void negative( const RGB_VIEW& src
00049              , const RGB_VIEW& dst )
00050 {
00051    // make sure src and dst have same dimensions.
00052 
00053    // for rgba do it only for rgb channels
00054 
00055    typedef typename channel_type< RGB_VIEW >::type channel_t;
00056    channel_t max = channel_traits<channel_t>::max_value();
00057 
00058    for( int y=0; y < src.height(); ++y )
00059    {
00060       typename RGB_VIEW::x_iterator src_it = src.row_begin( y );
00061       typename RGB_VIEW::x_iterator dst_it = dst.row_begin( y );
00062 
00063       for( int x = 0; x < src.width(); ++x )
00064       {
00065          static_for_each( dst_it[x], src_it[x], calc_negative() );
00066       }
00067    }
00068 }
00069 
00070 struct calc_brightness
00071 {
00072    float _factor;
00073 
00074    template < typename DST_CHANNEL
00075             , typename SRC_CHANNEL
00076             > void operator()( DST_CHANNEL&       dst 
00077                              , const SRC_CHANNEL& src ) const
00078    {
00079       float d = static_cast<float>( src ) * _factor;
00080 
00081       if( d > channel_traits< DST_CHANNEL >::max_value() )
00082       {
00083          dst = channel_traits< DST_CHANNEL >::max_value();
00084       }
00085       else
00086       {
00087          dst = static_cast< DST_CHANNEL >( d );
00088       }
00089    }
00090 };
00091 
00092 
00093 
00094 template< typename RGB_VIEW >
00095 void brightness( const RGB_VIEW& src
00096                , const RGB_VIEW& dst
00097                , float           factor )
00098 {
00099    calc_brightness calc;
00100    calc._factor = factor;
00101 
00102    for( int y=0; y < src.height(); ++y )
00103    {
00104       typename RGB_VIEW::x_iterator src_it = src.row_begin( y );
00105       typename RGB_VIEW::x_iterator dst_it = dst.row_begin( y );
00106 
00107       for( int x = 0; x < src.width(); ++x )
00108       {
00109          static_for_each( dst_it[x], src_it[x], calc );
00110       }
00111    }
00112 }
00113 
00114 template< typename VALUE >
00115 struct calc_brightness_
00116 {
00117    VALUE _number;
00118 
00119    template < typename DST_CHANNEL
00120             , typename SRC_CHANNEL
00121             > void operator()( DST_CHANNEL&       dst 
00122                              , const SRC_CHANNEL& src ) const
00123    {
00124       VALUE d = static_cast< VALUE >( src ) + _number;
00125 
00126       if( d > channel_traits< DST_CHANNEL >::max_value() )
00127       {
00128          dst = channel_traits< DST_CHANNEL >::max_value();
00129       }
00130       else
00131       {
00132          dst = d;
00133       }
00134    }
00135 };
00136 
00137 template< typename RGB_VIEW
00138         , typename VALUE >
00139 void brightness_( const RGB_VIEW& src
00140                 , const RGB_VIEW& dst
00141                 , VALUE           number )
00142 {
00143    calc_brightness_<VALUE> calc;
00144    calc._number = number;
00145 
00146    for( int y=0; y < src.height(); ++y )
00147    {
00148       typename RGB_VIEW::x_iterator src_it = src.row_begin( y );
00149       typename RGB_VIEW::x_iterator dst_it = dst.row_begin( y );
00150 
00151       for( int x = 0; x < src.width(); ++x )
00152       {
00153          static_for_each( dst_it[x], src_it[x], calc );
00154       }
00155    }
00156 }
00157 
00158 template< typename RGB_VIEW >
00159 void remove_channel( const RGB_VIEW& src
00160                    , unsigned int    c   )
00161 {
00162    typedef typename channel_type< RGB_VIEW >::type channel_t;
00163    channel_t min_value = channel_traits<channel_t>::min_value();
00164 
00165    for( int y = 0; y < src.dimensions().y; ++y )
00166    {
00167       typename RGB_VIEW::x_iterator src_it = src.row_begin( y );
00168 
00169       for( int x = 0; x < src.dimensions().x; ++x )
00170       {
00171          dynamic_at_c( src_it[x], c ) = min_value;
00172       }
00173    }
00174 }
00175 
00176 template< typename CHANNEL
00177         , typename RGB_VIEW >
00178 void remove_channel( const RGB_VIEW& src )
00179 {
00180    typedef typename channel_type< RGB_VIEW >::type channel_t;
00181    channel_t min = channel_traits<channel_t>::min_value();
00182 
00183    for( int y = 0; y < src.dimensions().y; ++y )
00184    {
00185       typename RGB_VIEW::x_iterator src_it = src.row_begin( y );
00186 
00187       for( int x = 0; x < src.dimensions().x; ++x )
00188       {
00189          get_color( src_it[x], CHANNEL() ) = min;
00190       }
00191    }
00192 }
00193 
00194 
00195 template< typename RGB_VIEW >
00196 void difference( const RGB_VIEW& src_1
00197                , const RGB_VIEW& src_2
00198                , const RGB_VIEW& dst    )
00199 {
00200    if( src_1.dimensions() != src_2.dimensions() )
00201    {
00202       BOOST_THROW_EXCEPTION( std::runtime_error( "Source image have different dimensions." ) );
00203    }
00204 
00205    if( src_1.dimensions() != dst.dimensions() )
00206    {
00207       BOOST_THROW_EXCEPTION( std::runtime_error( "Destination image must have equal dimensions as the source images." ) );
00208    }
00209 
00210    for( int y = 0; y < src_1.dimensions().y; ++y )
00211    {
00212       typename RGB_VIEW::x_iterator src_1_it = src_1.row_begin( y );
00213       typename RGB_VIEW::x_iterator src_2_it = src_2.row_begin( y );
00214 
00215       typename RGB_VIEW::x_iterator dst_it = dst.row_begin( y );
00216 
00217       typedef typename channel_type<RGB_VIEW>::type channel_t;
00218 
00219       for( int x = 0; x < src_1.dimensions().x; ++x )
00220       {
00221                          assert(false);
00222                 //TODO: what is calc_diff?
00223          //static_for_each( src_1_it[x], src_1_it[x], dst_it[x], calc_diff() );
00224       }
00225    }
00226 }
00227 
00228 } //namespace toolbox
00229 } //namespace gil
00230 } //namespace boost
00231 
00232 #endif // RGB_ALGORITHMS_HPP