TuttleOFX  1
NLMDenoiserPluginFactory.cpp
Go to the documentation of this file.
00001 #include "NLMDenoiserPluginFactory.hpp"
00002 #include "NLMDenoiserDefinitions.hpp"
00003 #include "NLMDenoiserPlugin.hpp"
00004 
00005 #include <ofxsImageEffect.h>
00006 #include <ofxsMultiThread.h>
00007 
00008 #include <boost/gil/gil_all.hpp>
00009 #include <boost/scoped_ptr.hpp>
00010 
00011 #include <string>
00012 #include <iostream>
00013 #include <cstdio>
00014 #include <cmath>
00015 
00016 namespace tuttle {
00017 namespace plugin {
00018 namespace nlmDenoiser {
00019 
00020 /**
00021  * @brief Function called to describe the plugin main features.
00022  * @param[in, out]   desc     Effect descriptor
00023  */
00024 void NLMDenoiserPluginFactory::describe( OFX::ImageEffectDescriptor &desc )
00025 {
00026     // basic labels
00027         desc.setLabels(
00028                 "TuttleNLMDenoiser",
00029                 "NLMDenoiser",
00030                 "Non Local-Means Denoiser" );
00031         desc.setPluginGrouping( "tuttle/image/process/filter" );
00032 
00033         desc.setDescription(
00034 "Optimized non Local-Means denoiser\n"
00035 "\n"
00036 "The Non Local Means denoiser is the state of the art in matter of high quality image denoising. "
00037 "But it's also the most expensive algorithm. "
00038 "\n"
00039 "\n"
00040 "Be careful to:\n"
00041 "- put the input image in the right colorspace. This colorspace is the original colorspace in which the noise has been generated (the space of your camera, eg. Cineon for pellicle).\n"
00042 "- the algorithm complexity: it takes a lot of time. We recommend you to tune the parameters using a small RoI."
00043 "\n"
00044 "Advices: \n"
00045 "- You can denoise a video using multiple frames via the 'depth' parameter. This doesn't introduce flick artefacts and clearly enhance the result. So with video, it's interesting to use a 'depth' parameter greater than region radius.\n"
00046 "- If the animation is very fast, select a larger region radius.\n"
00047 "- A good patch radius is about 2 or 3.\n"
00048 "- The higher 'radius' parameters are, the slower the algorithm is." );
00049         
00050     // add the supported contexts
00051     desc.addSupportedContext( OFX::eContextGeneral );
00052     desc.addSupportedContext( OFX::eContextFilter );
00053 
00054     // add supported pixel depths
00055     desc.addSupportedBitDepth( OFX::eBitDepthUByte );
00056     desc.addSupportedBitDepth( OFX::eBitDepthUShort );
00057     desc.addSupportedBitDepth( OFX::eBitDepthFloat );
00058 
00059     // set a few flags
00060         desc.setRenderThreadSafety( OFX::eRenderFullySafe );
00061     desc.setHostFrameThreading( false ); // The plugin is able to manage per frame threading
00062     desc.setSupportsMultiResolution( true );
00063     desc.setSupportsTiles( false );
00064     desc.setTemporalClipAccess( true );
00065     desc.setRenderTwiceAlways( false );
00066     desc.setSupportsMultipleClipPARs( false );
00067 }
00068 
00069 /**
00070  * @brief Function called to describe the plugin controls and features.
00071  * @param[in, out]   desc       Effect descriptor
00072  * @param[in]        context    Application context
00073  */
00074 void NLMDenoiserPluginFactory::describeInContext( OFX::ImageEffectDescriptor &desc,
00075                                                   OFX::EContext context )
00076 {
00077     // Source clip only in the filter context
00078     // create the mandated source clip
00079     OFX::ClipDescriptor *srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
00080     srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
00081     srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
00082     srcClip->setTemporalClipAccess( true );
00083     srcClip->setSupportsTiles( true );
00084     srcClip->setIsMask( false );
00085 
00086     // Create the mandated output clip
00087     OFX::ClipDescriptor *dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
00088     dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
00089     dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
00090     dstClip->setSupportsTiles( true );
00091 
00092     // Controls
00093     // Define NLMeans Based algorithm controls.
00094     OFX::GroupParamDescriptor *groupChGrSize = desc.defineGroupParam( "Per channel grain size" );
00095     OFX::DoubleParamDescriptor *redGrainSize = desc.defineDoubleParam( kParamRedGrainSize );
00096     redGrainSize->setLabels( kParamRedGrainSizeLabel, kParamRedGrainSizeLabel, kParamRedGrainSizeLabel );
00097     redGrainSize->setParent( *groupChGrSize );
00098     redGrainSize->setDefault( kParamDefaultBandwidthValueR );
00099     redGrainSize->setRange( -1.0, 100000.0 );
00100     redGrainSize->setDisplayRange( -1.0, 500.0 );
00101     redGrainSize->setHint( "Red grain size (strength of the smoothing, -1 = automatic)" );
00102         
00103     OFX::DoubleParamDescriptor *greenGrainSize = desc.defineDoubleParam( kParamGreenGrainSize );
00104     greenGrainSize->setLabels( kParamGreenGrainSizeLabel, kParamGreenGrainSizeLabel, kParamGreenGrainSizeLabel );
00105     greenGrainSize->setParent( *groupChGrSize );
00106     greenGrainSize->setDefault( kParamDefaultBandwidthValueG );
00107     greenGrainSize->setRange( -1.0, 100000.0 );
00108     greenGrainSize->setDisplayRange( -1.0, 500.0 );
00109     greenGrainSize->setHint( "Green grain size (strength of the smoothing, -1 = automatic)" );
00110         
00111     OFX::DoubleParamDescriptor *blueGrainSize = desc.defineDoubleParam( kParamBlueGrainSize );
00112     blueGrainSize->setLabels( kParamBlueGrainSizeLabel, kParamBlueGrainSizeLabel, kParamBlueGrainSizeLabel );
00113     blueGrainSize->setParent( *groupChGrSize );
00114     blueGrainSize->setDefault( kParamDefaultBandwidthValueB );
00115     blueGrainSize->setRange( -1.0, 100000.0 );
00116     blueGrainSize->setDisplayRange( -1.0, 500.0 );
00117     blueGrainSize->setHint( "Blue grain size (strength of the smoothing, -1 = automatic)" );
00118 
00119     OFX::GroupParamDescriptor *groupChStrength = desc.defineGroupParam( "Per channel strength" );
00120     OFX::DoubleParamDescriptor *redStrength = desc.defineDoubleParam( kParamRedStrength );
00121     redStrength->setParent( *groupChStrength );
00122     redStrength->setLabels( kParamRedStrengthLabel, kParamRedStrengthLabel, kParamRedStrengthLabel );
00123     redStrength->setDefault( 1.0 );
00124     redStrength->setRange( 0.0, 1.0 );
00125     redStrength->setDisplayRange( 0.0, 1.0 );
00126     redStrength->setHint( "Red effect strength (in percent)" );
00127         
00128     OFX::DoubleParamDescriptor *greenStrength = desc.defineDoubleParam( kParamGreenStrength );
00129     greenStrength->setLabels( kParamGreenStrengthLabel, kParamGreenStrengthLabel, kParamGreenStrengthLabel );
00130     greenStrength->setParent( *groupChStrength );
00131     greenStrength->setDefault( 1.0 );
00132     greenStrength->setRange( 0.0, 1.0 );
00133     greenStrength->setDisplayRange( 0.0, 1.0 );
00134     greenStrength->setHint( "Green effect strength (in percent)" );
00135         
00136     OFX::DoubleParamDescriptor *blueStrength = desc.defineDoubleParam( kParamBlueStrength );
00137     blueStrength->setLabels( kParamBlueStrengthLabel, kParamBlueStrengthLabel, kParamBlueStrengthLabel );
00138     blueStrength->setParent( *groupChStrength );
00139     blueStrength->setDefault( 1.0 );
00140     blueStrength->setRange( 0.0, 1.0 );
00141     blueStrength->setDisplayRange( 0.0, 1.0 );
00142     blueStrength->setHint( "Blue effect strength (in percent)" );
00143 
00144     OFX::GroupParamDescriptor *groupParams = desc.defineGroupParam( "NL-Means common parameters" );
00145     OFX::BooleanParamDescriptor *optimized = desc.defineBooleanParam( kParamOptimization );
00146         optimized->setLabels( kParamOptimizationLabel, kParamOptimizationLabel, kParamOptimizationLabel );
00147     optimized->setParent( *groupParams );
00148     optimized->setDefault( true );
00149     optimized->setIsSecret( true );
00150         
00151     OFX::DoubleParamDescriptor *preBlurring = desc.defineDoubleParam( kParamPreBlurring );
00152     preBlurring->setLabels( kParamPreBlurringLabel, kParamPreBlurringLabel, kParamPreBlurringLabel );
00153     preBlurring->setParent( *groupParams );
00154     preBlurring->setRange( 0.0, 10.0 );
00155     preBlurring->setDisplayRange( 0.0, 1.0 );
00156     preBlurring->setHint( "Pre-blurring will make noise to have lesser influence on similar patch research." );
00157     preBlurring->setDefault( 0.0 );
00158     preBlurring->setIsSecret( true );
00159 
00160     OFX::IntParamDescriptor *patchRadius = desc.defineIntParam( kParamPatchRadius );
00161     patchRadius->setLabels( kParamPatchRadiusLabel, kParamPatchRadiusLabel, kParamPatchRadiusLabel );
00162     patchRadius->setParent( *groupParams );
00163     patchRadius->setDefault( kParamDefaultPatchSizeValue );
00164     patchRadius->setRange( 1, 8 );
00165     patchRadius->setDisplayRange( 1, 8 );
00166     patchRadius->setHint( "Patch radius for nl-means algorithm" );
00167         
00168     OFX::IntParamDescriptor *regionRadius = desc.defineIntParam( kParamRegionRadius );
00169     regionRadius->setLabels( kParamRegionRadiusLabel, kParamRegionRadiusLabel, kParamRegionRadiusLabel );
00170     regionRadius->setParent( *groupParams );
00171     regionRadius->setDefault( kParamDefaultRegionValue );
00172         regionRadius->setRange( 1, 150 );
00173     regionRadius->setDisplayRange( 2, 15 );
00174     regionRadius->setHint( "Radius of the region where similar patchs are searched" );
00175         
00176     OFX::IntParamDescriptor *depth = desc.defineIntParam( kParamDepth );
00177     depth->setLabels( kParamDepthLabel, kParamDepthLabel, kParamDepthLabel );
00178     depth->setParent( *groupParams );
00179     depth->setDefault( kParamDefaultDepth );
00180     depth->setRange( 0, 20 );
00181     depth->setDisplayRange( 0, 4 );
00182     depth->setHint( "Searching depth (3D version) for the nl-means algorithm" );
00183 }
00184 
00185 /**
00186  * @brief Function called to create a plugin effect instance
00187  * @param[in]   handle  effect handle
00188  * @param[in]   context    Application context
00189  * @return  plugin instance
00190  */
00191 OFX::ImageEffect* NLMDenoiserPluginFactory::createInstance( OfxImageEffectHandle handle,
00192                                                             OFX::EContext context )
00193 {
00194     return new NLMDenoiserPlugin( handle );
00195 }
00196 
00197 }
00198 }
00199 }