CR2RE Pipeline Reference Manual 1.6.7
irplib_oddeven.c
1/* $Id: irplib_oddeven.c,v 1.9 2012-01-12 11:50:41 llundin Exp $
2 *
3 * This file is part of the irplib package
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: llundin $
23 * $Date: 2012-01-12 11:50:41 $
24 * $Revision: 1.9 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include <math.h>
37#include <cpl.h>
38
39#include "irplib_oddeven.h"
40
41/*-----------------------------------------------------------------------------
42 Functions prototypes
43 -----------------------------------------------------------------------------*/
44
45static cpl_imagelist * irplib_oddeven_cube_conv_xy_rtheta(cpl_imagelist *) ;
46static cpl_imagelist * irplib_oddeven_cube_conv_rtheta_xy(cpl_imagelist *) ;
47
48/*----------------------------------------------------------------------------*/
52/*----------------------------------------------------------------------------*/
53
56/*----------------------------------------------------------------------------*/
64/*----------------------------------------------------------------------------*/
66 const cpl_image * in,
67 int iquad,
68 double * r_even)
69{
70 cpl_image * extracted ;
71 cpl_image * labels ;
72 int * plabels ;
73 int llx, lly, urx, ury ;
74 int nx, ny ;
75 double f_even, f_tot ;
76 cpl_apertures * aperts ;
77 int i, j ;
78
79 /* Test entries */
80 if (in == NULL || r_even == NULL) return -1 ;
81 nx = cpl_image_get_size_x(in) ;
82 ny = cpl_image_get_size_y(in) ;
83
84 switch (iquad){
85 case 1:
86 llx = 1 ; lly = 1 ; urx = nx/2 ; ury = ny/2 ; break ;
87 case 2:
88 llx = (nx/2)+1 ; lly = 1 ; urx = nx ; ury = ny/2 ; break ;
89 case 3:
90 llx = 1 ; lly = (ny/2)+1 ; urx = nx/2 ; ury = ny ; break ;
91 case 4:
92 llx = (nx/2)+1 ; lly = (ny/2)+1 ; urx = nx ; ury = ny ; break ;
93 case 0:
94 llx = 1 ; lly = 1 ; urx = nx ; ury = ny ; break ;
95 default:
96 cpl_msg_error(cpl_func, "Unsupported mode") ;
97 *r_even = 0.0 ;
98 return -1 ;
99 }
100
101 /* Extract quadrant */
102 if ((extracted = cpl_image_extract(in, llx, lly, urx, ury)) == NULL) {
103 cpl_msg_error(cpl_func, "Cannot extract quadrant") ;
104 *r_even = 0.0 ;
105 return -1 ;
106 }
107 nx = cpl_image_get_size_x(extracted) ;
108 ny = cpl_image_get_size_y(extracted) ;
109
110 /* Get f_tot */
111 f_tot = cpl_image_get_median(extracted) ;
112 if (fabs(f_tot) < 1e-6) {
113 cpl_msg_warning(cpl_func, "Quadrant median is 0.0") ;
114 cpl_image_delete(extracted) ;
115 *r_even = 0.0 ;
116 return -1 ;
117 }
118
119 /* Create the label image to define the even columns */
120 labels = cpl_image_new(nx, ny, CPL_TYPE_INT) ;
121 plabels = cpl_image_get_data_int(labels) ;
122 for (i=0 ; i<nx ; i++) {
123 if (i % 2) for (j=0 ; j<ny ; j++) plabels[i+j*nx] = 0 ;
124 else for (j=0 ; j<ny ; j++) plabels[i+j*nx] = 1 ;
125 }
126
127 /* Get the median of even columns */
128 if ((aperts = cpl_apertures_new_from_image(extracted, labels)) == NULL) {
129 cpl_msg_error(cpl_func, "Cannot compute the even columns median") ;
130 cpl_image_delete(extracted) ;
131 cpl_image_delete(labels) ;
132 *r_even = 0.0 ;
133 return -1 ;
134 }
135 cpl_image_delete(extracted) ;
136 cpl_image_delete(labels) ;
137 f_even = cpl_apertures_get_median(aperts, 1) ;
138 cpl_apertures_delete(aperts) ;
139
140 /* Compute the even rate and return */
141 *r_even = f_even / f_tot ;
142 return 0 ;
143}
144
145/*----------------------------------------------------------------------------*/
151/*----------------------------------------------------------------------------*/
152cpl_image * irplib_oddeven_correct(const cpl_image * in)
153{
154 cpl_image * in_real ;
155 cpl_image * in_imag ;
156 cpl_imagelist * freq_i ;
157 cpl_imagelist * freq_i_amp ;
158 cpl_image * cur_im ;
159 double * pcur_im ;
160 cpl_image * cleaned ;
161 int nx ;
162 cpl_vector * hf_med ;
163
164 /* Test entries */
165 if (in==NULL) return NULL ;
166
167 nx = cpl_image_get_size_x(in) ;
168
169 /* Local copy of the input image in DOUBLE */
170 in_real = cpl_image_cast(in, CPL_TYPE_DOUBLE) ;
171 in_imag = cpl_image_duplicate(in_real) ;
172 cpl_image_multiply_scalar(in_imag, 0.0) ;
173
174 /* Apply FFT to input image */
175 cpl_image_fft(in_real, in_imag, CPL_FFT_DEFAULT) ;
176
177 /* Put the result in an image list */
178 freq_i = cpl_imagelist_new() ;
179 cpl_imagelist_set(freq_i, in_real, 0) ;
180 cpl_imagelist_set(freq_i, in_imag, 1) ;
181
182 /* Convert to amplitude/phase */
183 freq_i_amp = irplib_oddeven_cube_conv_xy_rtheta(freq_i);
184 cpl_imagelist_delete(freq_i) ;
185
186 /* Correct the odd-even frequency */
187 cur_im = cpl_imagelist_get(freq_i_amp, 0) ;
188 pcur_im = cpl_image_get_data_double(cur_im) ;
189 /* Odd-even frequency will be replaced by
190 the median of the 5 values around */
191 hf_med = cpl_vector_new(5);
192
193 cpl_vector_set(hf_med, 0, pcur_im[nx/2 + 1]);
194 cpl_vector_set(hf_med, 1, pcur_im[nx/2 + 2]);
195 cpl_vector_set(hf_med, 2, pcur_im[nx/2 + 3]);
196 cpl_vector_set(hf_med, 3, pcur_im[nx/2 ]);
197 cpl_vector_set(hf_med, 4, pcur_im[nx/2 -1]);
198
199 pcur_im[nx / 2 + 1] = cpl_vector_get_median(hf_med);
200 cpl_vector_delete(hf_med);
201
202 /* Convert to X/Y */
203 freq_i = irplib_oddeven_cube_conv_rtheta_xy(freq_i_amp) ;
204 cpl_imagelist_delete(freq_i_amp) ;
205 /* FFT back to image space */
206 cpl_image_fft(cpl_imagelist_get(freq_i, 0), cpl_imagelist_get(freq_i, 1),
207 CPL_FFT_INVERSE) ;
208 cleaned = cpl_image_cast(cpl_imagelist_get(freq_i, 0), CPL_TYPE_FLOAT) ;
209 cpl_imagelist_delete(freq_i) ;
210 return cleaned ;
211}
212
215/*----------------------------------------------------------------------------*/
226/*----------------------------------------------------------------------------*/
227static cpl_imagelist * irplib_oddeven_cube_conv_xy_rtheta(
228 cpl_imagelist * cube_in)
229{
230 cpl_imagelist * cube_out ;
231 double re, im ;
232 double mod, phase ;
233 int nx, ny, np ;
234 cpl_image * tmp_im ;
235 double * pim1 ;
236 double * pim2 ;
237 double * pim3 ;
238 double * pim4 ;
239 int i, j ;
240
241 /* Error handling : test entries */
242 if (cube_in == NULL) return NULL ;
243 np = cpl_imagelist_get_size(cube_in) ;
244 if (np != 2) return NULL ;
245
246 /* Initialise */
247 tmp_im = cpl_imagelist_get(cube_in, 0) ;
248 pim1 = cpl_image_get_data_double(tmp_im) ;
249 nx = cpl_image_get_size_x(tmp_im) ;
250 ny = cpl_image_get_size_y(tmp_im) ;
251 tmp_im = cpl_imagelist_get(cube_in, 1) ;
252 pim2 = cpl_image_get_data_double(tmp_im) ;
253
254 /* Allocate cube_out */
255 cube_out = cpl_imagelist_duplicate(cube_in) ;
256
257 tmp_im = cpl_imagelist_get(cube_out, 0) ;
258 pim3 = cpl_image_get_data_double(tmp_im) ;
259 tmp_im = cpl_imagelist_get(cube_out, 1) ;
260 pim4 = cpl_image_get_data_double(tmp_im) ;
261 /* Convert */
262 for (j=0 ; j<ny ; j++) {
263 for (i=0 ; i<nx ; i++) {
264 re = (double)pim1[i+j*nx] ;
265 im = (double)pim2[i+j*nx] ;
266 mod = (double)(sqrt(re*re + im*im)) ;
267 if (re != 0.0)
268 phase = (double)atan2(im, re) ;
269 else
270 phase = 0.0 ;
271 pim3[i+j*nx] = mod ;
272 pim4[i+j*nx] = phase ;
273 }
274 }
275 return cube_out ;
276}
277
278/*----------------------------------------------------------------------------*/
291/*----------------------------------------------------------------------------*/
292static cpl_imagelist * irplib_oddeven_cube_conv_rtheta_xy(
293 cpl_imagelist * cube_in)
294{
295 cpl_imagelist * cube_out ;
296 double re, im ;
297 double mod, phase ;
298 int nx, ny, np ;
299 cpl_image * tmp_im ;
300 double * pim1 ;
301 double * pim2 ;
302 double * pim3 ;
303 double * pim4 ;
304 int i, j ;
305
306 /* Error handling : test entries */
307 if (cube_in == NULL) return NULL ;
308 np = cpl_imagelist_get_size(cube_in) ;
309 if (np != 2) return NULL ;
310
311 /* Initialise */
312 tmp_im = cpl_imagelist_get(cube_in, 0) ;
313 pim1 = cpl_image_get_data_double(tmp_im) ;
314 nx = cpl_image_get_size_x(tmp_im) ;
315 ny = cpl_image_get_size_y(tmp_im) ;
316 tmp_im = cpl_imagelist_get(cube_in, 1) ;
317 pim2 = cpl_image_get_data_double(tmp_im) ;
318
319 /* Allocate cube_out */
320 cube_out = cpl_imagelist_duplicate(cube_in) ;
321
322 tmp_im = cpl_imagelist_get(cube_out, 0) ;
323 pim3 = cpl_image_get_data_double(tmp_im) ;
324 tmp_im = cpl_imagelist_get(cube_out, 1) ;
325 pim4 = cpl_image_get_data_double(tmp_im) ;
326 /* Convert */
327 for (j=0 ; j<ny ; j++) {
328 for (i=0 ; i<nx ; i++) {
329 mod = (double)pim1[i+j*nx] ;
330 phase = (double)pim2[i+j*nx] ;
331 re = (double)(mod * cos(phase));
332 im = (double)(mod * sin(phase));
333 pim3[i+j*nx] = re ;
334 pim4[i+j*nx] = im ;
335 }
336 }
337 return cube_out ;
338}
int irplib_oddeven_monitor(const cpl_image *in, int iquad, double *r_even)
Estimate the odd/even rate in an image quadrant.
cpl_image * irplib_oddeven_correct(const cpl_image *in)
Correct the odd/even in an image.