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_scale.c,v $
37 * Date : $Date: 2005/01/23 19:10:21 $
38 * Version : $Revision: 1.5 $
39 * CVS Id : $Id: imgPrc_scale.c,v 1.5 2005/01/23 19:10:21 paul Exp $
40 *
41 * Author : Legacy TINA
42 */
43
44 /**
45 * @file
46 * @brief Finding min and max and scaling (e.g. normalising) images values
47 *
48 */
49
50 #include "imgPrc_scale.h"
51
52 #if HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55
56 #include <math.h>
57 #include <float.h>
58 #include <tina/sys/sysDef.h>
59 #include <tina/sys/sysPro.h>
60 #include <tina/image/img_GenDef.h>
61 #include <tina/image/img_GenPro.h>
62
63
64 void imf_minmax(Imrect * im, float *pmin, float *pmax)
65 {
66 Imregion *roi;
67 float *row, min, max;
68 int lx, ux, ly, uy;
69 int i, j;
70
71 if (im == NULL)
72 {
73 *pmin = (float) 0.0;
74 *pmax = (float) 0.0;
75 return;
76 }
77 roi = im->region;
78 if (roi == NULL)
79 {
80 *pmin = (float) 0.0;
81 *pmax = (float) 0.0;
82 return;
83 }
84 lx = roi->lx;
85 ux = roi->ux;
86 ly = roi->ly;
87 uy = roi->uy;
88
89 row = fvector_alloc(lx, ux);
90 min = max = (float) im_get_pixf(im, ly, lx);
91 for (i = ly; i < uy; ++i)
92 {
93 im_get_rowf(row, im, i, lx, ux);
94 for (j = lx; j < ux; ++j)
95 {
96 if (min > row[j])
97 min = row[j];
98 if (max < row[j])
99 max = row[j];
100 }
101 }
102
103 *pmin = min;
104 *pmax = max;
105 fvector_free(row, lx);
106 }
107
108 void imf_minmax_nzero(Imrect * im, float *pmin, float *pmax)
109 {
110 Imregion *roi;
111 float *row, min, max;
112 int lx, ux, ly, uy;
113 int i, j;
114
115 if (im == NULL)
116 {
117 *pmin = (float) 0.0;
118 *pmax = (float) 0.0;
119 return;
120 }
121 roi = im->region;
122 if (roi == NULL)
123 {
124 *pmin = (float) 0.0;
125 *pmax = (float) 0.0;
126 return;
127 }
128 lx = roi->lx;
129 ux = roi->ux;
130 ly = roi->ly;
131 uy = roi->uy;
132
133 row = fvector_alloc(lx, ux);
134 min = FLT_MAX;
135 max = -FLT_MAX;
136 for (i = ly; i < uy; ++i)
137 {
138 im_get_rowf(row, im, i, lx, ux);
139 for (j = lx; j < ux; ++j)
140 {
141 if (min > row[j] && row[j] != 0.0)
142 min = row[j];
143 if (max < row[j] && row[j] != 0.0)
144 max = row[j];
145 }
146 }
147
148 *pmin = min;
149 *pmax = max;
150 fvector_free(row, lx);
151 }
152
153
154 double imf_min(Imrect * im, int *y, int *x)
155 {
156 Imregion *roi;
157 float *row, min;
158 int lx, ux, ly, uy;
159 int i, j;
160
161 if (im == NULL)
162 return (0.0);
163
164 roi = im->region;
165 if (roi == NULL)
166 return (0.0);
167
168 lx = roi->lx;
169 ux = roi->ux;
170 ly = roi->ly;
171 uy = roi->uy;
172
173 row = fvector_alloc(lx, ux);
174 min = (float) im_get_pixf(im, ly, lx);
175 if (y != NULL)
176 *y = 0;
177 if (x != NULL)
178 *x = 0;
179 for (i = ly; i < uy; ++i)
180 {
181 im_get_rowf(row, im, i, lx, ux);
182 for (j = lx; j < ux; ++j)
183 if (min > row[j])
184 {
185 min = row[j];
186 if (y != NULL)
187 *y = i;
188 if (x != NULL)
189 *x = j;
190 }
191 }
192
193 fvector_free(row, lx);
194 return (min);
195 }
196
197 double imf_max(Imrect * im, int *y, int *x)
198 {
199 Imregion *roi;
200 float *row, max;
201 int lx, ux, ly, uy;
202 int i, j;
203
204 if (im == NULL)
205 return (0.0);
206
207 roi = im->region;
208 if (roi == NULL)
209 return (0.0);
210
211 lx = roi->lx;
212 ux = roi->ux;
213 ly = roi->ly;
214 uy = roi->uy;
215
216 row = fvector_alloc(lx, ux);
217 max = (float) im_get_pixf(im, ly, lx);
218 if (y != NULL)
219 *y = 0;
220 if (x != NULL)
221 *x = 0;
222 for (i = ly; i < uy; ++i)
223 {
224 im_get_rowf(row, im, i, lx, ux);
225 for (j = lx; j < ux; ++j)
226 if (max < row[j])
227 {
228 max = row[j];
229 if (y != NULL)
230 *y = i;
231 if (x != NULL)
232 *x = j;
233 }
234 }
235
236 fvector_free(row, lx);
237 return (max);
238 }
239
240 Imrect *imf_scale(Imrect * im1, double low, double high)
241 {
242 Imrect *im2;
243 Imregion *roi;
244 float *row1, *row2;
245 int lx, ux, ly, uy;
246 int i, j;
247 float min, max, scale;
248
249 if (im1 == NULL)
250 return (NULL);
251
252 roi = im1->region;
253 if (roi == NULL)
254 return (NULL);
255
256 imf_minmax(im1, &min, &max);
257 if (max == min)
258 max = (float) (min + 1.0);
259
260 scale = (float) ((high - low) / (max - min));
261 low -= scale * min;
262
263 lx = roi->lx;
264 ux = roi->ux;
265 ly = roi->ly;
266 uy = roi->uy;
267
268 im2 = im_alloc(im1->height, im1->width, roi, float_v);
269 row1 = fvector_alloc(lx, ux);
270 row2 = fvector_alloc(lx, ux);
271
272 for (i = ly; i < uy; ++i)
273 {
274 im_get_rowf(row1, im1, i, lx, ux);
275 for (j = lx; j < ux; ++j)
276 row2[j] = (float) (low + scale * row1[j]);
277 im_put_rowf(row2, im2, i, lx, ux);
278 }
279
280 fvector_free(row1, lx);
281 fvector_free(row2, lx);
282 return (im2);
283 }
284
285 Imrect *imf_scale_nzero(Imrect * im1, double low, double high)
286 {
287 Imrect *im2;
288 Imregion *roi;
289 float *row1, *row2;
290 int lx, ux, ly, uy;
291 int i, j;
292 float min, max, scale;
293
294 if (im1 == NULL)
295 return (NULL);
296
297 roi = im1->region;
298 if (roi == NULL)
299 return (NULL);
300
301 imf_minmax_nzero(im1, &min, &max);
302 if (max == min)
303 {
304 if (min < 0.0)
305 max = 0.0;
306 else if (max > 0.0)
307 min = 0.0;
308 else
309 min = (float) (max - 1.0);
310 }
311
312 scale = (float) ((high - low) / (max - min));
313 low -= scale * min;
314
315 lx = roi->lx;
316 ux = roi->ux;
317 ly = roi->ly;
318 uy = roi->uy;
319
320 im2 = im_alloc(im1->height, im1->width, roi, float_v);
321 row1 = fvector_alloc(lx, ux);
322 row2 = fvector_alloc(lx, ux);
323
324 for (i = ly; i < uy; ++i)
325 {
326 im_get_rowf(row1, im1, i, lx, ux);
327 for (j = lx; j < ux; ++j)
328 row2[j] = (float) (low + scale * row1[j]);
329 im_put_rowf(row2, im2, i, lx, ux);
330 }
331
332 fvector_free(row1, lx);
333 fvector_free(row2, lx);
334 return (im2);
335 }
336
337 /*
338 * gamma scale the range oldlow, oldhigh in image im using newlow, newhigh,
339 * thresholding at threslow, threshigh
340 */
341 void im_gamma_scale_range_inplace(Imrect * im,
342 double gamma,
343 double oldlow, double oldhigh,
344 double newlow, double newhigh,
345 double threslow, double threshigh)
346 {
347 Imregion *roi;
348 float *row1, *row2;
349 int lx, ux, ly, uy;
350 double scale, base, range;
351 int i, j;
352
353 if (im == NULL)
354 return;
355
356 roi = im->region;
357 if (roi == NULL)
358 return;
359 lx = roi->lx;
360 ux = roi->ux;
361 ly = roi->ly;
362 uy = roi->uy;
363
364 if (oldlow == oldhigh)
365 scale = 1.0;
366 else
367 scale = 1.0 / (oldhigh - oldlow);
368 base = newlow;
369 range = newhigh - oldlow;
370
371 row1 = fvector_alloc(lx, ux);
372 row2 = fvector_alloc(lx, ux);
373 for (i = ly; i < uy; ++i)
374 {
375 im_get_rowf(row1, im, i, lx, ux);
376 for (j = lx; j < ux; ++j)
377 {
378 double val;
379
380 val = base + range * pow(scale * (row1[j] - oldlow), gamma);
381 val = MAX(val, threslow);
382 row2[j] = (float) MIN(val, threshigh);
383 }
384 im_put_rowf(row2, im, i, lx, ux);
385 }
386
387 fvector_free(row1, lx);
388 fvector_free(row2, lx);
389 }
390
391 /*
392 * scales the range oldlow, oldhigh in image im newlow, newhigh, thresholding
393 * at threslow, threshigh
394 */
395 void im_scale_range_inplace(Imrect * im,
396 double oldlow, double oldhigh,
397 double newlow, double newhigh,
398 double threslow, double threshigh)
399 {
400 Imregion *roi;
401 float *row1, *row2;
402 int lx, ux, ly, uy;
403 float scale, base;
404 int i, j;
405
406 if (im == NULL)
407 return;
408
409 roi = im->region;
410 if (roi == NULL)
411 return;
412 lx = roi->lx;
413 ux = roi->ux;
414 ly = roi->ly;
415 uy = roi->uy;
416
417 if (oldlow == oldhigh)
418 scale = (float) 1.0;
419 else
420 scale = (float) ((newhigh - newlow) / (oldhigh - oldlow));
421 base = (float) (newlow - scale * oldlow);
422
423 row1 = fvector_alloc(lx, ux);
424 row2 = fvector_alloc(lx, ux);
425 for (i = ly; i < uy; ++i)
426 {
427 im_get_rowf(row1, im, i, lx, ux);
428 for (j = lx; j < ux; ++j)
429 {
430 double val;
431
432 val = base + scale * row1[j];
433 val = MAX(val, threslow);
434 row2[j] = (float) MIN(val, threshigh);
435 }
436 im_put_rowf(row2, im, i, lx, ux);
437 }
438
439 fvector_free(row1, lx);
440 fvector_free(row2, lx);
441 }
442
443 void imf_times_inplace(double k, Imrect * im)
444 {
445 Imregion *roi;
446 float *row;
447 int lx, ux, ly, uy;
448 int i, j;
449
450 if (im == NULL)
451 return;
452 roi = im->region;
453 if (roi == NULL)
454 return;
455 lx = roi->lx;
456 ux = roi->ux;
457 ly = roi->ly;
458 uy = roi->uy;
459 row = fvector_alloc(lx, ux);
460 for (i = ly; i < uy; ++i)
461 {
462 im_get_rowf(row, im, i, lx, ux);
463 for (j = lx; j < ux; ++j)
464 row[j] *= (float) k;
465 im_put_rowf(row, im, i, lx, ux);
466 }
467 fvector_free(row, lx);
468 }
469
470 void imf_add_inplace(double k, Imrect * im)
471 {
472 Imregion *roi;
473 float *row;
474 int lx, ux, ly, uy;
475 int i, j;
476
477 if (im == NULL)
478 return;
479 roi = im->region;
480 if (roi == NULL)
481 return;
482 lx = roi->lx;
483 ux = roi->ux;
484 ly = roi->ly;
485 uy = roi->uy;
486 row = fvector_alloc(lx, ux);
487 for (i = ly; i < uy; ++i)
488 {
489 im_get_rowf(row, im, i, lx, ux);
490 for (j = lx; j < ux; ++j)
491 row[j] += (float) k;
492 im_put_rowf(row, im, i, lx, ux);
493 }
494 fvector_free(row, lx);
495 }
496
497 void imf_accum_inplace(Imrect * im1, double k, Imrect * im2)
498 {
499 Imregion *roi1, *roi2;
500 float *row1, *row2;
501 int lx, ux, ly, uy;
502 int i, j;
503
504 if (im1 == NULL || im2 == NULL)
505 return;
506
507 roi1 = im1->region;
508 roi2 = im2->region;
509 if (roi1 == NULL || roi2 == NULL)
510 return;
511 lx = MAX(roi1->lx, roi2->lx);
512 ly = MAX(roi1->ly, roi2->ly);
513 ux = MIN(roi1->ux, roi2->ux);
514 uy = MIN(roi1->uy, roi2->uy);
515 row1 = fvector_alloc(lx, ux);
516 row2 = fvector_alloc(lx, ux);
517 for (i = ly; i < uy; ++i)
518 {
519 im_get_rowf(row1, im1, i, lx, ux);
520 im_get_rowf(row2, im2, i, lx, ux);
521 for (j = lx; j < ux; ++j)
522 row1[j] += (float) (k * row2[j]);
523 im_put_rowf(row1, im1, i, lx, ux);
524 }
525 fvector_free(row1, lx);
526 fvector_free(row2, lx);
527 }
528
529 double imf_mean(Imrect * im)
530 {
531 Imregion *roi;
532 float *row;
533 double sum = 0;
534 int lx, ux, ly, uy;
535 int i, j;
536
537 if (im == NULL)
538 return (0);
539 roi = im->region;
540 if (roi == NULL)
541 return (0);
542 lx = roi->lx;
543 ux = roi->ux;
544 ly = roi->ly;
545 uy = roi->uy;
546 row = fvector_alloc(lx, ux);
547 for (i = ly; i < uy; ++i)
548 {
549 im_get_rowf(row, im, i, lx, ux);
550 for (j = lx; j < ux; ++j)
551 sum += row[j];
552 }
553 fvector_free(row, lx);
554 return (sum / ((uy - ly) * (ux - lx)));
555 }
556
557 void imf_scale_inplace(Imrect * im, double low, double high)
558 {
559 Imregion *roi;
560 float *row1, *row2;
561 int lx, ux, ly, uy;
562 float min, max, scale;
563 int i, j;
564
565 if (im == NULL)
566 return;
567
568 roi = im->region;
569 if (roi == NULL)
570 return;
571 lx = roi->lx;
572 ux = roi->ux;
573 ly = roi->ly;
574 uy = roi->uy;
575
576 imf_minmax(im, &min, &max);
577 if (max == min)
578 max = (float) (min + 1.0);
579
580 scale = (float) ((high - low) / (max - min));
581 low -= scale * min;
582
583 row1 = fvector_alloc(lx, ux);
584 row2 = fvector_alloc(lx, ux);
585
586 for (i = ly; i < uy; ++i)
587 {
588 im_get_rowf(row1, im, i, lx, ux);
589 for (j = lx; j < ux; ++j)
590 row2[j] = (float) (low + scale * row1[j]);
591 im_put_rowf(row2, im, i, lx, ux);
592 }
593
594 fvector_free(row1, lx);
595 fvector_free(row2, lx);
596 }
597
598 float im_locate_max(Imrect * im, int *y, int *x)
599 {
600 Imregion *roi;
601 float *row, max;
602 int lx, ux, ly, uy, xmax, ymax;
603 int i, j;
604
605 if (im == NULL)
606 {
607 *y = *x = 0;
608 return (0);
609 }
610 roi = im->region;
611 if (roi == NULL)
612 {
613 *y = *x = 0;
614 return (0);
615 }
616 lx = roi->lx;
617 ux = roi->ux;
618 ly = roi->ly;
619 uy = roi->uy;
620
621 row = fvector_alloc(lx, ux);
622 max = (float) im_get_pixf(im, ly, lx);
623 xmax = lx;
624 ymax = ly;
625 for (i = ly; i < uy; ++i)
626 {
627 im_get_rowf(row, im, i, lx, ux);
628 for (j = lx; j < ux; ++j)
629 if (max < row[j])
630 {
631 max = row[j];
632 xmax = j;
633 ymax = i;
634 }
635 }
636
637 *x = xmax;
638 *y = ymax;
639 fvector_free(row, lx);
640 return (max);
641 }
642
643 void im_locate_interest(Imrect * im, int *y, int *x)
644 {
645 Imregion *roi;
646 float *row1, *row2;
647 double max;
648 int lx, ux, ly, uy, minx=0, miny = 0;
649 int i, j;
650
651 if (im == NULL)
652 {
653 *y = *x = 0;
654 return;
655 }
656 roi = im->region;
657 if (roi == NULL)
658 {
659 *y = *x = 0;
660 return;
661 }
662 lx = roi->lx;
663 ux = roi->ux;
664 ly = roi->ly;
665 uy = roi->uy;
666
667 max = 0.0;
668 row1 = fvector_alloc(lx, ux);
669 row2 = fvector_alloc(lx, ux);
670 im_get_rowf(row2, im, ly, lx, ux);
671 for (i = ly + 1; i < uy - 1; ++i)
672 {
673 SWAP(float *, row1, row2);
674
675 im_get_rowf(row2, im, i + 1, lx, ux);
676 for (j = lx + 1; j < ux - 1; ++j)
677 {
678 double dxy;
679
680 dxy = fabs(row1[j - 1] - row2[j + 1]) + fabs(row1[j + 1] - row2[j - 1]);
681 if (max < dxy)
682 {
683 max = dxy;
684 minx = j;
685 miny = i;
686 }
687 }
688 }
689
690 *x = minx;
691 *y = miny;
692 fvector_free(row1, lx);
693 fvector_free(row2, lx);
694 }
695
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.