1 /**********
2 *
3 * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
4 * University of Manchester, UK. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * . Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * . Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * . Neither the name of the University of Manchester nor the names of its
17 * contributors may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 **********
34 *
35 * Program : TINA
36 * File : $Source: /home/tina/cvs/tina-libs/tina/image/imgPrc_lsf.c,v $
37 * Date : $Date: 2003/09/22 16:09:02 $
38 * Version : $Revision: 1.5 $
39 * CVS Id : $Id: imgPrc_lsf.c,v 1.5 2003/09/22 16:09:02 tony Exp $
40 *
41 * Author : Legacy TINA
42 */
43
44 /**
45 * @file
46 * @brief Linear sequential filter functions for smoothing of images with large exponential
47 * kenels. Otherwise known as IIR and FIR filters.
48 *
49 */
50
51 #include "imgPrc_lsf.h"
52
53 #if HAVE_CONFIG_H
54 #include <config.h>
55 #endif
56
57 #include <math.h>
58 #include <tina/sys/sysDef.h>
59 #include <tina/sys/sysPro.h>
60 #include <tina/math/mathDef.h>
61 #include <tina/math/mathPro.h>
62 #include <tina/image/img_GenDef.h>
63 #include <tina/image/img_GenPro.h>
64
65 static void lsf_smooth(int n1, int n2, float *u1, float *u2, double sigma, float *weight)
66 {
67 int i;
68 float *v1 = fvector_alloc(n1, n2);
69 float *v2 = fvector_alloc(n1, n2);
70 double a, b = exp(-1.0 / sigma), ab;
71
72 a = (1 - b) / (1 + b); /** makes filter sum to 1 **/
73 ab = a * b;
74
75 v1[n1] = (float) (a * u1[n1]);
76 for (i = n1 + 1; i < n2; i++)
77 v1[i] = (float) (a * u1[i] + b * v1[i - 1]);
78
79 v2[n2 - 1] = (float) 0.0;
80 for (i = n2 - 2; i >= n1; i--)
81 v2[i] = (float) (ab * u1[i + 1] + b * v2[i + 1]);
82
83 for (i = n1; i < n2; i++)
84 u2[i] = v1[i] + v2[i];
85
86 if (weight != NULL)
87 for (i = n1; i < n2; i++)
88 u2[i] /= weight[i];
89
90 fvector_free(v1, n1);
91 fvector_free(v2, n1);
92 }
93
94 static void lsf_smooth_side(int n1, int n2, float *u1, float *u2, double sigma, float *weight, int side)
95 {
96 int i;
97 double a, b = exp(-1.0 / sigma);
98
99 a = 1 - b; /** makes filter sum to 1 **/
100
101 if (side == 1)
102 {
103 u2[n1] = (float) (a * u1[n1]);
104 for (i = n1 + 1; i < n2; i++)
105 u2[i] = (float) (a * u1[i] + b * u2[i - 1]);
106 } else if (side == -1)
107 {
108 u2[n2 - 1] = (float) (a * u1[n2 - 1]);
109 for (i = n2 - 2; i >= n1; i--)
110 u2[i] = (float) (a * u1[i] + b * u2[i + 1]);
111 } else
112 {
113 for (i = n1; i < n2; i++)
114 u2[i] = (float) u1[i];
115 }
116
117 if (weight != NULL)
118 for (i = n1; i < n2; i++)
119 u2[i] /= weight[i];
120 }
121
122 Imrect *imf_lsf_smooth(Imrect * im1, double sigma)
123 {
124 Imrect *im2;
125 Imrect *im3;
126 Imregion *roi;
127 float *row1, *row2, *col1, *col2, *ones, *weight;
128 int lx, ux, ly, uy;
129 int i;
130
131 if (im1 == NULL)
132 return (NULL);
133
134 roi = im1->region;
135 if (roi == NULL)
136 return (NULL);
137 lx = roi->lx;
138 ux = roi->ux;
139 ly = roi->ly;
140 uy = roi->uy;
141
142
143 ones = fvector_alloc(lx, ux);
144 weight = fvector_alloc(lx, ux);
145 for (i = lx; i < ux; ++i)
146 ones[i] = (float) 1.0;
147 lsf_smooth(lx, ux, ones, weight, sigma, (float *) NULL);
148 fvector_free(ones, lx);
149
150 im2 = im_alloc(im1->height, im1->width, roi, float_v);
151 row1 = fvector_alloc(lx, ux);
152 row2 = fvector_alloc(lx, ux);
153 for (i = ly; i < uy; ++i)
154 {
155 im_get_rowf(row1, im1, i, lx, ux);
156 lsf_smooth(lx, ux, row1, row2, sigma, weight);
157 im_put_rowf(row2, im2, i, lx, ux);
158 }
159 fvector_free(row1, lx);
160 fvector_free(row2, lx);
161 fvector_free(weight, lx);
162
163 ones = fvector_alloc(ly, uy);
164 weight = fvector_alloc(ly, uy);
165 for (i = ly; i < uy; ++i)
166 ones[i] = (float) 1.0;
167 lsf_smooth(ly, uy, ones, weight, sigma, (float *) NULL);
168 fvector_free(ones, ly);
169
170 im3 = im_alloc(im1->height, im1->width, roi, float_v);
171 col1 = fvector_alloc(ly, uy);
172 col2 = fvector_alloc(ly, uy);
173 for (i = lx; i < ux; ++i)
174 {
175 im_get_colf(col1, im2, i, ly, uy);
176 lsf_smooth(ly, uy, col1, col2, sigma, weight);
177 im_put_colf(col2, im3, i, ly, uy);
178 }
179 fvector_free(col1, ly);
180 fvector_free(col2, ly);
181 fvector_free(weight, ly);
182
183 im_free(im2);
184
185 return (im3);
186 }
187
188 Imrect *imf_lsf_smooth_quad(Imrect * im1, double sigma, int sidex, int sidey)
189 {
190 Imrect *im2;
191 Imrect *im3;
192 Imregion *roi;
193 float *row1, *row2, *col1, *col2, *ones, *weight;
194 int lx, ux, ly, uy;
195 int i;
196
197 if (im1 == NULL)
198 return (NULL);
199
200 roi = im1->region;
201 if (roi == NULL)
202 return (NULL);
203 lx = roi->lx;
204 ux = roi->ux;
205 ly = roi->ly;
206 uy = roi->uy;
207
208
209 ones = fvector_alloc(lx, ux);
210 weight = fvector_alloc(lx, ux);
211 for (i = lx; i < ux; ++i)
212 ones[i] = (float) 1.0;
213 lsf_smooth_side(lx, ux, ones, weight, sigma, (float *) NULL, sidex);
214 fvector_free(ones, lx);
215
216 im2 = im_alloc(im1->height, im1->width, roi, float_v);
217 row1 = fvector_alloc(lx, ux);
218 row2 = fvector_alloc(lx, ux);
219 for (i = ly; i < uy; ++i)
220 {
221 im_get_rowf(row1, im1, i, lx, ux);
222 lsf_smooth_side(lx, ux, row1, row2, sigma, weight, sidex);
223 im_put_rowf(row2, im2, i, lx, ux);
224 }
225 fvector_free(row1, lx);
226 fvector_free(row2, lx);
227 fvector_free(weight, lx);
228
229 ones = fvector_alloc(ly, uy);
230 weight = fvector_alloc(ly, uy);
231 for (i = ly; i < uy; ++i)
232 ones[i] = (float) 1.0;
233 lsf_smooth_side(ly, uy, ones, weight, sigma, (float *) NULL, sidey);
234 fvector_free(ones, ly);
235
236 im3 = im_alloc(im1->height, im1->width, roi, float_v);
237 col1 = fvector_alloc(ly, uy);
238 col2 = fvector_alloc(ly, uy);
239 for (i = lx; i < ux; ++i)
240 {
241 im_get_colf(col1, im2, i, ly, uy);
242 lsf_smooth_side(ly, uy, col1, col2, sigma, weight, sidey);
243 im_put_colf(col2, im3, i, ly, uy);
244 }
245 fvector_free(col1, ly);
246 fvector_free(col2, ly);
247 fvector_free(weight, ly);
248
249 im_free(im2);
250
251 return (im3);
252 }
253
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.