IIINSTRUMENT Pipeline Reference Manual 4.6.2
visir_destripe_body.c
1/* $Id: visir_destripe_body.c,v 1.11 2012-02-14 08:53:14 jtaylor 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: jtaylor $
23 * $Date: 2012-02-14 08:53:14 $
24 * $Revision: 1.11 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#define TYPE_ADD(a) CONCAT2X(a, PIXEL_TYPE)
29#define TYPE_ADD_CONST(a) CONCAT2X(a, CONCAT2X(PIXEL_TYPE, const))
30
31/*----------------------------------------------------------------------------*/
48/*----------------------------------------------------------------------------*/
49static cpl_error_code
50TYPE_ADD(visir_destripe_find_max_index)(const cpl_image * self,
51 int per_stripe, int n_per,
52 int dimy, int off_min,
53 double * pmaximum,
54 int * pindex,
55 int * pmax_x, int * pmax_y)
56{
57 const PIXEL_TYPE * pimf = TYPE_ADD_CONST(cpl_image_get_data)(self);
58 double maximum = 0.0;
59 int iindex = -1; /* Avoid (false) uninit warning */
60 int max_x = -1; /* Avoid (false) uninit warning */
61 int max_y = -1; /* Avoid (false) uninit warning */
62 int i;
63
64
65 bug_if(self == NULL);
66 bug_if(cpl_image_get_type(self) != PIXEL_TYPE_CPL);
67 bug_if(pmaximum == NULL);
68 bug_if(pindex == NULL);
69 bug_if(pmax_x == NULL);
70 bug_if(pmax_y == NULL);
71 bug_if(off_min <= 0);
72 bug_if(pimf == NULL);
73 bug_if(dimy < 2 * off_min);
74 bug_if(n_per < 1);
75
76
77 /*find the maximum of the 'maxi' vector and the indice of the maximum*/
78 for (i = 0; i < n_per; i++) {
79 int istart;
80 for (istart = 0; istart < dimy - 2 * off_min; istart++) {
81 int istop = istart + off_min;
82 int j;
83 double ilen = (double)off_min;
84 double sum;
85 double sum_pix = 0.0;
86
87 for (j = istart; j < 1 + istop; j++)
88 sum_pix += pimf[i + j * per_stripe];
89
90 sum = sum_pix * sum_pix;
91 if (sum > maximum * ilen) {
92 maximum = sum / ilen;
93 max_x = istart;
94 max_y = istop;
95 iindex = i;
96 }
97
98 for (istop++; istop < dimy - off_min; istop++) {
99 sum_pix += pimf[i + istop * per_stripe];
100 sum = sum_pix * sum_pix;
101 ilen += 1.0;
102 if (sum > maximum * ilen) {
103 maximum = sum / ilen;
104 max_x = istart;
105 max_y = istop;
106 iindex = i;
107 }
108 }
109 }
110 }
111
112 *pindex = iindex;
113 *pmax_x = 1 + max_x;
114 *pmax_y = 1 + max_y;
115 *pmaximum = maximum;
116
117 cpl_msg_debug(cpl_func, "Maximum image is image nb %d", 1 + *pindex);
118 cpl_msg_debug(cpl_func, "Max x : %d Max y : %d", *pmax_x, *pmax_y);
119
120 end_skip;
121
122 return cpl_error_get_code();
123}
124
125/*----------------------------------------------------------------------------*/
138/*----------------------------------------------------------------------------*/
139static int TYPE_ADD(visir_destripe_image_one)(cpl_image * self,
140 double threshold,
141 double thres_detect,
142 cpl_boolean morpho,
143 cpl_boolean do_horizontal)
144{
145
146 /*period of stripe*/
147 const int per_stripe=16;
148 const int img_border = 2 + per_stripe;
149 const int dimx = cpl_image_get_size_y(self); /* Rotated */
150 const int dimy = cpl_image_get_size_x(self);
151 cpl_image * bkgd = NULL;
152 cpl_image * imabc = NULL;
153 cpl_image * image_extract = NULL;
154 double noise, bgd;
155 cpl_image * ima_med = NULL;
156 cpl_image * supp_total = NULL;
157 cpl_mask * supp_total_mask = NULL;
158 cpl_image * imf = NULL;
159 cpl_image * suppf = NULL;
160 int n_per;
161 /*minimum size of stripe*/
162 int off_min=20;
163 cpl_image * stripes = NULL;
164 double maximum = 0.0; /* Avoid (false) uninit warning */
165 int max_x = 0; /* Avoid (false) uninit warning */
166 int max_y = 0; /* Avoid (false) uninit warning */
167 int indice = 0; /* Avoid (false) uninit warning */
168 int ind;
169 int i,j;
170 cpl_vector * val_stripe = NULL;
171 cpl_mask * kernel = cpl_mask_new(29, 29);
172 cpl_mask * kernel3 = cpl_mask_new(3, 3);
173 int isdone = 0;
174
175
176 bug_if(0);
177 bug_if(cpl_image_get_type(self) != PIXEL_TYPE_CPL);
178
179 /* Low-pass filter 29x29 */
180 bkgd = TYPE_ADD(cpl_image_wrap)(dimy, dimx,
181 cpl_malloc(dimx*dimy*sizeof(PIXEL_TYPE)));
182
183 bug_if(cpl_mask_not(kernel));
184 bug_if(cpl_image_filter_mask(bkgd, self, kernel, CPL_FILTER_AVERAGE_FAST,
185 CPL_BORDER_FILTER));
186
187 imabc = cpl_image_subtract_create(self, bkgd);
188 cpl_image_delete(bkgd);
189 bkgd = NULL;
190 bug_if(0);
191
192 if (do_horizontal) {
193 /* Stripes have to be vertical
194 - turn the image to destripe horizontally */
195 bug_if (cpl_image_turn(imabc, -1));
196 }
197
198 /* Extract an image to calculate the stdev and background */
199 /* because of the low quality borders */
200 image_extract = cpl_image_extract(imabc, img_border, img_border,
201 dimx-img_border, dimy-img_border);
202
203 bug_if (image_extract == NULL);
204
205 noise = visir_image_sigma_clip(image_extract, &bgd);
206 skip_if (0);
207
208 cpl_image_delete(image_extract);
209 image_extract = NULL;
210
211 cpl_msg_debug(cpl_func, "imabc noise = %g", noise);
212 cpl_msg_debug(cpl_func, "imabc bgd = %g", bgd);
213 bug_if(cpl_image_subtract_scalar(imabc, bgd));
214
215 /* Create supp_total */
216 ima_med = TYPE_ADD(cpl_image_wrap)(dimy, dimx,
217 cpl_malloc(dimx*dimy*sizeof(PIXEL_TYPE)));
218 bug_if(cpl_mask_not(kernel3));
219 bug_if(cpl_image_filter_mask(ima_med, imabc, kernel3, CPL_FILTER_MEDIAN,
220 CPL_BORDER_FILTER));
221
222 /*CAREFUL:ima_med changed in abs(ima_med)*/
223 bug_if (cpl_image_abs(ima_med));
224 supp_total_mask = cpl_mask_threshold_image_create(ima_med,
225 -0.5 * DBL_MAX,
226 thres_detect * noise);
227
228 bug_if (supp_total_mask == NULL);
229 cpl_image_delete(ima_med);
230 ima_med = NULL;
231 cpl_msg_debug(cpl_func, "Stripe mask = %d/%d [pixel]",
232 (int)cpl_mask_count(supp_total_mask),
233 (int)(cpl_mask_get_size_x(supp_total_mask)*
234 cpl_mask_get_size_y(supp_total_mask)));
235
236 supp_total = cpl_image_new_from_mask(supp_total_mask);
237#ifndef _OPENMP
238 bug_if(cpl_image_save(supp_total, "supp_total_1.fits", CPL_BPP_8_UNSIGNED,
239 NULL, CPL_IO_DEFAULT));
240#endif
241
242 if (morpho) {
243
244 bug_if(visir_destripe_mask(supp_total_mask));
245
246 cpl_image_delete(supp_total); /* :-( */
247 supp_total = cpl_image_new_from_mask(supp_total_mask);
248
249#ifndef _OPENMP
250 bug_if(cpl_image_save(supp_total, "supp_total_2.fits",
251 CPL_BPP_8_UNSIGNED, NULL, CPL_IO_DEFAULT));
252#endif
253 }
254
255 cpl_mask_delete(supp_total_mask);
256 supp_total_mask = NULL;
257
258 /* imabc *= supp_total / noise */
259 bug_if(cpl_image_multiply(imabc, supp_total));
260 bug_if(cpl_image_divide_scalar(imabc, noise));
261
262 /* Extract the 16 first columns */
263 /*sum of 16 columns by 16 columns*/
264 imf = cpl_image_extract(imabc, 1, 1, per_stripe, dimy);
265 bug_if( imf == NULL);
266
267 suppf = cpl_image_extract(supp_total, 1, 1, per_stripe, dimy);
268 bug_if( suppf == NULL);
269
270 n_per=dimx/per_stripe;
271 for (i=1; i <n_per; i ++)
272 {
273 cpl_image * suppf_tmp;
274 cpl_image * imf_tmp =
275 cpl_image_extract(imabc, (per_stripe*i)+1, 1,
276 per_stripe*(i+1), dimy);
277 cpl_error_code error = cpl_image_add(imf, imf_tmp);
278
279 cpl_image_delete(imf_tmp);
280
281 bug_if(error);
282
283 suppf_tmp = cpl_image_extract(supp_total, (per_stripe*i)+1, 1,
284 per_stripe*(i+1), dimy);
285 error = cpl_image_add(suppf, suppf_tmp);
286 cpl_image_delete(suppf_tmp);
287 bug_if(error);
288 }
289 bug_if(cpl_image_divide_scalar(imf, n_per));
290
291 /* Set to 0 in imf the pixels that are equal to 0 in suppf */
292 bug_if(cpl_image_threshold(suppf, -0.5*DBL_MAX, 1, 0, 1));
293 bug_if(cpl_image_multiply(imf, suppf));
294 cpl_image_delete(suppf);
295 suppf = NULL;
296
297 bug_if (TYPE_ADD(visir_destripe_find_max_index)(imf, per_stripe, n_per, dimy,
298 off_min, &maximum, &indice,
299 &max_x, &max_y));
300 cpl_image_delete(imf);
301 imf = NULL;
302
303 /* If maximum too low, no stripes found */
304 if (maximum < threshold) {
305 cpl_msg_info(cpl_func,"No stripes found: maximum=%g < treshold=%g",
306 maximum, threshold);
307 isdone = 1;
308 } else {
309
310 const int * psupp_total;
311 const PIXEL_TYPE * pimabc;
312 cpl_boolean is_ok = CPL_FALSE;
313
314 pimabc = TYPE_ADD_CONST(cpl_image_get_data)(imabc);
315 psupp_total = cpl_image_get_data_int_const(supp_total);
316
317 /*average stripes: take the median*/
318 val_stripe = cpl_vector_new(n_per);
319
320 for (i=0; i < n_per; i++) {
321 double value = 0.0;
322 int N = 0;
323 for (j=max_x; j<max_y+1; j++)
324 {
325 ind = i*per_stripe+indice + j * dimx;
326 if (psupp_total[ind] == 1)
327 {
328 value += pimabc[ind];
329 N++;
330 }
331 }
332 if (N > 0) {
333 value /= N;
334 is_ok = CPL_TRUE;
335 }
336#ifdef VISIR_DESTRIPE_AVERAGE
337 for (j=max_x; j<max_y+1; j++) {
338 pima[i*per_stripe+indice+j*dimx] = value;
339 }
340#else
341 cpl_vector_set(val_stripe, i, value);
342#endif
343 }
344 if (is_ok) {
345#ifdef VISIR_DESTRIPE_AVERAGE
346 cpl_msg_info(cpl_func,"Destriping: maximum=%g < treshold=%g",
347 maximum, threshold);
348
349 /*to recompensate for the normalisation*/
350 bug_if(cpl_image_multiply_scalar(stripes, noise));
351#else
352 const double stripe_median = noise
353 * cpl_vector_get_median(val_stripe);
354 PIXEL_TYPE * pima;
355
356 stripes = cpl_image_new(dimx, dimy, PIXEL_TYPE_CPL);
357 pima = TYPE_ADD(cpl_image_get_data)(stripes);
358
359 bug_if(0);
360
361 for (i=0; i<n_per; i++) {
362 for (j=max_x; j<max_y+1; j++) {
363 pima[i*per_stripe+indice+j*dimx] = stripe_median;
364 }
365 }
366 cpl_msg_info(cpl_func,"Destriping: maximum=%g < treshold=%g. "
367 "value=%g @ %dX%d. (noise=%g)", maximum, threshold,
368 stripe_median, n_per, max_y+1-max_x, noise);
369#endif
370
371 if (do_horizontal) {
372 bug_if(cpl_image_turn(stripes, 1));
373 }
374
375 bug_if(cpl_image_subtract(self, stripes));
376 /* cpl_plot_image("", "", "", stripes); */
377 } else {
378 cpl_msg_warning(cpl_func, "Destriping found no stripes");
379 isdone = 1;
380 }
381 cpl_vector_delete(val_stripe);
382 val_stripe = NULL;
383 }
384
385 bug_if(0);
386
387 end_skip;
388
389 cpl_mask_delete(kernel);
390 cpl_mask_delete(kernel3);
391 cpl_image_delete(imabc);
392 cpl_vector_delete(val_stripe);
393 cpl_image_delete(imf);
394 cpl_image_delete(suppf);
395 cpl_mask_delete(supp_total_mask);
396 cpl_image_delete(ima_med);
397 cpl_image_delete(image_extract);
398 cpl_image_delete(stripes);
399 cpl_image_delete(bkgd);
400 cpl_image_delete(supp_total);
401
402 return cpl_error_get_code() ? -1 : isdone;
403}
404