TuttleOFX
1
|
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