TuttleOFX
1
|
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, ¶ms); 00119 } 00120 00121 } 00122 } 00123 } 00124 }