1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 c-style: "K&R" -*- */
4 libgpiv - library for Particle Image Velocimetry
6 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
9 This file is part of libgpiv.
10 Libgpiv is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation,
22 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 -------------------------------------------------------------------------------
27 FILENAME: imgproc_deform.c
29 EXTERNAL FUNCTIONS: gpiv_imgproc_deform
31 LOCAL FUNCTIONS: compare_float
33 LAST MODIFICATION DATE: $Id: imgproc_deform.c,v 1.7 2008-09-25 13:19:53 gerber Exp $
35 -------------------------------------------------------------------------------
38 This software is provided by P. Thévenaz and based on the following paper:
40 P. Thévenaz, T. Blu, M. Unser, "Interpolation Revisited," IEEE
41 Transactions on Medical Imaging, vol. 19, no. 7, pp. 739-758, July 2000.
45 Bldg. BM-Ecublens 4.137
47 phone (CET): +41(21)693.51.61
49 RFC-822: philippe.thevenaz@epfl.ch
50 X-400: /C=ch/A=400net/P=switch/O=epfl/S=thevenaz/G=philippe/
51 URL: http://bigwww.epfl.ch/
52 ------------------------------------------------------------------------------*/
55 /* #include <math.h> */
56 /* #include <stddef.h> */
57 /* #include <stdio.h> */
58 /* #include <stdlib.h> */
64 * Prototyping of static functions
67 ConvertToInterpolationCoefficients
68 (double c
[], /* input samples --> output coefficients */
69 long DataLength
, /* number of samples or coefficients */
70 double z
[], /* poles */
71 long NbPoles
, /* number of poles */
72 double Tolerance
/* admissible relative error */
76 GetColumn (float *Image
, /* input image array */
77 long Width
, /* width of the image */
78 long x
, /* x coordinate of the selected line */
79 double Line
[], /* output linear array */
80 long Height
/* length of the line and height of the image */
84 GetRow (float *Image
, /* input image array */
85 long y
, /* y coordinate of the selected line */
86 double Line
[], /* output linear array */
87 long Width
/* length of the line and width of the image */
91 InitialCausalCoefficient (double c
[], /* coefficients */
92 long DataLength
, /* number of coefficients */
93 double z
, /* actual pole */
94 double Tolerance
/* admissible relative error */
98 InitialAntiCausalCoefficient (double c
[], /* coefficients */
99 long DataLength
, /* number of samples or coefficients */
100 double z
/* actual pole */
104 PutColumn (float *Image
, /* output image array */
105 long Width
, /* width of the image */
106 long x
, /* x coordinate of the selected line */
107 double Line
[], /* input linear array */
108 long Height
/* length of the line and height of the image */
112 PutRow (float *Image
, /* output image array */
113 long y
, /* y coordinate of the selected line */
114 double Line
[], /* input linear array */
115 long Width
/* length of the line and width of the image */
121 SamplesToCoefficients (float *Image
, /* in-place processing */
122 long Width
, /* width of the image */
123 long Height
, /* height of the image */
124 long SplineDegree
/* degree of the spline model */
128 imgproc_deform_frame_from_pivdata(guint16
**img
,
129 const GpivImagePar
*image_par
,
130 const GpivPivData
*piv_data
,
131 const gdouble magnitude
135 imgproc_deform_frame (guint16
**img
,
136 const GpivImagePar
*image_par
,
137 const GpivPivData
*piv_data
141 InterpolatedValue (float *Bcoeff
, /* input B-spline array of coefficients */
142 const long Width
, /* width of the image */
143 const long Height
, /* height of the image */
144 const double x
, /* x coordinate where to interpolate */
145 const double y
, /* y coordinate where to interpolate */
146 const long SplineDegree
/* degree of the spline model */
153 gpiv_imgproc_deform (GpivImage
*image
,
154 const GpivPivData
*piv_data
156 /*-----------------------------------------------------------------------------
158 * Image shifting and deformation routine for a single exposed, double
159 * frame PIV image pair with magnitude of PIV estimations at each pixel
160 * Deforms first frame halfway forward and second frame halfway backward.
162 *---------------------------------------------------------------------------*/
164 gchar
*err_msg
= NULL
;
167 if (image
->header
->x_corr__set
== FALSE
168 || image
->header
->x_corr
== FALSE
) {
169 err_msg
= "gpiv_imgproc_deform: only to be used for cross correlation";
173 if (image
->frame1
[0] == NULL
) {
174 err_msg
= "gpiv_imgproc_deform: image->frame1 == NULL";
178 if (image
->frame2
[0] == NULL
) {
179 err_msg
= "gpiv_imgproc_deform: image->frame2 == NULL";
184 * Deform first image frame with half shift forwards
185 * and second frame with half shift backwards.
187 /* OK: results approved */
188 #pragma omp parallel sections
193 imgproc_deform_frame_from_pivdata(image
->frame1
, image
->header
,
207 imgproc_deform_frame_from_pivdata(image
->frame2
, image
->header
,
226 * Definition of static functions
230 ConvertToInterpolationCoefficients (
231 double c
[], /* input samples --> output coefficients */
232 long DataLength
, /* number of samples or coefficients */
233 double z
[], /* poles */
234 long NbPoles
, /* number of poles */
235 double Tolerance
/* admissible relative error */
237 /*--------------------------------------------------------------------------*/
241 /* special case required by mirror boundaries */
242 if (DataLength
== 1L) {
245 /* compute the overall gain */
246 for (k
= 0L; k
< NbPoles
; k
++) {
247 Lambda
= Lambda
* (1.0 - z
[k
]) * (1.0 - 1.0 / z
[k
]);
250 for (n
= 0L; n
< DataLength
; n
++) {
253 /* loop over all poles */
254 for (k
= 0L; k
< NbPoles
; k
++) {
255 /* causal initialization */
256 c
[0] = InitialCausalCoefficient(c
, DataLength
, z
[k
], Tolerance
);
257 /* causal recursion */
258 for (n
= 1L; n
< DataLength
; n
++) {
259 c
[n
] += z
[k
] * c
[n
- 1L];
261 /* anticausal initialization */
262 c
[DataLength
- 1L] = InitialAntiCausalCoefficient(c
, DataLength
, z
[k
]);
263 /* anticausal recursion */
264 for (n
= DataLength
- 2L; 0 <= n
; n
--) {
265 c
[n
] = z
[k
] * (c
[n
+ 1L] - c
[n
]);
273 InitialCausalCoefficient (
274 double c
[], /* coefficients */
275 long DataLength
, /* number of coefficients */
276 double z
, /* actual pole */
277 double Tolerance
/* admissible relative error */
279 /*--------------------------------------------------------------------------*/
281 double Sum
, zn
, z2n
, iz
;
283 /* this initialization corresponds to mirror boundaries */
284 Horizon
= DataLength
;
285 if (Tolerance
> 0.0) {
286 Horizon
= (long)ceil(log(Tolerance
) / log(fabs(z
)));
288 if (Horizon
< DataLength
) {
289 /* accelerated loop */
292 for (n
= 1L; n
< Horizon
; n
++) {
302 z2n
= pow(z
, (double)(DataLength
- 1L));
303 Sum
= c
[0] + z2n
* c
[DataLength
- 1L];
305 for (n
= 1L; n
<= DataLength
- 2L; n
++) {
306 Sum
+= (zn
+ z2n
) * c
[n
];
310 return(Sum
/ (1.0 - zn
* zn
));
318 float *Image
, /* input image array */
319 long Width
, /* width of the image */
320 long x
, /* x coordinate of the selected line */
321 double Line
[], /* output linear array */
322 long Height
/* length of the line */
324 /*--------------------------------------------------------------------------*/
325 { /* begin GetColumn */
327 Image
= Image
+ (ptrdiff_t)x
;
328 for (y
= 0L; y
< Height
; y
++) {
329 Line
[y
] = (double)*Image
;
330 Image
+= (ptrdiff_t)Width
;
332 } /* end GetColumn */
338 float *Image
, /* input image array */
339 long y
, /* y coordinate of the selected line */
340 double Line
[], /* output linear array */
341 long Width
/* length of the line */
343 /*--------------------------------------------------------------------------*/
346 Image
= Image
+ (ptrdiff_t)(y
* Width
);
347 for (x
= 0L; x
< Width
; x
++) {
348 Line
[x
] = (double)*Image
++;
355 InitialAntiCausalCoefficient (
356 double c
[], /* coefficients */
357 long DataLength
, /* number of samples or coefficients */
358 double z
/* actual pole */
360 /*--------------------------------------------------------------------------*/
362 /* this initialization corresponds to mirror boundaries */
363 return((z
/ (z
* z
- 1.0)) * (z
* c
[DataLength
- 2L] + c
[DataLength
- 1L]));
370 float *Image
, /* output image array */
371 long Width
, /* width of the image */
372 long x
, /* x coordinate of the selected line */
373 double Line
[], /* input linear array */
374 long Height
/* length of the line and height of the image */
376 /*--------------------------------------------------------------------------*/
379 Image
= Image
+ (ptrdiff_t)x
;
380 for (y
= 0L; y
< Height
; y
++) {
381 *Image
= (float)Line
[y
];
382 Image
+= (ptrdiff_t)Width
;
390 float *Image
, /* output image array */
391 long y
, /* y coordinate of the selected line */
392 double Line
[], /* input linear array */
393 long Width
/* length of the line and width of the image */
395 /*--------------------------------------------------------------------------*/
398 Image
= Image
+ (ptrdiff_t)(y
* Width
);
399 for (x
= 0L; x
< Width
; x
++) {
400 *Image
++ = (float)Line
[x
];
407 SamplesToCoefficients (
408 float *Image
, /* in-place processing */
409 long Width
, /* width of the image */
410 long Height
, /* height of the image */
411 long SplineDegree
/* degree of the spline model */
413 /*--------------------------------------------------------------------------*/
419 /* recover the poles from a lookup table */
421 switch (SplineDegree
) {
424 Pole
[0] = sqrt(8.0) - 3.0;
428 Pole
[0] = sqrt(3.0) - 2.0;
432 Pole
[0] = sqrt(664.0 - sqrt(438976.0)) + sqrt(304.0) - 19.0;
433 Pole
[1] = sqrt(664.0 + sqrt(438976.0)) - sqrt(304.0) - 19.0;
437 Pole
[0] = sqrt(135.0 / 2.0 - sqrt(17745.0 / 4.0)) + sqrt(105.0 / 4.0)
439 Pole
[1] = sqrt(135.0 / 2.0 + sqrt(17745.0 / 4.0)) - sqrt(105.0 / 4.0)
443 printf("Invalid spline degree\n");
448 * convert the image samples into interpolation coefficients
449 * in-place separable process, along x
451 Line
= (double *)malloc((size_t)(Width
* (long)sizeof(double)));
452 if (Line
== (double *)NULL
) {
453 printf("Row allocation failed\n");
458 /* BUGFIX SamplesToCoefficients: OMP causes error */
459 /* KEEP OUT! #pragma omp parallel for */
460 for (y
= 0L; y
< Height
; y
++) {
461 GetRow(Image
, y
, Line
, Width
);
462 ConvertToInterpolationCoefficients(Line
, Width
, Pole
, NbPoles
,
464 PutRow(Image
, y
, Line
, Width
);
469 /* in-place separable process, along y */
470 Line
= (double *)malloc((size_t)(Height
* (long)sizeof(double)));
471 if (Line
== (double *)NULL
) {
472 printf("Column allocation failed\n");
477 /* BUGFIX SamplesToCoefficients: OMP causes error */
478 /* KEEP OUT! #pragma omp parallel for */
479 for (x
= 0L; x
< Width
; x
++) {
480 GetColumn(Image
, Width
, x
, Line
, Height
);
481 ConvertToInterpolationCoefficients(Line
, Height
, Pole
, NbPoles
, DBL_EPSILON
);
482 PutColumn(Image
, Width
, x
, Line
, Height
);
494 float *Bcoeff
, /* input B-spline array of coefficients */
495 const long Width
, /* width of the image */
496 const long Height
, /* height of the image */
497 const double x
, /* x coordinate where to interpolate */
498 const double y
, /* y coordinate where to interpolate */
499 const long SplineDegree
/* degree of the spline model */
501 /*--------------------------------------------------------------------------*/
504 double xWeight
[6], yWeight
[6];
506 double w
, w2
, w4
, t
, t0
, t1
;
507 long xIndex
[6], yIndex
[6];
508 long Width2
= 2L * Width
- 2L, Height2
= 2L * Height
- 2L;
512 * compute the interpolation indexes
514 if (SplineDegree
& 1L) {
515 i
= (long)floor(x
) - SplineDegree
/ 2L;
516 j
= (long)floor(y
) - SplineDegree
/ 2L;
517 for (k
= 0L; k
<= SplineDegree
; k
++) {
522 i
= (long)floor(x
+ 0.5) - SplineDegree
/ 2L;
523 j
= (long)floor(y
+ 0.5) - SplineDegree
/ 2L;
524 for (k
= 0L; k
<= SplineDegree
; k
++) {
531 * compute the interpolation weights
533 switch (SplineDegree
) {
538 w
= x
- (double)xIndex
[1];
539 xWeight
[1] = 3.0 / 4.0 - w
* w
;
540 xWeight
[2] = (1.0 / 2.0) * (w
- xWeight
[1] + 1.0);
541 xWeight
[0] = 1.0 - xWeight
[1] - xWeight
[2];
545 w
= y
- (double)yIndex
[1];
546 yWeight
[1] = 3.0 / 4.0 - w
* w
;
547 yWeight
[2] = (1.0 / 2.0) * (w
- yWeight
[1] + 1.0);
548 yWeight
[0] = 1.0 - yWeight
[1] - yWeight
[2];
555 w
= x
- (double)xIndex
[1];
556 xWeight
[3] = (1.0 / 6.0) * w
* w
* w
;
557 xWeight
[0] = (1.0 / 6.0) + (1.0 / 2.0) * w
* (w
- 1.0) - xWeight
[3];
558 xWeight
[2] = w
+ xWeight
[0] - 2.0 * xWeight
[3];
559 xWeight
[1] = 1.0 - xWeight
[0] - xWeight
[2]
564 w
= y
- (double)yIndex
[1];
565 yWeight
[3] = (1.0 / 6.0) * w
* w
* w
;
566 yWeight
[0] = (1.0 / 6.0) + (1.0 / 2.0) * w
* (w
- 1.0) - yWeight
[3];
567 yWeight
[2] = w
+ yWeight
[0] - 2.0 * yWeight
[3];
568 yWeight
[1] = 1.0 - yWeight
[0] - yWeight
[2]
576 w
= x
- (double)xIndex
[2];
578 t
= (1.0 / 6.0) * w2
;
579 xWeight
[0] = 1.0 / 2.0 - w
;
580 xWeight
[0] *= xWeight
[0];
581 xWeight
[0] *= (1.0 / 24.0) * xWeight
[0];
582 t0
= w
* (t
- 11.0 / 24.0);
583 t1
= 19.0 / 96.0 + w2
* (1.0 / 4.0 - t
);
584 xWeight
[1] = t1
+ t0
;
585 xWeight
[3] = t1
- t0
;
586 xWeight
[4] = xWeight
[0] + t0
+ (1.0 / 2.0) * w
;
587 xWeight
[2] = 1.0 - xWeight
[0] - xWeight
[1] - xWeight
[3] - xWeight
[4];
591 w
= y
- (double)yIndex
[2];
593 t
= (1.0 / 6.0) * w2
;
594 yWeight
[0] = 1.0 / 2.0 - w
;
595 yWeight
[0] *= yWeight
[0];
596 yWeight
[0] *= (1.0 / 24.0) * yWeight
[0];
597 t0
= w
* (t
- 11.0 / 24.0);
598 t1
= 19.0 / 96.0 + w2
* (1.0 / 4.0 - t
);
599 yWeight
[1] = t1
+ t0
;
600 yWeight
[3] = t1
- t0
;
601 yWeight
[4] = yWeight
[0] + t0
+ (1.0 / 2.0) * w
;
602 yWeight
[2] = 1.0 - yWeight
[0] - yWeight
[1] - yWeight
[3] - yWeight
[4];
609 w
= x
- (double)xIndex
[2];
611 xWeight
[5] = (1.0 / 120.0) * w
* w2
* w2
;
616 xWeight
[0] = (1.0 / 24.0) * (1.0 / 5.0 + w2
+ w4
) - xWeight
[5];
617 t0
= (1.0 / 24.0) * (w2
* (w2
- 5.0) + 46.0 / 5.0);
618 t1
= (-1.0 / 12.0) * w
* (t
+ 4.0);
619 xWeight
[2] = t0
+ t1
;
620 xWeight
[3] = t0
- t1
;
621 t0
= (1.0 / 16.0) * (9.0 / 5.0 - t
);
622 t1
= (1.0 / 24.0) * w
* (w4
- w2
- 5.0);
623 xWeight
[1] = t0
+ t1
;
624 xWeight
[4] = t0
- t1
;
628 w
= y
- (double)yIndex
[2];
630 yWeight
[5] = (1.0 / 120.0) * w
* w2
* w2
;
635 yWeight
[0] = (1.0 / 24.0) * (1.0 / 5.0 + w2
+ w4
) - yWeight
[5];
636 t0
= (1.0 / 24.0) * (w2
* (w2
- 5.0) + 46.0 / 5.0);
637 t1
= (-1.0 / 12.0) * w
* (t
+ 4.0);
638 yWeight
[2] = t0
+ t1
;
639 yWeight
[3] = t0
- t1
;
640 t0
= (1.0 / 16.0) * (9.0 / 5.0 - t
);
641 t1
= (1.0 / 24.0) * w
* (w4
- w2
- 5.0);
642 yWeight
[1] = t0
+ t1
;
643 yWeight
[4] = t0
- t1
;
647 printf("Invalid spline degree\n");
652 * apply the mirror boundary conditions
654 for (k
= 0L; k
<= SplineDegree
; k
++) {
655 xIndex
[k
] = (Width
== 1L) ? (0L) : ((xIndex
[k
] < 0L) ?
657 * ((-xIndex
[k
]) / Width2
))
658 : (xIndex
[k
] - Width2
659 * (xIndex
[k
] / Width2
)));
660 if (Width
<= xIndex
[k
]) {
661 xIndex
[k
] = Width2
- xIndex
[k
];
663 yIndex
[k
] = (Height
== 1L) ? (0L) : ((yIndex
[k
] < 0L) ?
664 (-yIndex
[k
] - Height2
665 * ((-yIndex
[k
]) / Height2
))
666 : (yIndex
[k
] - Height2
667 * (yIndex
[k
] / Height2
)));
668 if (Height
<= yIndex
[k
]) {
669 yIndex
[k
] = Height2
- yIndex
[k
];
674 * perform interpolation
677 for (j
= 0L; j
<= SplineDegree
; j
++) {
678 p
= Bcoeff
+ (ptrdiff_t)(yIndex
[j
] * Width
);
680 for (i
= 0L; i
<= SplineDegree
; i
++) {
681 w
+= xWeight
[i
] * p
[xIndex
[i
]];
683 interpolated
+= yWeight
[j
] * w
;
685 return(interpolated
);
691 imgproc_deform_frame_from_pivdata(guint16
**img
,
692 const GpivImagePar
*image_par
,
693 const GpivPivData
*piv_data
,
694 const gdouble magnitude
)
695 /*-----------------------------------------------------------------------------
698 gchar
*err_msg
= NULL
;
700 GpivPivData
*pd
= NULL
;
701 gint k
, l
, count
= 0, window
= 4;
702 gfloat dy_sum
, dx_sum
;
705 if (img
[0] == NULL
) {
706 err_msg
= "imgproc_deform_frame_from_pivdata: image->frame1 == NULL";
711 * Interpolate piv data at each pixel point of the images.
714 pd
= gpiv_alloc_pivdata (image_par
->ncolumns
,
716 /* OK: results approved */
717 #pragma omp parallel for shared(pd) private(i, j)
718 for (i
= 0; i
< pd
->ny
; i
++) {
719 for (j
= 0; j
< pd
->nx
; j
++) {
720 pd
->point_x
[i
][j
] = (float) j
;
721 pd
->point_y
[i
][j
] = (float) i
;
724 gpiv_piv_dxdy_at_new_grid (piv_data
, pd
);
731 for (i
= 0; i
< pd
->ny
; i
++) {
732 for (j
= 0; j
< pd
->nx
; j
++) {
733 for (k
= -window
/ 2; k
< window
/ 2; k
++) {
734 if (i
+ k
> 0 && i
+ k
< pd
->ny
) {
735 for (l
= -window
/ 2; l
< window
/ 2; l
++) {
736 if (j
+ l
> 0 && j
+ l
< pd
->nx
) {
737 dy_sum
+= pd
->dy
[i
+k
][j
+l
];
738 dx_sum
+= pd
->dx
[i
+k
][j
+l
];
749 /* OK: results approved */
750 #pragma omp parallel for shared(pd) private(i, j)
751 for (i
= 0; i
< pd
->ny
; i
++) {
752 for (j
= 0; j
< pd
->nx
; j
++) {
753 pd
->dx
[i
][j
] = magnitude
* pd
->dx
[i
][j
];
754 pd
->dy
[i
][j
] = magnitude
* pd
->dy
[i
][j
];
758 imgproc_deform_frame (img
, image_par
, pd
);
761 gpiv_free_pivdata (pd
);
770 imgproc_deform_frame (guint16
**img
,
771 const GpivImagePar
*image_par
,
772 const GpivPivData
*piv_data
774 /*-----------------------------------------------------------------------------
776 * Image deformation/interpolation routine for a single image frame
777 * Origins from demo.c
780 * piv_data: PIV data structure which defines shift/deformation at
782 * img: input image frame
785 * img: deformed image frame
789 *---------------------------------------------------------------------------*/
791 float *ImageRasterArray
= NULL
, *OutputImage
= NULL
;
794 long Width
= image_par
->ncolumns
, Height
= image_par
->nrows
;
795 long SplineDegree
= 5;
800 guint img_top
= (1 << image_par
->depth
) - 1;
804 /* double a11, a12, a21, a22; */
805 /* double x0, y0, x1, y1; */
806 /* double xOrigin = 0.0, yOrigin = 0.0; */
807 /* double Angle = 1.0, xShift = 0.0, yShift = 0.0; */
812 ImageRasterArray
= gpiv_vector (image_par
->nrows
* image_par
->ncolumns
);
813 p
= ImageRasterArray
;
815 /* OK: results approved */
816 #pragma omp parallel for shared(image_par, img, p) private(i, j)
817 for (i
= 0; i
< image_par
->nrows
; i
++) {
818 for (j
= 0; j
< image_par
->ncolumns
; j
++) {
819 p
[i
*image_par
->ncolumns
+ j
] = (float) img
[i
][j
];
820 /* *p++ = (float) img[i][j]; */
826 * convert between a representation based on image samples
827 * and a representation based on image B-spline coefficients
829 if (Error
= SamplesToCoefficients (ImageRasterArray
, Width
, Height
,
831 gpiv_free_vector (ImageRasterArray
);
832 g_warning("LIBGPIV internal error: imgproc_deform_frame: Change of basis failed");
837 * visit all pixels of the output image and assign their value
839 OutputImage
= gpiv_vector (image_par
->nrows
* image_par
->ncolumns
);
842 /* BUGFIX imgproc_deform_frame: OMP causes differences in results */
843 /* BUGFIX imgproc_deform_frame: When disabled OMP in imgproc_deform */
844 /* KEEP OUT! #pragma omp parallel for private(x1, y1) */
845 for (i
= 0; i
< image_par
->nrows
; i
++) {
846 for (j
= 0; j
< image_par
->ncolumns
; j
++) {
847 x1
= (double) j
- (double) piv_data
->dx
[i
][j
];
848 y1
= (double) i
- (double) piv_data
->dy
[i
][j
];
851 || (((double)Width
- 0.5) <= x1
)
853 || (((double)Height
- 0.5) <= y1
)) {
855 p
[i
*image_par
->ncolumns
+ j
] = 0.0F
;
858 p
[i
*image_par
->ncolumns
+ j
] =
859 (float)InterpolatedValue (ImageRasterArray
,
861 x1
, y1
, SplineDegree
);
865 p
[i
*image_par
->ncolumns
+ j
] =
866 (float)InterpolatedValue (ImageRasterArray
,
868 x1
, y1
, SplineDegree
);
875 * Store back into img
879 /* OK: results approved */
880 #pragma omp parallel for private(i, j, rounded)
881 for (i
= 0; i
< image_par
->nrows
; i
++) {
882 for (j
= 0; j
< image_par
->ncolumns
; j
++) {
883 rounded
= (long)floor ((double) p
[i
*image_par
->ncolumns
+ j
] + 0.5);
884 if (rounded
< 0.0) rounded
= 0.0;
885 if (rounded
> (gfloat
) img_top
/* 255.0 */) rounded
= (gfloat
) img_top
/* 255.0 */;
886 img
[i
][j
] = (guint16
) rounded
;
892 gpiv_free_vector (ImageRasterArray
);
893 gpiv_free_vector (OutputImage
);