• 快速高斯模糊


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

    算法来源及介绍请参考博主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
  • 相关阅读:
    Spark Streaming 的容错
    Master 接受其它组件的注册
    Spark Context 概述
    Python 使用random模块生成随机数
    Python 中print 和return 的区别
    Python 访问字典(dictionary)中元素
    PIL:处理图像的好模块
    2.线性回归
    3.梯度下降法
    4.pca与梯度上升法
  • 原文地址:https://www.cnblogs.com/utopiaT/p/4549936.html
Copyright © 2020-2023  润新知