📄 convolve.h
字号:
// {{{ Copyright notice// }}}// {{{ file documentation/** * @file * @brief Convolution operations for blitz 1D, 2D and 3D arrays. * * Defines convolution operations for blitz arrays. Currently, * 1D, 2D and 3D blitz arrays are supported. * * @warning Functions are defined using for loops and does not * use Expression Templates and Meta Programming techniques of * blitz arrays. */// }}}#ifndef _LEAR_CONVOLVE_H_#define _LEAR_CONVOLVE_H_// {{{ headers#include <blitz/array.h>#include <blitz/tinyvec.h>#include <blitz/tinyvec-et.h>// }}}BZ_NAMESPACE(blitz)// {{{ CPolicy_Mirror/** * @defgroup overloaded convolveMirrorExact functions * @brief Convolution operationeds limited to array boundaries only * (for example Quite handy for convolving images) * Array is mirrored accross boundaries. * * Define convolution of two arrays. * Array B and C are convolved with result in A. * Array B is mirrored accross boundaries. Return array has same size as array B. * * @param Array B (input Array) * @param Array C (convolution kernel) * @param Array A (convolution result) * * @warning Array C is assumed to be centered around 0. Also, size of B must be * greater than half the size of C. */struct CPolicy_Mirror { /// @brief 1D convolution. template<class TB, class TC> inline blitz::Array<typename blitz::promote_trait<TB,TC>::T_promote, 1> operator()( const blitz::Array<TB,1>& B, const blitz::Array<TC,1>& C, blitz::Array<typename blitz::promote_trait<TB,TC>::T_promote,1>& A ) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; const int Bl = B.lbound(0), Bh = B.ubound(0); const int Cl = C.lbound(0), Ch = C.ubound(0); for (int i=Bl; i <= Bh; ++i) { TA result = 0; int tj=0; for (int j=i-Ch; j <= i-Cl; ++j) { if (j<Bl) tj = 2*Bl - j; else if (j>Bh) tj = 2*Bh - j; else tj =j; result += B(tj) * C(i-j); } A(i) = result; } return A; }// }}} /// @brief 1D convolution at a point. template<class TB, class TC> inline typename blitz::promote_trait<TB,TC>::T_promote operator()( const blitz::Array<TB,1>& B, const blitz::Array<TC,1>& C, const int i) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; const int Bl = B.lbound(0), Bh = B.ubound(0); const int Cl = C.lbound(0), Ch = C.ubound(0); TA result = 0; int tj=0; for (int j=i-Ch; j <= i-Cl; ++j) { if (j<Bl) tj = 2*Bl - j; else if (j>Bh) tj = 2*Bh - j; else tj =j; result += B(tj) * C(i-j); } return result; }// }}} /// @brief Convolve 2D array with 1D array at a point. template<class TB, class TC> inline typename blitz::promote_trait<TB,TC>::T_promote operator() ( const blitz::Array<TB,2>& B, const blitz::Array<TC,1>& C, const blitz::TinyVector<int,2>& i) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; Range all = Range::all(); Array<TA,1> tmp (C.lbound(),C.extent()); const int Bl = B.lbound(1), Bh = B.ubound(1); const int Cl = C.lbound(0), Ch = C.ubound(0); tmp =0; int tj=0; for (int j=i[1]-Ch, k=Ch; j <= i[1]-Cl; ++j, --k) { if (j<Bl) tj = 2*Bl - j; else if (j>Bh) tj = 2*Bh - j; else tj =j; tmp(k) = (*this)( B(all,tj), C, i[0] ); } return sum(tmp*C); }// }}} /// @brief Convolve 2D array with 1D array at a point. template<class TB, class TC> inline typename blitz::promote_trait<TB,TC>::T_promote operator() ( const blitz::Array<TB,2>& B, const blitz::Array<TC,1>& CX, const blitz::Array<TC,1>& CY, const blitz::TinyVector<int,2>& i) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; Range all = Range::all(); Array<TA,1> tmp (CY.lbound(),CY.extent()); const int Bl = B.lbound(1), Bh = B.ubound(1); const int Cl = CY.lbound(0), Ch = CY.ubound(0); tmp =0; int tj=0; for (int j=i[1]-Ch, k=Ch; j <= i[1]-Cl; ++j, --k) { if (j<Bl) tj = 2*Bl - j; else if (j>Bh) tj = 2*Bh - j; else tj =j; tmp(k) = (*this)( B(all,tj), CX, i[0] ); } return sum(tmp*CY); }// }}}};// }}}//{{{ CPolicy_Chop/** * @brief Convolution is chopped off at array boundary.** Define convolution of two arrays. * Array B and C are convolved with result in A. * Array B is chopped off at boundaries. Return array has same size as array B.** @param Array B (input Array)* @param Array C (convolution kernel)* @param Array A (convolution result)** @warning size of B must be greater than half the size of C.*/struct CPolicy_Chop { /// @brief 1D convolution. template<class TB, class TC> inline blitz::Array<typename blitz::promote_trait<TB,TC>::T_promote, 1> operator()( const blitz::Array<TB,1>& B, const blitz::Array<TC,1>& C, blitz::Array<typename blitz::promote_trait<TB,TC>::T_promote,1>& A ) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; const int Bl = B.lbound(0), Bh = B.ubound(0); const int Cl = C.lbound(0), Ch = C.ubound(0); for (int i=Bl; i <= Bh; ++i) { int jl = i - Ch; if (jl < Bl) jl = Bl; int jh = i - Cl; if (jh > Bh) jh = Bh; TA result; result = 0; for (int j=jl; j <= jh; ++j) result += B(j) * C(i-j); A(i) = result; } return A; }// }}} /// @brief 1D convolution at a point. template<class TB, class TC> inline typename blitz::promote_trait<TB,TC>::T_promote operator()( const blitz::Array<TB,1>& B, const blitz::Array<TC,1>& C, const int i) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; const int Bl = B.lbound(0), Bh = B.ubound(0); const int Cl = C.lbound(0), Ch = C.ubound(0); int jl = i - Ch; if (jl < Bl) jl = Bl; int jh = i - Cl; if (jh > Bh) jh = Bh; TA result = 0; for (int j=jl; j <= jh; ++j) result += B(j) * C(i-j); return result; }// }}} ///@brief Convolve 2D array with 1D array at a point. template<class TB, class TC> inline typename blitz::promote_trait<TB,TC>::T_promote operator()( const blitz::Array<TB,2>& B, const blitz::Array<TC,1>& C, const blitz::TinyVector<int,2>& i) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; Range all = Range::all(); Array<TA,1> tmp (C.lbound(),C.extent()); const int Bl = B.lbound(1), Bh = B.ubound(1); const int Cl = C.lbound(0), Ch = C.ubound(0); int jl = i[1] - Ch; if (jl < Bl) jl = Bl; int jh = i[1] - Cl; if (jh > Bh) jh = Bh; tmp =0; for (int j= jl; j<= jh; ++j) { tmp(i[1] - j) = (*this)( B(all,j), C, i[0] ); } return sum(tmp*C); }// }}} ///@brief Convolve 2D array with 1D array at a point. /** * Use CX along X-axis and CY along y-axis for convolving. */ template<class TB, class TC> inline typename blitz::promote_trait<TB,TC>::T_promote operator()( const blitz::Array<TB,2>& B, const blitz::Array<TC,1>& CX, const blitz::Array<TC,1>& CY, const blitz::TinyVector<int,2>& i) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; Range all = Range::all(); Array<TA,1> tmp (CY.lbound(),CY.extent()); const int Bl = B.lbound(1), Bh = B.ubound(1); const int Cl = CY.lbound(0), Ch = CY.ubound(0); int jl = i[1] - Ch; if (jl < Bl) jl = Bl; int jh = i[1] - Cl; if (jh > Bh) jh = Bh; tmp =0; for (int j= jl; j<= jh; ++j) { tmp(i[1] - j) = (*this)( B(all,j), CX, i[0] ); } return sum(tmp*CY); }// }}}};//}}}//{{{ CPolicy_Stretch/** * @brief Convolution array is stretched at array boundary.** Define convolution of two arrays. * Array B and C are convolved with result in A. * Array B is stretched at boundaries. Return array has same size as array B.** @param Array B (input Array)* @param Array C (convolution kernel)* @param Array A (convolution result)** @warning size of B must be greater than half the size of C.*/struct CPolicy_Stretch { /// @brief 1D convolution. template<class TB, class TC> inline blitz::Array<typename blitz::promote_trait<TB,TC>::T_promote, 1> operator()( const blitz::Array<TB,1>& B, const blitz::Array<TC,1>& C, blitz::Array<typename blitz::promote_trait<TB,TC>::T_promote,1>& A ) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; const int Bl = B.lbound(0), Bh = B.ubound(0); const int Cl = C.lbound(0), Ch = C.ubound(0); for (int i=Bl; i <= Bh; ++i) { TA result; result = 0; int tj=0; for (int j=i-Ch; j <= i-Cl; ++j) { if (j<Bl) tj = Bl; else if (j>Bh) tj = Bh; else tj =j; result += B(tj) * C(i-j); } A(i) = result; } return A; }// }}} /// @brief 1D convolution at a point. template<class TB, class TC> inline typename blitz::promote_trait<TB,TC>::T_promote operator()( const blitz::Array<TB,1>& B, const blitz::Array<TC,1>& C, const int i) const {// {{{ using namespace blitz; typedef typename blitz::promote_trait<TB,TC>::T_promote TA; const int Bl = B.lbound(0), Bh = B.ubound(0); const int Cl = C.lbound(0), Ch = C.ubound(0); TA result = 0; int tj=0; for (int j=i-Ch; j <= i-Cl; ++j) { if (j<Bl) tj = Bl; else if (j>Bh) tj = Bh; else tj =j; result += B(tj) * C(i-j); } return result; }// }}} ///@brief Convolve 2D array with 1D array at a point. template<class TB, class TC> inline
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -