00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 #ifdef HAVE_CONFIG_H
00200 # include <config.h>
00201 #endif
00202 #include "sinfo_vltPort.h"
00203
00204
00205
00206
00207 #include <errno.h>
00208
00209
00210
00211
00212 #include "sinfo_image_ops.h"
00213 #include "sinfo_error.h"
00214 #include "sinfo_resampling.h"
00215 #include "sinfo_local_types.h"
00216 #include "sinfo_utils_wrappers.h"
00217
00225 static cpl_image *
00226 sinfo_gen_lowpass(const int xs,
00227 const int ys,
00228 const double sigma_x,
00229 const double sigma_y);
00230
00231
00232 static void quicksort_int(int* data, int left, int right);
00235
00236
00237
00238
00239
00240
00252 cpl_error_code
00253 sinfo_image_line_corr(const int width,
00254 const int filt_rad,
00255 const int kappa,
00256 cpl_image* ima_in,
00257 cpl_image** ima_out)
00258 {
00259
00260 cpl_image* mask=NULL;
00261
00262 cpl_image* ima_backpix=NULL;
00263 cpl_image* ima_backpos=NULL;
00264 cpl_image* ima_ybackpix=NULL;
00265 cpl_image* ima_diffbackpix=NULL;
00266 cpl_image* ima_filt=NULL;
00267 cpl_image* ima = NULL;
00268
00269 cpl_matrix* filter=NULL;
00270
00271 cpl_mask* bpm_bad=NULL;
00272
00273 int sx=0;
00274 int sy=0;
00275 int i=0;
00276 int j=0;
00277 int k=0;
00278 double med_back=0;
00279 double sigma_back=0;
00280 double medvalue=0;
00281
00282 float* pima=NULL;
00283 float* ppix=NULL;
00284 float* pmsk=NULL;
00285 int* ppos=NULL;
00286 int* pbackpix=NULL;
00287 cpl_binary* pbin=NULL;
00288 double tot=0;
00289 double mean=0;
00290 int* ybad=NULL;
00291
00292 int nrow=0;
00293 int nbad=0;
00294 int yval=0;
00295 int yprev=0;
00296
00297
00298 check_nomsg(sx=cpl_image_get_size_x(ima_in));
00299 check_nomsg(sy=cpl_image_get_size_y(ima_in));
00300 check_nomsg(*ima_out=cpl_image_duplicate(ima_in));
00301
00302 check_nomsg(mask=cpl_image_new(sx,sy,CPL_TYPE_FLOAT));
00303 check_nomsg(pmsk=cpl_image_get_data_float(mask));
00304
00305 for(i=0;i<width;i++) {
00306 for(j=width;j<sy-width;j++) {
00307 pmsk[j*sx+i]=1;
00308 }
00309 }
00310
00311 for(i=sx-width;i<sx;i++) {
00312 for(j=width;j<sy-width;j++) {
00313 pmsk[j*sx+i]=1;
00314 }
00315 }
00316 sinfo_free_image(&mask);
00317
00318
00319 nrow=2*width*(sy-2*width);
00320 check_nomsg(ima_backpix=cpl_image_new(nrow,1,CPL_TYPE_FLOAT));
00321 check_nomsg(ima_backpos=cpl_image_new(nrow,1,CPL_TYPE_INT));
00322
00323 check_nomsg(pima=cpl_image_get_data_float(ima_in));
00324 check_nomsg(ppix=cpl_image_get_data_float(ima_backpix));
00325 check_nomsg(ppos=cpl_image_get_data_int(ima_backpos));
00326
00327 k=0;
00328 for(i=0;i<width;i++) {
00329 for(j=width;j<sy-width;j++) {
00330 ppix[k]=pima[j*sx+i];
00331 ppos[k]=j*sx+i;
00332 k++;
00333 }
00334 }
00335
00336 for(i=sx-width;i<sx;i++) {
00337 for(j=width;j<sy-width;j++) {
00338 ppix[k]=pima[j*sx+i];
00339 ppos[k]=j*sx+i;
00340 k++;
00341 }
00342 }
00343
00344 check_nomsg(ima_ybackpix=cpl_image_duplicate(ima_backpos));
00345 sinfo_free_image(&ima_backpos);
00346
00347 check_nomsg(pbackpix=cpl_image_get_data_int(ima_ybackpix));
00348
00349 check_nomsg(cpl_image_divide_scalar(ima_ybackpix,sx));
00350 check_nomsg(pbackpix=cpl_image_get_data_int(ima_ybackpix));
00351
00352
00353 check_nomsg(med_back=cpl_image_get_median(ima_backpix));
00354 check_nomsg(ima_diffbackpix=cpl_image_duplicate(ima_backpix));
00355 check_nomsg(cpl_image_subtract_scalar(ima_diffbackpix,med_back));
00356
00357
00358
00359 check_nomsg(filter=cpl_matrix_new(1,filt_rad));
00360 check_nomsg(cpl_matrix_fill(filter,1.));
00361 check_nomsg(ima_filt=sinfo_image_filter_median(ima_diffbackpix,filter));
00362 sinfoni_free_matrix(&filter);
00363
00364
00365
00366
00367 check_nomsg(sigma_back=cpl_image_get_stdev(ima_filt));
00368 sinfo_free_image(&ima_filt);
00369
00370 check_nomsg(ima=cpl_image_duplicate(ima_diffbackpix));
00371 sinfo_free_image(&ima_diffbackpix);
00372
00373 check_nomsg(cpl_image_abs(ima));
00374
00375
00376 check_nomsg(bpm_bad=cpl_mask_threshold_image_create(ima,kappa*sigma_back,
00377 SINFO_DBL_MAX));
00378
00379
00380
00381
00382 check_nomsg(cpl_image_reject_from_mask(ima_backpix,bpm_bad));
00383 check_nomsg(medvalue=cpl_image_get_median(ima_backpix));
00384 check_nomsg(nbad=cpl_mask_count(bpm_bad));
00385
00386 check_nomsg(cpl_image_reject_from_mask(ima_backpix,bpm_bad));
00387 sinfo_free_image(&ima_backpix);
00388
00389 yprev=-1;
00390
00391 check_nomsg(pbin=cpl_mask_get_data(bpm_bad));
00392 check_nomsg(pbackpix=cpl_image_get_data_int(ima_ybackpix));
00393 cpl_msg_debug(cpl_func, "%d lines detected", nbad);
00394 if(nbad)
00395 {
00396
00397 ybad = cpl_calloc(nbad,sizeof(int));
00398 k=0;
00399
00400 for(i=0;i<nrow;i++) {
00401 if(pbin[i] == CPL_BINARY_1) {
00402 ybad[k]=pbackpix[i] + 1;
00403 k++;
00404 }
00405 }
00406 sinfo_free_mask(&bpm_bad);
00407 sinfo_free_image(&ima_ybackpix);
00408
00409 quicksort_int(&(ybad[0]), 0, nbad-1);
00410 yprev=-1;
00411 for(k=0;k<nbad;k++) {
00412 yval=ybad[k];
00413 if(yval == yprev) {
00414 sinfo_msg_debug("skyp %d",yval);
00415 }
00416 else {
00417 yprev=yval;
00418 sinfo_msg_debug("correct raw %d",yval);
00419 check_nomsg(tot=cpl_image_get_flux_window(ima_in,1,yval,width,yval));
00420 check_nomsg(tot+=cpl_image_get_flux_window(ima_in,sx-width+1,
00421 yval,sx,yval));
00422 mean=tot/(2. * width);
00423 check_nomsg(pima=cpl_image_get_data_float(*ima_out));
00424 for(i=width;i<sx-width;i++) {
00425 pima[i+(yval-1)*sx]+=(float)(mean-medvalue);
00426 }
00427
00428 }
00429 }
00430 }
00431
00432
00433 cleanup:
00434
00435 sinfo_free_image(&mask);
00436 sinfo_free_image(&ima_backpos);
00437 sinfoni_free_matrix(&filter);
00438 sinfo_free_image(&ima_filt);
00439 sinfo_free_image(&ima_diffbackpix);
00440
00441 sinfo_free_image(&ima_backpix);
00442 sinfo_free_mask(&bpm_bad);
00443 sinfo_free_image(&ima_ybackpix);
00444 cpl_image_delete(ima);
00445 cpl_free(ybad);
00446 return cpl_error_get_code();
00447
00448 }
00449
00450
00459 double sinfo_new_my_median_image(cpl_image* im)
00460 {
00461 double m=0;
00462 register int i=0;
00463 int n=0;
00464 pixelvalue* pv=0;
00465 int ilx=0;
00466 int ily=0;
00467 float* pidata=NULL;
00468
00469
00470 if(im==NULL) sinfo_msg_error("Null Image");
00471 ilx=cpl_image_get_size_x(im);
00472 ily=cpl_image_get_size_y(im);
00473 pidata=cpl_image_get_data_float(im);
00474
00475 for ( i = 0 ; i < (int) ilx*ily ; i++ )
00476 {
00477 if ( isnan(pidata[i]) )
00478 {
00479
00480 } else {
00481 n++;
00482 }
00483 }
00484 pv = cpl_calloc(n,sizeof(pixelvalue));
00485 n=0;
00486 for ( i = 0 ; i < (int) ilx*ily ; i++ )
00487 {
00488 if ( isnan(pidata[i]) )
00489 {
00490
00491 } else {
00492 pv[n]=pidata[i];
00493 n++;
00494 }
00495 }
00496 if(pv == NULL || n == 0) {
00497 m=0;
00498 } else {
00499 m=sinfo_new_median(pv,n);
00500 }
00501 cpl_free(pv);
00502 if(isnan(m)){
00503 m=0;
00504 }
00505 return m;
00506 }
00507
00516 Vector * sinfo_new_mean_of_columns( cpl_image *im )
00517 {
00518 Vector * row=NULL ;
00519 int i=0;
00520 int j=0;
00521 int ilx=0;
00522 int ily=0;
00523 float* pidata=NULL;
00524
00525 if ( im == NULL )
00526 {
00527 sinfo_msg_error ("null image") ;
00528 return NullVector ;
00529 }
00530 ilx=cpl_image_get_size_x(im);
00531 ily=cpl_image_get_size_y(im);
00532 pidata=cpl_image_get_data_float(im);
00533
00534
00535 if ( NULL == (row = sinfo_new_vector (ilx)) )
00536 {
00537 sinfo_msg_error ("not able to allocate a sinfo_vector" ) ;
00538 return NullVector ;
00539 }
00540
00541 for ( i = 0 ; i < ilx ; i++ )
00542 {
00543 for ( j = 0 ; j < ily ; j++ )
00544 {
00545 if (!isnan(pidata[i+j*ilx]))
00546 {
00547 row->data[i] += pidata[i + j*(ilx)] ;
00548 }
00549 }
00550
00551 row->data[i] /= ily ;
00552 }
00553 return row ;
00554 }
00566 cpl_image * sinfo_new_clean_mean_of_columns( cpl_image *im,
00567 float lo_reject,
00568 float hi_reject)
00569 {
00570 cpl_image * row=NULL ;
00571 pixelvalue* buffer=NULL ;
00572 int i=0;
00573 int j=0;
00574 int k=0;
00575 int nv=0;
00576 int lo_n=0;
00577 int hi_n=0;
00578 int ilx=0;
00579 int ily=0;
00580 float* pidata=NULL;
00581 float* podata=NULL;
00582
00583 if ( im == NULL )
00584 {
00585 sinfo_msg_error ("null image") ;
00586 return NULL ;
00587 }
00588 ilx=cpl_image_get_size_x(im);
00589 ily=cpl_image_get_size_y(im);
00590 pidata=cpl_image_get_data_float(im);
00591
00592 if ((lo_reject + hi_reject) > 0.9)
00593 {
00594 sinfo_msg_error("illegal rejection thresholds: [%f] and [%f]",
00595 lo_reject, hi_reject) ;
00596 sinfo_msg_error("threshold sum should not be over "
00597 "0.90 aborting average") ;
00598 return NULL ;
00599 }
00600
00601 lo_n = (int) (ily * lo_reject + 0.5) ;
00602 hi_n = (int) (ily * hi_reject + 0.5) ;
00603 if (lo_n + hi_n >= ily)
00604 {
00605 sinfo_msg_error ("everything would be rejected") ;
00606 return NULL ;
00607 }
00608
00609
00610 if ( NULL == (row = cpl_image_new (ilx, 1,CPL_TYPE_FLOAT)) )
00611 {
00612 sinfo_msg_error ("cannot allocate new image") ;
00613 return NULL ;
00614 }
00615 podata=cpl_image_get_data_float(row);
00616
00617 buffer=(pixelvalue*) cpl_calloc(ily,sizeof(pixelvalue)) ;
00618
00619 for ( i = 0 ; i < ilx ; i++ )
00620 {
00621 for ( j = 0 ; j < ily ; j++ )
00622 {
00623 buffer[j] = pidata[i + j*(ilx)] ;
00624 }
00625 sinfo_pixel_qsort (buffer, ily) ;
00626
00627 nv = 0 ;
00628 for (k = lo_n ; k < ily - hi_n ; k ++)
00629 {
00630 if ( !isnan(buffer[k]) )
00631 {
00632 podata[i] += buffer[k] ;
00633 nv ++ ;
00634 }
00635 }
00636 podata[i] /= nv ;
00637
00638 }
00639 cpl_free(buffer);
00640 return row ;
00641 }
00642
00643
00653 cpl_image * sinfo_new_div_image_by_row( cpl_image *im, Vector *row )
00654 {
00655 cpl_image *image=NULL ;
00656 int i=0;
00657 int j=0;
00658 int ilx=0;
00659 int ily=0;
00660 float* pidata=NULL;
00661 float* podata=NULL;
00662
00663 if ( im == NULL || row == NULL )
00664 {
00665 sinfo_msg_error ("null image or null row") ;
00666 return NULL ;
00667 }
00668 ilx=cpl_image_get_size_x(im);
00669 ily=cpl_image_get_size_y(im);
00670 pidata=cpl_image_get_data_float(im);
00671
00672 if ( ilx != row -> n_elements )
00673 {
00674 sinfo_msg_error("image and row size not compatible") ;
00675 return NULL ;
00676 }
00677
00678 if ( NULL == (image = cpl_image_duplicate (im)) )
00679 {
00680 sinfo_msg_error ("cannot copy image") ;
00681 return NULL ;
00682 }
00683 podata=cpl_image_get_data_float(image);
00684
00685 for (i = 0 ; i < ilx ; i++ )
00686 {
00687 for (j = 0 ; j < ily ; j++)
00688 {
00689 if ( !isnan(pidata[i + j*(ilx)]) )
00690 {
00691 podata[i + j*(ilx)] = pidata[i + j*(ilx)] / row -> data[i] ;
00692 }
00693 }
00694 }
00695 return image ;
00696 }
00697
00698
00708 cpl_image * sinfo_new_mult_row_to_image( cpl_image *im, Vector *row )
00709 {
00710 cpl_image *image=NULL;
00711 int i=0;
00712 int j=0;
00713 int ilx=0;
00714 int ily=0;
00715 float* pidata=NULL;
00716 float* podata=NULL;
00717
00718
00719
00720
00721 if ( im == NULL || row == NULL )
00722 {
00723 sinfo_msg_error ("null image or null row") ;
00724 return NULL ;
00725 }
00726 ilx=cpl_image_get_size_x(im);
00727 ily=cpl_image_get_size_y(im);
00728 pidata=cpl_image_get_data_float(im);
00729
00730 if ( ilx != row -> n_elements )
00731 {
00732 sinfo_msg_error("image and row size not compatible") ;
00733 return NULL ;
00734 }
00735
00736 if ( NULL == (image = cpl_image_duplicate (im)) )
00737 {
00738 sinfo_msg_error ("cannot copy image") ;
00739 return NULL ;
00740 }
00741 podata=cpl_image_get_data_float(image);
00742
00743 for (i = 0 ; i < ilx ; i++ )
00744 {
00745 for (j = 0 ; j < ily ; j++)
00746 {
00747 if ( !isnan(pidata[i + j*(ilx)]) )
00748 {
00749 podata[i + j*(ilx)] = pidata[i + j*(ilx)] * row -> data[i] ;
00750 }
00751 }
00752 }
00753 return image ;
00754 }
00755
00756
00757
00758
00759
00760
00784 cpl_image * sinfo_new_col_tilt ( cpl_image * image, float sigmaFactor )
00785 {
00786 cpl_image * im=NULL;
00787 float * column=NULL ;
00788 double sum=0;
00789 double sum2=0;
00790 double mean=0;
00791 float sinfo_median=0;
00792 float noise=0 ;
00793 float * sig=NULL;
00794 float * dat=NULL;
00795 float a=0;
00796 float b=0;
00797 float siga=0;
00798 float sigb=0;
00799 float chi2=0;
00800 float q=0;
00801 int i=0;
00802 int j=0;
00803 int colnum=0;
00804 int npix=0;
00805 int mwt=0 ;
00806 int lx=0;
00807 int ly=0;
00808 float* p_in_data=NULL;
00809 float* p_ou_data=NULL;
00810
00811
00812 if ( image == NULL )
00813 {
00814 sinfo_msg_error ("no image given" ) ;
00815 return NULL ;
00816 }
00817
00818 if ( sigmaFactor <= 0. )
00819 {
00820 sinfo_msg_error ("no or negative sigma factor") ;
00821 return NULL ;
00822 }
00823 lx = cpl_image_get_size_x(image);
00824 ly = cpl_image_get_size_y(image);
00825
00826
00827
00828 if ( NULL == (im = cpl_image_new (lx,ly,CPL_TYPE_FLOAT )) )
00829 {
00830 sinfo_msg_error ("cannot allocate new image" ) ;
00831 return NULL ;
00832 }
00833
00834
00835 p_in_data = cpl_image_get_data_float(image);
00836 p_ou_data = cpl_image_get_data_float(im);
00837 for ( i = 0 ; i < lx ; i ++ )
00838 {
00839
00840 colnum = 0 ;
00841 column = (float *) cpl_calloc ( ly , sizeof (float *) ) ;
00842 sig = (float *) cpl_calloc ( ly , sizeof (float *) ) ;
00843 dat = (float *) cpl_calloc ( ly , sizeof (float *) ) ;
00844
00845
00846 for ( j = 0 ; j < ly ; j++ )
00847 {
00848 if ( !isnan(p_in_data[i + j*lx]) )
00849 {
00850 column[j] = p_in_data[i + j*lx] ;
00851 colnum ++ ;
00852 }
00853 }
00854 if ( colnum < 10 )
00855 {
00856
00857
00858 for ( j = 0 ; j < ly ; j++ )
00859 {
00860 p_ou_data[i + j*lx] = ZERO;
00861 }
00862
00863
00864
00865
00866
00867
00868 }
00869
00870
00871
00872
00873
00874
00875
00876 sinfo_pixel_qsort (column, colnum) ;
00877
00878 sum = 0. ;
00879 sum2 = 0. ;
00880 npix = 0 ;
00881
00882 for ( j = 0.1*colnum + 1 ; j <= 0.9*colnum ; j++ )
00883 {
00884 sum += column[j] ;
00885 sum2 += column[j] * column[j] ;
00886 npix ++ ;
00887 }
00888
00889 if (npix <= 1)
00890 {
00891 noise = sigmaFactor * 1000.;
00892 }
00893 else
00894 {
00895 mean = sum/(float)npix ;
00896 noise = sqrt( (sum2 - sum*mean)/(double)(npix -1) ) ;
00897 noise *= sigmaFactor ;
00898 }
00899
00900
00901
00902
00903
00904
00905
00906 if ( colnum % 2 == 1 )
00907 {
00908 sinfo_median = column[colnum/2] ;
00909 }
00910 else
00911 {
00912 sinfo_median = (column[colnum/2 - 1] + column[colnum/2])/2. ;
00913 }
00914
00915
00916
00917 colnum = 0 ;
00918 for ( j = 0; j < ly ; j ++ )
00919 {
00920 if ( !isnan(p_in_data[i+j*lx]) &&
00921 fabs ( (p_in_data[i+j*lx]) - sinfo_median) <= noise )
00922 {
00923 column[colnum] = p_in_data[i+j*lx] ;
00924 dat[colnum] = (float) j ;
00925 sig[colnum] = 1. ;
00926 colnum ++ ;
00927 }
00928 }
00929
00930 if ( colnum == 0 )
00931 {
00932
00933
00934
00935
00936
00937
00938
00939
00940 a=0./0.;
00941 b=0./0.;
00942 }
00943 else
00944 {
00945 mwt = 0 ;
00946 sinfo_my_fit ( dat, column, colnum, sig, mwt, &a,
00947 &b, &siga, &sigb, &chi2, &q ) ;
00948 }
00949 if ( fabs(b) >= SLOPE || fabs(a) >= SATURATION ||
00950 isnan(b) || isnan(a))
00951 {
00952 sinfo_msg_warning ("linear fit: slope is greater than limit: %f"
00953 " saturation level is reached: %f in column"
00954 " number %d ", b, a , i+1) ;
00955 }
00956
00957
00958 for ( j = 0; j < ly; j++ )
00959 {
00960 if ( !isnan(p_in_data[i+j*lx]) &&
00961 fabs(b) < SLOPE && fabs(a) < SATURATION )
00962 {
00963 p_ou_data[i+j*lx] = p_in_data[i+j*lx] - (a + b * (float)j) ;
00964 }
00965 else if ( isnan(p_in_data[i+j*lx]) )
00966 {
00967 p_ou_data[i+j*lx] = ZERO ;
00968 }
00969 else if ( (fabs(b) >= SLOPE ||
00970 fabs(a) >= SATURATION || isnan(a) || isnan(b)) &&
00971 !isnan(p_in_data[i+j*lx]) )
00972 {
00973 p_ou_data[i+j*lx] -= sinfo_median ;
00974 }
00975 else
00976 {
00977 sinfo_msg_error (" case is not possible! %f %f", b,a) ;
00978
00979
00980
00981
00982
00983 }
00984 }
00985 cpl_free (column) ;
00986 cpl_free (sig) ;
00987 cpl_free (dat) ;
00988 }
00989
00990 return im ;
00991 }
00992
00993
00994
00995
00996
01020 cpl_image * sinfo_new_median_image( cpl_image * im, float fmedian )
01021 {
01022 cpl_image * image=NULL ;
01023 pixelvalue * value=NULL ;
01024 pixelvalue sinfo_median=0 ;
01025 int * position=NULL ;
01026 int nposition=0 ;
01027 int n=0;
01028 int i=0;
01029 int j=0;
01030 int lx=0;
01031 int ly=0;
01032 float* p_in_data=NULL;
01033 float* p_ou_data=NULL;
01034 int im_size=0;
01035 if ( im == NULL )
01036 {
01037 sinfo_msg_error ("no image input") ;
01038 return NULL ;
01039 }
01040
01041 image = cpl_image_duplicate ( im ) ;
01042 lx=cpl_image_get_size_x(im);
01043 ly=cpl_image_get_size_y(im);
01044 im_size=lx*ly;
01045 p_in_data=cpl_image_get_data_float(im);
01046 p_ou_data=cpl_image_get_data_float(image);
01047
01048
01049
01050
01051
01052 for ( i = 0 ; i < im_size ; i++ )
01053 {
01054
01055 if ( isnan(p_in_data[i]) )
01056 {
01057 continue ;
01058 }
01059
01060
01061 value = (pixelvalue * )cpl_calloc ( 8, sizeof ( pixelvalue * ) ) ;
01062 position = ( int * ) cpl_calloc ( 8, sizeof ( int * ) ) ;
01063
01064
01065
01066
01067
01068 position[0] = i + lx - 1 ;
01069 position[1] = i + lx ;
01070 position[2] = i + lx + 1 ;
01071 position[3] = i + 1 ;
01072 position[4] = i - lx + 1 ;
01073 position[5] = i - lx ;
01074 position[6] = i - lx - 1 ;
01075 position[7] = i - 1 ;
01076
01077
01078
01079
01080
01081
01082
01083 if ( i >= 0 && i < lx )
01084 {
01085 position[4] += 2 * lx ;
01086 position[5] += 2 * lx ;
01087 position[6] += 2 * lx ;
01088 }
01089 else if ( i >= ((int) lx*ly - lx ) && i < (int) lx*ly )
01090 {
01091 position[0] -= 2 * lx ;
01092 position[1] -= 2 * lx ;
01093 position[2] -= 2 * lx ;
01094 }
01095 else if ( i % lx == 0 )
01096 {
01097 position[0] += 2 ;
01098 position[6] += 2 ;
01099 position[7] += 2 ;
01100 }
01101 else if ( i % lx == lx - 1 )
01102 {
01103 position[2] -= 2 ;
01104 position[3] -= 2 ;
01105 position[4] -= 2 ;
01106 }
01107
01108
01109
01110
01111
01112
01113 nposition = 8 ;
01114 n = 0 ;
01115 for ( j = 0 ; j < nposition ; j ++ )
01116 {
01117 if((position[j] >-1 ) && (position[j]<im_size)) {
01118 if ( !isnan(p_in_data[position[j]]) )
01119 {
01120 value[n] = p_in_data[position[j]] ;
01121 n ++ ;
01122 }
01123 }
01124 }
01125 nposition = n ;
01126
01127 if ( nposition <= 1 )
01128 {
01129 p_ou_data[i] = ZERO ;
01130 cpl_free(value) ;
01131 cpl_free(position) ;
01132 continue ;
01133 }
01134
01135
01136
01137 sinfo_pixel_qsort ( value, nposition ) ;
01138 if ( nposition % 2 == 1 )
01139 {
01140 sinfo_median = value [ nposition/2 ] ;
01141 }
01142 else
01143 {
01144 sinfo_median = ( value [nposition/2 - 1] +
01145 value [nposition/2] ) / 2. ;
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162 if ( fmedian == 0 )
01163 {
01164 p_ou_data[i] = sinfo_median ;
01165 }
01166 else if ( fmedian < 0 &&
01167 fabs ( sinfo_median - p_in_data[i] ) >= -fmedian )
01168 {
01169 p_ou_data[i] = sinfo_median ;
01170 }
01171 else if ( fmedian > 0 &&
01172 fabs ( sinfo_median - p_in_data[i] ) >= fmedian *
01173 sqrt(fabs(sinfo_median)) )
01174 {
01175 p_ou_data[i] = sinfo_median ;
01176 }
01177 else
01178 {
01179 cpl_free (value) ;
01180 cpl_free (position) ;
01181 continue ;
01182 }
01183
01184 cpl_free (value) ;
01185 cpl_free (position) ;
01186 }
01187 return image ;
01188 }
01189
01190
01191
01192
01203 cpl_image *
01204 sinfo_new_compare_images(cpl_image * im1,cpl_image * im2,cpl_image * origim )
01205 {
01206 cpl_image * image=NULL ;
01207 int i=0 ;
01208 int lx1=0;
01209 int ly1=0;
01210 int lx2=0;
01211 int ly2=0;
01212 float* p_in1_data=NULL;
01213 float* p_in2_data=NULL;
01214 float* p_ou_data=NULL;
01215 float* p_org_data=NULL;
01216
01217
01218 if ( im1 == NULL || im2 == NULL || origim == NULL )
01219 {
01220 sinfo_msg_error ("Null images as input" ) ;
01221 return NULL ;
01222 }
01223 lx1=cpl_image_get_size_x(im1);
01224 ly1=cpl_image_get_size_y(im1);
01225
01226 lx2=cpl_image_get_size_x(im2);
01227 ly2=cpl_image_get_size_y(im2);
01228
01229 p_in1_data=cpl_image_get_data_float(im1);
01230 p_in2_data=cpl_image_get_data_float(im2);
01231 p_org_data=cpl_image_get_data_float(origim);
01232 if ( lx1 != lx2 || ly1 != ly2 )
01233 {
01234 sinfo_msg_error ("incompatible image sizes" ) ;
01235 return NULL ;
01236 }
01237
01238
01239 if ( NULL == (image = cpl_image_new ( lx1, ly1, CPL_TYPE_FLOAT )) )
01240 {
01241 sinfo_msg_error ("cannot allocate new image" ) ;
01242 return NULL ;
01243 }
01244 p_ou_data=cpl_image_get_data_float(image);
01245 for ( i = 0 ; i < (int) lx1*ly1 ; i ++ )
01246 {
01247 if ( isnan(p_in1_data[i]) && isnan(p_in2_data[i]) )
01248 {
01249 p_ou_data[i] = ZERO ;
01250 }
01251 else
01252 {
01253 if ( p_in1_data[i] == p_in2_data[i] )
01254 {
01255 p_ou_data[i] = p_org_data[i] ;
01256 }
01257 else
01258 {
01259 p_ou_data[i] = ZERO ;
01260 }
01261 }
01262 }
01263 return image ;
01264 }
01265
01266
01267
01279 cpl_image *
01280 sinfo_new_promote_image_to_mask (cpl_image * im, int * n_badpixels )
01281 {
01282 cpl_image * reImage=NULL ;
01283 int i=0 ;
01284 int lx=0;
01285 int ly=0;
01286 float* p_in_data=NULL;
01287 float* p_ou_data=NULL;
01288
01289 if ( NULL == im )
01290 {
01291 sinfo_msg_error("no input image given!") ;
01292 return NULL ;
01293 }
01294 lx=cpl_image_get_size_x(im);
01295 ly=cpl_image_get_size_y(im);
01296 p_in_data=cpl_image_get_data_float(im);
01297
01298
01299 if ( NULL == (reImage = cpl_image_new (lx,ly,CPL_TYPE_FLOAT )) )
01300 {
01301 sinfo_msg_error ("cannot allocate new image!") ;
01302 return NULL ;
01303 }
01304 p_ou_data=cpl_image_get_data_float(reImage);
01305
01306 *n_badpixels = 0 ;
01307 for ( i = 0 ; i < (int) lx*ly ; i ++ )
01308 {
01309 if ( isnan(p_in_data[i]) )
01310 {
01311 p_ou_data[i] = 0. ;
01312 (*n_badpixels)++ ;
01313 }
01314 else
01315 {
01316 p_ou_data[i] = 1. ;
01317 }
01318 }
01319 return reImage ;
01320 }
01321
01322
01333 cpl_image * sinfo_new_mult_image_by_mask (cpl_image * im,cpl_image * mask )
01334 {
01335 cpl_image * reImage=NULL ;
01336 int i=0 ;
01337 int ix=0;
01338 int iy=0;
01339 int mx=0;
01340 int my=0;
01341
01342
01343 float* pmdata=NULL;
01344 float* podata=NULL;
01345
01346 if ( NULL == im )
01347 {
01348 sinfo_msg_error("no input image given!") ;
01349 return NULL ;
01350 }
01351 if ( NULL == mask )
01352 {
01353 sinfo_msg_error("no mask image given!") ;
01354 return NULL ;
01355 }
01356 ix=cpl_image_get_size_x(im);
01357 iy=cpl_image_get_size_y(im);
01358 mx=cpl_image_get_size_x(mask);
01359 my=cpl_image_get_size_y(mask);
01360
01361 if ( ix != mx || iy != my)
01362 {
01363 sinfo_msg_error("image sizes are not correspondent!") ;
01364 return NULL ;
01365 }
01366
01367 reImage = cpl_image_duplicate( im ) ;
01368 podata=cpl_image_get_data_float(reImage);
01369 pmdata=cpl_image_get_data_float(mask);
01370
01371 for ( i = 0 ; i < (int) ix*iy ; i ++ )
01372 {
01373 if ( pmdata[i] == 0. )
01374 {
01375 podata[i] = ZERO ;
01376 }
01377 }
01378
01379 return reImage ;
01380 }
01381
01382
01383
01393 cpl_image *
01394 sinfo_new_thresh_image (cpl_image * im, float lo_cut, float hi_cut )
01395 {
01396 cpl_image * image=NULL ;
01397 float* p_inp_data=NULL;
01398 float* p_out_data=NULL;
01399 int lx=0;
01400 int ly=0;
01401
01402 int i=0 ;
01403
01404 if (im == NULL)
01405 {
01406 sinfo_msg_error ("null image given") ;
01407 return NULL ;
01408 }
01409 lx=cpl_image_get_size_x(im);
01410 ly=cpl_image_get_size_y(im);
01411
01412 image = cpl_image_duplicate(im) ;
01413 p_inp_data=cpl_image_get_data(im);
01414 p_out_data=cpl_image_get_data(image);
01415 for ( i = 0 ; i < (int) lx*ly ; i ++ )
01416 {
01417 if ( p_inp_data[i] > (pixelvalue) hi_cut ||
01418 p_inp_data[i] < (pixelvalue) lo_cut )
01419 {
01420 p_out_data[i] = ZERO ;
01421 }
01422 }
01423 return image ;
01424 }
01425
01426
01427
01428
01453 cpl_image * sinfo_new_interpol_image ( cpl_image * im,
01454 cpl_image * mask,
01455 int max_radius,
01456 int n_pixels )
01457 {
01458 cpl_image * returnImage=NULL ;
01459 float* neighbors=NULL ;
01460 float sum=0;
01461 float mean=0;
01462 int i=0;
01463 int j=0;
01464 int k=0;
01465 int row=0;
01466 int col=0;
01467 int n_valid=0;
01468 int agreed=0;
01469
01470 int ilx=0;
01471 int ily=0;
01472 int mlx=0;
01473 int mly=0;
01474 float* pidata=NULL;
01475 float* podata=NULL;
01476 float* pmdata=NULL;
01477
01478 if ( NULL == im )
01479 {
01480 sinfo_msg_error("sorry, no input image given!") ;
01481 return NULL ;
01482 }
01483 ilx=cpl_image_get_size_x(im);
01484 ily=cpl_image_get_size_y(im);
01485 pidata=cpl_image_get_data_float(im);
01486
01487 if ( NULL == mask )
01488 {
01489 sinfo_msg_error("sorry, no mask image given!") ;
01490 return NULL ;
01491 }
01492
01493 mlx=cpl_image_get_size_x(mask);
01494 mly=cpl_image_get_size_y(mask);
01495 pmdata=cpl_image_get_data_float(mask);
01496
01497 if ( mlx != ilx || mly != mly )
01498 {
01499 sinfo_msg_error("images not compatible !") ;
01500 return NULL ;
01501 }
01502
01503 if ( max_radius <= 0 )
01504 {
01505 sinfo_msg_error("wrong number of pixels for maximal "
01506 "search radius given!") ;
01507 return NULL ;
01508 }
01509
01510 if ( n_pixels <= 2 )
01511 {
01512 sinfo_msg_error("wrong number of pixels used "
01513 "for interpolation given!") ;
01514 return NULL ;
01515 }
01516
01517 returnImage = cpl_image_duplicate ( im ) ;
01518 podata=cpl_image_get_data_float(returnImage);
01519
01520
01521 neighbors=cpl_calloc(4*max_radius*max_radius,sizeof(float)) ;
01522
01523 for ( col = 0 ; col < ilx ; col++ )
01524 {
01525 for ( row = 0 ; row < ily ; row++ )
01526 {
01527
01528 if ( isnan(pmdata[col+row*ilx]) || pmdata[col+row*ilx] == 0. )
01529 {
01530
01531 n_valid = 0 ;
01532 agreed = 0 ;
01533 for ( j = 1 ; j <= max_radius ; j++ )
01534 {
01535
01536
01537 for ( k = -j ; k < j ; k++ )
01538 {
01539 if ( col-j >= 0 && row+k < ily && row+k >= 0 )
01540 {
01541 if ( !isnan(pmdata[col-j+(row+k)*mlx]) ||
01542 pmdata[col-j+(row+k)*mlx] != 0 )
01543 {
01544 neighbors[n_valid]=pidata[col-j+(row+k)*ilx] ;
01545 n_valid++ ;
01546 }
01547 }
01548 }
01549
01550
01551 for ( k = -j ; k < j ; k++ )
01552 {
01553 if ( col+k < ilx && col+k >= 0 && row+j < ily )
01554 {
01555 if ( !isnan(pmdata[col+k+(row+j)*mlx]) ||
01556 pmdata[col+k+(row+j)*mlx] != 0. )
01557 {
01558 neighbors[n_valid]=pidata[col+k+(row+j)*ilx] ;
01559 n_valid++ ;
01560 }
01561 }
01562 }
01563
01564
01565 for ( k = -j ; k < j ; k++ )
01566 {
01567 if ( col+j < ilx && row-k >= 0 && row-k < ily )
01568 {
01569 if ( !isnan(pmdata[col+j+(row-k)*mlx]) ||
01570 pmdata[col+j+(row-k)*mlx] != 0. )
01571 {
01572 neighbors[n_valid]=pidata[col+j+(row-k)*ilx] ;
01573 n_valid++ ;
01574 }
01575 }
01576 }
01577
01578
01579 for ( k = -j ; k < j ; k++ )
01580 {
01581 if ( col-k >= 0 && col-k < ilx && row-j < ily )
01582 {
01583 if ( !isnan(pmdata[col-k+(row-j)*mlx]) ||
01584 pmdata[col-k+(row-j)*mlx] != 0. )
01585 {
01586 neighbors[n_valid]=pidata[col-k+(row-j)*ilx] ;
01587 n_valid++ ;
01588 }
01589 }
01590 }
01591
01592
01593 if ( n_valid >= n_pixels )
01594 {
01595 agreed = 1 ;
01596 break ;
01597 }
01598
01599 if ( j == 1 && n_valid >= 2 )
01600 {
01601 agreed = 1 ;
01602 break ;
01603 }
01604 }
01605 if ( n_valid < n_pixels && agreed == 0 )
01606 {
01607 sinfo_msg_error("not enough valid neighbors found to "
01608 "interpolate bad pixel in col: "
01609 "%d, row: %d", col, row ) ;
01610 return NULL ;
01611 }
01612 else
01613 {
01614
01615
01616
01617
01618
01619 if ( n_valid <= 8 )
01620 {
01621 sum = 0. ;
01622
01623 for ( i = 0 ; i < n_valid ; i++ )
01624 {
01625 sum += neighbors[i] ;
01626 }
01627 mean = sum / n_valid ;
01628
01629 podata[col+row*ilx] = mean ;
01630 }
01631 else
01632 {
01633 podata[col+row*ilx]=sinfo_new_median(neighbors,n_valid);
01634 }
01635 }
01636 }
01637 }
01638 }
01639 cpl_free(neighbors);
01640 return returnImage ;
01641 }
01642
01643
01666 cpl_image * sinfo_interpol_source_image ( cpl_image * im,
01667 cpl_image * mask,
01668 int max_rad,
01669 float ** slit_edges )
01670 {
01671 cpl_image * returnImage=NULL ;
01672 float validpixel[6] ;
01673 float sum=0 ;
01674 int n=0;
01675 int row=0;
01676 int col=0;
01677 int i=0;
01678 int k=0;
01679 int slitlet=0;
01680 int n_slitlets=0;
01681 int ilx=0;
01682 int ily=0;
01683 int mlx=0;
01684 int mly=0;
01685
01686 float* pidata=NULL;
01687 float* podata=NULL;
01688 float* pmdata=NULL;
01689
01690
01691 if ( NULL == im )
01692 {
01693 sinfo_msg_error("sorry, no input image given!") ;
01694 return NULL ;
01695 }
01696 ilx=cpl_image_get_size_x(im);
01697 ily=cpl_image_get_size_y(im);
01698 pidata=cpl_image_get_data_float(im);
01699
01700 if ( NULL == mask )
01701 {
01702 sinfo_msg_error("sorry, no bad pixel mask image given!") ;
01703 return NULL ;
01704 }
01705 mlx=cpl_image_get_size_x(mask);
01706 mly=cpl_image_get_size_y(mask);
01707 pmdata=cpl_image_get_data_float(mask);
01708
01709 if ( mlx != ilx || mly != ily )
01710 {
01711 sinfo_msg_error("images not compatible in size!") ;
01712 return NULL ;
01713 }
01714
01715 if ( max_rad < 1 )
01716 {
01717 sinfo_msg_error("sorry, wrong maximum distance given!") ;
01718 return NULL ;
01719 }
01720
01721 if ( slit_edges == NULL )
01722 {
01723 sinfo_msg_error("sorry, array slit_edges is empty!") ;
01724 return NULL ;
01725 }
01726
01727
01728 n_slitlets = N_SLITLETS ;
01729
01730
01731 returnImage = cpl_image_duplicate( im ) ;
01732 podata=cpl_image_get_data_float(returnImage);
01733
01734
01735
01736 for ( row = 0 ; row < ily ; row++ )
01737 {
01738 for ( col = 0 ; col < ilx ; col++ )
01739 {
01740 n = 0 ;
01741 if ( isnan(pmdata[col + row*mlx]) ||
01742 pmdata[col + row*mlx] == 0. ||
01743 isnan(pidata[col + row*mlx]) )
01744 {
01745
01746 slitlet = -1000 ;
01747 for ( k = 0 ; k < n_slitlets ; k++ )
01748 {
01749 if ( sinfo_new_nint(slit_edges[k][0]) <= col &&
01750 sinfo_new_nint(slit_edges[k][1]) >= col )
01751 {
01752 slitlet = k ;
01753 }
01754
01755
01756
01757
01758
01759
01760
01761 }
01762 for ( i = 0 ; i < 6 ; i++ )
01763 {
01764 validpixel[i] = 0. ;
01765 }
01766
01767
01768 for ( i = 1 ; i <= max_rad ; i++ )
01769 {
01770 if ( row + i < ily)
01771 {
01772 if ( !isnan(pmdata[col + (row+i) * mlx])
01773 && pmdata[col + (row+i) * mlx] != 0. &&
01774 !isnan(pidata[col + (row+i) * ilx]) )
01775 {
01776 validpixel[n] = pidata[col + (row+i) * ilx] ;
01777 n++ ;
01778 }
01779 }
01780 if ( row - i >= 0 )
01781 {
01782 if ( !isnan(pmdata[col + (row-i) * mlx])
01783 && pmdata[col + (row-i) * mlx] != 0. &&
01784 !isnan(pidata[col + (row-i) * ilx]) )
01785 {
01786 validpixel[n] = pidata[col + (row-i) * ilx] ;
01787 n++ ;
01788 }
01789 }
01790
01791
01792
01793 if ( col + i < ilx )
01794 {
01795 if ( slitlet != -1000 )
01796 {
01797 if (col+i <= sinfo_new_nint(slit_edges[slitlet][1]) &&
01798 !isnan(pmdata[col + i + row * mlx]) &&
01799 pmdata[col + i + row * mlx] != 0. &&
01800 !isnan(pidata[col + i + row * ilx]) )
01801 {
01802 validpixel[n] = pidata[col + i + row * ilx] ;
01803 n++ ;
01804 }
01805 }
01806 }
01807 if ( col - i >= 0 )
01808 {
01809 if ( slitlet != -1000 )
01810 {
01811 if (col-i >= sinfo_new_nint(slit_edges[slitlet][0]) &&
01812 !isnan(pmdata[col - i + row * mlx]) &&
01813 pmdata[col - i + row * mlx] != 0. &&
01814 !isnan(pidata[col - i + row * ilx]) )
01815 {
01816 validpixel[n] = pidata[col - i + row * ilx] ;
01817 n++ ;
01818 }
01819 }
01820 }
01821
01822 if ( i == 1 && n > 1 )
01823 {
01824 break ;
01825 }
01826 if ( n > 2 )
01827 {
01828 break ;
01829 }
01830 }
01831
01832 if ( n == 0 )
01833 {
01834 podata[col + row*ilx] = ZERO ;
01835
01836
01837
01838
01839 }
01840 else
01841 {
01842
01843
01844 sum = 0. ;
01845 for ( i = 0 ; i < n ; i++ )
01846 {
01847 sum += validpixel[i] ;
01848 }
01849 podata[col + row*ilx] = sum/n ;
01850 }
01851 }
01852 }
01853 }
01854
01855 return returnImage ;
01856 }
01857
01867 cpl_image * sinfo_new_stack_row_to_image ( Vector * row, int ly )
01868 {
01869 cpl_image * image=NULL;
01870 int col=0;
01871 int ro=0;
01872 float* podata=NULL;
01873
01874 if ( row == NullVector )
01875 {
01876 sinfo_msg_error ("Null sinfo_vector as input" ) ;
01877 return NULL ;
01878 }
01879 if ( ly <= 1 )
01880 {
01881 sinfo_msg_error ("wrong image length given" ) ;
01882 return NULL ;
01883 }
01884
01885
01886 if (NULL == (image = cpl_image_new(row->n_elements ,ly,CPL_TYPE_FLOAT )) )
01887 {
01888 sinfo_msg_error ("cannot allocate new image" ) ;
01889 return NULL ;
01890 }
01891 podata=cpl_image_get_data_float(image);
01892
01893 for ( col = 0 ; col < row -> n_elements ; col++ )
01894 {
01895 for ( ro = 0 ; ro < ly ; ro++ )
01896 {
01897 podata[col + ro*ly] = row -> data[col] ;
01898 }
01899 }
01900 return image ;
01901 }
01902
01918 Stats * sinfo_new_image_stats_on_rectangle ( cpl_image * im,
01919 float loReject,
01920 float hiReject,
01921 int llx,
01922 int lly,
01923 int urx,
01924 int ury )
01925 {
01926 Stats * retstats=NULL;
01927 int i=0 ;
01928 int row=0;
01929 int col=0;
01930 int n=0;
01931 int npix=0;
01932 int lo_n=0;
01933 int hi_n=0;
01934 double pix_sum=0;
01935 double sqr_sum=0;
01936 float * pix_array=NULL;
01937 int im_lx=0;
01938 int im_ly=0;
01939 float* pim=NULL;
01940
01941 if ( NULL == im )
01942 {
01943 sinfo_msg_error("sorry, no input image given!") ;
01944 return NULL ;
01945 }
01946 if ( loReject+hiReject >= 100. )
01947 {
01948 sinfo_msg_error("sorry, too much pixels rejected!") ;
01949 return NULL ;
01950 }
01951 if ( loReject < 0. || loReject >= 100. ||
01952 hiReject < 0. || hiReject >= 100. )
01953 {
01954 sinfo_msg_error("sorry, negative reject values!") ;
01955 return NULL ;
01956 }
01957
01958 im_lx=cpl_image_get_size_x(im);
01959 im_ly=cpl_image_get_size_y(im);
01960
01961 if ( llx < 0 || lly < 0 || urx < 0 || ury < 0 ||
01962 llx >= im_lx || lly >= im_ly || urx >= im_lx ||
01963 ury >= im_ly || ury <= lly || urx <= llx )
01964 {
01965 sinfo_msg_error("sorry, wrong pixel coordinates of rectangle!") ;
01966 return NULL ;
01967 }
01968
01969
01970 retstats = (Stats*) cpl_calloc(1, sizeof(Stats)) ;
01971 npix = (urx - llx + 1) * (ury - lly + 1) ;
01972 pix_array = (float*) cpl_calloc ( npix, sizeof(float) ) ;
01973
01974
01975
01976
01977 n = 0 ;
01978 pim = cpl_image_get_data_float(im);
01979 for ( row = lly ; row <= ury ; row++ )
01980 {
01981 for ( col = llx ; col <= urx ; col++ )
01982 {
01983 if ( !isnan(pim[col + row*im_lx]) )
01984 {
01985 pix_array[n] = pim[col + row*im_lx] ;
01986 n++ ;
01987 }
01988 }
01989 }
01990
01991 npix = n;
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002 if ( FLT_MAX == (retstats->cleanmean = sinfo_new_clean_mean(pix_array,
02003 npix, loReject, hiReject)) )
02004 {
02005 sinfo_msg_error("sinfo_new_clean_mean() did not work!") ;
02006 cpl_free(retstats) ;
02007 cpl_free(pix_array) ;
02008 return NULL ;
02009 }
02010
02011
02012
02013 lo_n = (int) (loReject / 100. * (float)npix) ;
02014 hi_n = (int) (hiReject / 100. * (float)npix) ;
02015 pix_sum = 0. ;
02016 sqr_sum = 0. ;
02017 n = 0 ;
02018 for ( i = lo_n ; i <= npix - hi_n ; i++ )
02019 {
02020 pix_sum += (double)pix_array[i] ;
02021 sqr_sum += ((double)pix_array[i] * (double)pix_array[i]) ;
02022 n++ ;
02023 }
02024
02025 if ( n == 0 )
02026 {
02027 sinfo_msg_error("number of clean pixels is zero!") ;
02028 cpl_free(retstats) ;
02029 cpl_free(pix_array) ;
02030 return NULL ;
02031 }
02032 retstats -> npix = n ;
02033 pix_sum /= (double) n ;
02034 sqr_sum /= (double) n ;
02035 retstats -> cleanstdev = (float)sqrt(sqr_sum - pix_sum * pix_sum) ;
02036 cpl_free (pix_array) ;
02037 return retstats ;
02038 }
02039
02040
02041
02050 cpl_image * sinfo_new_normalize_to_central_pixel ( cpl_image * image )
02051 {
02052 int col=0;
02053 int row=0;
02054 int i=0;
02055 int n=0;
02056 float* array=NULL ;
02057 float divisor=0;
02058 cpl_image * retImage=NULL;
02059 int ilx=0;
02060 int ily=0;
02061 float* pidata=NULL;
02062 float* podata=NULL;
02063
02064 if ( image == NULL )
02065 {
02066 sinfo_msg_error("no image given!") ;
02067 return NULL ;
02068 }
02069 ilx=cpl_image_get_size_x(image);
02070 ily=cpl_image_get_size_y(image);
02071 pidata=cpl_image_get_data_float(image);
02072
02073 retImage = cpl_image_duplicate(image) ;
02074 podata=cpl_image_get_data_float(retImage);
02075
02076 n = 0 ;
02077
02078
02079 array=cpl_calloc(2*ilx,sizeof(float)) ;
02080
02081 for ( row = ily/2 ; row < ily/2+1 ; row++ )
02082 {
02083 for ( col = 0 ; col < ilx ; col++ )
02084 {
02085 if ( !isnan(pidata[col+ilx*row]) )
02086 {
02087 array[n] = pidata[col+ilx*row] ;
02088 n++ ;
02089 }
02090 }
02091 }
02092
02093
02094 if ( isnan(divisor = sinfo_new_median(array, n) ) )
02095 {
02096 sinfo_msg_error("no sinfo_median possible!") ;
02097 return NULL ;
02098 }
02099 if ( 0 == divisor )
02100 {
02101 sinfo_msg_error("cannot divide by 0") ;
02102 return NULL ;
02103 }
02104
02105 for ( i = 0 ; i < (int) ilx*ily ; i++ )
02106 {
02107 if ( isnan(pidata[i]) )
02108 {
02109 podata[i] = ZERO ;
02110 }
02111 else
02112 {
02113 podata[i] = pidata[i]/divisor ;
02114 }
02115 }
02116 cpl_free(array);
02117 return retImage ;
02118 }
02119
02120
02149
02150
02151 cpl_image *
02152 sinfo_new_mpe_shift_image(
02153 cpl_image * image_in,
02154 double shift_x,
02155 double shift_y,
02156 double * interp_kernel)
02157 {
02158 cpl_image * shifted=NULL ;
02159 pixelvalue * first_pass=NULL ;
02160 pixelvalue * second_pass=NULL ;
02161 int samples = KERNEL_SAMPLES ;
02162 int i=0, j=0 ;
02163 double fx=0, fy=0 ;
02164 double rx=0, ry=0 ;
02165 int px=0, py=0 ;
02166 int tabx=0, taby=0 ;
02167 double value=0 ;
02168 size_t pos ;
02169 register pixelvalue * pix ;
02170 register pixelvalue * pixint ;
02171 int mid=0;
02172 double norm=0 ;
02173 double * ker=NULL ;
02174 int freeKernel = 1 ;
02175
02176 int ilx=0;
02177 int ily=0;
02178 float* pidata=NULL;
02179 float* psdata=NULL;
02180
02181
02182
02183 if (image_in==NULL) return NULL ;
02184
02185
02186 if ((fabs(shift_x)<1e-2) && (fabs(shift_y)<1e-2))
02187 return cpl_image_duplicate(image_in) ;
02188 ilx=cpl_image_get_size_x(image_in);
02189 ily=cpl_image_get_size_y(image_in);
02190 pidata=cpl_image_get_data_float(image_in);
02191
02192
02193
02194 if (interp_kernel == NULL) {
02195 ker = sinfo_generate_interpolation_kernel("default") ;
02196 if (ker == NULL) {
02197 sinfo_msg_error("kernel generation failure:aborting resampling") ;
02198 return NULL ;
02199 }
02200 } else {
02201 ker = interp_kernel ;
02202 freeKernel = 0 ;
02203 }
02204
02205 mid = (int)samples/(int)2 ;
02206 first_pass = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
02207 shifted = cpl_image_new(ilx, ily,CPL_TYPE_FLOAT) ;
02208 psdata=cpl_image_get_data_float(shifted);
02209
02210 second_pass = psdata ;
02211
02212 pix = pidata ;
02213 if ( ilx != 1 )
02214 {
02215 for (j=0 ; j<ily ; j++)
02216 {
02217 for (i=0 ; i<ilx ; i++) {
02218 fx = (double)i-shift_x ;
02219 px = (int)fx ;
02220 rx = fx - (double)px ;
02221 pos = px + j * ilx ;
02222
02223 if ((px>1) && (px<(ilx-2)))
02224 {
02225 tabx = (int)(fabs((double)mid * rx)) ;
02226
02227 if (isnan(pix[pos]))
02228 {
02229 value = ZERO ;
02230 }
02231 else
02232 {
02233 if (isnan(pix[pos-1]))
02234 {
02235 pix[pos-1] = 0. ;
02236 }
02237 if (isnan(pix[pos+1]))
02238 {
02239 pix[pos+1] = 0. ;
02240 }
02241 if (isnan(pix[pos+2]))
02242 {
02243 pix[pos+2] = 0. ;
02244 }
02245
02246
02247
02248
02249
02250 value = (double)pix[pos-1] * ker[mid+tabx] +
02251 (double)pix[pos] * ker[tabx] +
02252 (double)pix[pos+1] * ker[mid-tabx] +
02253 (double)pix[pos+2] * ker[samples-tabx-1] ;
02254
02255
02256
02257
02258 norm = (double)ker[mid+tabx] +
02259 (double)ker[tabx] +
02260 (double)ker[mid-tabx] +
02261 (double)ker[samples-tabx-1] ;
02262 if (fabs(norm) > 1e-4) {
02263 value /= norm ;
02264 }
02265 }
02266 } else {
02267 value = ZERO ;
02268 }
02269
02270
02271
02272
02273 if ( isnan(value) )
02274 {
02275 first_pass[i+j*ilx] = ZERO ;
02276 }
02277 else
02278 {
02279 first_pass[i+j*ilx] = (pixelvalue)value ;
02280 }
02281 }
02282 }
02283 }
02284 else
02285 {
02286 memcpy(first_pass,pix,ily*sizeof(pixelvalue));
02287 }
02288
02289 pixint = first_pass ;
02290 for (i=0 ; i<ilx ; i++) {
02291 for (j=0 ; j<ily ; j++) {
02292 fy = (double)j - shift_y ;
02293 py = (int)fy ;
02294 ry = fy - (double)py ;
02295 pos = i + py * ilx ;
02296
02297 taby = (int)(fabs((double)mid * ry)) ;
02298
02299 if ((py>(int)1) && (py<(ily-2))) {
02300
02301 if (isnan(pixint[pos]) && ilx != 1 )
02302 {
02303 value = ZERO ;
02304 }
02305 else
02306 {
02307 if (isnan(pixint[pos-ilx]))
02308 {
02309 pixint[pos-ilx] = 0. ;
02310 }
02311 if (isnan(pixint[pos+ilx]))
02312 {
02313 pixint[pos+ilx] = 0. ;
02314 }
02315 if (isnan(pixint[pos+2*ilx]))
02316 {
02317 pixint[pos+2*ilx] = 0. ;
02318 }
02319
02320
02321
02322
02323 value = (double)pixint[pos-ilx] * ker[mid+taby] +
02324 (double)pixint[pos] * ker[taby] +
02325 (double)pixint[pos+ilx] * ker[mid-taby] +
02326 (double)pixint[pos+2*ilx]*ker[samples-taby-1];
02327
02328
02329
02330
02331 norm = (double)ker[mid+taby] +
02332 (double)ker[taby] +
02333 (double)ker[mid-taby] +
02334 (double)ker[samples-taby-1] ;
02335
02336 if (fabs(norm) > 1e-4) {
02337 value /= norm ;
02338 }
02339 }
02340 } else {
02341 value = ZERO ;
02342 }
02343 if (isnan(value))
02344 {
02345 second_pass[i+j*ilx] = ZERO ;
02346 }
02347 else
02348 {
02349 second_pass[i+j*ilx] = (pixelvalue)value ;
02350 }
02351 }
02352 }
02353
02354 cpl_free(first_pass) ;
02355 if (freeKernel)
02356 cpl_free(ker) ;
02357 return shifted ;
02358 }
02359
02360
02361
02392
02393
02394 void
02395 sinfo_new_shift_image_in_cube(
02396 cpl_image * image_in,
02397 double shift_x,
02398 double shift_y,
02399 double * interp_kernel,
02400 cpl_image * shifted,
02401 pixelvalue * first_pass)
02402 {
02403 pixelvalue * second_pass=NULL ;
02404 int samples = KERNEL_SAMPLES ;
02405 int i=0, j=0 ;
02406 double fx=0, fy=0 ;
02407 double rx=0, ry=0 ;
02408 int px=0, py=0 ;
02409 int tabx=0, taby=0 ;
02410 double value=0 ;
02411 size_t pos ;
02412 register pixelvalue * pix ;
02413 register pixelvalue * pixint ;
02414 int mid=0;
02415 double norm=0 ;
02416 double * ker=NULL ;
02417 int freeKernel = 1 ;
02418
02419 int ilx=0;
02420 int ily=0;
02421 int slx=0;
02422 int sly=0;
02423 float* pidata=NULL;
02424 float* psdata=NULL;
02425
02426
02427 if (image_in==NULL) shifted = NULL ;
02428 pidata=cpl_image_get_data_float(image_in);
02429 ilx=cpl_image_get_size_x(image_in);
02430 ily=cpl_image_get_size_y(image_in);
02431
02432 shifted=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
02433 slx=ilx;
02434 sly=ily;
02435
02436 psdata=cpl_image_get_data_float(shifted);
02437
02438
02439 if ((fabs(shift_x)<1e-2) && (fabs(shift_y)<1e-2))
02440 memcpy(psdata,pidata, (size_t) slx*sly * sizeof(pixelvalue)) ;
02441
02442
02443 if (interp_kernel == NULL) {
02444 ker = sinfo_generate_interpolation_kernel("default") ;
02445 if (ker == NULL) {
02446 sinfo_msg_error("kernel generation failure:aborting resampling") ;
02447 shifted = NULL ;
02448 }
02449 } else {
02450 ker = interp_kernel ;
02451 freeKernel = 0 ;
02452 }
02453
02454 mid = (int)samples/(int)2 ;
02455 second_pass = psdata ;
02456
02457 pix = pidata ;
02458 for (j=0 ; j<ily ; j++) {
02459 for (i=1 ; i<ilx-2 ; i++) {
02460 fx = (double)i-shift_x ;
02461 px = (int)fx ;
02462 rx = fx - (double)px ;
02463
02464 pos = px + j * ilx ;
02465
02466 if ((px>1) && (px<(ilx-2))) {
02467 tabx = (int)(fabs((double)mid * rx)) ;
02468
02469 if (isnan(pix[pos]))
02470 {
02471 value = ZERO ;
02472 }
02473 else
02474 {
02475 if (isnan(pix[pos-1]))
02476 {
02477 pix[pos-1] = 0. ;
02478 }
02479 if (isnan(pix[pos+1]))
02480 {
02481 pix[pos+1] = 0. ;
02482 }
02483 if (isnan(pix[pos+2]))
02484 {
02485 pix[pos+2] = 0. ;
02486 }
02487
02488
02489
02490
02491
02492 value = (double)pix[pos-1] * ker[mid+tabx] +
02493 (double)pix[pos] * ker[tabx] +
02494 (double)pix[pos+1] * ker[mid-tabx] +
02495 (double)pix[pos+2] * ker[samples-tabx-1] ;
02496
02497
02498
02499
02500 norm = (double)ker[mid+tabx] +
02501 (double)ker[tabx] +
02502 (double)ker[mid-tabx] +
02503 (double)ker[samples-tabx-1] ;
02504 if (fabs(norm) > 1e-4) {
02505 value /= norm ;
02506 }
02507 }
02508 } else {
02509 value = 0.0 ;
02510 }
02511
02512
02513
02514
02515 if ( isnan(value) )
02516 {
02517 first_pass[i+j*ilx] = ZERO ;
02518 }
02519 else
02520 {
02521 first_pass[i+j*ilx] = (pixelvalue)value ;
02522 }
02523 }
02524 }
02525 pixint = first_pass ;
02526 for (i=0 ; i< ilx ; i++) {
02527 for (j=1 ; j< ily-2 ; j++) {
02528 fy = (double)j - shift_y ;
02529 py = (int)fy ;
02530 ry = fy - (double)py ;
02531 pos = i + py * ilx ;
02532
02533 taby = (int)(fabs((double)mid * ry)) ;
02534
02535 if ((py>(int)1) && (py<(ily-2))) {
02536
02537 if (isnan(pixint[pos]))
02538 {
02539 value = ZERO ;
02540 }
02541 else
02542 {
02543 if (isnan(pixint[pos-ilx]))
02544 {
02545 pixint[pos-ilx] = 0. ;
02546 }
02547 if (isnan(pixint[pos+ilx]))
02548 {
02549 pixint[pos+ilx] = 0. ;
02550 }
02551 if (isnan(pixint[pos+2*ilx]))
02552 {
02553 pixint[pos+2*ilx] = 0. ;
02554 }
02555
02556
02557
02558
02559 value = (double)pixint[pos-ilx] * ker[mid+taby] +
02560 (double)pixint[pos] * ker[taby] +
02561 (double)pixint[pos+ilx] * ker[mid-taby] +
02562 (double)pixint[pos+2*ilx]*ker[samples-taby-1];
02563
02564
02565
02566
02567 norm = (double)ker[mid+taby] +
02568 (double)ker[taby] +
02569 (double)ker[mid-taby] +
02570 (double)ker[samples-taby-1] ;
02571
02572 if (fabs(norm) > 1e-4) {
02573 value /= norm ;
02574 }
02575 }
02576 } else {
02577
02578 }
02579 if (isnan(value))
02580 {
02581 second_pass[i+j*ilx] = ZERO ;
02582 }
02583 else
02584 {
02585 second_pass[i+j*ilx] = (pixelvalue)value ;
02586 }
02587 }
02588 }
02589
02590 if (freeKernel)
02591 cpl_free(ker) ;
02592 }
02593
02594
02595 void sinfo_new_del_Stats( Stats * st)
02596 {
02597 cpl_free (st) ;
02598 }
02599
02606 cpl_image *
02607 sinfo_new_combine_masks ( cpl_image * firstMask, cpl_image * secondMask )
02608 {
02609 cpl_image * retMask=NULL ;
02610 int n=0 ;
02611 int olx=0;
02612 int oly=0;
02613 float* podata=NULL;
02614 float* pm1data=NULL;
02615 float* pm2data=NULL;
02616
02617 if ( firstMask == NULL || secondMask == NULL )
02618 {
02619 sinfo_msg_error ("no input mask image given!") ;
02620 return NULL ;
02621 }
02622 retMask = cpl_image_duplicate (firstMask) ;
02623 podata = cpl_image_get_data_float(retMask);
02624 pm1data = cpl_image_get_data_float(firstMask);
02625 pm2data = cpl_image_get_data_float(secondMask);
02626 olx=cpl_image_get_size_x(retMask);
02627 oly=cpl_image_get_size_y(retMask);
02628
02629 for ( n = 0 ; n < (int) olx*oly ; n++ )
02630 {
02631 if ( podata[n] == 0. || pm2data[n] == 0. )
02632 {
02633 podata[n] = 0. ;
02634 }
02635 else
02636 {
02637 podata[n] = 1. ;
02638 }
02639 }
02640 return retMask ;
02641 }
02642
02651 cpl_image * sinfo_new_slice_cube (cpl_imagelist * cube, int x, int y )
02652 {
02653 cpl_image * retImage=NULL ;
02654 int col=0, row=0, z=0 ;
02655 int inp=0;
02656 int ilx=0;
02657 int ily=0;
02658 cpl_image* img=NULL;
02659 float* podata=NULL;
02660 float* pidata=NULL;
02661
02662 if ( cube == NULL )
02663 {
02664 sinfo_msg_error("no cube given!") ;
02665 return NULL ;
02666 }
02667 if ( x > 31 || y > 31 )
02668 {
02669 sinfo_msg_warning("wrong x or y values!") ;
02670 }
02671
02672 img=cpl_imagelist_get(cube,0);
02673 ilx=cpl_image_get_size_x(img);
02674 ily=cpl_image_get_size_y(img);
02675 inp=cpl_imagelist_get_size(cube);
02676 if ( x < 0 )
02677 {
02678
02679 if ( NULL == (retImage = cpl_image_new(ilx, inp, CPL_TYPE_FLOAT)) )
02680 {
02681 sinfo_msg_error("could not allocate memory!") ;
02682 return NULL ;
02683 }
02684 podata=cpl_image_get_data_float(retImage);
02685 for ( z = 0 ; z < inp ; z++ )
02686 {
02687
02688 pidata=cpl_image_get_data_float(cpl_imagelist_get(cube,z));
02689 for ( col = 0 ; col < ilx ; col++ )
02690 {
02691 podata[col+z*ilx] = pidata[col+y*ilx] ;
02692 }
02693 }
02694 }
02695 else if ( y < 0 )
02696 {
02697
02698 if ( NULL == (retImage = cpl_image_new(ily, inp,CPL_TYPE_FLOAT)) )
02699 {
02700 sinfo_msg_error("could not allocate memory!") ;
02701 return NULL ;
02702 }
02703 podata=cpl_image_get_data_float(retImage);
02704
02705 for ( z = 0 ; z < inp ; z++ )
02706 {
02707 pidata=cpl_image_get_data_float(cpl_imagelist_get(cube,z));
02708 for ( row = 0 ; row < ily ; row++ )
02709 {
02710 podata[row+z*ily] = pidata[x+row*ily] ;
02711 }
02712 }
02713 }
02714 else
02715 {
02716 sinfo_msg_error("wrong input!") ;
02717 return NULL ;
02718 }
02719 return retImage ;
02720 }
02721
02733 cpl_image * sinfo_new_div_images_robust ( cpl_image * im1, cpl_image * im2 )
02734 {
02735 cpl_image * retIm=NULL ;
02736 float help=0 ;
02737 int i=0 ;
02738 int lx1=0;
02739 int ly1=0;
02740 int lx2=0;
02741 int ly2=0;
02742
02743 float* p1data=NULL;
02744 float* p2data=NULL;
02745 float* podata=NULL;
02746
02747 if ( im1 == NULL || im2 == NULL )
02748 {
02749 sinfo_msg_error("no input images given!") ;
02750 return NULL ;
02751 }
02752 lx1=cpl_image_get_size_x(im1);
02753 ly1=cpl_image_get_size_y(im1);
02754 lx2=cpl_image_get_size_x(im2);
02755 ly2=cpl_image_get_size_y(im2);
02756 p1data=cpl_image_get_data_float(im1);
02757 p2data=cpl_image_get_data_float(im2);
02758
02759 if ( lx1 != lx2 || ly1 != ly2 )
02760 {
02761 sinfo_msg_error("images not compatible!") ;
02762 return NULL ;
02763 }
02764 if ( NULL == (retIm = cpl_image_new(lx1, ly1, CPL_TYPE_FLOAT)) )
02765 {
02766 sinfo_msg_error("could not allocate memory!") ;
02767 return NULL ;
02768 }
02769 podata=cpl_image_get_data_float(retIm);
02770
02771 for ( i = 0 ; i < (int) lx2*ly2 ; i++ )
02772 {
02773 if ( !isnan(p2data[i]) )
02774 {
02775 help = 1./p2data[i] ;
02776 if (fabs( help )> THRESH )
02777 {
02778 help = 1. ;
02779 }
02780 }
02781 else
02782 {
02783 help = ZERO ;
02784 }
02785 if ( isnan(help) || isnan(p1data[i]) )
02786 {
02787 podata[i] = ZERO ;
02788 }
02789 else
02790 {
02791 podata[i] = p1data[i] * help ;
02792 }
02793 }
02794 return retIm ;
02795 }
02796
02797 cpl_image * sinfo_new_null_edges ( cpl_image * image)
02798 {
02799 cpl_image * new=NULL ;
02800 int i=0,j=0 ;
02801 int ilx=0;
02802 int ily=0;
02803 int olx=0;
02804 int oly=0;
02805
02806 float* pidata=NULL;
02807 float* podata=NULL;
02808
02809 if ( image == NULL )
02810 {
02811 sinfo_msg_error ("no input image given!\n") ;
02812 return NULL ;
02813 }
02814
02815
02816 new = cpl_image_duplicate (image) ;
02817 ilx=cpl_image_get_size_x(image);
02818 ily=cpl_image_get_size_y(image);
02819 olx=cpl_image_get_size_x(new);
02820 oly=cpl_image_get_size_y(new);
02821 pidata=cpl_image_get_data_float(image);
02822 podata=cpl_image_get_data_float(new);
02823
02824 for ( i = 0 ; i < olx ; i++ )
02825 {
02826 for ( j = 0 ; j < 4 ; j++)
02827 {
02828 podata[i+j*olx]=0;
02829 podata[i+(oly-j-1)*olx]=0;
02830 }
02831 }
02832 for ( i = 0 ; i < oly ; i++ )
02833 {
02834 for ( j = 0 ; j < 4 ; j++)
02835 {
02836 podata[j+i*olx]=0;
02837 podata[(olx-j-1)+i*olx]=0;
02838 }
02839 }
02840 return new ;
02841 }
02842
02843
02844 void sinfo_new_used_cor_map( cpl_image *im, cpl_image *map)
02845 {
02846 int i=0,j=0,loc_index=0;
02847 float temp_array[2048];
02848 int lx=cpl_image_get_size_x(im);
02849 int ly=cpl_image_get_size_y(im);
02850 float* pidata=cpl_image_get_data_float(im);
02851 float* pmdata=cpl_image_get_data_float(map);
02852
02853 for( j=0; j<ly; j++)
02854 {
02855 for( i=0;i<lx;i++)
02856 {
02857 loc_index = (int)pmdata[i+j*lx];
02858 temp_array[i] = pidata[loc_index+j*lx];
02859 }
02860 for( i=0;i<lx;i++)
02861 {
02862 pidata[i+j*lx]= temp_array[i];
02863 }
02864 }
02865 }
02866
02867
02868
02869
02870
02893
02894
02895 cpl_image *
02896 sinfo_new_shift_image(
02897 cpl_image * image_in,
02898 double shift_x,
02899 double shift_y,
02900 double * interp_kernel)
02901 {
02902 cpl_image * shifted=NULL ;
02903 float * first_pass=NULL ;
02904 float * second_pass=NULL ;
02905 int samples = KERNEL_SAMPLES ;
02906 int i=0, j=0 ;
02907 double fx=0, fy=0 ;
02908 double rx=0, ry=0 ;
02909 int px=0, py=0 ;
02910 int tabx=0, taby=0 ;
02911 double value=0 ;
02912 size_t pos ;
02913 register float * pix=NULL ;
02914 register float * pixint=NULL ;
02915 int mid=0;
02916 double norm=0 ;
02917 double * ker=NULL ;
02918 int freeKernel = 1 ;
02919 int ilx=0;
02920 int ily=0;
02921
02922
02923 if (image_in==NULL) return NULL ;
02924
02925
02926 if ((fabs(shift_x)<1e-2) && (fabs(shift_y)<1e-2))
02927 return cpl_image_duplicate(image_in) ;
02928
02929
02930 if (interp_kernel == NULL) {
02931 ker = sinfo_generate_interpolation_kernel("default") ;
02932 if (ker == NULL) {
02933 sinfo_msg_error("kernel generation failure: aborting resampling") ;
02934 return NULL ;
02935 }
02936 } else {
02937 ker = interp_kernel ;
02938 freeKernel = 0 ;
02939 }
02940
02941 ilx=cpl_image_get_size_x(image_in);
02942 ily=cpl_image_get_size_y(image_in);
02943
02944
02945 pix = cpl_image_get_data_float(image_in);
02946 if (pix)
02947 {
02948 mid = (int)samples/(int)2 ;
02949 first_pass = cpl_calloc(ilx, ily*sizeof(float)) ;
02950 shifted = cpl_image_new(ilx, ily,CPL_TYPE_FLOAT) ;
02951 second_pass = cpl_image_get_data_float(shifted);
02952 for (j=0 ; j<ily ; j++) {
02953 for (i=1 ; i<ilx-2 ; i++) {
02954 fx = (double)i-shift_x ;
02955 px = (int)fx ;
02956 rx = fx - (double)px ;
02957
02958 pos = px + j * ilx ;
02959
02960 if ((px>1) && (px<(ilx-3))) {
02961 tabx = (int)(fabs((double)mid * rx)) ;
02962
02963
02964
02965
02966 value = (double)pix[pos-1] * ker[mid+tabx] +
02967 (double)pix[pos] * ker[tabx] +
02968 (double)pix[pos+1] * ker[mid-tabx] +
02969 (double)pix[pos+2] * ker[samples-tabx-1] ;
02970
02971
02972
02973
02974 norm = (double)ker[mid+tabx] +
02975 (double)ker[tabx] +
02976 (double)ker[mid-tabx] +
02977 (double)ker[samples-tabx-1] ;
02978 if (fabs(norm) > 1e-4) {
02979 value /= norm ;
02980 }
02981 } else {
02982 value = 0.0 ;
02983 }
02984
02985
02986
02987
02988 first_pass[i+j*ilx] = (float)value ;
02989 }
02990 }
02991 pixint = first_pass ;
02992 for (i=0 ; i<ilx ; i++) {
02993 for (j=1 ; j<ily-3 ; j++) {
02994 fy = (double)j - shift_y ;
02995 py = (int)fy ;
02996 ry = fy - (double)py ;
02997 pos = i + py * ilx ;
02998
02999 taby = (int)(fabs((double)mid * ry)) ;
03000
03001 if ((py>(int)1) && (py<(ily-2))) {
03002
03003
03004
03005
03006 value = (double)pixint[pos-ilx] * ker[mid+taby] +
03007 (double)pixint[pos] * ker[taby] +
03008 (double)pixint[pos+ilx] * ker[mid-taby] +
03009 (double)pixint[pos+2*ilx]*ker[samples-taby-1];
03010
03011
03012
03013
03014 norm = (double)ker[mid+taby] +
03015 (double)ker[taby] +
03016 (double)ker[mid-taby] +
03017 (double)ker[samples-taby-1] ;
03018
03019 if (fabs(norm) > 1e-4) {
03020 value /= norm ;
03021 }
03022 } else {
03023 value = 0.0 ;
03024 }
03025 second_pass[i+j*ilx] = (float)value ;
03026 }
03027 }
03028 }
03029 else
03030 {
03031 cpl_msg_warning(cpl_func, "cannot get a data from an image");
03032 }
03033 cpl_free(first_pass) ;
03034 if (freeKernel)
03035 cpl_free(ker) ;
03036 return shifted ;
03037 }
03038
03039
03040
03054
03055
03056 cpl_image *
03057 sinfo_image_hermite_interpol(cpl_image * inp)
03058 {
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071 float* pinp=NULL;
03072 float* pout=NULL;
03073 int sx=0;
03074 int sy=0;
03075 int i=0;
03076 int j=0;
03077 int r=5;
03078 int k=0;
03079
03080 cpl_image* out=NULL;
03081
03082 cknull(inp,"Null in put image, exit");
03083 check_nomsg(out=cpl_image_duplicate(inp));
03084 check_nomsg(sx=cpl_image_get_size_x(inp));
03085 check_nomsg(sy=cpl_image_get_size_y(inp));
03086 check_nomsg(pinp=cpl_image_get_data_float(inp));
03087 check_nomsg(pout=cpl_image_get_data_float(out));
03088 for(j=r;j<sy-r;j++) {
03089 for(i=0;i<sx;i++) {
03090 for(k=-r;k<r;k++) {
03091 pout[j*sx+i]+=pinp[(j+k)*sx+i];
03092 }
03093 pout[j*sx+i]/=2*r;
03094 }
03095 }
03096
03097 cleanup:
03098
03099 if(cpl_error_get_code() != CPL_ERROR_NONE) {
03100 return NULL;
03101 } else {
03102 return out;
03103
03104 }
03105
03106 }
03107
03108
03109
03110
03124
03125
03126 cpl_image *
03127 sinfo_image_smooth_y(cpl_image * inp, const int r)
03128 {
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138 float* pinp=NULL;
03139 float* pout=NULL;
03140 int sx=0;
03141 int sy=0;
03142 int i=0;
03143 int j=0;
03144 int k=0;
03145
03146 cpl_image* out=NULL;
03147
03148 cknull(inp,"Null in put image, exit");
03149 check_nomsg(out=cpl_image_duplicate(inp));
03150 check_nomsg(sx=cpl_image_get_size_x(inp));
03151 check_nomsg(sy=cpl_image_get_size_y(inp));
03152 check_nomsg(pinp=cpl_image_get_data_float(inp));
03153 check_nomsg(pout=cpl_image_get_data_float(out));
03154 for(j=r;j<sy-r;j++) {
03155 for(i=0;i<sx;i++) {
03156 for(k=-r;k<r;k++) {
03157 pout[j*sx+i]+=pinp[(j+k)*sx+i];
03158 }
03159 pout[j*sx+i]/=2*r;
03160 }
03161 }
03162
03163 cleanup:
03164
03165 if(cpl_error_get_code() != CPL_ERROR_NONE) {
03166 return NULL;
03167 } else {
03168 return out;
03169
03170 }
03171
03172 }
03173
03174
03175
03189
03190
03191 cpl_image *
03192 sinfo_image_smooth_mean_y(cpl_image * inp, const int r)
03193 {
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203 float* pinp=NULL;
03204 float* pout=NULL;
03205 int sx=0;
03206 int sy=0;
03207 int i=0;
03208 int j=0;
03209 int k=0;
03210
03211 cpl_image* out=NULL;
03212
03213 cknull(inp,"Null in put image, exit");
03214 check_nomsg(out=cpl_image_duplicate(inp));
03215 check_nomsg(sx=cpl_image_get_size_x(inp));
03216 check_nomsg(sy=cpl_image_get_size_y(inp));
03217 check_nomsg(pinp=cpl_image_get_data_float(inp));
03218 check_nomsg(pout=cpl_image_get_data_float(out));
03219 for(j=r;j<sy-r;j++) {
03220 for(i=0;i<sx;i++) {
03221 for(k=-r;k<r;k++) {
03222 pout[j*sx+i]+=pinp[(j+k)*sx+i];
03223 }
03224 pout[j*sx+i]/=2*r;
03225 }
03226 }
03227
03228 cleanup:
03229
03230 if(cpl_error_get_code() != CPL_ERROR_NONE) {
03231 return NULL;
03232 } else {
03233 return out;
03234
03235 }
03236
03237 }
03238
03239
03240
03254
03255
03256 cpl_image *
03257 sinfo_image_smooth_median_y(cpl_image * inp, const int r)
03258 {
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268 float* pout=NULL;
03269 int sx=0;
03270 int sy=0;
03271 int i=0;
03272 int j=0;
03273
03274 cpl_image* out=NULL;
03275
03276
03277 cknull(inp,"Null in put image, exit");
03278 check_nomsg(out=cpl_image_duplicate(inp));
03279 check_nomsg(sx=cpl_image_get_size_x(inp));
03280 check_nomsg(sy=cpl_image_get_size_y(inp));
03281 check_nomsg(pout=cpl_image_get_data_float(out));
03282
03283 for(j=r+1;j<sy-r;j++) {
03284 for(i=1;i<sx;i++) {
03285 pout[j*sx+i]=(float)cpl_image_get_median_window(inp,i,j,i,j+r);
03286 }
03287 }
03288
03289 cleanup:
03290
03291 if(cpl_error_get_code() != CPL_ERROR_NONE) {
03292 return NULL;
03293 } else {
03294 return out;
03295
03296 }
03297
03298 }
03299
03300
03313
03314
03315 cpl_image *
03316 sinfo_image_smooth_fft(cpl_image * inp, const int fy)
03317 {
03318
03319 int sx=0;
03320 int sy=0;
03321
03322 cpl_image* out=NULL;
03323 cpl_image* im_re=NULL;
03324 cpl_image* im_im=NULL;
03325 cpl_image* ifft_re=NULL;
03326 cpl_image* ifft_im=NULL;
03327 cpl_image* filter=NULL;
03328
03329 int sigma_x=0;
03330 int sigma_y=fy;
03331
03332 cknull(inp,"Null in put image, exit");
03333 check_nomsg(im_re = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
03334 check_nomsg(im_im = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
03335
03336
03337 check_nomsg(cpl_image_fft(im_re,im_im,CPL_FFT_DEFAULT));
03338
03339 check_nomsg(sx=cpl_image_get_size_x(inp));
03340 check_nomsg(sy=cpl_image_get_size_y(inp));
03341 sigma_x=sx;
03342
03343
03344 check_nomsg(filter = sinfo_gen_lowpass(sx,sy,sigma_x,sigma_y));
03345
03346
03347 cpl_image_multiply(im_re,filter);
03348 cpl_image_multiply(im_im,filter);
03349
03350 sinfo_free_image(&filter);
03351
03352 check_nomsg(ifft_re = cpl_image_duplicate(im_re));
03353 check_nomsg(ifft_im = cpl_image_duplicate(im_im));
03354
03355 sinfo_free_image(&im_re);
03356 sinfo_free_image(&im_im);
03357
03358
03359 check_nomsg(cpl_image_fft(ifft_re,ifft_im,CPL_FFT_INVERSE));
03360 check_nomsg(out = cpl_image_cast(ifft_re, CPL_TYPE_FLOAT));
03361
03362 cleanup:
03363
03364 sinfo_free_image(&ifft_re);
03365 sinfo_free_image(&ifft_im);
03366 sinfo_free_image(&filter);
03367 sinfo_free_image(&im_re);
03368 sinfo_free_image(&im_im);
03369
03370 if(cpl_error_get_code() != CPL_ERROR_NONE) {
03371 return NULL;
03372 } else {
03373 return out;
03374 }
03375
03376 }
03377
03378
03379
03380
03396
03397 static cpl_image *
03398 sinfo_gen_lowpass(const int xs,
03399 const int ys,
03400 const double sigma_x,
03401 const double sigma_y)
03402 {
03403
03404 int i= 0.0;
03405 int j= 0.0;
03406 int hlx= 0.0;
03407 int hly = 0.0;
03408 double x= 0.0;
03409 double y= 0.0;
03410 double gaussval= 0.0;
03411 double inv_sigma_x=1./sigma_x;
03412 double inv_sigma_y=1./sigma_y;
03413
03414 float *data;
03415
03416 cpl_image *lowpass_image=NULL;
03417
03418
03419 lowpass_image = cpl_image_new (xs, ys, CPL_TYPE_FLOAT);
03420 if (lowpass_image == NULL) {
03421 sinfo_msg_error("Cannot generate lowpass filter <%s>",
03422 cpl_error_get_message());
03423 return NULL;
03424 }
03425
03426 hlx = xs/2;
03427 hly = ys/2;
03428
03429 data = cpl_image_get_data_float(lowpass_image);
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441 data[0] = 1.0;
03442
03443
03444 for (i=1 ; i<=hlx ; i++) {
03445 x = i * inv_sigma_x;
03446 gaussval = exp(-0.5*x*x);
03447 data[i] = gaussval;
03448 data[xs-i] = gaussval;
03449 }
03450
03451 for (j=1; j<=hly ; j++) {
03452 y = j * inv_sigma_y;
03453
03454 data[j*xs] = exp(-0.5*y*y);
03455 data[(ys-j)*xs] = exp(-0.5*y*y);
03456
03457 for (i=1 ; i<=hlx ; i++) {
03458
03459 x = i * inv_sigma_x;
03460 gaussval = exp (-0.5*(x*x+y*y));
03461 data[j*xs+i] = gaussval;
03462 data[(j+1)*xs-i] = gaussval;
03463 data[(ys-j)*xs+i] = gaussval;
03464 data[(ys+1-j)*xs-i] = gaussval;
03465
03466 }
03467 }
03468
03469
03470
03471
03472
03473 if(errno != 0)
03474 errno = 0;
03475
03476 return lowpass_image;
03477 }
03478
03479 static void quicksort_int(int* data, int left, int right)
03480 {
03481 int i = left;
03482 int j = right;
03483 int pivot = (i + j) / 2;
03484 double index_value = data[pivot];
03485 do
03486 {
03487 while(data[i] < index_value) i++;
03488 while(data[j] > index_value) j--;
03489 if (i <= j)
03490 {
03491 if(i < j)
03492 {
03493 int tmp = data[i];
03494 data[i]=data[j];
03495 data[j]=tmp;
03496 }
03497 i++;
03498 j--;
03499 }
03500 } while (i <= j);
03501
03502 if (i < right)
03503 {
03504 quicksort_int(data, i, right);
03505 }
03506 if (left < j)
03507 {
03508 quicksort_int(data, left, j);
03509 }
03510 }
03511
03512