快速高斯模糊

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

算法来源及介绍请参考博主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
原文地址:https://www.cnblogs.com/utopiaT/p/4549936.html