OPENCV学习一(滤波)

来源:互联网 发布:adobe reader for mac 编辑:程序博客网 时间:2024/05/19 00:17

opencv中常见的4种滤波算有均值滤波,高斯滤波,中值滤波,双边滤波。

双边滤波:

  1. /****************************************************************************************\ 
  2.                                    Bilateral Filtering 
  3. \****************************************************************************************/  
  4.   
  5. namespace cv  
  6. {  
  7.   
  8. static void  
  9. bilateralFilter_8u( const Mat& src, Mat& dst, int d,  
  10.                     double sigma_color, double sigma_space,  
  11.                     int borderType )  
  12. {  
  13.     int cn = src.channels();  
  14.     int i, j, k, maxk, radius;  
  15.     Size size = src.size();  
  16.   
  17.     CV_Assert( (src.type() == CV_8UC1 || src.type() == CV_8UC3) &&  
  18.         src.type() == dst.type() && src.size() == dst.size() &&  
  19.         src.data != dst.data );  
  20.   
  21.     if( sigma_color <= 0 )  
  22.         sigma_color = 1;  
  23.     if( sigma_space <= 0 )  
  24.         sigma_space = 1;  
  25.   
  26.     double gauss_color_coeff = -0.5/(sigma_color*sigma_color);  
  27.     double gauss_space_coeff = -0.5/(sigma_space*sigma_space);  
  28.   
  29.     if( d <= 0 )  
  30.         radius = cvRound(sigma_space*1.5);  
  31.     else  
  32.         radius = d/2;  
  33.     radius = MAX(radius, 1);  
  34.     d = radius*2 + 1;  
  35.   
  36.     Mat temp;  
  37.     copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );  
  38.   
  39.     vector<float> _color_weight(cn*256);  
  40.     vector<float> _space_weight(d*d);  
  41.     vector<int> _space_ofs(d*d);  
  42.     float* color_weight = &_color_weight[0];  
  43.     float* space_weight = &_space_weight[0];  
  44.     int* space_ofs = &_space_ofs[0];  
  45.   
  46.     // initialize color-related bilateral filter coefficients  
  47.     for( i = 0; i < 256*cn; i++ )  
  48.         color_weight[i] = (float)std::exp(i*i*gauss_color_coeff);  
  49.   
  50.     // initialize space-related bilateral filter coefficients  
  51.     for( i = -radius, maxk = 0; i <= radius; i++ )  
  52.         for( j = -radius; j <= radius; j++ )  
  53.         {  
  54.             double r = std::sqrt((double)i*i + (double)j*j);  
  55.             if( r > radius )  
  56.                 continue;  
  57.             space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff);  
  58.             space_ofs[maxk++] = (int)(i*temp.step + j*cn);  
  59.         }  
  60.   
  61.     for( i = 0; i < size.height; i++ )  
  62.     {  
  63.         const uchar* sptr = temp.data + (i+radius)*temp.step + radius*cn;  
  64.         uchar* dptr = dst.data + i*dst.step;  
  65.   
  66.         if( cn == 1 )  
  67.         {  
  68.             for( j = 0; j < size.width; j++ )  
  69.             {  
  70.                 float sum = 0, wsum = 0;  
  71.                 int val0 = sptr[j];  
  72.                 for( k = 0; k < maxk; k++ )  
  73.                 {  
  74.                     int val = sptr[j + space_ofs[k]];  
  75.                     float w = space_weight[k]*color_weight[std::abs(val - val0)];  
  76.                     sum += val*w;  
  77.                     wsum += w;  
  78.                 }  
  79.                 // overflow is not possible here => there is no need to use CV_CAST_8U  
  80.                 dptr[j] = (uchar)cvRound(sum/wsum);  
  81.             }  
  82.         }  
  83.         else  
  84.         {  
  85.             assert( cn == 3 );  
  86.             for( j = 0; j < size.width*3; j += 3 )  
  87.             {  
  88.                 float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0;  
  89.                 int b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2];  
  90.                 for( k = 0; k < maxk; k++ )  
  91.                 {  
  92.                     const uchar* sptr_k = sptr + j + space_ofs[k];  
  93.                     int b = sptr_k[0], g = sptr_k[1], r = sptr_k[2];  
  94.                     float w = space_weight[k]*color_weight[std::abs(b - b0) +  
  95.                         std::abs(g - g0) + std::abs(r - r0)];  
  96.                     sum_b += b*w; sum_g += g*w; sum_r += r*w;  
  97.                     wsum += w;  
  98.                 }  
  99.                 wsum = 1.f/wsum;  
  100.                 b0 = cvRound(sum_b*wsum);  
  101.                 g0 = cvRound(sum_g*wsum);  
  102.                 r0 = cvRound(sum_r*wsum);  
  103.                 dptr[j] = (uchar)b0; dptr[j+1] = (uchar)g0; dptr[j+2] = (uchar)r0;  
  104.             }  
  105.         }  
  106.     }  

opencv中调用:
  1. bilateralFilter(InputArray src, OutputArray dst, int n, double sigmaColor, double sigmaSpace,  
  2.                       int borderType=BORDER_DEFAULT );  

便于自己学习查询,特记录学习点滴

阅读全文
0 0
原创粉丝点击