快速高斯模糊,高斯模糊
以前寫過兩篇關於快速高斯濾波的文章,但是代碼都沒寫完整。
算法來源及介紹請參考博主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