TuttleOFX  1
AnisotropicTensorsPlugin.cpp
Go to the documentation of this file.
00001 #include "AnisotropicTensorsDefinition.hpp"
00002 #include "AnisotropicTensorsPlugin.hpp"
00003 #include "AnisotropicTensorsPluginFactory.hpp"
00004 #include "AnisotropicTensorsProcess.hpp"
00005 
00006 #include <iostream>
00007 #include <ofxsImageEffect.h>
00008 #include <ofxsMultiThread.h>
00009 #include <boost/gil/gil_all.hpp>
00010 
00011 
00012 namespace tuttle {
00013 namespace plugin {
00014 namespace anisotropicFilter {
00015 namespace tensors {
00016 
00017 using namespace boost::gil;
00018 
00019 TensorsPlugin::TensorsPlugin( OfxImageEffectHandle handle )
00020 : ImageEffectGilPlugin( handle )
00021 {
00022     _paramDisplayMargin = fetchBooleanParam( kParamDisplayEffectMargin );
00023         _paramAlpha = fetchDoubleParam( kParamAlpha );
00024         _paramSigma = fetchDoubleParam( kParamSigma );
00025 }
00026 
00027 int TensorsPlugin::getMargin()
00028 {
00029         // Compute newton approximation to get the margin pixel size (alpha)
00030         float a = 1.695f / _paramAlpha->getValue( );
00031         float k = std::pow( ( 1.0f - std::exp( -a ) ), 2.0f ) / ( 1.0f + 2.0f * a * std::exp( -a ) - std::exp( -2.0f * a ) );
00032         float x = 1.5f;
00033         // S is the computation precision
00034         const float S = 0.000001f;
00035         // 20 iterations should be enough
00036         for( int n = 1; n <= 20; ++n )
00037         {
00038                 x = x + 1.0f - ( 1.0f / ( 1.0f - x ) ) + ( S / ( k * std::exp( 1.0f ) ) ) * std::exp( x ) / ( 1.0f - x );
00039         }
00040         int fAdd1 = ( int ) ( std::max( ( x - 1.0f ) / a, 2.0f ) );
00041         // Computation for sigma
00042         a = static_cast<float>(1.695f / _paramSigma->getValue());
00043         k = std::pow( ( 1.0f - std::exp( -a ) ), 2.0f ) / ( 1.0f + 2.0f * a * std::exp( -a ) - std::exp( -2.0f * a ) );
00044         x = 1.5f;
00045         // Compute newton approximation to get the margin pixel size (sigma)
00046         for( int n = 1; n <= 20; ++n )
00047         {
00048                 x = x + 1.0f - ( 1.0f / ( 1.0f - x ) ) + ( S / ( k * std::exp( 1.0f ) ) ) * std::exp( x ) / ( 1.0f - x );
00049         }
00050         int fAdd2 = ( int ) ( std::max( ( x - 1.0f ) / a, 2.0f ) );
00051         // fAdd is the margin in pixels
00052         int margin = fAdd1 + fAdd2;
00053         if( margin < 0 )
00054                 margin = 0;
00055         return margin;
00056 }
00057 
00058 void TensorsPlugin::getRegionsOfInterest( const OFX::RegionsOfInterestArguments& args, OFX::RegionOfInterestSetter& rois )
00059 {
00060         const double margin = (double)getMargin() * _clipSrc->getPixelAspectRatio();
00061 
00062         _overSizedRect.x1 = double(args.regionOfInterest.x1 - margin);
00063         _overSizedRect.y1 = double(args.regionOfInterest.y1 - margin);
00064         _overSizedRect.x2 = double(args.regionOfInterest.x2 + margin + 1);
00065         _overSizedRect.y2 = double(args.regionOfInterest.y2 + margin + 1);
00066 
00067         rois.setRegionOfInterest( *_clipSrc, _overSizedRect );
00068 }
00069 
00070 /**
00071  * @brief The overridden render function
00072  * @param[in]   args     Rendering parameters
00073  */
00074 void TensorsPlugin::render( const OFX::RenderArguments &args )
00075 {
00076         doGilRender<AnisotropicTensorsProcess>( *this, args );
00077 }
00078 
00079 
00080 }
00081 }
00082 }
00083 }