TuttleOFX  1
AnisotropicTensorsProcess.tcc
Go to the documentation of this file.
00001 
00002 namespace tuttle {
00003 namespace plugin {
00004 namespace anisotropicFilter {
00005 namespace tensors {
00006 
00007 /**
00008  * @brief Constructor of the TensorsBase class
00009  *
00010  * @param[in, out]  instance     Plugin instance
00011  */
00012 template<class View>
00013 AnisotropicTensorsProcess<View>::AnisotropicTensorsProcess( TensorsPlugin &instance )
00014 : ImageGilFilterProcessor<View>( instance, eImageOrientationIndependant )
00015 , _plugin( instance )
00016 {
00017     _stAlgo = instance.fetchChoiceParam( kParamEdgeDetectAlgo );
00018     _algorithm = instance.fetchBooleanParam( kParamDisplayStructureTensors );
00019     _alpha = instance.fetchDoubleParam( kParamAlpha );
00020     _sigma = instance.fetchDoubleParam( kParamSigma );
00021     _sharpness = instance.fetchDoubleParam( kParamSharpness );
00022     _anisotropy = instance.fetchDoubleParam( kParamAnisotropy );
00023     _geom_fact = instance.fetchDoubleParam( kParamGeometryFactor );
00024     _threshold = instance.fetchDoubleParam( kParamThresholdingQuantization );
00025 }
00026 
00027 /**
00028  * @brief Function for the effect processing.
00029  * @param[in]   args     Rendering parameters
00030  */
00031 template<class View>
00032 void AnisotropicTensorsProcess<View>::setup( const OFX::RenderArguments &args )
00033 {
00034         // fetch main upscaled input image
00035         this->_src.reset( _plugin._clipSrc->fetchImage( args.time ) );
00036         if( !this->_src.get( ) )
00037                 BOOST_THROW_EXCEPTION(exception::ImageNotReady() );
00038         _upScaledSrcBounds = this->_src->getBounds();
00039 
00040         // fetch output image
00041         this->_dst.reset( _plugin._clipDst->fetchImage( args.time ) );
00042         if( !this->_dst.get( ) )
00043                         BOOST_THROW_EXCEPTION(exception::ImageNotReady() );
00044         _dBounds = this->_dst->getBounds();
00045 
00046         // Make sure bit depths are same
00047         OFX::EBitDepth srcBitDepth = this->_src->getPixelDepth( );
00048         OFX::EPixelComponent srcComponents = this->_src->getPixelComponents( );
00049         OFX::EBitDepth dstBitDepth = this->_dst->getPixelDepth( );
00050         OFX::EPixelComponent dstComponents = this->_dst->getPixelComponents( );
00051 
00052         // See if they have the same depths and bytes and all
00053         if( srcBitDepth != dstBitDepth || srcComponents != dstComponents )
00054         {
00055                         BOOST_THROW_EXCEPTION(exception::BitDepthMismatch() );
00056         }
00057 
00058         this->_srcView = interleaved_view( _upScaledSrcBounds.x2 - _upScaledSrcBounds.x1,
00059                                                                  _upScaledSrcBounds.y2 - _upScaledSrcBounds.y1,
00060                                                                  ( Pixel * ) this->_src->getPixelData( ), this->_src->getRowDistanceBytes( ) );
00061 
00062         this->_dstView = interleaved_view( _dBounds.x2 - _dBounds.x1, _dBounds.y2 - _dBounds.y1,
00063                                                                            ( Pixel * ) this->_dst->getPixelData( ), this->_dst->getRowDistanceBytes( ) );
00064 
00065 }
00066 
00067 /**
00068  * @brief Function called by rendering thread each time a process must be done.
00069  * @param[in] procWindowRoW  Processing window in RoW
00070  */
00071 template<class View>
00072 void AnisotropicTensorsProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW )
00073 {
00074         int margin = _plugin.getMargin();
00075         imageUtils::tensor_t<View> params;
00076         params.stAlgo = _stAlgo->getValue();
00077         params.algorithm = _algorithm->getValue();
00078         params.alpha = _alpha->getValue();
00079         params.sigma = _sigma->getValue();
00080         params.sharpness = _sharpness->getValue();
00081         params.anisotropy = _anisotropy->getValue();
00082         params.geom_fact = _geom_fact->getValue();
00083         params.threshold = _threshold->getValue();
00084 
00085         // dest width and height
00086         params.dw = procWindowRoW.x2 - procWindowRoW.x1;
00087         params.dh = procWindowRoW.y2 - procWindowRoW.y1;
00088 
00089         // Set upscaled source
00090         OfxRectI srcRect;
00091         srcRect.x1 = procWindowRoW.x1 - margin;
00092         srcRect.y1 = procWindowRoW.y1 - margin;
00093         srcRect.x2 = procWindowRoW.x2 + margin + 1;
00094         srcRect.y2 = procWindowRoW.y2 + margin + 1;
00095 
00096         srcRect = rectanglesIntersection(srcRect, _upScaledSrcBounds);
00097 
00098         // dest starting offset among x and y
00099         params.dox = procWindowRoW.x1 - srcRect.x1;
00100         params.doy = procWindowRoW.y1 - srcRect.y1;
00101         params.dw  = params.dox + procWindowRoW.x2 - procWindowRoW.x1;
00102         params.dh  = params.doy + procWindowRoW.y2 - procWindowRoW.y1;
00103 
00104         // We want to work in the source roi space
00105         View src = subimage_view(this->_srcView,
00106                                  srcRect.x1 - _upScaledSrcBounds.x1,
00107                                  srcRect.y1 - _upScaledSrcBounds.y1,
00108                                  srcRect.x2 - srcRect.x1,
00109                                  srcRect.y2 - srcRect.y1);
00110         // We want to work in the source roi space
00111         View dst = subimage_view(this->_dstView,
00112                                  procWindowRoW.x1 - this->_renderArgs.renderWindow.x1,
00113                                  procWindowRoW.y1 - this->_renderArgs.renderWindow.y1,
00114                                  procWindowRoW.x2 - procWindowRoW.x1,
00115                                  procWindowRoW.y2 - procWindowRoW.y1);
00116 
00117         imageUtils::ImageTensors<View> dv(dst);
00118         dv.process( src, imageUtils::ImageTensors<View>::eAnisotGradient, this, &params);
00119 }
00120 
00121 }
00122 }
00123 }
00124 }