TuttleOFX  1
IdKeyerProcess.tcc
Go to the documentation of this file.
00001 #include <boost/numeric/conversion/cast.hpp>
00002 
00003 #include <terry/globals.hpp>
00004 #include <terry/algorithm/transform_pixels_progress.hpp>
00005 #include <terry/numeric/operations.hpp>
00006 #include <terry/numeric/assign.hpp>
00007 #include <terry/numeric/init.hpp>
00008 #include <terry/numeric/assign.hpp>
00009 #include <terry/numeric/sqrt.hpp>
00010 #include <terry/numeric/operations_assign.hpp>
00011 
00012 namespace tuttle {
00013 namespace plugin {
00014 namespace idKeyer {
00015 
00016 template<class View>
00017 IdKeyerProcess<View>::IdKeyerProcess( IdKeyerPlugin& instance )
00018         : Parent( instance, eImageOrientationIndependant )
00019         , _plugin( instance )
00020 {}
00021 
00022 template<class View>
00023 void IdKeyerProcess<View>::setup( const OFX::RenderArguments& args )
00024 {
00025         using namespace boost::gil;
00026         Parent::setup( args );
00027 
00028         _params = _plugin.getProcessParams<View>();
00029 }
00030 
00031 struct id_keyer_t
00032 {
00033         typedef std::vector<terry::rgba32f_pixel_t> PixelList;
00034         PixelList _colors;
00035         double    _tolerance;
00036         bool      _useAlpha;
00037 
00038         id_keyer_t( PixelList colors, double tolerance, bool useAlpha )
00039                 : _colors    ( colors )
00040                 , _tolerance ( tolerance )
00041                 , _useAlpha  ( useAlpha )
00042         {
00043         }
00044 
00045         template<class Pixel>
00046         Pixel operator()( const Pixel& src ) const
00047         {
00048                 using namespace terry;
00049                 typedef rgba32f_pixel_t P;
00050                 
00051                 Pixel res = src;
00052 
00053                 bool isSelectPixel = false;
00054                 
00055                 for( PixelList::const_iterator color = _colors.begin(); color != _colors.end(); ++color )
00056                 {
00057                         //TUTTLE_LOG_WARNING( get_color( res, red_t()   ) << "\t" << get_color( *color, red_t()   ) );
00058                         P min( *color );
00059                         P max( *color );
00060                         double minFactor = 1.0 - _tolerance;
00061                         double maxFactor = 1.0 + _tolerance;
00062                         numeric::pixel_multiplies_scalar_assign_t<double, P>( )( minFactor, min ); // min *= minFactor
00063                         numeric::pixel_multiplies_scalar_assign_t<double, P>( )( maxFactor, max ); // max *= maxFactor
00064                         
00065                         if( get_color( res, red_t()   ) >= get_color( min, red_t()   ) &&
00066                                 get_color( res, red_t()   ) <= get_color( max, red_t()   ) &&
00067                                 get_color( res, green_t() ) >= get_color( min, green_t() ) &&
00068                                 get_color( res, green_t() ) <= get_color( max, green_t() ) &&
00069                                 get_color( res, blue_t()  ) >= get_color( min, blue_t()  ) &&
00070                                 get_color( res, blue_t()  ) <= get_color( max, blue_t()  ) &&
00071                                 ( ! _useAlpha ||
00072                                         ( get_color( res, alpha_t() ) >= get_color( min, alpha_t() ) &&
00073                                           get_color( res, alpha_t() ) <= get_color( max, alpha_t() ) )
00074                                 )
00075                                 )
00076                         {
00077                                 isSelectPixel = true;
00078                         }
00079                 }
00080 
00081                 get_color( res, alpha_t() ) = isSelectPixel ? 1.0 : 0.0;
00082                 return res;
00083         }
00084 };
00085 
00086 
00087 /**
00088  * @brief Function called by rendering thread each time a process must be done.
00089  * @param[in] procWindowRoW  Processing window in RoW
00090  */
00091 template<class View>
00092 void IdKeyerProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW )
00093 {
00094         using namespace terry;
00095         using namespace terry::algorithm;
00096         const OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates( procWindowRoW );
00097         const OfxRectI procWindowSrc = translateRegion( procWindowRoW, this->_srcPixelRod );
00098         const OfxPointI procWindowSize = { procWindowRoW.x2 - procWindowRoW.x1,
00099                                                                            procWindowRoW.y2 - procWindowRoW.y1 };
00100         View src = subimage_view( this->_srcView, procWindowSrc.x1, procWindowSrc.y1,
00101                                                           procWindowSize.x, procWindowSize.y );
00102         View dst = subimage_view( this->_dstView, procWindowOutput.x1, procWindowOutput.y1,
00103                                                           procWindowSize.x, procWindowSize.y );
00104 
00105         transform_pixels_progress(
00106                         src,
00107                         dst,
00108                         id_keyer_t( _params._colors, _params._tolerance, _params._useAlpha ),
00109                         *this );
00110 }
00111 
00112 }
00113 }
00114 }