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

Generated on 8 Mar 2011 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1