sinfo_detlin.c

00001 /*
00002  * This file is part of the ESO SINFONI Pipeline
00003  * Copyright (C) 2004,2005 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00018  */
00019 /*******************************************************************************
00020 * E.S.O. - VLT project
00021 *
00022 *
00023 *
00024 * who       when      what
00025 * --------  --------  ----------------------------------------------
00026 * amodigli  18/04/02  created
00027 */
00028 
00029 #ifdef HAVE_CONFIG_H
00030 #  include <config.h>
00031 #endif
00032 #define POSIX_SOURCE 1
00033 #include "sinfo_vltPort.h"
00034 
00035 /*
00036  * System Headers
00037  */
00038 
00039 /*
00040  * Local Headers
00041  */
00042 
00043 #include "sinfo_detlin.h"
00044 #include "sinfo_recipes.h"
00045 #include "sinfo_fit_curve.h"
00046 
00054 /*----------------------------------------------------------------------------
00055  *                            Function codes
00056  *--------------------------------------------------------------------------*/
00057 
00079 cpl_imagelist * 
00080 sinfo_new_fit_intensity_course(cpl_imagelist * flatStack,
00081                               int       order,
00082                               float     loReject,
00083                               float     hiReject )
00084 {
00085     cpl_imagelist * ret_iml ;
00086     dpoint  * points ;
00087     int       i, z ;
00088     double * coeffs ;
00089     Stats  ** stats=NULL ;
00090     int sx;
00091     int sy;
00092     int sz;
00093     float* psrcdata;
00094     float* presdata;
00095     cpl_image* img_tmp=NULL;
00096     sx=cpl_image_get_size_x(cpl_imagelist_get(flatStack,0));
00097     sy=cpl_image_get_size_y(cpl_imagelist_get(flatStack,0));
00098     sz=cpl_imagelist_get_size(flatStack);
00099 
00100     stats=(Stats**) cpl_calloc(sz,sizeof(Stats*)) ;
00101   
00102     if ( NULL == flatStack )
00103     {
00104         sinfo_msg_error("no input cube given!") ;
00105         return NULL ;
00106     }
00107     if ( order <= 0 )
00108     {
00109         sinfo_msg_error("wrong order of polynomial given!") ;
00110         return NULL ;
00111     }
00112     /* allocate memory for returned cube */
00113     ret_iml = cpl_imagelist_new();
00114     for ( z = 0 ; z < order+1 ; z++ )
00115     {
00116       img_tmp=cpl_image_new(sx,sy,CPL_TYPE_FLOAT);
00117       cpl_imagelist_set(ret_iml,img_tmp,z);
00118     }
00119 
00120     for ( z = 0 ; z < sz ; z++ )
00121     {
00122       stats[z]=
00123        sinfo_new_image_stats_on_rectangle(cpl_imagelist_get(flatStack,z), 
00124                                                 loReject, 
00125                                                 hiReject, 
00126                                                 0, 
00127                                                 0, 
00128                                                 sx-1, 
00129                                                 sy-1) ;
00130         if ( stats[z] == NULL )
00131         {
00132             sinfo_msg_error("could not compute image statistics "
00133                             "in plane: %d", z) ;
00134             cpl_imagelist_delete(ret_iml) ;
00135             return NULL ;
00136         }
00137     }
00138 
00139     /* go through the image plane and store the spectra in a double 
00140        points data structure */
00141     
00142     for ( i = 0 ; i < sx*sy ; i++ )
00143     {
00144       /* allocate dpoint object */
00145       if ( NULL == ( points = (dpoint*) cpl_calloc(sz, sizeof(dpoint)) ) )
00146     {
00147       sinfo_msg_error("could not allocate memory!\n") ;
00148       cpl_imagelist_delete(ret_iml) ;
00149       return NULL ;
00150     }
00151 
00152       for ( z = 0 ; z < sz ; z++ )
00153       {
00154       if(NULL==(img_tmp = cpl_imagelist_get(flatStack,z))) {
00155         sinfo_msg_error("could not get image!");
00156           cpl_imagelist_delete(ret_iml) ;
00157             return NULL;
00158       } else {
00159         psrcdata=cpl_image_get_data_float(img_tmp);
00160         points[z].x = (double)stats[z]->cleanmean ;
00161         points[z].y = (double)psrcdata[i] ;
00162       }
00163       }
00164 
00165 
00166       if ( NULL == ( coeffs = sinfo_fit_1d_poly(order, points, sz, NULL) ) )
00167       {
00168       sinfo_msg_warning("could not fit spectrum of pixel: %d\n", i) ;
00169       for ( z = 0 ; z < order+1 ; z++ )
00170         {
00171           presdata=cpl_image_get_data_float(cpl_imagelist_get(ret_iml,z));
00172           presdata[i] = ZERO ;
00173         }
00174       }
00175       else
00176       {
00177     for ( z = 0 ; z < order+1 ; z++ )
00178         {
00179           if(NULL==(img_tmp = cpl_imagelist_get(ret_iml,z))) {
00180         sinfo_msg_error("could not get image!");
00181         cpl_imagelist_delete(ret_iml) ;
00182         return NULL;
00183           } else {
00184         presdata=cpl_image_get_data_float(img_tmp);
00185         presdata[i] = coeffs[z] ;
00186           }
00187     }
00188       }
00189       cpl_free(points) ;
00190       cpl_free(coeffs) ;
00191     }
00192 
00193     for ( z = 0 ; z < sz ; z++ )
00194     {
00195         cpl_free (stats[z]) ;
00196     }
00197     cpl_free(stats);
00198     return ret_iml ;
00199 }
00200 
00201 
00225 cpl_image * sinfo_new_search_bad_pixels( cpl_imagelist *  coeffs,
00226                             double     threshSigmaFactor,
00227                             double     nonlinearThresh,
00228                             float      loReject,
00229                             float      hiReject )
00230 {
00231      int i, z ;
00232     Stats * stats ;
00233     int sx=0;
00234     int sy=0;
00235     int sz=0;
00236 
00237     cpl_image * img_res ;
00238     cpl_image* img_src=NULL;
00239 
00240     float* psrcdata=NULL;
00241     float* presdata=NULL;
00242 
00243     if ( NULL == coeffs )
00244     {
00245         sinfo_msg_error("no input cube given!\n") ;
00246         return NULL ;
00247     }
00248     if ( threshSigmaFactor <= 0. )
00249     {
00250         sinfo_msg_error("wrong sigma factor given, 0 or negativ!\n") ;
00251         return NULL ;
00252     }
00253     if ( nonlinearThresh <= 0. )
00254     {
00255         sinfo_msg_error("wrong nonlinear threshold value given, "
00256                         "0 or negative!") ;
00257         return NULL ;
00258     }
00259 
00260     sz=cpl_imagelist_get_size(coeffs);
00261 
00262     if ( sz <= 1 )
00263     {
00264         sinfo_msg_error("no cube given, only one plane!\n") ;
00265         return NULL ;
00266     }
00267 
00268     /* Note that we refer to image #1! */
00269     img_src=cpl_imagelist_get(coeffs,1);
00270     sx=cpl_image_get_size_x(img_src);
00271     sy=cpl_image_get_size_y(img_src);
00272 
00273     /* allocate memory for return image */
00274     if ( NULL == (img_res = cpl_image_new(sx, sy,CPL_TYPE_FLOAT)) )
00275     {
00276         sinfo_msg_error("could not allocate memory!\n") ;
00277         return NULL ;
00278     }
00279 
00280 
00281     /* first test the sensitivity deviations of each pixel */
00282     /* determine the clean mean and clean standard deviation 
00283        in the whole image frame */
00284    
00285     stats = sinfo_new_image_stats_on_rectangle(img_src, 
00286                                                loReject, 
00287                                                hiReject, 0, 0, 
00288                                                sx-1, sy-1) ;
00289     if ( NULL == stats )
00290     {
00291         sinfo_msg_error("could not determine image statistics!\n") ;
00292         cpl_image_delete(img_res) ;
00293         return NULL ;
00294     }
00295     
00296 
00297     psrcdata=cpl_image_get_data_float(img_src);
00298     presdata=cpl_image_get_data_float(img_res);
00299     for ( i = 0 ; i < (int) sx*sy ; i++ )
00300     {
00301 
00302         if ( isnan(psrcdata[i]) )
00303         {
00304             presdata[i] = 0. ;
00305         }
00306         else if ( stats->cleanmean - psrcdata[i] > 
00307                   threshSigmaFactor*stats->cleanstdev )
00308         {
00309             presdata[i] = 0. ;
00310         }
00311         else
00312         {
00313            presdata[i] = 1. ;
00314         }
00315     }
00316     cpl_free(stats) ;
00317 
00318 
00319     /* -----------------------------------------------------
00320      * now test additionally the non-linearity if available. 
00321      * if a strong non-linearity occurs for pixels which are 
00322      * declared "good" so far (normal linear coefficients)
00323      * these pixels will be declared bad.    
00324      */
00325     if (sz > 1) 
00326     {
00327         for ( z = 2 ; z < sz ; z++ )
00328         {
00329       img_src=cpl_imagelist_get(coeffs,z);
00330           sx=cpl_image_get_size_x(img_src);
00331           sy=cpl_image_get_size_y(img_src);
00332 
00333           psrcdata=cpl_image_get_data_float(img_src);
00334             stats = sinfo_new_image_stats_on_rectangle(img_src, loReject, 
00335                                                  hiReject, 0, 0, sx-1, sy-1) ;
00336             if ( NULL == stats )
00337             {
00338                 sinfo_msg_error("could not determine image statistics!\n") ;
00339                 cpl_image_delete(img_res) ;
00340                 return NULL ;
00341             }
00342           presdata=cpl_image_get_data_float(img_res);
00343             for ( i = 0 ; i < (int) sx*sy ; i++ )
00344             {
00345                 if ( presdata[i] == 1. && 
00346                      (fabs(psrcdata[i] - stats->cleanmean) > 
00347                                      threshSigmaFactor*stats->cleanstdev ||
00348               fabs(psrcdata[i]) > nonlinearThresh ) ) 
00349                 {
00350                     presdata[i] = 0. ;
00351                 }
00352             }
00353             cpl_free(stats) ;
00354         }
00355     }
00356 
00357     return img_res ;
00358 }
00359 
00360 
00361 
00362 
00383 cpl_image * sinfo_new_search_bad_pixels_via_noise(cpl_imagelist *  darks,
00384                                     float      threshSigmaFactor,
00385                                     float      loReject,
00386                                     float      hiReject )
00387 {
00388     cpl_image * bp_map ;
00389     int        z, n, i ;
00390     int        lx, ly ;
00391     int        row, col ;
00392     int        low_n, high_n ;
00393     float    * spectrum ;
00394     double     pix_sum ;
00395     double     sqr_sum ;
00396     Stats    * stats ;
00397     cpl_image* img_src=NULL;
00398 
00399     float* psrcdata=NULL;
00400     float* pbpdata=NULL;
00401 
00402     int lz=0;
00403     
00404     if ( NULL == darks )
00405     {
00406         sinfo_msg_error("no input cube given!\n") ;
00407         return NULL ;
00408     }
00409 
00410     if ( threshSigmaFactor <= 0. )
00411     {
00412         sinfo_msg_error("factor is smaller or equal zero!\n") ;
00413         return NULL ;
00414     }
00415     if ( loReject < 0. || hiReject < 0. || (loReject + hiReject) >= 100.  )
00416     {
00417         sinfo_msg_error("wrong reject percentage values!\n") ;
00418         return NULL ;
00419     }
00420 
00421     lz=cpl_imagelist_get_size(darks);
00422     if ( lz < 1 )
00423     {
00424         sinfo_msg_error("not enough dark frames given for good statistics!") ;
00425         return NULL ;
00426     }
00427     img_src=cpl_imagelist_get(darks,0);
00428     
00429     lx = cpl_image_get_size_x(img_src) ;
00430     ly = cpl_image_get_size_y(img_src) ;
00431   
00432     low_n  = (int)(loReject/100. *(float)lz) ;
00433     high_n = (int)(hiReject/100. *(float)lz) ;
00434     if (NULL == (bp_map = cpl_image_new (lx, ly,CPL_TYPE_FLOAT) ) )
00435     {
00436         sinfo_msg_error("could not allocate new memory!\n") ;
00437         return NULL ;
00438     }
00439     pbpdata=cpl_image_get_data(bp_map);
00440     if (NULL == (spectrum = (float*) cpl_calloc(lz, sizeof(float)) ) )
00441     {
00442         sinfo_msg_error("could not allocate new memory!\n") ;
00443         return NULL ;
00444     }
00445     for ( row = 0 ; row < ly ; row++ ) {
00446 
00447       for ( col = 0 ; col < lx ; col++ ) {
00448 
00449     for ( z = 0 ; z < lz ; z++ ) {
00450       img_src=cpl_imagelist_get(darks,z);
00451       psrcdata=cpl_image_get_data(img_src);
00452       spectrum[z] = psrcdata[col+lx*row] ;
00453     }
00454     sinfo_pixel_qsort(spectrum, lz) ;
00455     n = 0  ;
00456     pix_sum = 0.; 
00457     sqr_sum = 0.; 
00458     for ( i = low_n ; i < lz - high_n ; i++ ) {
00459       pix_sum += (double)spectrum[i] ;
00460       sqr_sum += ((double)spectrum[i]*(double)spectrum[i]) ;
00461       n++ ;
00462     }
00463         /* compute the noise in each pixel */
00464     pix_sum /= (double)n ;
00465     sqr_sum /= (double)n ;
00466 
00467         pbpdata[col+lx*row] = (float)sqrt(sqr_sum - pix_sum*pix_sum) ;
00468       }
00469     }
00470     cpl_free(spectrum) ;
00471     if ( NULL == (stats = sinfo_new_image_stats_on_rectangle (bp_map, loReject, 
00472                                        hiReject, 200, 200, 800, 800) ) )
00473     {
00474         sinfo_msg_error("could not get image statistics!\n") ;
00475         cpl_image_delete (bp_map) ;
00476         return NULL ;
00477     }
00478  
00479 
00480     /* now build the bad pixel mask */
00481     for ( row = 0 ; row < ly ; row++ ) {
00482       for ( col = 0 ; col < lx ; col++ ) {
00483          if (pbpdata[col+lx*row] >
00484              stats->cleanmean+threshSigmaFactor*stats->cleanstdev ||
00485              pbpdata[col+lx*row] < 
00486              stats->cleanmean-threshSigmaFactor*stats->cleanstdev) 
00487        {
00488              pbpdata[col+lx*row] = 0. ;
00489        }
00490            else
00491            {
00492          pbpdata[col+lx*row] = 1. ;
00493            }
00494       }
00495     }
00496     cpl_free (stats) ;
00497     return bp_map ;
00498 }
00499 
00500 
00501 
00510 int sinfo_new_count_bad_pixels (cpl_image * bad )
00511 {
00512     int i, n ;
00513     int sx=cpl_image_get_size_x(bad);
00514     int sy=cpl_image_get_size_y(bad);
00515     float* pbpdata=cpl_image_get_data(bad);
00516 
00517     n = 0 ;
00518     for ( i = 0 ; i < (int) sx*sy ; i++ )
00519     {
00520         if ( pbpdata[i] == 0 || isnan(pbpdata[i]) )
00521         {
00522             n++ ;
00523         }
00524     }
00525     return n ;
00526 }
00527 
00528 
00556 cpl_image * sinfo_new_abs_dist_image(cpl_image * im, float fmedian )
00557 {
00558 
00559     cpl_image *   image       ;
00560     pixelvalue * value       ;
00561     pixelvalue   dist      ;
00562     pixelvalue   median_dist      ;
00563     pixelvalue*   pix_dist=NULL ;
00564     int        * position    ;
00565     int          nposition   ;
00566     int          n, m, i, j ;
00567     double       sum, sum2 ;
00568     double       stdev ;
00569     float* pdata=NULL;
00570     int lx=0;
00571     int ly=0;
00572 
00573     if ( im == NULL )
00574      {
00575         sinfo_msg_error ("no image input\n") ;
00576         return NULL ;
00577     }
00578 
00579     image = cpl_image_duplicate ( im ) ;
00580 
00581     /*----------------------------------------------------------------------
00582      * go through all pixels
00583      */
00584 
00585     sum = 0. ;
00586     sum2 = 0. ;
00587     m = 0 ;
00588     
00589     pdata = cpl_image_get_data(im);
00590     lx=cpl_image_get_size_x(im);
00591     ly=cpl_image_get_size_y(im);
00592     pix_dist=(pixelvalue*)cpl_calloc(lx*ly,sizeof(pixelvalue)) ;
00593 
00594     for ( i = 0 ;  i < (int) lx*ly ; i++ )
00595     {
00596       /* blank pixels are not replaced */
00597       if ( isnan(pdata[i]) )
00598         {
00599       continue ;
00600         }
00601 
00602         /* initialize the buffer variables for the 8 nearest neighbors */
00603         value = (pixelvalue * )cpl_calloc ( 8, sizeof ( pixelvalue * ) ) ;
00604         position = ( int * ) cpl_calloc ( 8, sizeof ( int * ) ) ;
00605 
00606         /*--------------------------------------------------------------------
00607          * determine the pixel position of the 8 nearest neighbors
00608          */
00609 
00610         position[0] = i + lx - 1 ; /* upper left  */
00611         position[1] = i + lx     ; /* upper       */
00612         position[2] = i + lx + 1 ; /* upper right */
00613         position[3] = i + 1      ; /* right       */
00614         position[4] = i - lx + 1 ; /* lower right */
00615         position[5] = i - lx     ; /* lower       */
00616         position[6] = i - lx - 1 ; /* lower left  */
00617         position[7] = i - 1      ; /* left        */
00618 
00619         /*--------------------------------------------------------------------
00620          * determine the positions of the image margins, top positions are 
00621          * changed to low positions and vice versa. Right positions are 
00622          * changed to left positions and vice versa.
00623          */
00624 
00625         if ( i >= 0 && i < lx )    /* bottom line */
00626         {
00627             position[4] += 2 * lx ;
00628             position[5] += 2 * lx ;
00629             position[6] += 2 * lx ;
00630         }
00631         else if ( i >= ((int) lx*ly - lx ) && i < (int) lx*ly ) /* top line */
00632         {
00633             position[0] -= 2 * lx ;
00634             position[1] -= 2 * lx ;
00635             position[2] -= 2 * lx ;
00636         }
00637         else if ( i % lx == 0 )    /* left side */
00638         {
00639             position[0] += 2 ;
00640             position[6] += 2 ;
00641             position[7] += 2 ;
00642         }
00643         else if ( i % lx == lx - 1 )    /* right side */
00644         {
00645             position[2] -= 2 ;
00646             position[3] -= 2 ;
00647             position[4] -= 2 ;
00648         }
00649 
00650         /* -------------------------------------------------------------------
00651          * read the pixel values of the neighboring pixels,
00652          * blanks are not considered
00653          */
00654 
00655         nposition = 8 ;
00656         n = 0 ;
00657         for ( j = 0 ; j < nposition ; j ++ )
00658         {
00659             if ( !isnan(pdata[position[j]]) )
00660             {
00661                 value[n] = pdata[position[j]] ;
00662                 n ++ ;
00663             }
00664         }
00665         nposition = n ;
00666 
00667         if ( nposition <= 1 )  /* almost all neighbors are blank */
00668         {
00669             pdata[i] = ZERO ;
00670             cpl_free(value) ;
00671             cpl_free(position) ;
00672             continue ;
00673         }
00674 
00675         /* determine the absolute distances */
00676         dist = 0. ;
00677         for ( n = 0 ; n < nposition ; n++ )
00678         {
00679             dist += (pdata[i] - value[n])*(pdata[i] - value[n]) ;    
00680         }
00681         dist = sqrt(dist)/(float) nposition ;
00682         pix_dist[m] = dist ;
00683         m++ ;
00684         sum += (double)dist ;
00685         sum2 += (double)dist * (double)dist ;
00686         cpl_free(value) ;
00687         cpl_free(position) ;
00688     }
00689     sum /= (double)m ;
00690     sum2 /= (double)m ;
00691     stdev = sqrt(sum2 - sum*sum) ;
00692 
00693     median_dist = sinfo_new_median(pix_dist, m) ;
00694 
00695     for ( i = 0 ; i < (int) lx*ly ; i++ )
00696     {
00697         /* blank pixels are not replaced */
00698         if ( isnan(pdata[i]) )
00699         {
00700             continue ;
00701         }
00702 
00703         /* initialize the buffer variables for the 8 nearest neighbors */
00704         value = (pixelvalue * )cpl_calloc ( 8, sizeof ( pixelvalue * ) ) ;
00705         position = ( int * ) cpl_calloc ( 8, sizeof ( int * ) ) ;
00706 
00707         /*-------------------------------------------------------------------
00708          * determine the pixel position of the 8 nearest neighbors
00709          */
00710 
00711         position[0] = i + lx - 1 ; /* upper left  */
00712         position[1] = i + lx     ; /* upper       */
00713         position[2] = i + lx + 1 ; /* upper right */
00714         position[3] = i + 1      ; /* right       */
00715         position[4] = i - lx + 1 ; /* lower right */
00716         position[5] = i - lx     ; /* lower       */
00717         position[6] = i - lx - 1 ; /* lower left  */
00718         position[7] = i - 1      ; /* left        */
00719 
00720         /*-------------------------------------------------------------
00721          * determine the positions of the image margins, top positions are 
00722          * changed to low positions and vice versa. Right positions are 
00723          * changed to left positions and vice versa.
00724          */
00725 
00726         if ( i >= 0 && i < lx )    /* bottom line */
00727         {
00728             position[4] += 2 * lx ;
00729             position[5] += 2 * lx ;
00730             position[6] += 2 * lx ;
00731         }
00732         else if ( i >= ((int) lx*ly - lx ) && i < (int) lx*ly ) /* top line */
00733         {
00734             position[0] -= 2 * lx ;
00735             position[1] -= 2 * lx ;
00736             position[2] -= 2 * lx ;
00737         }
00738         else if ( i % lx == 0 )    /* left side */
00739         {
00740             position[0] += 2 ;
00741             position[6] += 2 ;
00742             position[7] += 2 ;
00743         }
00744         else if ( i % lx == lx - 1 )    /* right side */
00745         {
00746             position[2] -= 2 ;
00747             position[3] -= 2 ;
00748             position[4] -= 2 ;
00749         }
00750 
00751         /* -------------------------------------------------------------------
00752          * read the pixel values of the neighboring pixels,
00753          * blanks are not considered
00754          */
00755 
00756         nposition = 8 ;
00757         n = 0 ;
00758         for ( j = 0 ; j < nposition ; j ++ )
00759         {
00760             if ( !isnan(pdata[position[j]]) )
00761             {
00762                 value[n] = pdata[position[j]] ;
00763                 n ++ ;
00764             }
00765         }
00766         nposition = n ;
00767 
00768         if ( nposition <= 1 )  /* almost all neighbors are blank */
00769         {
00770             pdata[i] = ZERO ;
00771             cpl_free(value) ;
00772             cpl_free(position) ;
00773             continue ;
00774         }
00775 
00776         /* determine the absolute distances */
00777         dist = 0. ;
00778         for ( n = 0 ; n < nposition ; n++ )
00779         {
00780             dist += (pdata[i] - value[n])*(pdata[i] - value[n]) ;    
00781         }
00782         dist = sqrt(dist)/(float) nposition ;
00783 
00784 
00785         /* -----------------------------------------------------------------
00786          * replace the pixel value by the sinfo_median on conditions:
00787          * fmedian = 0: always replace with sinfo_median.
00788          * fmedian < 0: interpret as absolute condition:
00789          *              if |pixel - sinfo_median| > -fmedian
00790          *              replace with sinfo_median.
00791          * fmedian > 0: replace by sinfo_median (fmedian as a factor of
00792          *              the square root of the sinfo_median itself)
00793          *              if |pixel - median| >= fmedian * sqrt ( median )
00794          *              considers a dependence on the pixel value.
00795          *              This can be used to consider photon noise.
00796          */
00797 
00798         if ( fmedian == 0 )
00799         {
00800             pdata[i] = dist ;
00801         }
00802         else if ( fmedian < 0 &&
00803                   fabs ( median_dist - dist ) >= -fmedian*stdev )
00804         {
00805             pdata[i] = dist ;
00806         }
00807         else if ( fmedian > 0 &&
00808                   fabs ( median_dist - dist ) >= 
00809                   fmedian*stdev * sqrt(fabs(dist)) )
00810         {
00811             pdata[i] = dist ;
00812         }
00813         else
00814         {
00815             cpl_free (value) ;
00816             cpl_free (position) ;
00817             continue ;
00818         }
00819 
00820         cpl_free (value) ;
00821         cpl_free (position) ;
00822     }
00823     cpl_free(pix_dist);
00824     return image ;
00825 }
00826 
00827 
00828 
00829 
00830 
00831 
00832 /*----------------------------------------------------------------------------
00833    Function:       sinfo_new_local_median_image()
00834    In      :       im: input image
00835                    fmedian:  a factor to the local standard deviation
00836                    loReject, hiReject: fraction of rejected values to determine
00837                                        a clean standard deviation
00838                    half_box_size: integer half size of the running box to 
00839                               determine the local clean standard deviation
00840    Out     :       resulting image
00841    Job     :       filter, calculates the local stdev in a moving box
00842                    Then it calculates the difference of the pixel to the median
00843                    of the nearest neighbors
00844                    by using the 8 closest pixels of every pixel.
00845                    The values in the output image are determined according
00846                    to the values of the input parameter.
00847                    If fmedian = 0: always replace by median
00848                    if fmedian < 0: replace median if |median_dist - dist| >
00849                                    fmedian * stdev 
00850                    if fmedian > 0: replace by median (fmedian as a factor of
00851                                    the square root of the median itself)
00852                                    if |pixel - median| >= fmedian*sqrt(median)
00853                    This can be used to consider photon noise.
00854                    This considers a dependence of the differences on the
00855                    pixel values themselves.
00856    Notice       :  it is assumed that most of the 8 nearest neighbor pixels
00857                    are not bad pixels!
00858                    blank pixels are not replaced!
00859  ---------------------------------------------------------------------------*/
00860 
00861 cpl_image * sinfo_new_local_median_image( cpl_image * im, 
00862                              float fmedian, 
00863                              float loReject,
00864                              float hiReject,
00865                              int half_box_size )
00866 {
00867     cpl_image *   image       ;
00868     pixelvalue * value       ;
00869     pixelvalue   median      ;
00870     int        * position    ;
00871     int          nposition   ;
00872     int          n, i, j ;
00873     int          llx, lly, urx, ury ;
00874     Stats *      stats ;
00875     int lx=0;
00876     int ly=0;
00877     float* pidata=NULL;
00878     float* podata=NULL;
00879 
00880     if ( im == NULL )
00881     {
00882         sinfo_msg_error ("no image input") ;
00883         return NULL ;
00884     }
00885     if ( half_box_size < 0 )
00886     {
00887         sinfo_msg_error ("negativ box_size given") ;
00888         return NULL ;
00889     }
00890 
00891     image = cpl_image_duplicate ( im ) ;
00892     lx=cpl_image_get_size_x(im);
00893     ly=cpl_image_get_size_y(im);
00894     pidata=cpl_image_get_data(im);
00895     podata=cpl_image_get_data(image);
00896     /*----------------------------------------------------------------------
00897      * go through all pixels
00898      */
00899 
00900     for ( i = 0 ; i < (int) lx*ly ; i++ )
00901     {
00902         /* blank pixels are not replaced */
00903         if ( isnan(pidata[i]) )
00904         {
00905             continue ;
00906         }
00907 
00908         /* compute the image statistics in the box area */
00909         llx = i%lx - half_box_size ; 
00910         if ( llx < 0 ) llx = 0 ;
00911         lly = i%ly - half_box_size ;
00912         if ( lly < 0 ) lly = 0 ;
00913         urx = i%lx + half_box_size ; 
00914         if ( urx >= lx ) urx = lx - 1 ;
00915         ury = i%ly + half_box_size ;
00916         if ( ury >= ly ) ury = ly - 1 ;
00917 
00918         if ( NULL == (stats = sinfo_new_image_stats_on_rectangle (im, loReject,
00919                                hiReject, llx, lly, urx, ury)) ) 
00920         {
00921             sinfo_msg_warning("could not determine image statistics ");
00922             sinfo_msg_warning("in pixel %d", i) ;
00923             continue ;
00924         }
00925 
00926         /* initialize the buffer variables for the 8 nearest neighbors */
00927         value = (pixelvalue * )cpl_calloc ( 8, sizeof ( pixelvalue * ) ) ;
00928         position = ( int * ) cpl_calloc ( 8, sizeof ( int * ) ) ;
00929 
00930         /*----------------------------------------------------------------------
00931          * determine the pixel position of the 8 nearest neighbors
00932          */
00933 
00934         position[0] = i + lx - 1 ; /* upper left  */
00935         position[1] = i + lx     ; /* upper       */
00936         position[2] = i + lx + 1 ; /* upper right */
00937         position[3] = i + 1            ; /* right       */
00938         position[4] = i - lx + 1 ; /* lower right */
00939         position[5] = i - lx     ; /* lower       */
00940         position[6] = i - lx - 1 ; /* lower left  */
00941         position[7] = i - 1            ; /* left        */
00942 
00943         /*---------------------------------------------------------------------
00944          * determine the positions of the image margins, top positions are 
00945          * changed to low positions and vice versa. Right positions are 
00946          * changed to left positions and vice versa.
00947          */
00948 
00949         if ( i >= 0 && i < lx )    /* bottom line */
00950         {
00951             position[4] += 2 * lx ;
00952             position[5] += 2 * lx ;
00953             position[6] += 2 * lx ;
00954         }
00955         else if ( i >= ((int) lx*ly - lx ) && i < (int) lx*ly ) /* top line */
00956         {
00957             position[0] -= 2 * lx ;
00958             position[1] -= 2 * lx ;
00959             position[2] -= 2 * lx ;
00960         }
00961         else if ( i % lx == 0 )    /* left side */
00962         {
00963             position[0] += 2 ;
00964             position[6] += 2 ;
00965             position[7] += 2 ;
00966         }
00967         else if ( i % lx == lx - 1 )    /* right side */
00968         {
00969             position[2] -= 2 ;
00970             position[3] -= 2 ;
00971             position[4] -= 2 ;
00972         }
00973 
00974         /* ------------------------------------------------------------------
00975          * read the pixel values of the neighboring pixels,
00976          * blanks are not considered
00977          */
00978 
00979         nposition = 8 ;
00980         n = 0 ;
00981         for ( j = 0 ; j < nposition ; j ++ )
00982         {
00983             if ( !isnan(pidata[position[j]]) )
00984             {
00985                 value[n] = pidata[position[j]] ;
00986                 n ++ ;
00987             }
00988         }
00989         nposition = n ;
00990 
00991         if ( nposition <= 1 )  /* almost all neighbors are blank */
00992         {
00993             podata[i] = ZERO ;
00994             cpl_free(value) ;
00995             cpl_free(position) ;
00996             cpl_free(stats) ;
00997             continue ;
00998         }
00999 
01000         /* sort the values and determine the median */
01001 
01002         sinfo_pixel_qsort( value, nposition ) ;
01003         if ( nposition % 2 == 1 )
01004         {
01005             median = value [ nposition/2 ] ;
01006         }
01007         else
01008         {
01009             median = ( value [nposition/2 - 1] + value [nposition/2] ) / 2. ;
01010         }
01011 
01012         /* -----------------------------------------------------------------
01013          * replace the pixel value by the median on conditions:
01014          * fmedian = 0: always replace with median.
01015          * fmedian > 0: replace by median (fmedian as a factor of
01016          *              the square root of the median itself)
01017          *              if |pixel - median| >= fmedian * sqrt ( median )
01018          *              considers a dependence on the pixel value.
01019          *              This can be used to consider photon noise.
01020          */
01021 
01022         if ( fmedian == 0 )
01023         {
01024             podata[i] = median ;
01025         }
01026         else if ( fmedian < 0 &&
01027                   fabs ( median - pidata[i] ) >= -fmedian * stats->cleanstdev)
01028         {
01029             podata[i] = median ;
01030         }
01031         else if ( fmedian > 0 &&
01032                   fabs ( median - pidata[i] ) >= fmedian * sqrt(fabs(median)) )
01033         {
01034             podata[i] = median ;
01035         }
01036         else
01037         {
01038             cpl_free (value) ;
01039             cpl_free (position) ;
01040             cpl_free (stats) ;
01041             continue ;
01042         }
01043 
01044         cpl_free (value) ;
01045         cpl_free (position) ;
01046         cpl_free (stats) ;
01047     }
01048     return image ;
01049 }
01050 
01051 
01052 
01053 /*----------------------------------------------------------------------------
01054    Function:       sinfo_new_mean_image_in_spec()
01055    In      :       image, a threshold parameter
01056    Out     :       resulting image
01057    Job     :       mean filter, calculates the mean for an image
01058                    by using the 4 closest pixels of every pixel in spectral 
01059                    direction (column).
01060                    The values in the output image are determined according
01061                    to the values of the input parameter.
01062                    If fmedian = 0: always replace by mean
01063                    if fmedian < 0: replace by mean if |pixel - mean| >
01064                                         -fmedian
01065                    if fmedian > 0: replace by mean (fmedian as a factor of
01066                                    the square root of the mean itself)
01067                                    if |pixel - mean| >= fmedian * sqrt ( mean )
01068                    This can be used to consider photon noise.
01069                    This considers a dependence of the differences on the
01070                    pixel values themselves.
01071    Notice       :  it is assumed that most of the 4 nearest neighbor pixels
01072                    are not bad pixels!
01073                    blank pixels are not replaced!
01074  ---------------------------------------------------------------------------*/
01075 
01076 cpl_image * sinfo_new_mean_image_in_spec( cpl_image * im, float fmedian )
01077 {
01078     cpl_image *   image       ;
01079     pixelvalue * value       ;
01080     pixelvalue   mean      ;
01081     int        * position    ;
01082     int          nposition   ;
01083     int          n, i, j ;
01084     int lx=0;
01085     int ly=0;
01086     float* pidata=NULL;
01087     float* podata=NULL;
01088 
01089     if ( im == NULL )
01090     {
01091         sinfo_msg_error ("no image input") ;
01092         return NULL ;
01093     }
01094 
01095     image = cpl_image_duplicate ( im ) ;
01096     lx=cpl_image_get_size_x(im);
01097     ly=cpl_image_get_size_y(im);
01098     pidata=cpl_image_get_data(im);
01099     podata=cpl_image_get_data(image);
01100 
01101     /*----------------------------------------------------------------------
01102      * go through all pixels
01103      */
01104 
01105     for ( i = 0 ; i < (int) lx*ly ; i++ )
01106     {
01107         /* blank pixels are not replaced */
01108         if ( isnan(pidata[i]) )
01109         {
01110             continue ;
01111         }
01112 
01113         /* initialize the buffer variables for the 2 nearest 
01114            spectral neighbors */
01115         value = (pixelvalue * )cpl_calloc ( 4, sizeof ( pixelvalue * ) ) ;
01116         position = ( int * ) cpl_calloc ( 4, sizeof ( int * ) ) ;
01117 
01118         /*--------------------------------------------------------------------
01119          * determine the pixel position of the 8 nearest neighbors
01120          */
01121 
01122         position[0] = i + lx     ; /* upper       */
01123         position[1] = i + 2*lx   ; /* upper       */
01124         position[2] = i - lx     ; /* lower       */
01125         position[3] = i - 2*lx   ; /* lower       */
01126 
01127         /*-------------------------------------------------------------------
01128          * determine the positions of the image margins, top positions are 
01129          * changed to low positions and vice versa. Right positions are changed
01130          * to left positions and vice versa.
01131          */
01132 
01133         if ( i >= 0 && i < lx )    /* bottom line */
01134         {
01135             position[2] += 2 * lx ;
01136             position[3] += 4 * lx ;
01137         }
01138         else if ( i >= ((int) lx*ly - lx ) && i < (int) lx*ly ) /* top line */
01139         {
01140             position[0] -= 2 * lx ;
01141             position[1] -= 4 * lx ;
01142         }
01143 
01144         /* -------------------------------------------------------------------
01145          * read the pixel values of the neighboring pixels,
01146          * blanks are not considered
01147          */
01148 
01149         nposition = 4 ;
01150         n = 0 ;
01151         for ( j = 0 ; j < nposition ; j ++ )
01152         {
01153             if ( !isnan(pidata[position[j]]) )
01154             {
01155                 value[n] = pidata[position[j]] ;
01156                 n ++ ;
01157             }
01158         }
01159         nposition = n ;
01160 
01161         if ( nposition < 1 )  /* all neighbors are blank */
01162         {
01163             podata[i] = ZERO ;
01164             cpl_free(value) ;
01165             cpl_free(position) ;
01166             continue ;
01167         }
01168 
01169         /* determine the mean */
01170         mean = 0. ;
01171         for ( n = 0 ; n < nposition ; n++ )
01172         {
01173             mean += value[n] ;
01174         }
01175         mean /= (float) nposition ;
01176 
01177         /* -----------------------------------------------------------------
01178          * replace the pixel value by the median on conditions:
01179          * fmedian = 0:","always replace with mean.
01180          * fmedian < 0: interpret as absolute condition:
01181          *              if |pixel - mean| > -fmedian
01182          *              replace with mean.
01183          */
01184 
01185         if ( fmedian == 0 )
01186         {
01187             podata[i] = mean ;
01188         }
01189         else if ( fmedian < 0 &&
01190                   fabs ( mean - pidata[i] ) >= -fmedian )
01191         {
01192             podata[i] = mean ;
01193         }
01194         else if ( fmedian > 0 &&
01195                   fabs ( mean - pidata[i] ) >= fmedian * sqrt(fabs(mean)) )
01196         {
01197             podata[i] = mean ;
01198         }
01199         else
01200         {
01201             cpl_free (value) ;
01202             cpl_free (position) ;
01203             continue ;
01204         }
01205 
01206         cpl_free (value) ;
01207         cpl_free (position) ;
01208     }
01209     return image ;
01210 }
01211 
01212 
01213 
01214 
01215 
01216 

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1