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