Mercurial > hg > wm
comparison Meerwald/dwt.c @ 0:be303a3f5ea8
import
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Sun, 12 Aug 2007 13:14:34 +0200 |
parents | |
children | acb6967ee76d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:be303a3f5ea8 |
---|---|
1 #include "wm.h" | |
2 #include "dwt.h" | |
3 | |
4 char filter_file[MAXPATHLEN] = ""; | |
5 AllFilters dwt_allfilters; | |
6 FilterGH *dwt_filters = NULL; | |
7 int dwt_method; | |
8 int dwt_cols; | |
9 int dwt_rows; | |
10 int dwt_levels; | |
11 int dwt_filter; | |
12 | |
13 void init_dwt(int cols, int rows, const char *filter_name, int filter, int level, int method) { | |
14 int i; | |
15 | |
16 if (strcmp(filter_file, filter_name)) { | |
17 if (filter_name) | |
18 strcpy(filter_file, filter_name); | |
19 else | |
20 strcpy(filter_file, "filter.dat"); | |
21 /* memory leak here - there is no function unload_filters() */ | |
22 dwt_allfilters = load_filters(filter_file); | |
23 if (!dwt_allfilters) { | |
24 fprintf(stderr, "init_dwt(): unable to open filter definition file %s\n", filter_file); | |
25 return; | |
26 } | |
27 } | |
28 | |
29 #ifdef DEBUG | |
30 if (level <= 0 || level > rint(log(MIN(cols, rows))/log(2.0)) - 2) { | |
31 fprintf(stderr, "init_dwt(): level parameter does not match image width/height\n"); | |
32 return; | |
33 } | |
34 #endif | |
35 | |
36 if (dwt_filters && level != dwt_levels) { | |
37 free(dwt_filters); | |
38 dwt_filters = NULL; | |
39 } | |
40 | |
41 dwt_levels = level; | |
42 | |
43 if (!dwt_filters) | |
44 dwt_filters = calloc(level + 1, sizeof(FilterGH)); | |
45 | |
46 for (i = 0; i < level + 1; i++) | |
47 dwt_filters[i] = (dwt_allfilters->filter)[filter]; | |
48 | |
49 dwt_filter = filter; | |
50 dwt_method = method; | |
51 dwt_cols = cols; | |
52 dwt_rows = rows; | |
53 } | |
54 | |
55 Image_tree fdwt(gray **pixels) { | |
56 Image image; | |
57 Image_tree tree; | |
58 int i, j; | |
59 | |
60 image = new_image(dwt_cols, dwt_rows); | |
61 | |
62 for (i = 0; i < dwt_rows; i++) | |
63 for (j = 0; j < dwt_cols; j++) | |
64 set_pixel(image, j, i, pixels[i][j]); | |
65 | |
66 tree = wavelettransform(image, dwt_levels, dwt_filters, dwt_method); | |
67 free_image(image); | |
68 | |
69 return tree; | |
70 } | |
71 | |
72 Image_tree fdwt_wp(gray **pixels) { | |
73 Image image; | |
74 Image_tree tree; | |
75 int i, j; | |
76 | |
77 image = new_image(dwt_cols, dwt_rows); | |
78 | |
79 for (i = 0; i < dwt_rows; i++) | |
80 for (j = 0; j < dwt_cols; j++) | |
81 set_pixel(image, j, i, pixels[i][j]); | |
82 | |
83 tree = wavelettransform_wp(image, dwt_levels, dwt_filters, dwt_method); | |
84 free_image(image); | |
85 | |
86 return tree; | |
87 } | |
88 | |
89 void idwt(Image_tree dwts, gray **pixels) { | |
90 Image image; | |
91 int i, j; | |
92 | |
93 image = inv_transform(dwts, dwt_filters, dwt_method + 1); | |
94 | |
95 for (i = 0; i < dwt_rows; i++) | |
96 for (j = 0; j < dwt_cols; j++) | |
97 pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); | |
98 | |
99 free_image(image); | |
100 } | |
101 | |
102 void idwt_wp(Image_tree dwts, gray **pixels) { | |
103 Image image; | |
104 int i, j; | |
105 | |
106 image = inv_transform(dwts, dwt_filters, dwt_method + 1); | |
107 | |
108 for (i = 0; i < dwt_rows; i++) | |
109 for (j = 0; j < dwt_cols; j++) | |
110 pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); | |
111 | |
112 free_image(image); | |
113 } | |
114 | |
115 int gen_pollen_filter(double *filter, double alpha, double beta, int which) { | |
116 int i, j, k, filterlength; | |
117 double tf[6]; | |
118 | |
119 /* parameter alpha, beta have to be in range -Pi .. Pi */ | |
120 if (alpha < -M_PI || alpha >= M_PI) { | |
121 fprintf(stderr, "alpha %f out of range\n", alpha); | |
122 return -1; | |
123 } | |
124 | |
125 if (beta < -M_PI || beta >= M_PI) { | |
126 fprintf(stderr, "beta %f out of range\n", beta); | |
127 return -1; | |
128 } | |
129 | |
130 /* generate Pollen filter coefficients, see http://www.dfw.net/~cody for details */ | |
131 tf[0] = ((1.0 + cos(alpha) + sin(alpha)) * (1.0 - cos(beta) - sin(beta)) + 2.0 * sin(beta) * cos(alpha)) / 4.0; | |
132 tf[1] = ((1.0 - cos(alpha) + sin(alpha)) * (1.0 + cos(beta) - sin(beta)) - 2.0 * sin(beta) * cos(alpha)) / 4.0; | |
133 tf[2] = (1.0 + cos(alpha - beta) + sin(alpha - beta)) / 2.0; | |
134 tf[3] = (1.0 + cos(alpha - beta) - sin(alpha - beta)) / 2.0; | |
135 tf[4] = 1.0 - tf[0] - tf[2]; | |
136 tf[5] = 1.0 - tf[1] - tf[3]; | |
137 | |
138 /* set close-to-zero filter coefficients to zero */ | |
139 for (i = 0; i < 6; i++) | |
140 if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; | |
141 | |
142 /* find the first non-zero wavelet coefficient */ | |
143 i = 0; | |
144 while (tf[i] == 0.0) i++; | |
145 | |
146 /* find the last non-zero wavelet coefficient */ | |
147 j = 5; | |
148 while (tf[j] == 0.0) j--; | |
149 | |
150 filterlength = j - i + 1; | |
151 for (k = 0; k < filterlength; k++) | |
152 switch (which) { | |
153 case FILTERH: | |
154 filter[k] = tf[j--] / 2.0; | |
155 break; | |
156 case FILTERG: | |
157 filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i++] / 2.0; | |
158 break; | |
159 case FILTERHi: | |
160 filter[k] = tf[j--]; | |
161 break; | |
162 case FILTERGi: | |
163 filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i++]; | |
164 break; | |
165 default: | |
166 return -1; | |
167 } | |
168 | |
169 while (k < 6) | |
170 filter[k++] = 0.0; | |
171 | |
172 return filterlength; | |
173 } | |
174 | |
175 void dwt_pollen_filter(double alpha, double beta) { | |
176 FilterGH filter; | |
177 int i; | |
178 | |
179 filter = malloc(sizeof(struct FilterGHStruct)); | |
180 #ifdef DEBUG | |
181 if (!filter) { | |
182 fprintf(stderr, "dwt_pollen_filter(): malloc failed()\n"); | |
183 return; | |
184 } | |
185 #endif | |
186 | |
187 filter->type = FTOther; | |
188 filter->name = "pollen"; | |
189 | |
190 filter->g = new_filter(6); | |
191 filter->g->type = FTSymm; | |
192 filter->g->hipass = 1; | |
193 filter->g->len = gen_pollen_filter(filter->g->data, alpha, beta, FILTERG); | |
194 filter->g->start = -filter->g->len / 2; | |
195 filter->g->end = filter->g->len / 2 - 1; | |
196 | |
197 filter->h = new_filter(6); | |
198 filter->h->type = FTSymm; | |
199 filter->h->hipass = 0; | |
200 filter->h->len = gen_pollen_filter(filter->h->data, alpha, beta, FILTERH); | |
201 filter->h->start = -filter->h->len / 2; | |
202 filter->h->end = filter->h->len / 2 - 1; | |
203 | |
204 filter->gi = new_filter(6); | |
205 filter->gi->type = FTSymm; | |
206 filter->gi->hipass = 1; | |
207 filter->gi->len = gen_pollen_filter(filter->gi->data, alpha, beta, FILTERGi); | |
208 filter->gi->start = -filter->gi->len / 2; | |
209 filter->gi->end = filter->gi->len / 2 - 1; | |
210 | |
211 filter->hi = new_filter(6); | |
212 filter->hi->type = FTSymm; | |
213 filter->hi->hipass = 0; | |
214 filter->hi->len = gen_pollen_filter(filter->hi->data, alpha, beta, FILTERHi); | |
215 filter->hi->start = -filter->hi->len / 2; | |
216 filter->hi->end = filter->hi->len / 2 - 1; | |
217 | |
218 #ifdef DEBUG | |
219 if (dwt_levels <= 0) { | |
220 fprintf(stderr, "dwt_pollen_filter(): level invalid - set to zero\n"); | |
221 return; | |
222 } | |
223 #endif | |
224 | |
225 #ifdef DEBUG | |
226 if (!dwt_filters) { | |
227 fprintf(stderr, "dwt_pollen_filter(): wm_dwt not initialized, call init_dwt() first\n"); | |
228 return; | |
229 } | |
230 #endif | |
231 | |
232 for (i = 0; i < dwt_levels + 1; i++) | |
233 dwt_filters[i] = filter; | |
234 } | |
235 | |
236 int gen_param_filter(double *filter, int n, double alpha[], int which) { | |
237 int i, j, k, filterlength; | |
238 double *tf, *t; | |
239 | |
240 tf = malloc(2 * (n + 1) * sizeof(double)); | |
241 t = malloc(2 * (n + 1) * sizeof(double)); | |
242 if (!tf) { | |
243 fprintf(stderr, "gen_param_filter(): malloc() failed\n"); | |
244 return -1; | |
245 } | |
246 | |
247 tf[0] = 1.0 / sqrt(2.0); | |
248 tf[1] = 1.0 / sqrt(2.0); | |
249 | |
250 for (k = 0; k < n; k++) { | |
251 for (i = 0; i < 2 * (k + 2); i++) { | |
252 | |
253 #define H(X) (((X) < 0 || (X) >= 2 * (k + 1)) ? 0.0 : tf[X]) | |
254 | |
255 t[i] = 0.5 * (H(i - 2) + H(i) + | |
256 cos(alpha[k]) * (H(i - 2) - H(i)) + | |
257 (i & 1 ? -1.0 : 1.0) * sin(alpha[k]) * (H(2 * (k + 2) - i - 1) - H(2 * (k + 2) - i - 3))); | |
258 } | |
259 for (i = 0; i < 2 * (k + 2); i++) tf[i] = t[i]; | |
260 } | |
261 | |
262 /* set close-to-zero filter coefficients to zero */ | |
263 for (i = 0; i < 2 * (n + 1) ; i++) | |
264 if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; | |
265 | |
266 /* find the first non-zero wavelet coefficient */ | |
267 i = 0; | |
268 while (tf[i] == 0.0) i++; | |
269 | |
270 /* find the last non-zero wavelet coefficient */ | |
271 j = 2 * (n + 1) - 1; | |
272 while (tf[j] == 0.0) j--; | |
273 | |
274 filterlength = j - i + 1; | |
275 for (k = 0; k < filterlength; k++) | |
276 switch (which) { | |
277 case FILTERG: | |
278 case FILTERGi: | |
279 filter[k] = (double) (((i+1 & 0x01) * 2) - 1) * tf[i++]; | |
280 break; | |
281 case FILTERH: | |
282 case FILTERHi: | |
283 filter[k] = tf[j--]; | |
284 break; | |
285 default: | |
286 return -1; | |
287 } | |
288 | |
289 while (k < 2 * (n + 1)) | |
290 filter[k++] = 0.0; | |
291 | |
292 return filterlength; | |
293 } | |
294 | |
295 void dwt_param_filter(double alpha[], int n) { | |
296 FilterGH filter; | |
297 int i; | |
298 | |
299 filter = malloc(sizeof(struct FilterGHStruct)); | |
300 #ifdef DEBUG | |
301 if (!filter) { | |
302 fprintf(stderr, "dwt_param_filter(): malloc failed()\n"); | |
303 return; | |
304 } | |
305 #endif | |
306 | |
307 filter->type = FTOrtho; | |
308 filter->name = "param"; | |
309 | |
310 filter->g = new_filter(2 * (n + 1)); | |
311 filter->g->type = FTSymm; | |
312 filter->g->hipass = 1; | |
313 filter->g->len = gen_param_filter(filter->g->data, n, alpha, FILTERG); | |
314 filter->g->start = -filter->g->len / 2; | |
315 filter->g->end = filter->g->len / 2 - 1; | |
316 | |
317 filter->h = new_filter(2 * (n + 1)); | |
318 filter->h->type = FTSymm; | |
319 filter->h->hipass = 0; | |
320 filter->h->len = gen_param_filter(filter->h->data, n, alpha, FILTERH); | |
321 filter->h->start = -filter->h->len / 2; | |
322 filter->h->end = filter->h->len / 2 - 1; | |
323 | |
324 #ifdef DEBUG | |
325 if (dwt_levels <= 0) { | |
326 fprintf(stderr, "dwt_pollen_filter(): level invalid - set to zero\n"); | |
327 return; | |
328 } | |
329 #endif | |
330 | |
331 #ifdef DEBUG | |
332 if (!dwt_filters) { | |
333 fprintf(stderr, "dwt_pollen_filter(): wm_dwt not initialized, call init_dwt() first\n"); | |
334 return; | |
335 } | |
336 #endif | |
337 | |
338 for (i = 0; i < dwt_levels + 1; i++) | |
339 dwt_filters[i] = filter; | |
340 } | |
341 | |
342 void done_dwt() { | |
343 } |