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