作者:苏小宝 | 来源:互联网 | 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 );elseCV_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);elseradius &#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];}elseexpLUT[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);elseradius &#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);
}