VISIR Pipeline Reference Manual  4.1.7
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 /*----------------------------------------------------------------------------*/
49 static cpl_error_code
50 TYPE_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 /*----------------------------------------------------------------------------*/
139 static 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