CR2RE Pipeline Reference Manual 1.6.2
irplib_fft.c
1/*
2 * This file is part of the IRPLIB Pipeline
3 * Copyright (C) 2002,2003,2014 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include "irplib_fft.h"
29
30/*----------------------------------------------------------------------------*/
34/*----------------------------------------------------------------------------*/
35
39/*----------------------------------------------------------------------------*/
52/*----------------------------------------------------------------------------*/
53cpl_error_code irplib_image_find_shift(const cpl_image * self,
54 const cpl_image * other,
55 double * px,
56 double * py)
57{
58 const cpl_size nx = cpl_image_get_size_x(self);
59 const cpl_size ny = cpl_image_get_size_y(self);
60 const cpl_size type = cpl_image_get_type(self);
61 const size_t bufsz = (size_t)(nx * ny)
62 * cpl_type_get_sizeof(type | CPL_TYPE_COMPLEX);
63 cpl_imagelist * iml;
64 cpl_imagelist * fml;
65 cpl_image * fself;
66 cpl_image * fother;
67 void * fdata;
68 cpl_error_code code = CPL_ERROR_NONE;
69
70 cpl_ensure_code(px != NULL, CPL_ERROR_NULL_INPUT);
71 cpl_ensure_code(py != NULL, CPL_ERROR_NULL_INPUT);
72
73 iml = cpl_imagelist_new();
74 /* Input images _not_ modified */
75 CPL_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
76 cpl_imagelist_set(iml, (cpl_image *)self, 0);
77 cpl_imagelist_set(iml, (cpl_image *)other, 1);
78 CPL_DIAG_PRAGMA_POP;
79
80 fdata = cpl_calloc(2, bufsz); /* Don't need two calloc()s here */
81
82 fml = cpl_imagelist_new();
83 fself = cpl_image_wrap(nx, ny, type | CPL_TYPE_COMPLEX, fdata);
84 fother = cpl_image_wrap(nx, ny, type | CPL_TYPE_COMPLEX, (char*)fdata
85 + bufsz);
86
87 cpl_imagelist_set(fml, fself, 0);
88 cpl_imagelist_set(fml, fother, 1);
89
90 if (cpl_fft_imagelist(fml, iml, CPL_FFT_FORWARD)) {
91 code = cpl_error_set_where(cpl_func);
92 } else {
93 /* Should not be able to fail now */
94 cpl_size xmax = 1, ymax = 1;
95 /* Share pixel buffer with fself which is not needed at the same time */
96 cpl_image * imgpos = cpl_image_wrap(nx, ny, type,
97 cpl_image_get_data(fself));
98
99 /* Cross-correlate */
100 cpl_image_conjugate(fother, fother);
101 cpl_image_multiply(fother, fself);
102
103 cpl_fft_image(imgpos, fother, CPL_FFT_BACKWARD | CPL_FFT_NOSCALE);
104
105 cpl_image_get_maxpos(imgpos, &xmax, &ymax);
106
107 (void)cpl_image_unwrap(imgpos);
108
109 /* The pixel position starts from 1, the offset from 0 */
110 xmax--;
111 ymax--;
112
113 /* The offset is signed, from -N/2 to N/2-1 */
114 *px = 2 * xmax >= nx ? xmax - nx : xmax;
115 *py = 2 * ymax >= ny ? ymax - ny : ymax;
116 }
117
118 cpl_imagelist_unwrap(iml);
119 cpl_image_unwrap(cpl_imagelist_unset(fml, 1));
120 cpl_imagelist_delete(fml);
121
122 return code;
123}
124