visir_destripe_body.c

00001 /* $Id: visir_destripe_body.c,v 1.8 2010/02/01 10:01:19 llundin Exp $
00002  *
00003  * This file is part of the irplib package 
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2010/02/01 10:01:19 $
00024  * $Revision: 1.8 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #define TYPE_ADD(a) CONCAT2X(a, PIXEL_TYPE)
00029 #define TYPE_ADD_CONST(a) CONCAT2X(a, CONCAT2X(PIXEL_TYPE, const))
00030 
00031 /*----------------------------------------------------------------------------*/
00048 /*----------------------------------------------------------------------------*/
00049 static cpl_error_code
00050 TYPE_ADD(visir_destripe_find_max_index)(const cpl_image * self,
00051                                         int per_stripe, int n_per,
00052                                         int dimy, int off_min,
00053                                         double * pmaximum,
00054                                         int * pindex,
00055                                         int * pmax_x, int * pmax_y)
00056 {
00057     const PIXEL_TYPE * pimf = TYPE_ADD_CONST(cpl_image_get_data)(self);
00058     double maximum = 0.0;
00059     int iindex = -1; /* Avoid (false) uninit warning */
00060     int max_x  = -1; /* Avoid (false) uninit warning */
00061     int max_y  = -1; /* Avoid (false) uninit warning */
00062     int i;
00063 
00064 
00065     bug_if(self == NULL);
00066     bug_if(cpl_image_get_type(self) != PIXEL_TYPE_CPL);
00067     bug_if(pmaximum == NULL);
00068     bug_if(pindex == NULL);
00069     bug_if(pmax_x == NULL);
00070     bug_if(pmax_y == NULL);
00071     bug_if(off_min <= 0);
00072     bug_if(pimf == NULL);
00073     bug_if(dimy < 2 * off_min);
00074     bug_if(n_per < 1);
00075 
00076 
00077     /*find the maximum of the 'maxi' vector and the indice of the maximum*/
00078     for (i = 0; i < n_per; i++) {
00079         int istart;
00080         for (istart = 0; istart < dimy - 2 * off_min; istart++) {
00081             int istop = istart + off_min;
00082             int j;
00083             double ilen = (double)off_min;
00084             double sum;
00085             double sum_pix = 0.0;
00086 
00087             for (j = istart; j <= istop; j++)
00088                 sum_pix += pimf[i + j * per_stripe];
00089 
00090             sum = sum_pix * sum_pix;
00091             if (sum > maximum * ilen) {
00092                 maximum = sum / ilen;
00093                 max_x = istart;
00094                 max_y = istop;
00095                 iindex = i;
00096             }
00097 
00098             for (istop++; istop < dimy - off_min; istop++) {
00099                 sum_pix += pimf[i + istop * per_stripe];
00100                 sum = sum_pix * sum_pix;
00101                 ilen += 1.0;
00102                 if (sum > maximum * ilen) {
00103                     maximum = sum / ilen;
00104                     max_x = istart;
00105                     max_y = istop;
00106                     iindex = i;
00107                 }
00108             }
00109         }
00110     }
00111 
00112     *pindex = iindex;
00113     *pmax_x = 1 + max_x;
00114     *pmax_y = 1 + max_y;
00115     *pmaximum = maximum;
00116 
00117     cpl_msg_debug(cpl_func, "Maximum image is image nb %d", 1 + *pindex);
00118     cpl_msg_debug(cpl_func, "Max x : %d   Max y : %d", *pmax_x, *pmax_y);
00119 
00120     end_skip;
00121 
00122     return cpl_error_get_code();
00123 }
00124 
00125 /*----------------------------------------------------------------------------*/
00138 /*----------------------------------------------------------------------------*/
00139 static int TYPE_ADD(visir_destripe_image_one)(cpl_image * self,
00140                                               double      threshold,
00141                                               double      thres_detect,
00142                                               cpl_boolean morpho,
00143                                               cpl_boolean do_horizontal)
00144 {
00145 
00146     /*period of stripe*/
00147     const int           per_stripe=16;
00148     const int           img_border = 2 + per_stripe;
00149     const int           dimx = cpl_image_get_size_y(self); /* Rotated */
00150     const int           dimy = cpl_image_get_size_x(self);
00151     cpl_image       *   bkgd = NULL;
00152     cpl_image       *   imabc = NULL;
00153     cpl_image       *   image_extract = NULL;
00154     double              noise, bgd;
00155     cpl_image       *   ima_med = NULL;
00156     cpl_image       *   supp_total = NULL;
00157     cpl_mask        *   supp_total_mask = NULL;
00158     cpl_image       *   imf = NULL;
00159     cpl_image       *   suppf = NULL;
00160     int                 n_per;
00161     /*minimum size of stripe*/
00162     int                 off_min=20;
00163     cpl_image       *   stripes = NULL;
00164     double              maximum = 0.0; /* Avoid (false) uninit warning */
00165     int                 max_x   = 0;   /* Avoid (false) uninit warning */
00166     int                 max_y   = 0;   /* Avoid (false) uninit warning */
00167     int                 indice  = 0;   /* Avoid (false) uninit warning */
00168     int                 ind;
00169     int                 i,j;
00170     cpl_vector      *   val_stripe = NULL;
00171     cpl_mask        *   kernel = cpl_mask_new(29, 29);
00172     cpl_mask        *   kernel3 = cpl_mask_new(3, 3);
00173     int                 isdone = 0;
00174 
00175 
00176     bug_if(0);
00177     bug_if(cpl_image_get_type(self) != PIXEL_TYPE_CPL);
00178 
00179     /* Low-pass filter 29x29 */
00180     bkgd = TYPE_ADD(cpl_image_wrap)(dimy, dimx,
00181                                     cpl_malloc(dimx*dimy*sizeof(PIXEL_TYPE)));
00182 
00183     bug_if(cpl_mask_not(kernel));
00184     bug_if(cpl_image_filter_mask(bkgd, self, kernel, CPL_FILTER_AVERAGE,
00185                                  CPL_BORDER_FILTER));
00186 
00187     imabc = cpl_image_subtract_create(self, bkgd);
00188     cpl_image_delete(bkgd);
00189     bkgd = NULL;
00190     bug_if(0);
00191 
00192     if (do_horizontal) {
00193         /* Stripes have to be vertical
00194            - turn the image to destripe horizontally */
00195         bug_if (cpl_image_turn(imabc, -1));
00196     }
00197 
00198     /* Extract an image to calculate the stdev and background  */
00199     /* because of the low quality borders  */
00200     image_extract = cpl_image_extract(imabc, img_border, img_border,
00201                                       dimx-img_border, dimy-img_border);
00202 
00203     bug_if (image_extract == NULL);
00204 
00205     noise = visir_image_sigma_clip(image_extract, &bgd);
00206     skip_if (0);
00207 
00208     cpl_image_delete(image_extract);
00209     image_extract = NULL;
00210 
00211     cpl_msg_debug(cpl_func, "imabc noise = %g", noise);
00212     cpl_msg_debug(cpl_func, "imabc bgd   = %g", bgd);
00213     bug_if(cpl_image_subtract_scalar(imabc, bgd));
00214 
00215     /* Create supp_total */
00216     ima_med = TYPE_ADD(cpl_image_wrap)(dimy, dimx,
00217                                    cpl_malloc(dimx*dimy*sizeof(PIXEL_TYPE)));
00218     bug_if(cpl_mask_not(kernel3));
00219     bug_if(cpl_image_filter_mask(ima_med, imabc, kernel3, CPL_FILTER_MEDIAN,
00220                                  CPL_BORDER_FILTER));
00221 
00222     /*CAREFUL:ima_med changed in abs(ima_med)*/
00223     bug_if (cpl_image_abs(ima_med));
00224     supp_total_mask = cpl_mask_threshold_image_create(ima_med,
00225                                                       -0.5 * DBL_MAX,
00226                                                       thres_detect * noise);
00227 
00228     bug_if (supp_total_mask == NULL);
00229     cpl_image_delete(ima_med);
00230     ima_med = NULL;
00231     cpl_msg_debug(cpl_func, "Stripe mask = %d/%d [pixel]",
00232                   cpl_mask_count(supp_total_mask),
00233                   cpl_mask_get_size_x(supp_total_mask)*
00234                   cpl_mask_get_size_y(supp_total_mask));
00235 
00236     supp_total = cpl_image_new_from_mask(supp_total_mask);
00237 #ifndef _OPENMP
00238     bug_if(cpl_image_save(supp_total, "supp_total_1.fits", CPL_BPP_8_UNSIGNED,
00239                           NULL, CPL_IO_DEFAULT));
00240 #endif
00241 
00242     if (morpho) {
00243 
00244         bug_if(visir_destripe_mask(supp_total_mask));
00245 
00246         cpl_image_delete(supp_total); /* :-( */
00247         supp_total = cpl_image_new_from_mask(supp_total_mask);
00248 
00249 #ifndef _OPENMP
00250         bug_if(cpl_image_save(supp_total, "supp_total_2.fits",
00251                               CPL_BPP_8_UNSIGNED, NULL, CPL_IO_DEFAULT));
00252 #endif
00253     }
00254 
00255     cpl_mask_delete(supp_total_mask);
00256     supp_total_mask = NULL;
00257 
00258     /* imabc *= supp_total / noise */
00259     bug_if(cpl_image_multiply(imabc, supp_total));
00260     bug_if(cpl_image_divide_scalar(imabc, noise));
00261 
00262     /* Extract the 16 first columns */
00263     /*sum of 16 columns by 16 columns*/
00264     imf   = cpl_image_extract(imabc,      1, 1, per_stripe, dimy);
00265     bug_if( imf == NULL);
00266 
00267     suppf = cpl_image_extract(supp_total, 1, 1, per_stripe, dimy);
00268     bug_if( suppf == NULL);
00269 
00270     n_per=dimx/per_stripe;
00271     for (i=1; i <n_per; i ++)
00272     {
00273         cpl_image * suppf_tmp;
00274         cpl_image * imf_tmp =
00275             cpl_image_extract(imabc, (per_stripe*i)+1, 1,
00276                               per_stripe*(i+1), dimy);
00277         cpl_error_code error = cpl_image_add(imf, imf_tmp);
00278 
00279         cpl_image_delete(imf_tmp);
00280 
00281         bug_if(error);
00282 
00283         suppf_tmp = cpl_image_extract(supp_total, (per_stripe*i)+1, 1,
00284                                      per_stripe*(i+1), dimy);
00285         error = cpl_image_add(suppf, suppf_tmp);
00286         cpl_image_delete(suppf_tmp);
00287         bug_if(error);
00288     }
00289     bug_if(cpl_image_divide_scalar(imf, n_per));
00290 
00291     /* Set to 0 in imf the pixels that are equal to 0 in suppf */
00292     bug_if(cpl_image_threshold(suppf, -0.5*DBL_MAX, 1, 0, 1));
00293     bug_if(cpl_image_multiply(imf, suppf));
00294     cpl_image_delete(suppf);
00295     suppf = NULL;
00296 
00297     bug_if (TYPE_ADD(visir_destripe_find_max_index)(imf, per_stripe, n_per, dimy,
00298                                                     off_min, &maximum, &indice,
00299                                                     &max_x, &max_y));
00300     cpl_image_delete(imf);
00301     imf = NULL;
00302 
00303     /* If maximum too low, no stripes found */
00304     if (maximum < threshold) {
00305         cpl_msg_info(cpl_func,"No stripes found: maximum=%g < treshold=%g",
00306                      maximum, threshold);
00307         isdone = 1;
00308     } else {
00309 
00310         const int   * psupp_total;
00311         const PIXEL_TYPE * pimabc;
00312         cpl_boolean   is_ok = CPL_FALSE;
00313 
00314         pimabc = TYPE_ADD_CONST(cpl_image_get_data)(imabc);
00315         psupp_total = cpl_image_get_data_int_const(supp_total);
00316 
00317         /*average stripes: take the median*/
00318         val_stripe = cpl_vector_new(n_per);
00319 
00320         for (i=0; i < n_per; i++) {
00321             double value = 0.0;
00322             int    N = 0;
00323             for (j=max_x; j<max_y+1; j++)
00324                 {
00325                     ind = i*per_stripe+indice + j * dimx;
00326                     if (psupp_total[ind] == 1)
00327                         {
00328                             value += pimabc[ind];
00329                             N++;
00330                         }
00331                 }
00332             if (N > 0) {
00333                 value /= N;
00334                 is_ok = CPL_TRUE;
00335             }
00336 #ifdef VISIR_DESTRIPE_AVERAGE
00337             for (j=max_x; j<max_y+1; j++) {
00338                 pima[i*per_stripe+indice+j*dimx] = value;
00339             }
00340 #else
00341             cpl_vector_set(val_stripe, i, value);
00342 #endif
00343         }
00344         if (is_ok) {
00345 #ifdef VISIR_DESTRIPE_AVERAGE
00346             cpl_msg_info(cpl_func,"Destriping: maximum=%g < treshold=%g",
00347                          maximum, threshold);
00348 
00349             /*to recompensate for the normalisation*/
00350             bug_if(cpl_image_multiply_scalar(stripes, noise));
00351 #else
00352             const double stripe_median = noise
00353                 * cpl_vector_get_median(val_stripe);
00354             PIXEL_TYPE * pima;
00355 
00356             stripes = cpl_image_new(dimx, dimy, PIXEL_TYPE_CPL);
00357             pima = TYPE_ADD(cpl_image_get_data)(stripes);
00358 
00359             bug_if(0);
00360 
00361             for (i=0; i<n_per; i++) {
00362                 for (j=max_x; j<max_y+1; j++) {
00363                     pima[i*per_stripe+indice+j*dimx] = stripe_median;
00364                 }
00365             }
00366             cpl_msg_info(cpl_func,"Destriping: maximum=%g < treshold=%g. "
00367                          "value=%g @ %dX%d. (noise=%g)", maximum, threshold,
00368                          stripe_median, n_per, max_y+1-max_x, noise);
00369 #endif
00370 
00371             if (do_horizontal) {
00372                 bug_if(cpl_image_turn(stripes, 1));
00373             }
00374 
00375             bug_if(cpl_image_subtract(self, stripes));
00376             /* cpl_plot_image("", "", "", stripes); */
00377         } else {
00378             cpl_msg_warning(cpl_func, "Destriping found no stripes");
00379             isdone = 1;
00380         }
00381         cpl_vector_delete(val_stripe);
00382         val_stripe = NULL;
00383     }
00384 
00385     bug_if(0);
00386 
00387     end_skip;
00388 
00389     cpl_mask_delete(kernel);
00390     cpl_mask_delete(kernel3);
00391     cpl_image_delete(imabc);
00392     cpl_vector_delete(val_stripe);
00393     cpl_image_delete(imf);
00394     cpl_image_delete(suppf);
00395     cpl_mask_delete(supp_total_mask);
00396     cpl_image_delete(ima_med);
00397     cpl_image_delete(image_extract);
00398     cpl_image_delete(stripes);
00399     cpl_image_delete(bkgd);
00400     cpl_image_delete(supp_total);
00401 
00402     return cpl_error_get_code() ? -1 : isdone;
00403 }
00404 

Generated on Thu Mar 24 11:59:39 2011 for VISIR Pipeline Reference Manual by  doxygen 1.5.8