作者:苏小宝 | 来源:互联网 | 2023-10-11 20:18
双边滤波OpenCV源码1、源码路径2、源码代码1、源码路径OpenCV\modules\opencv_imgproc\Src\bilateral_filter.dispatch
1、源码路径 OpenCV\modules\opencv_imgproc\Src\bilateral_filter.dispatch.cpp
2、源码代码 void bilateralFilter ( InputArray _src, OutputArray _dst, int d, double sigmaColor, double sigmaSpace, int borderType ) { CV_INSTRUMENT_REGION ( ) ; CV_Assert ( ! _src. empty ( ) ) ; _dst. create ( _src. size ( ) , _src. type ( ) ) ; CV_OCL_RUN ( _src. dims ( ) <&#61; 2 && _dst. isUMat ( ) , ocl_bilateralFilter_8u ( _src, _dst, d, sigmaColor, sigmaSpace, borderType) ) Mat src &#61; _src. getMat ( ) , dst &#61; _dst. getMat ( ) ; CV_IPP_RUN_FAST ( ipp_bilateralFilter ( src, dst, d, sigmaColor, sigmaSpace, borderType) ) ; if ( src. depth ( ) &#61;&#61; CV_8U ) bilateralFilter_8u ( src, dst, d, sigmaColor, sigmaSpace, borderType ) ; else if ( src. depth ( ) &#61;&#61; CV_32F ) bilateralFilter_32f ( src, dst, d, sigmaColor, sigmaSpace, borderType ) ; else CV_Error ( CV_StsUnsupportedFormat, "Bilateral filtering is only implemented for 8u and 32f images" ) ; }
static void bilateralFilter_32f ( const Mat& src, Mat& dst, int d, double sigma_color, double sigma_space, int borderType ) { CV_INSTRUMENT_REGION ( ) ; int cn &#61; src. channels ( ) ; int i, j, maxk, radius; double minValSrc&#61; - 1 , maxValSrc&#61; 1 ; const int kExpNumBinsPerChannel &#61; 1 << 12 ; int kExpNumBins &#61; 0 ; float lastExpVal &#61; 1.f ; float len, scale_index; CV_Assert ( ( src. type ( ) &#61;&#61; CV_32FC1 || src. type ( ) &#61;&#61; CV_32FC3) && src. data !&#61; dst. data ) ; if ( sigma_color <&#61; 0 ) sigma_color &#61; 1 ; if ( sigma_space <&#61; 0 ) sigma_space &#61; 1 ; double gauss_color_coeff &#61; - 0.5 / ( sigma_color* sigma_color) ; double gauss_space_coeff &#61; - 0.5 / ( sigma_space* sigma_space) ; if ( d <&#61; 0 ) radius &#61; cvRound ( sigma_space* 1.5 ) ; else radius &#61; d/ 2 ; radius &#61; MAX ( radius, 1 ) ; d &#61; radius* 2 &#43; 1 ; minMaxLoc ( src. reshape ( 1 ) , & minValSrc, & maxValSrc ) ; if ( std:: abs ( minValSrc - maxValSrc) < FLT_EPSILON) { src. copyTo ( dst) ; return ; } Mat temp; copyMakeBorder ( src, temp, radius, radius, radius, radius, borderType ) ; std:: vector< float > _space_weight ( d* d) ; std:: vector< int > _space_ofs ( d* d) ; float * space_weight &#61; & _space_weight[ 0 ] ; int * space_ofs &#61; & _space_ofs[ 0 ] ; len &#61; ( float ) ( maxValSrc - minValSrc) * cn; kExpNumBins &#61; kExpNumBinsPerChannel * cn; std:: vector< float > _expLUT ( kExpNumBins&#43; 2 ) ; float * expLUT &#61; & _expLUT[ 0 ] ; scale_index &#61; kExpNumBins/ len; for ( i &#61; 0 ; i < kExpNumBins&#43; 2 ; i&#43;&#43; ) { if ( lastExpVal > 0.f ) { double val &#61; i / scale_index; expLUT[ i] &#61; ( float ) std:: exp ( val * val * gauss_color_coeff) ; lastExpVal &#61; expLUT[ i] ; } else expLUT[ i] &#61; 0.f ; } for ( i &#61; - radius, maxk &#61; 0 ; i <&#61; radius; i&#43;&#43; ) for ( j &#61; - radius; j <&#61; radius; j&#43;&#43; ) { double r &#61; std:: sqrt ( ( double ) i* i &#43; ( double ) j* j) ; if ( r > radius || ( i &#61;&#61; 0 && j &#61;&#61; 0 ) ) continue ; space_weight[ maxk] &#61; ( float ) std:: exp ( r* r* gauss_space_coeff) ; space_ofs[ maxk&#43;&#43; ] &#61; ( int ) ( i* ( temp. step/ sizeof ( float ) ) &#43; j* cn) ; } CV_CPU_DISPATCH ( bilateralFilterInvoker_32f, ( cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT) , CV_CPU_DISPATCH_MODES_ALL) ; }
static void bilateralFilter_8u ( const Mat& src, Mat& dst, int d, double sigma_color, double sigma_space, int borderType ) { CV_INSTRUMENT_REGION ( ) ; int cn &#61; src. channels ( ) ; int i, j, maxk, radius; CV_Assert ( ( src. type ( ) &#61;&#61; CV_8UC1 || src. type ( ) &#61;&#61; CV_8UC3) && src. data !&#61; dst. data ) ; if ( sigma_color <&#61; 0 ) sigma_color &#61; 1 ; if ( sigma_space <&#61; 0 ) sigma_space &#61; 1 ; double gauss_color_coeff &#61; - 0.5 / ( sigma_color* sigma_color) ; double gauss_space_coeff &#61; - 0.5 / ( sigma_space* sigma_space) ; if ( d <&#61; 0 ) radius &#61; cvRound ( sigma_space* 1.5 ) ; else radius &#61; d/ 2 ; radius &#61; MAX ( radius, 1 ) ; d &#61; radius* 2 &#43; 1 ; Mat temp; copyMakeBorder ( src, temp, radius, radius, radius, radius, borderType ) ; std:: vector< float > _color_weight ( cn* 256 ) ; std:: vector< float > _space_weight ( d* d) ; std:: vector< int > _space_ofs ( d* d) ; float * color_weight &#61; & _color_weight[ 0 ] ; float * space_weight &#61; & _space_weight[ 0 ] ; int * space_ofs &#61; & _space_ofs[ 0 ] ; for ( i &#61; 0 ; i < 256 * cn; i&#43;&#43; ) color_weight[ i] &#61; ( float ) std:: exp ( i* i* gauss_color_coeff) ; for ( i &#61; - radius, maxk &#61; 0 ; i <&#61; radius; i&#43;&#43; ) { j &#61; - radius; for ( ; j <&#61; radius; j&#43;&#43; ) { double r &#61; std:: sqrt ( ( double ) i* i &#43; ( double ) j* j) ; if ( r > radius ) continue ; space_weight[ maxk] &#61; ( float ) std:: exp ( r* r* gauss_space_coeff) ; space_ofs[ maxk&#43;&#43; ] &#61; ( int ) ( i* temp. step &#43; j* cn) ; } } CV_CPU_DISPATCH ( bilateralFilterInvoker_8u, ( dst, temp, radius, maxk, space_ofs, space_weight, color_weight) , CV_CPU_DISPATCH_MODES_ALL) ; }