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_median.c,v $
37 * Date : $Date: 2003/10/13 15:51:23 $
38 * Version : $Revision: 1.5 $
39 * CVS Id : $Id: imgPrc_median.c,v 1.5 2003/10/13 15:51:23 neil Exp $
40 *
41 * Author : Legacy TINA
42 */
43
44 /**
45 * @file
46 * @brief Median (3x3) filter
47 *
48 */
49
50 #include "imgPrc_median.h"
51
52 #if HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55
56 #include <math.h>
57 #include <float.h>
58 #include <limits.h>
59 #include <tina/sys/sysDef.h>
60 #include <tina/sys/sysPro.h>
61 #include <tina/math/mathDef.h>
62 #include <tina/math/mathPro.h>
63 #include <tina/image/img_GenDef.h>
64 #include <tina/image/img_GenPro.h>
65
66 int med3by3(int *b1, int *b2, int *b3)
67 {
68 int r[9];
69 int label[9];
70 int i, j;
71 int max = -INT_MAX, min = INT_MAX;
72 int max_label = 0, min_label = 0;
73
74 r[0] = b1[-1];
75 r[1] = b1[0];
76 r[2] = b1[1];
77 r[3] = b2[-1];
78 r[4] = b2[0];
79 r[5] = b2[1];
80 r[6] = b3[-1];
81 r[7] = b3[0];
82 r[8] = b3[1];
83 for (i = 0; i < 9; i++)
84 label[i] = 1;
85 for (j = 0; j < 5; j++)
86 {
87 for (i = 0; i < 9; i++)
88 {
89 if (label[i] && (r[i] <= min))
90 {
91 min_label = i;
92 min = r[i];
93 }
94 if (label[i] && (r[i] >= max))
95 {
96 max_label = i;
97 max = r[i];
98 }
99 }
100 label[max_label] = 0;
101 label[min_label] = 0;
102 max = -INT_MAX;
103 min = INT_MAX;
104 }
105 return (r[min_label]);
106
107 }
108
109 float med3by3f(float *b1, float *b2, float *b3)
110 {
111 float r[9];
112 int label[9];
113 int i, j;
114 float max = -FLT_MAX, min = FLT_MAX;
115 int max_label = 0, min_label = 0;
116
117 r[0] = b1[-1];
118 r[1] = b1[0];
119 r[2] = b1[1];
120 r[3] = b2[-1];
121 r[4] = b2[0];
122 r[5] = b2[1];
123 r[6] = b3[-1];
124 r[7] = b3[0];
125 r[8] = b3[1];
126 for (i = 0; i < 9; i++)
127 label[i] = 1;
128 for (j = 0; j < 5; j++)
129 {
130 for (i = 0; i < 9; i++)
131 {
132 if (label[i] && (r[i] <= min))
133 {
134 min_label = i;
135 min = r[i];
136 }
137 if (label[i] && (r[i] >= max))
138 {
139 max_label = i;
140 max = r[i];
141 }
142 }
143 label[max_label] = 0;
144 label[min_label] = 0;
145 max = -FLT_MAX;
146 min = FLT_MAX;
147 }
148 return (r[min_label]);
149 }
150 /**
151 3x3 median filter
152 At edges adds e.g. new first row equal to old before filtering
153 **/
154
155 Imrect *imc_median(Imrect * im1)
156 {
157 Imrect *im2;
158 Imregion *roi;
159 int *row, *row1, *row2, *row3;
160 int lx, ux, ly, uy;
161 int i, j;
162
163 if (im1 == NULL)
164 return (NULL);
165
166 roi = im1->region;
167 if (roi == NULL)
168 return (NULL);
169 lx = roi->lx;
170 ux = roi->ux;
171 ly = roi->ly;
172 uy = roi->uy;
173
174 im2 = im_alloc(im1->height, im1->width, roi, uchar_v);
175 row = ivector_alloc(lx, ux);
176 row1 = ivector_alloc(lx - 1, ux + 1);
177 row2 = ivector_alloc(lx - 1, ux + 1);
178 row3 = ivector_alloc(lx - 1, ux + 1);
179 im_get_row(row2, im1, ly, lx, ux);
180 row2[lx - 1] = row2[lx];
181 row2[ux] = row2[ux - 1];
182 im_get_row(row3, im1, ly, lx, ux);
183 row3[lx - 1] = row3[lx];
184 row3[ux] = row3[ux - 1];
185 for (i = ly; i < uy; ++i)
186 {
187 int *temp = row1;
188 row1 = row2;
189 row2 = row3;
190 row3 = temp;
191
192 if (i != uy - 1)
193 im_get_row(row3, im1, i + 1, lx, ux);
194 else
195 im_get_row(row3, im1, i, lx, ux);
196 row3[lx - 1] = row3[lx];
197 row3[ux] = row3[ux - 1];
198
199 for (j = lx; j < ux; ++j)
200 row[j] = med3by3(&row1[j], &row2[j], &row3[j]);
201
202 im_put_row(row, im2, i, lx, ux);
203 }
204
205 ivector_free(row, lx);
206 ivector_free(row1, lx - 1);
207 ivector_free(row2, lx - 1);
208 ivector_free(row3, lx - 1);
209 return (im2);
210 }
211
212 Imrect *imi_median(Imrect * im1)
213 {
214 Imrect *im2;
215 Imregion *roi;
216 int *row, *row1, *row2, *row3;
217 int lx, ux, ly, uy;
218 int i, j;
219
220 if (im1 == NULL)
221 return (NULL);
222
223 roi = im1->region;
224 if (roi == NULL)
225 return (NULL);
226 lx = roi->lx;
227 ux = roi->ux;
228 ly = roi->ly;
229 uy = roi->uy;
230
231 im2 = im_alloc(im1->height, im1->width, roi, int_v);
232 row = ivector_alloc(lx, ux);
233 row1 = ivector_alloc(lx - 1, ux + 1);
234 row2 = ivector_alloc(lx - 1, ux + 1);
235 row3 = ivector_alloc(lx - 1, ux + 1);
236 im_get_row(row2, im1, ly, lx, ux);
237 row2[lx - 1] = row2[lx];
238 row2[ux] = row2[ux - 1];
239 im_get_row(row3, im1, ly, lx, ux);
240 row3[lx - 1] = row3[lx];
241 row3[ux] = row3[ux - 1];
242 for (i = ly; i < uy; ++i)
243 {
244 int *temp = row1;
245 row1 = row2;
246 row2 = row3;
247 row3 = temp;
248
249 if (i != uy - 1)
250 im_get_row(row3, im1, i + 1, lx, ux);
251 else
252 im_get_row(row3, im1, i, lx, ux);
253 row3[lx - 1] = row3[lx];
254 row3[ux] = row3[ux - 1];
255
256 for (j = lx; j < ux; ++j)
257 row[j] = med3by3(&row1[j], &row2[j], &row3[j]);
258
259 im_put_row(row, im2, i, lx, ux);
260 }
261
262 ivector_free(row, lx);
263 ivector_free(row1, lx - 1);
264 ivector_free(row2, lx - 1);
265 ivector_free(row3, lx - 1);
266 return (im2);
267 }
268
269 Imrect *imf_median(Imrect * im1)
270 {
271 Imrect *im2;
272 Imregion *roi;
273 float *row, *row1, *row2, *row3;
274 int lx, ux, ly, uy;
275 int i, j;
276
277 if (im1 == NULL)
278 return (NULL);
279
280 roi = im1->region;
281 if (roi == NULL)
282 return (NULL);
283 lx = roi->lx;
284 ux = roi->ux;
285 ly = roi->ly;
286 uy = roi->uy;
287
288 im2 = im_alloc(im1->height, im1->width, roi, float_v);
289 row = fvector_alloc(lx, ux);
290 row1 = fvector_alloc(lx - 1, ux + 1);
291 row2 = fvector_alloc(lx - 1, ux + 1);
292 row3 = fvector_alloc(lx - 1, ux + 1);
293 im_get_rowf(row2, im1, ly, lx, ux);
294 row2[lx - 1] = row2[lx];
295 row2[ux] = row2[ux - 1];
296 im_get_rowf(row3, im1, ly, lx, ux);
297 row3[lx - 1] = row3[lx];
298 row3[ux] = row3[ux - 1];
299 for (i = ly; i < uy; ++i)
300 {
301 float *temp = row1;
302 row1 = row2;
303 row2 = row3;
304 row3 = temp;
305
306 if (i != uy - 1)
307 im_get_rowf(row3, im1, i + 1, lx, ux);
308 else
309 im_get_rowf(row3, im1, i, lx, ux);
310 row3[lx - 1] = row3[lx];
311 row3[ux] = row3[ux - 1];
312
313 for (j = lx; j < ux; ++j)
314 row[j] = med3by3f(&row1[j], &row2[j], &row3[j]);
315
316 im_put_rowf(row, im2, i, lx, ux);
317 }
318
319 fvector_free(row, lx);
320 fvector_free(row1, lx - 1);
321 fvector_free(row2, lx - 1);
322 fvector_free(row3, lx - 1);
323 return (im2);
324 }
325
326 Imrect *imz_median(Imrect * im)
327 {
328 return (NULL);
329 }
330
331 Imrect *im_median(Imrect * im)
332 {
333 if (im == NULL)
334 return (NULL);
335 switch (im->vtype)
336 {
337 case uchar_v:
338 return (imc_median(im));
339 case short_v:
340 case ushort_v:
341 case int_v:
342 return (imi_median(im));
343 case float_v:
344 return (imf_median(im));
345 case complex_v:
346 return (imz_median(im));
347 default:
348 return (NULL);
349 }
350 }
351
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.