sinfo_merge.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 * schreib  04/07/00  created
00027 */
00028 
00029 /************************************************************************
00030 *   NAME              
00031 *        sinfo_merge.c - merges the rows of two image data frames into
00032 *                  one frame with doubled column length     
00033 *        
00034 *   SYNOPSIS
00035 *   #include "merge.h"
00036 *
00037 *   a) cpl_image * sinfo_sinfo_merge_images ( cpl_image * im1, 
00038 *                               cpl_image * im2, 
00039 *                               cpl_image * res_image )
00040 *
00041 *   1) cpl_image * sinfo_new_remove_general_offset( cpl_image * im1, 
00042 *                                      cpl_image * im2, 
00043 *                                      cpl_image * res_image, 
00044 *                                      int n )
00045 *
00046 *   2) cpl_image * sinfo_new_remove_regional_tilt ( cpl_image * im1,
00047 *                                      cpl_image * im2, 
00048 *                                      cpl_image * res_image )
00049 *
00050 *   3) cpl_image * sinfo_new_remove_column_offset ( cpl_image * im1, 
00051 *                                      cpl_image * im2, 
00052 *                                      cpl_image * res_image )
00053 *
00054 *   4) cpl_image * sinfo_new_remove_residual_tilt ( cpl_image * im2, 
00055                                                    cpl_image * res_image )
00056 *
00057 *   5) cpl_image * sinfo_new_remove_residual_offset( cpl_image * im2, 
00058                                                     cpl_image * res_image )
00059 *
00060 *   DESCRIPTION
00061 *   a) merges the rows of two image frames in a way that the resulting
00062 *      image has double length in y-direction
00063 *
00064 *        The procedures are used in the SPIFFI data reduction to merge two 
00065 *        data frames. In order to fully match the two input frames there
00066 *        are five steps (procedures) foreseen:
00067 *        1) remove general offset between the frames, created by e.g. different
00068 *           air masses. 
00069 *        2) remove regional tilt between frames, created by e.g. different 
00070 *           emissivities.
00071 *        3) remove individual column offsets, created e.g. by imperfect 
00072 *           guiding, offset is divided out.
00073 *        4) remove residual individual column tilts, created by previous 
00074 *           operations.
00075 *        5) remove residual column offsets by subtracting the sinfo_median.
00076 *
00077 *   FILES
00078 *
00079 *   ENVIRONMENT
00080 *
00081 *   RETURN VALUES 
00082 *   always the pointer to the image data structure cpl_image
00083 *
00084 *   CAUTIONS 
00085 *
00086 *   EXAMPLES
00087 *
00088 *   SEE ALSO
00089 *   Python script merging.py
00090 *
00091 *   BUGS   
00092 *
00093 *------------------------------------------------------------------------
00094 */
00095 
00096 #ifdef HAVE_CONFIG_H
00097 #  include <config.h>
00098 #endif
00099 #include "sinfo_vltPort.h"
00100 
00101 /* 
00102  * System Headers
00103  */
00104 
00105 /* 
00106  * Local Headers
00107  */
00108 
00109 #include "sinfo_merge.h"
00110 #include "sinfo_globals.h"
00130 cpl_image * sinfo_sinfo_merge_images ( cpl_image * im1, 
00131                          cpl_image * im2, 
00132                          cpl_image * res_image )
00133 {
00134     cpl_image * out_image ;
00135     cpl_image * residual ;
00136     int i, j ;
00137 
00138     int lx1=0;
00139     int ly1=0;
00140     int lx2=0;
00141     int ly2=0;
00142 
00143 
00144     float* pi1data=NULL;
00145     float* pi2data=NULL;
00146     float* pirdata=NULL;
00147     float* poutdata=NULL;
00148     float* ptmpdata=NULL;
00149 
00150 
00151 
00152     if ( im1 == NULL || im2 == NULL || res_image == NULL)
00153     {
00154         sinfo_msg_error (" null image as input") ;
00155         return NULL ;
00156     }
00157     lx1=cpl_image_get_size_x(im1);
00158     ly1=cpl_image_get_size_y(im1);
00159 
00160     lx2=cpl_image_get_size_x(im2);
00161     ly2=cpl_image_get_size_y(im2);
00162 
00163 
00164 
00165     pi1data=cpl_image_get_data_float(im1);
00166     pi2data=cpl_image_get_data_float(im2);
00167     pirdata=cpl_image_get_data_float(res_image);
00168 
00169 
00170     if ( lx1 != lx2 || ly1 != ly2 )
00171     {
00172         sinfo_msg_error ("input images are not compatible in size") ;
00173         return NULL ;
00174     }
00175 
00176     /* allocate memory */
00177     if ( NULL == (out_image = cpl_image_new (lx1, 2 * ly1,CPL_TYPE_FLOAT)) )
00178     {
00179         sinfo_msg_error (" cannot allocate new image") ;
00180         return NULL ;
00181     }
00182     poutdata=cpl_image_get_data_float(out_image);
00183 
00184     if ( NULL == (residual = cpl_image_new (lx1, ly1,CPL_TYPE_FLOAT)) )
00185     {
00186         sinfo_msg_error (" cannot allocate new image ") ;
00187         return NULL ;
00188     }
00189     ptmpdata=cpl_image_get_data_float(residual);
00190 
00191     /* now compute the final residual image */
00192     for ( i = 0 ; i < (int) lx1*ly1 ; i ++ )
00193     {
00194         if ( isnan(pi1data[i]) || isnan(pi2data[i]) )
00195         {
00196             ptmpdata[i] = ZERO ;
00197         }   
00198         else
00199         {
00200             ptmpdata[i] = pi1data[i] - pi2data[i] ;
00201         }
00202         pirdata[i] = ptmpdata[i] ;
00203     }
00204 
00205     /* now merge the two images */
00206     for ( i = 0 ; i < ly1 ; i ++ )
00207     {
00208         for ( j = 0 ; j < lx1 ; j ++ )
00209         {
00210             /* transfer rows to output */
00211             poutdata[2*i*lx1 + j] = pi1data[i*lx1 + j]  ;
00212             poutdata[(2*i+1) * lx1 + j] = pi2data[i*lx1 + j] ;
00213         }     
00214     }
00215 
00216     cpl_image_delete (residual) ;
00217 
00218     return out_image ;
00219 }
00220     
00221 
00238 cpl_image * sinfo_new_remove_general_offset( cpl_image * im1, 
00239                                 cpl_image * im2, 
00240                                 cpl_image * res_image, 
00241                                 int n )
00242 {
00243     cpl_image * out_image ;
00244     cpl_image * residual  ;
00245     pixelvalue sum, sqr_sum ;
00246     pixelvalue mean, stdev  ;
00247     int i, npix ;
00248 
00249     int lx1=0;
00250     int ly1=0;
00251     int lx2=0;
00252     int ly2=0;
00253     int lxr=0;
00254     int lyr=0;
00255     int lxt=0;
00256     int lyt=0;
00257 
00258     float* pi1data=NULL;
00259     float* pi2data=NULL;
00260     float* pirdata=NULL;
00261     float* poutdata=NULL;
00262     float* ptmpdata=NULL;
00263 
00264 
00265 
00266     if ( im1 == NULL || im2 == NULL )
00267     {
00268         sinfo_msg_error (" null image as input") ;
00269         return NULL ;
00270     }
00271     lx1=cpl_image_get_size_x(im1);
00272     ly1=cpl_image_get_size_y(im1);
00273 
00274     lx2=cpl_image_get_size_x(im2);
00275     ly2=cpl_image_get_size_y(im2);
00276 
00277 
00278 
00279     pi1data=cpl_image_get_data_float(im1);
00280     pi2data=cpl_image_get_data_float(im2);
00281 
00282 
00283     if ( lx1 != lx2 || ly1 != ly2 )
00284     {
00285         sinfo_msg_error (" input images are not compatible in size") ;
00286         return NULL ;
00287     }
00288     
00289     if ( n <= 0 )
00290     {
00291         sinfo_msg_error("number of rows for offset determination "
00292                         "is 0 or smaller ") ;
00293         return NULL ;
00294     }
00295         
00296     /* allocate memory */
00297     if ( NULL == (residual = cpl_image_new (lx1, ly1, CPL_TYPE_FLOAT)) )
00298     {
00299         sinfo_msg_error (" cannot allocate new image ") ;
00300         return NULL ;
00301     }
00302        
00303     out_image = cpl_image_duplicate( im2 ) ;
00304     poutdata=cpl_image_get_data_float(out_image);
00305     ptmpdata=cpl_image_get_data_float(residual);
00306     lxt=cpl_image_get_size_x(residual);
00307     lyt=cpl_image_get_size_y(residual);
00308 
00309     /* ---------------------------------------------------------------------
00310      * first we determine the "good" pixels and subtract the two images 
00311      * then we determine the mean and 3 sigma
00312      */
00313 
00314     sum = 0. ;
00315     sqr_sum = 0. ;
00316     npix = 0 ;
00317     for ( i = 0 ; i < (int) lx1*ly1 ; i ++ )
00318     {
00319         if ( isnan(pi1data[i]) || isnan(pi2data[i]) )
00320         {
00321             ptmpdata[i] = ZERO ;
00322             continue ;
00323         }   
00324         else
00325         {
00326             ptmpdata[i] = pi1data[i] - pi2data[i] ;
00327         }
00328 
00329         sum += ptmpdata[i] ;
00330         sqr_sum += (ptmpdata[i]) * (ptmpdata[i]) ;
00331         npix ++ ;
00332     }
00333     if ( npix <= 1 )
00334     {
00335         mean = 0. ;
00336         stdev = 0. ;
00337     }
00338     else
00339     {
00340         mean = sum / (pixelvalue) npix ;   
00341         /* stdev is 3 sigma */
00342         stdev = 3 * sqrt(( sqr_sum - sum*mean ) / (pixelvalue)(npix - 1)) ;
00343     }
00344     
00345     /* exclude everything > 3 sigma */
00346     
00347     for ( i = 0 ; i < (int) lxt*lyt ; i++ )
00348     {
00349         if ( fabs( ptmpdata[i] - mean ) > stdev )
00350         {
00351             ptmpdata[i] = ZERO ;
00352         }
00353     }
00354     
00355     /* now subtract the general offset which is determined 
00356        as mean of the first n rows */
00357     
00358     sum = 0. ;
00359     npix = 0 ;
00360     for ( i = 0 ; i < n * lxt ; i++ )
00361     {
00362         if ( isnan(ptmpdata[i]) )
00363         {
00364             continue ;
00365         }
00366 
00367         sum += ptmpdata[i] ;
00368         npix ++ ;
00369     }
00370     if ( npix == 0 )
00371     {
00372         mean = 0. ;
00373     }
00374     else
00375     {
00376         mean = sum / (pixelvalue) npix ;      
00377     } 
00378     
00379     /* now apply this to the second input image */
00380     for ( i = 0 ; i < (int) lx2*ly2 ; i++ )
00381     {
00382         if ( isnan(pi2data[i]) )
00383         {
00384             poutdata[i] = ZERO ;
00385             continue ;
00386         }
00387         poutdata[i] = pi2data[i] + mean ;
00388     }    
00389  
00390     /* now determine the residual image if available */
00391     if ( res_image != NULL )
00392     {
00393 
00394        lxr=cpl_image_get_size_x(res_image);
00395        lyr=cpl_image_get_size_y(res_image);
00396        pirdata=cpl_image_get_data_float(res_image);
00397 
00398 
00399         for ( i = 0 ; i < (int) lxt*lyt ; i++ )
00400         {
00401             if ( isnan(ptmpdata[i]) )
00402             {
00403                 pirdata[i] = ZERO ;
00404                 continue ;
00405             }
00406             pirdata[i] = ptmpdata[i] - mean ;
00407         }
00408     }    
00409 
00410     cpl_image_delete (residual) ;
00411 
00412     return out_image ;
00413 }
00414 
00427 cpl_image * sinfo_new_remove_regional_tilt ( cpl_image * im1, 
00428                                 cpl_image * im2, 
00429                                 cpl_image * res_image )
00430 {
00431     cpl_image * out_image ;
00432     cpl_image * filtered  ;
00433     int i, j, k, npix, nrunning ;
00434     pixelvalue a, b, sum, sumx, sumy, sumc, sum2 ;
00435     int lx1=0;
00436     int ly1=0;
00437     int lx2=0;
00438     int ly2=0;
00439     int lxr=0;
00440     int lyr=0;
00441     int lxf=0;
00442     int lyf=0;
00443 
00444     float* pi1data=NULL;
00445     float* pi2data=NULL;
00446     float* pirdata=NULL;
00447     float* poutdata=NULL;
00448     float* pfildata=NULL;
00449 
00450 
00451     if ( im1 == NULL || im2 == NULL || res_image == NULL )
00452     {
00453         sinfo_msg_error ("null image as input") ;
00454         return NULL ;
00455     }
00456     lx1=cpl_image_get_size_x(im1);
00457     ly1=cpl_image_get_size_y(im1);
00458 
00459     lx2=cpl_image_get_size_x(im2);
00460     ly2=cpl_image_get_size_y(im2);
00461 
00462     lxr=cpl_image_get_size_x(res_image);
00463     lyr=cpl_image_get_size_y(res_image);
00464 
00465 
00466     pi1data=cpl_image_get_data_float(im1);
00467     pi2data=cpl_image_get_data_float(im2);
00468     pirdata=cpl_image_get_data_float(res_image);
00469 
00470     if ( lx1 != lx2 || ly1 != ly2 ||
00471          lx2 != lxr || ly2 != lyr )
00472     {
00473         sinfo_msg_error ("input images are not compatible in size") ;
00474         return NULL ;
00475     }
00476 
00477     /* allocate memory */
00478     if ( NULL == ( filtered = cpl_image_new (lx2, ly2,CPL_TYPE_FLOAT)) )
00479     {
00480         sinfo_msg_error ("cannot allocate new image ") ;
00481         return NULL ;
00482     }
00483 
00484     out_image = cpl_image_duplicate( im2 ) ;
00485     poutdata=cpl_image_get_data_float(out_image);
00486     pfildata=cpl_image_get_data_float(filtered);
00487     lxf=cpl_image_get_size_x(filtered);
00488     lyf=cpl_image_get_size_y(filtered);
00489     
00490     /*-------------------------------------------------------------------------
00491      * Now work in the given difference image res_image on each 
00492        column separately. This image is first smoothed columnwise 
00493        by a running box
00494      */
00495     
00496     nrunning = 31 ; /* # of points in the running box, odd number required */
00497 
00498     for ( j = 0 ; j < lyr ; j ++ ) /* select a row */
00499     {
00500         for ( i = 0 ; i < lxr ; i ++ ) /* go through one row */
00501         {
00502             npix = 0 ;
00503             sum = 0. ;
00504             for (k = i - (nrunning-1)/2 ; k < i + (nrunning+1)/2; k ++ )
00505             {
00506                 /* marginal pixels are not considered */
00507                 if ( k < 2 )
00508                 {
00509                     continue ;
00510                 }
00511                 if ( k > (lxr) - 2 )
00512                 {
00513                     break ;
00514 
00515                 }
00516                 if ( isnan(pirdata[j*lxr + k]) )
00517                 {
00518                     continue ;
00519                 }
00520                 npix ++ ;
00521                 sum += pirdata[j*lxr + k] ;
00522             }
00523             if ( npix != 0 )
00524             {
00525                 pfildata[j*lxr + i] = sum/npix ;
00526             }
00527             else
00528             {
00529                 pfildata[j*lxr + i] = ZERO ;
00530             }
00531         }
00532     }                  
00533    
00534     /*------------------------------------------------------------------
00535      * now determine the tilt in each column and remove it in such a way
00536      * that the first rows are used as references that are not changed
00537      * a free regression fit is (index i means the sum over i):
00538      * ax + b: a = [<xiyi>-<xi><yi>]/[<xi^2>-<xi>^2]
00539      * =>    : a = [xiyi - xi<yi>]/[xi^2 - xi<xi>]
00540      *         b = <yi> - a<xi>
00541      */
00542     
00543     for ( i = 0 ; i < lxf ; i ++ ) /* one column selected */
00544     {
00545         sumy = 0. ;                   /* yi   */
00546         sumc = 0. ;                   /* xiyi */
00547         sumx = 0. ;                   /* xi   */
00548         sum2 = 0. ;                   /* xi^2 */
00549         npix = 0  ;  
00550           
00551         for ( j = 0 ; j < lyf ; j ++ ) 
00552         {
00553             if ( isnan(pfildata[i + j*lxf]) )
00554             {
00555                 continue ;
00556             }
00557             sumy +=  pfildata[i + j*lxf] ;
00558             sumc += (pfildata[i + j*lxf]) * j ;
00559             sum2 += j*j ;
00560             sumx += j   ;
00561             npix ++     ;
00562         }
00563         if ( npix > 2 && fabs(sum2 - sumx*sumx/npix) >= 1e-6 ) 
00564         {
00565             a = ( sumc - sumx*sumy/npix ) / ( sum2 - sumx*sumx/npix ) ;
00566             b = ( sumy - a*sumx ) / npix ;
00567         } 
00568         else
00569         {
00570             a = ZERO ;
00571             b = ZERO ;
00572         }
00573 
00574         /*-----------------------------------------------------------
00575          * now correct the second input image im2 and the res_image.
00576          */ 
00577 
00578         if ( !isnan(a) && !isnan(b) && fabs(a) < 1e8 && fabs(b) < 1e8 )
00579         {
00580             for ( j = 0 ; j < lyf ; j ++ ) /* the same column */
00581             {
00582                 if ( !isnan(poutdata[i + j*lxf]) )
00583                 {
00584                     poutdata[i + j*lxf] += a*j+b ;        
00585                 }
00586             }
00587         }
00588     }
00589    
00590     /* now compute the final residual image */
00591     for ( i = 0 ; i < (int) lx1*ly1 ; i ++ )
00592     {
00593         if ( isnan(pi1data[i]) || isnan(poutdata[i]) )
00594         {
00595             pirdata[i] = ZERO ;
00596         }   
00597         else
00598         {
00599             pirdata[i] = pi1data[i] - poutdata[i] ;
00600         }
00601     }
00602 
00603     cpl_image_delete (filtered) ;
00604    
00605     return out_image ;
00606 }
00607 
00608 
00621 cpl_image * sinfo_new_remove_column_offset ( cpl_image * im1, 
00622                                 cpl_image * im2, 
00623                                 cpl_image * res_image )
00624 {
00625     cpl_image * out_image ;
00626     int i, j, npix, nrunning ;
00627     pixelvalue sum, sum2, mean, stdev, median1, median2, ratio ;
00628     pixelvalue * column1, * column2 ;
00629     int lx1=0;
00630     int ly1=0;
00631     int lx2=0;
00632     int ly2=0;
00633     int lxr=0;
00634     int lyr=0;
00635     float* pi1data=NULL;
00636     float* pi2data=NULL;
00637     float* pirdata=NULL;
00638     float* poutdata=NULL;
00639 
00640     if ( im1 == NULL || im2 == NULL || res_image == NULL )
00641     {
00642         sinfo_msg_error ("null image as input") ;
00643         return NULL ;
00644     }
00645     lx1=cpl_image_get_size_x(im1);
00646     ly1=cpl_image_get_size_y(im1);
00647 
00648     lx2=cpl_image_get_size_x(im2);
00649     ly2=cpl_image_get_size_y(im2);
00650 
00651     lxr=cpl_image_get_size_x(res_image);
00652     lyr=cpl_image_get_size_y(res_image);
00653 
00654 
00655     pi1data=cpl_image_get_data_float(im1);
00656     pi2data=cpl_image_get_data_float(im2);
00657     pirdata=cpl_image_get_data_float(res_image);
00658 
00659     if ( lx1 != lx2 || ly1 != ly2 ||
00660          lx2 != lxr || ly2 != lyr )
00661     {
00662         sinfo_msg_error ("input images are not compatible in size") ;
00663         return NULL ;
00664     }
00665 
00666     out_image = cpl_image_duplicate( im2 ) ;
00667     poutdata=cpl_image_get_data_float(out_image);
00668 
00669     /*------------------------------------------------------------------------- 
00670      *  now we deal with a constant offset in every column. We assume that it 
00671         is due to redistribution of the flux. So we should divide the offset 
00672         out.  The ratio is derived from the medians of the contributions 
00673         rather than the means.
00674      */
00675 
00676     for ( i = 0 ; i < lx2 ; i ++ ) /* select a column */
00677     {
00678         /* statistics on columns */
00679         sum  = 0.  ;
00680         sum2 = 0. ;
00681         npix = 0  ;
00682         for ( j = 0 ; j < ly2 ; j ++ )
00683         {
00684             /* first select only the good pixels */
00685             if ( isnan(pirdata[i + j*lxr]) )
00686             {
00687                 continue ;
00688             }
00689             sum  += pirdata[i + j*lxr] ;
00690             sum2 += pirdata[i + j*lxr] * 
00691                     pirdata[i + j*lxr] ; 
00692             npix ++ ;
00693         }
00694         if ( npix <= 1 )
00695         {
00696             continue ;
00697         }
00698         else
00699         {
00700             mean  = sum/(pixelvalue) npix ;
00701             if ( (sum2 - sum * mean) < 0 )
00702             {
00703                 sinfo_msg_error ("variance is negative") ; 
00704                 continue ;
00705             }
00706             else
00707             {
00708                 /* 2 sigma */
00709                 stdev = 2 * sqrt ( (sum2 - sum*mean)/(pixelvalue)(npix - 1) ) ;
00710             }
00711         }
00712 
00713         /* do it only if the S/N is high enough */
00714         if ( fabs(mean)/stdev < 0.5 )
00715         {
00716             continue ;
00717         }
00718 
00719         /* exclude everything > 2 sigma */
00720         for ( j = 0 ; j < lyr ; j ++ )
00721         {
00722             if ( pirdata[i + j*lxr] < mean - stdev ||
00723                  pirdata[i + j*lxr] > mean + stdev )
00724             {
00725                 pirdata[i + j*lxr] = ZERO ;
00726             }
00727         } 
00728         
00729         /* now deal with the offset */
00730         median1 = 0. ;
00731         median2 = 0. ;
00732         nrunning = 0 ;
00733         /* allocate memory for the column buffers */
00734         column1 = (pixelvalue *) cpl_calloc ( ly1 , sizeof (pixelvalue *) ) ;
00735         column2 = (pixelvalue *) cpl_calloc ( ly2 , sizeof (pixelvalue *) ) ; 
00736 
00737         for ( j = 0 ; j < lyr ; j++ ) /* go through one column */
00738         {
00739             if ( isnan(pirdata[i + j*lxr]) )
00740             {
00741                 continue ;
00742             }
00743             if ( isnan(pi1data[i+j*lx1]) || isnan(pi2data[i+j*lx2]) )
00744             {
00745                 continue ;
00746             }
00747         column1[nrunning] = pi1data[i + j*lx1] ;
00748             column2[nrunning] = pi2data[i + j*lx2] ;
00749             nrunning ++ ;
00750         }
00751 
00752         /* change the second input image only if there are more then 
00753            10 % good pixels in a column */
00754         if ( nrunning > 0.1*lyr )
00755         {
00756             /* --------------------------------------------------------------
00757              * determine the medians of the columns of both images and compute 
00758                the ratio, the columns of the second input image are multiplied 
00759                by this ratio to adjust the column offsets. 
00760              */
00761             median2 = sinfo_new_median( column2, nrunning ) ;
00762             if ( median2 != 0. )
00763             {
00764                 median1 = sinfo_new_median( column1, nrunning ) ;
00765                 ratio = median1 / median2 ;
00766                 if ( ratio > 0 )
00767                 {
00768                     for ( j = 0 ; j < ly2 ; j++ ) /* go through one column */
00769                     {
00770                         if ( !isnan(pi2data[i + j*lx2]) )
00771                         {
00772                             poutdata[i + j*lx2] = pi2data[i + j*lx2] * ratio ;
00773                         }
00774                         else
00775                         {
00776                             poutdata[i + j*lx2] = ZERO ;
00777                         }
00778                     }
00779                 }
00780             }
00781         }   
00782         cpl_free ( column1 ) ;
00783         cpl_free ( column2 ) ;
00784     }
00785 
00786     /* now compute the final residual image */
00787     for ( i = 0 ; i < (int) lx1*ly1 ; i ++ )
00788     {
00789         if ( isnan(pi1data[i]) || isnan(poutdata[i]) )
00790         {
00791             pirdata[i] = ZERO ;
00792         }   
00793         else
00794         {
00795             pirdata[i] = pi1data[i] - poutdata[i] ;
00796         }
00797     }
00798    
00799     return out_image ;
00800 }
00801 
00802 
00812 cpl_image * 
00813 sinfo_new_remove_residual_tilt ( cpl_image * im2, cpl_image * res_image )
00814 {
00815     cpl_image * out_image ;
00816     cpl_image * residual  ;
00817     int i, j, npix ;
00818     pixelvalue a, b, sum, sumx, sumy, sumc, sum2, mean, stdev ;
00819     int lx2=0;
00820     int ly2=0;
00821     int rlx=0;
00822     int rly=0;
00823     float* pi2data=NULL;
00824     float* pirdata=NULL;
00825     float* poutdata=NULL;
00826     float* ptmpdata=NULL;
00827 
00828 
00829 
00830 
00831     if ( im2 == NULL || res_image == NULL )
00832     {
00833         sinfo_msg_error ("null image as input") ;
00834         return NULL ;
00835     }
00836     lx2=cpl_image_get_size_x(im2);
00837     ly2=cpl_image_get_size_y(im2);
00838     rlx=cpl_image_get_size_x(res_image);
00839     rly=cpl_image_get_size_y(res_image);
00840     pi2data=cpl_image_get_data_float(im2);
00841     pirdata=cpl_image_get_data_float(res_image);
00842 
00843     if ( lx2 != rlx || ly2 != rly )
00844     {
00845         sinfo_msg_error ("input images are not compatible in size") ;
00846         return NULL ;
00847     }
00848 
00849     out_image = cpl_image_duplicate( im2 ) ;
00850     residual  = cpl_image_duplicate( res_image ) ;
00851     poutdata=cpl_image_get_data_float(out_image);
00852     ptmpdata=cpl_image_get_data_float(residual);
00853 
00854     for ( i = 0 ; i < lx2; i++ ) /* select one column */
00855     {
00856         sum  = 0. ;
00857         sum2 = 0. ;
00858         npix = 0  ;
00859         for ( j = 0 ; j < ly2 ; j++ ) 
00860         {
00861             /* first select good pixels and derive the mean 
00862                and sigma of each column */
00863             if ( isnan(pirdata[i + j*rlx]) )
00864             {
00865                 continue ;
00866             }
00867             sum  += pirdata[i + j*rlx] ;
00868             sum2 += pirdata[i + j*rlx] *
00869                     pirdata[i + j*rlx] ;
00870             npix ++ ;
00871         }
00872         
00873         if ( npix <= 1 )
00874         {
00875             continue ;
00876         }
00877         else
00878         {
00879             mean  = sum / (pixelvalue) npix ;
00880             stdev = 1.5 * sqrt( (sum2 - sum*mean) / (pixelvalue)(npix - 1) ) ;
00881         }
00882  
00883         /* exclude everything > 1.5 sigma */
00884         for ( j = 0 ; j < ly2 ; j++ )
00885         {
00886             if ( pirdata[i + j*rlx] < mean - stdev ||
00887                  pirdata[i + j*rlx] > mean + stdev )
00888             {
00889                 pirdata[i + j*rlx] = ZERO ;
00890             }
00891         }
00892 
00893         /* now determine the tilt, see function sinfo_removeRegionalTilt 
00894            for explanation */
00895         sumy = 0. ;                   /* yi   */
00896         sumc = 0. ;                   /* xiyi */
00897         sumx = 0. ;                   /* xi   */
00898         sum2 = 0. ;                   /* xi^2 */
00899         npix = 0  ;  
00900           
00901         for ( j = 0 ; j < rly ; j ++ ) 
00902         {
00903             if ( isnan(pirdata[i + j*rlx]) )
00904             {
00905                 continue ;
00906             }
00907             sumy +=  pirdata[i + j*rlx] ;
00908             sumc += (pirdata[i + j*rlx]) * j ;
00909             sum2 += j*j ;
00910             sumx += j   ;
00911             npix ++     ;
00912         }
00913         if ( npix > 2 && fabs(sum2 - sumx*sumx/npix) >= 1e-6 ) 
00914         {
00915             a = ( sumc - sumx*sumy/npix ) / ( sum2 - sumx*sumx/npix ) ;
00916             b = ( sumy - a*sumx ) / npix ;
00917         } 
00918         else
00919         {
00920             a = ZERO ;
00921             b = ZERO ;
00922         }
00923 
00924         /*-------------------------------------------------------------------
00925          * now correct the second input image im2 and the res_image.
00926          */ 
00927 
00928         if ( !isnan(a) && !isnan(b) && fabs(a) < 1e8 && fabs(b) < 1e8 )
00929         {
00930             for ( j = 0 ; j < ly2 ; j ++ ) /* the same column */
00931             {
00932                 if ( !isnan(poutdata[i+j*lx2]) )
00933                 {
00934                     poutdata[i + j*lx2] += a*j+b ;        
00935                     pirdata[i + j*lx2] = ptmpdata[i + j*lx2] -(a*j+b) ;
00936                 }
00937             }
00938         }
00939     }
00940 
00941     cpl_image_delete (residual) ;
00942 
00943     return out_image ;
00944 }
00945 
00946 
00957 cpl_image * 
00958 sinfo_new_remove_residual_offset( cpl_image * im2, cpl_image * res_image )
00959 {
00960     cpl_image * out_image ;
00961     int i, j, npix ;
00962     pixelvalue res_median ;
00963     pixelvalue * column ;
00964     int lx2=0;
00965     int ly2=0;
00966     int rlx=0;
00967     int rly=0;
00968     int olx=0;
00969     int oly=0;
00970     float* pi2data=NULL;
00971     float* pirdata=NULL;
00972     float* poudata=NULL;
00973 
00974 
00975     if ( im2 == NULL || res_image == NULL )
00976     {
00977         sinfo_msg_error ("null image as input") ;
00978         return NULL ;
00979     }
00980     lx2=cpl_image_get_size_x(im2);
00981     ly2=cpl_image_get_size_y(im2);
00982     rlx=cpl_image_get_size_x(res_image);
00983     rly=cpl_image_get_size_y(res_image);
00984     pi2data=cpl_image_get_data_float(im2);
00985     pirdata=cpl_image_get_data_float(res_image);
00986 
00987 
00988     if ( lx2 != rlx || ly2 != rly )
00989     {
00990         sinfo_msg_error ("input images are not compatible in size") ;
00991         return NULL ;
00992     }
00993 
00994     out_image = cpl_image_duplicate( im2 ) ;
00995     poudata=cpl_image_get_data_float(res_image);
00996     olx=cpl_image_get_size_x(res_image);
00997     oly=cpl_image_get_size_y(res_image);
00998 
00999     column = (pixelvalue *) cpl_calloc ( ly2 , sizeof (pixelvalue *) ) ;
01000     
01001     for ( i = 0 ; i < lx2 ; i++ ) /* select one column */
01002     {
01003         npix = 0  ;
01004     for (j=0;j<ly2;j++)
01005         column[j]=0;
01006 
01007         for ( j = 0 ; j < rly ; j++ ) /* go through one column */
01008         {
01009             if ( isnan(pirdata[i + j*rlx]) )
01010             {
01011                 continue ;
01012             }
01013    
01014             column[npix] = pirdata[i + j*rlx] ;
01015             npix ++ ;
01016         }
01017             
01018         /* determine the sinfo_median of a column of the residual image */
01019         if ( npix > 0.1 * rly )
01020         {
01021             res_median = sinfo_new_median( column, npix ) ;
01022         }
01023         else
01024         {
01025             continue ;
01026         }
01027         
01028         for ( j = 0 ; j < ly2 ; j++ ) /* go through one column */
01029         {
01030             if ( !isnan(pi2data[i+j*lx2]))
01031             {
01032                 poudata[i + j*lx2] = pi2data[i + j*lx2] + res_median ;
01033             }
01034             else
01035             {
01036                 poudata[i + j*lx2] = ZERO ;
01037             }
01038             if ( !isnan(pirdata[i + j*rlx]) )
01039             {
01040                 pirdata[i + j*rlx] -= res_median ;
01041             }
01042         }
01043     }
01044     cpl_free ( column ) ;
01045     return out_image ;
01046 }
01048 /*___oOo___*/

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