zoukankan      html  css  js  c++  java
  • 快速高斯模糊

    以前写过两篇关于快速高斯滤波的文章,但是代码都没写完整。

    算法来源及介绍请参考博主Imageshop的博文http://www.cnblogs.com/Imageshop/archive/2013/01/07/2849782.html

    为了避免需要的朋友在看我的文章时过于浪费时间,所以删除前两篇文章,重写此篇目的为需要的朋友提供有用的信息。

    下面给出的是功能完整的 c代码,下面代码无论是格式还是速度都可以进一步优化,请自行处理

      1 /****************************************
      2 * src    : 原始图像数据                 *
      3 * dst    : 模糊后图像数据               *
      4 * width  : 图像宽                       *
      5 * height : 图像高                       *
      6 * stride : 图像每一行字节数                *
      7 * chan   : 图像通道数                   *
      8 * sigma  : 高斯参数                     *
      9 * chan   : 图像通道数                   *
     10 *****************************************/
     11 void IMG_GaussBlur(unsigned char* src, unsigned char* dst, int width, int height, int stride, int chan, float sigma)
     12 {
     13     int i = 0;
     14     int h,w;
     15     int row    = 0;
     16     int col    = 0;
     17     int pos    = 0;
     18     int channel    = 0;
     19     int n = 0;
     20     int bufsize = 0;        
     21     int size = 0;
     22     int rowstride = 0;
     23     int itemp0 = 0;
     24     int itemp1 = 0;    
     25     float temp = 0;
     26     float fTab[256] = {0};
     27     unsigned char* ps;
     28     float *pIn;
     29 
     30     int blurH = height+3;
     31     int blurW = width+3;
     32     for (i=0; i<256; i++)
     33     {
     34         fTab[i] = i+1;
     35     }
     36 
     37     int    channelsize = width*height+(width+height)*6;
     38 
     39     if (width>height)
     40     {
     41         bufsize = width+6;
     42     }
     43     else
     44     {
     45         bufsize = height+6;
     46     }    
     47 
     48     float* w1    = (float *) malloc (bufsize * sizeof (float));
     49     float *w2    = (float *) malloc (bufsize * sizeof (float));
     50     float *in    = (float *) malloc (channelsize * sizeof (float));
     51     float *out    = (float *) malloc (channelsize * sizeof (float));
     52 
     53 //----------------计算高斯核---------------------------------------//
     54     float  q    = 0; 
     55     float  q2, q3;    
     56     double b0;
     57     double b1;
     58     double b2;
     59     double b3;
     60     double B    = 0;
     61     int    N    = 3;
     62 
     63     if (sigma >= 2.5)
     64     {
     65         q = 0.98711 * sigma - 0.96330;
     66     }
     67     else if ((sigma >= 0.5) && (sigma < 2.5))
     68     {
     69         q = 3.97156 - 4.14554 * (float) sqrt ((double) 1 - 0.26891 * sigma);
     70     }
     71     else
     72     {
     73         q = 0.1147705018520355224609375;
     74     }
     75 
     76     q2 = q * q;
     77     q3 = q * q2;
     78     b0 = (1.57825+(2.44413*q)+(1.4281 *q2)+(0.422205*q3));
     79     b1 = (        (2.44413*q)+(2.85619*q2)+(1.26661 *q3));
     80     b2 = (                   -((1.4281*q2)+(1.26661 *q3)));
     81     b3 = (                                 (0.422205*q3));
     82     B = 1.0-((b1+b2+b3)/b0);
     83 
     84     //加速方法 减少循环多次/b0
     85     b1 /= b0;
     86     b2 /= b0;
     87     b3 /= b0;
     88 
     89 //----------------计算高斯核结束---------------------------------------//    
     90     // 处理图像的多个通道
     91     for (channel = 0; channel < chan; channel++)
     92     {
     93         // 获取一个通道的所有像素值
     94         pIn = in;
     95         for (h=0; h<height; h++)
     96         {
     97             ps = src + h*stride;
     98             for (w=0;w<width;w++)
     99             {
    100                 /* 0-255 => 1-256 */
    101                 *pIn++ = fTab[ps[channel]];
    102                 
    103                 if (w==width-1)
    104                 {
    105                     *pIn++ = fTab[ps[channel]];
    106                     *pIn++ = fTab[ps[channel]];
    107                     *pIn++ = fTab[ps[channel]];
    108                 }
    109                 ps+=chan;
    110             }
    111         } 
    112         memcpy(in+(height)*(width+3), in+(height-1)*(width+3), (width+3)*sizeof(float));
    113         memcpy(in+(height+1)*(width+3), in+(height-1)*(width+3), (width+3)*sizeof(float));
    114         memcpy(in+(height+2)*(width+3), in+(height-1)*(width+3), (width+3)*sizeof(float));
    115 
    116         //纵向处理
    117         size        = blurW;    
    118         bufsize     = size+3;
    119         size        -= 1;
    120         for (row=0 ;row < blurH; row++)
    121         {
    122             pos      = row * blurW; 
    123             temp  = (in + pos)[0];  
    124             w1[0] = temp;
    125             w1[1] = temp;
    126             w1[2] = temp;
    127 
    128             for ( i = 0 , n=3; i <= size ; i++, n++)
    129             {
    130                 w1[n] = (float)(B*(in + pos)[i] +    ((b1*w1[n-1] +     b2*w1[n-2] + b3*w1[n-3] )));
    131             }
    132 
    133             temp =  w1[size+3];
    134             w2[size+1]= temp;
    135             w2[size+2]= temp;
    136             w2[size+3]= temp;
    137             for (i = size, n = i; i >= 0; i--, n--)
    138             {
    139                  (out + pos)[i] = w2[n] = (float)(B*w1[n] +    ((b1*w2[n+1] +    b2*w2[n+2] + b3*w2[n+3] )));
    140             }    
    141         }    
    142         
    143 
    144         //横向处理
    145         size        = blurH;
    146         rowstride   = blurW;
    147         bufsize     = size+3;
    148         size        -= 1;
    149         for (col=0; col < blurW; col++)
    150         {
    151             temp  = (out + col)[0];
    152             w1[0] = temp;
    153             w1[1] = temp;
    154             w1[2] = temp;
    155             for ( i = 0 , n=3; i <= size ; i++, n++)
    156             {
    157                 w1[n] = (float)(B*(out + col)[i*rowstride] + ((b1*w1[n-1] + b2*w1[n-2] + b3*w1[n-3] )));
    158             }
    159             
    160             temp        = w1[size+3];
    161             w2[size+1]    = temp;
    162             w2[size+2]    = temp;
    163             w2[size+3]    = temp;
    164             for (i = size, n = i; i >= 0; i--, n--)
    165             {
    166                 (in + col)[i * rowstride] =w2[n]= (float)(B*w1[n] +  ((b1*w2[n+1] + b2*w2[n+2] + b3*w2[n+3] )));
    167             }                
    168         }
    169     
    170         //修正偏移的拷贝方法
    171         for(int y=0; y<height; y++)
    172         {
    173             ps = dst+ y*stride;
    174             itemp1 = (y+3)*blurW;                                // +3
    175             for (int x=0; x<width; x++)
    176             {        
    177                 ps[channel] = in[itemp1+x+3]-1;
    178                 ps+=chan;
    179             }
    180         }         
    181     }
    182 
    183     free (w1);
    184     free (w2);
    185     free (in);
    186     free (out);
    187 }
    View Code

      调用参考

    1 IplImage* src = cvLoadImage("./test.jpg", 1);
    2 IplImage* dst = cvLoadImage("./test.jpg", 1);
    3 
    4 IMG_GaussBlur((unsigned char*)src->imageData, 
    5               (unsigned char*)dst->imageData, 
    6               src->width, src->height, 
    7               src->widthStep,
    8               src->nChannels, 2);
    View Code
  • 相关阅读:
    [CodeForces]Codeforces Round #429 (Div. 2) ABC(待补)
    About Me
    2018-06-14
    Codeforces Codeforces Round #484 (Div. 2) E. Billiard
    Codeforces Codeforces Round #484 (Div. 2) D. Shark
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
    Codeforces Avito Code Challenge 2018 D. Bookshelves
    Codeforces Round #485 (Div. 2) D. Fair
    Codeforces Round #485 (Div. 2) F. AND Graph
  • 原文地址:https://www.cnblogs.com/utopiaT/p/4549936.html
Copyright © 2011-2022 走看看