00001 #include "sadie.h"
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 void FILTER (
00040 IMAGE *in,
00041 double (*flt)(double, double, double, double),
00042
00043 double xradius,
00044 double yradius,
00045 double option,
00046
00047
00048
00049
00050 IMAGE **out
00051
00052
00053 ) { register short i, j, k;
00054 char msg[SLEN];
00055 double fx, fy, ampl, pinc, psum;
00056 IMAGE *scratch=0;
00057
00058 if (TIMES) TIMING(T_FILTER);
00059 if (NAMES) {
00060 MESSAGE('I',"");
00061 MESSAGE('I',"FILTER");
00062 MESSAGE('I',"");
00063 sprintf(msg," Input image: %s",in->text);
00064 MESSAGE('I',msg);
00065 if (flt == FLTBOX) {
00066 MESSAGE('I'," Box filter");
00067 } else if (flt == FLTCONE) {
00068 MESSAGE('I'," Cone filter");
00069 } else if (flt == FLTCYL) {
00070 MESSAGE('I'," Cylinder filter");
00071 } else if (flt == FLTEXP) {
00072 MESSAGE('I'," Exponential filter");
00073 } else if (flt == FLTGAUSS) {
00074 MESSAGE('I'," Gaussian filter");
00075 }
00076 sprintf(msg," Filter radius: cycles/line: %8.4f",yradius);
00077 MESSAGE('I',msg);
00078 sprintf(msg," cycles/pixel: %8.4f",xradius);
00079 MESSAGE('I',msg);
00080 if (option == 0.0) {
00081 MESSAGE('I'," Low-pass filter");
00082 } else if (option == 1.0) {
00083 MESSAGE('I'," High-pass filter");
00084 } else {
00085 sprintf(msg," Parametric high-boost filter, c = %5.2f",option);
00086 MESSAGE('I',msg);
00087 }
00088 MESSAGE('I'," ...............");
00089 }
00090
00091
00092 if (!CHECKIMG(in)) {
00093 MESSAGE('E'," Can't identify image.");
00094 goto the_end;
00095 } else if (in->nlin != 1L<<rnd(log10((double)in->nlin)/log10(2.0))) {
00096 MESSAGE('E'," Number of lines must be a power of two.");
00097 goto the_end;
00098 } else if (in->npix != 1L<<rnd(log10((double)in->npix)/log10(2.0))) {
00099 MESSAGE('E'," Number of pixels/line must be a power of two.");
00100 goto the_end;
00101 } else if (!flt) {
00102 MESSAGE('E'," Can't identify filter function.");
00103 goto the_end;
00104 }
00105
00106
00107 FFT2D(in,FORWARD,&scratch);
00108 if (ABORT || !scratch) goto the_end;
00109 sprintf(scratch->text,"Scratch");
00110
00111
00112 if (LINES && !PROGRESS(psum=0.0)) goto the_end;
00113 pinc = 1.0/(double)scratch->nbnd/(double)(scratch->nlin/2-1);
00114
00115
00116 for (i=0; i<scratch->nbnd; i++) {
00117 for (j=1; j<scratch->nlin/2; j++) {
00118 fy = 0.5-(double)j/(double)scratch->nlin;
00119 for (k=2; k<scratch->npix/2-1; k+=2) {
00120 fx = 0.5-(double)k/(double)(scratch->npix);
00121 ampl = (*flt)(fx,fy,xradius,yradius);
00122 if (option != 0.0) ampl = option - ampl;
00123
00124
00125 scratch->data[i][j][k] *= ampl;
00126 scratch->data[i][j][scratch->npix-k] *= ampl;
00127
00128
00129 scratch->data[i][scratch->nlin-j][k] = scratch->data[i][j][scratch->npix-k];
00130 scratch->data[i][scratch->nlin-j][scratch->npix-k] = scratch->data[i][j][k];
00131
00132
00133 scratch->data[i][j][k+1] *= ampl;
00134 scratch->data[i][j][scratch->npix-k+1] *= ampl;
00135
00136
00137 scratch->data[i][scratch->nlin-j][k+1] = -scratch->data[i][j][scratch->npix-k+1];
00138 scratch->data[i][scratch->nlin-j][scratch->npix-k+1] = -scratch->data[i][j][k+1];
00139 }
00140 if (LINES && !PROGRESS(psum+=pinc)) goto the_end;
00141 }
00142 }
00143
00144
00145 for (i=0; i<scratch->nbnd; i++) {
00146 for (j=1; j<scratch->nlin; j++) {
00147 fx = 0.0;
00148 fy = 0.5 - (double)j/(double)scratch->nlin;
00149 ampl = (*flt)(fx,fy,xradius,yradius);
00150 if (option != 0.0) ampl = option - ampl;
00151 scratch->data[i][j][scratch->npix/2] *= ampl;
00152 scratch->data[i][j][scratch->npix/2+1] *= ampl;
00153 }
00154 }
00155 for (i=0; i<scratch->nbnd; i++) {
00156 for (k=2; k<scratch->npix; k+=2) {
00157 fx = 0.5 - (double)k/(double)scratch->npix;
00158 fy = 0.0;
00159 ampl = (*flt)(fx,fy,xradius,yradius);
00160 if (option != 0.0) ampl = option - ampl;
00161 scratch->data[i][scratch->nlin/2][k] *= ampl;
00162 scratch->data[i][scratch->nlin/2][k+1] *= ampl;
00163 }
00164 }
00165
00166
00167 for (i=0; i<scratch->nbnd; i++) {
00168 for (j=0; j<scratch->nlin; j++) {
00169 fx = 0.5;
00170 fy = 0.5-(double)j/(double)scratch->nlin;
00171 ampl = (*flt)(fx,fy,xradius,yradius);
00172 if (option != 0.0) ampl = option - ampl;
00173 scratch->data[i][j][0] *= ampl;
00174 scratch->data[i][j][1] *= ampl;
00175 }
00176 }
00177 for (i=0; i<scratch->nbnd; i++) {
00178 for (k=2; k<scratch->npix; k+=2) {
00179 fx = 0.5-(double)k/(double)scratch->npix;
00180 fy = 0.5;
00181 ampl = (*flt)(fx,fy,xradius,yradius);
00182 if (option != 0.0) ampl = option - ampl;
00183 scratch->data[i][0][k] *=ampl;
00184 scratch->data[i][0][k+1] *= ampl;
00185 }
00186 }
00187
00188
00189 FFT2D(scratch,INVERSE,out);
00190
00191 the_end:
00192 if (scratch) RELMEM(scratch);
00193 if (TIMES) TIMING(T_EXIT);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 double FLTBOX (
00206 double fx,
00207 double fy,
00208 double xradius,
00209 double yradius
00210
00211 ) { double ampl;
00212
00213 if (TIMES) TIMING(T_FLTBOX);
00214
00215 ampl = fabs(fx/xradius) <= 1.0 && fabs(fy/yradius) <= 1.0 ? 1.0 : 0.0;
00216
00217 the_end:
00218 if (TIMES) TIMING(T_EXIT);
00219 return(ampl);
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 double FLTCONE (
00232 double fx,
00233 double fy,
00234 double xradius,
00235 double yradius
00236
00237 ) { double ampl;
00238
00239 if (TIMES) TIMING(T_FLTCONE);
00240
00241 ampl = max(0.0,1.0-sqrt((fx*fx)/(xradius*xradius)+(fy*fy)/(yradius*yradius)));
00242
00243 the_end:
00244 if (TIMES) TIMING(T_EXIT);
00245 return(ampl);
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 double FLTCYL (
00258 double fx,
00259 double fy,
00260 double xradius,
00261 double yradius
00262
00263 ) { double ampl;
00264
00265 if (TIMES) TIMING(T_FLTCYL);
00266
00267 ampl = sqrt((fx*fx)/(xradius*xradius)+(fy*fy)/(yradius*yradius)) <= 1.0 ? 1.0 : 0.0;
00268
00269 the_end:
00270 if (TIMES) TIMING(T_EXIT);
00271 return(ampl);
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 double FLTEXP (
00285 double fx,
00286 double fy,
00287 double xradius,
00288 double yradius
00289
00290 ) { double ampl;
00291
00292 if (TIMES) TIMING(T_FLTEXP);
00293
00294 ampl = exp(-sqrt((fx*fx)/(xradius*xradius)+(fy*fy)/(yradius*yradius)));
00295
00296 the_end:
00297 if (TIMES) TIMING(T_EXIT);
00298 return(ampl);
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 double FLTGAUSS (
00311 double fx,
00312 double fy,
00313 double xradius,
00314 double yradius
00315
00316 ) { double ampl;
00317
00318 if (TIMES) TIMING(T_FLTGAUSS);
00319
00320 ampl = exp(-((fx*fx)/(xradius*xradius)+(fy*fy)/(yradius*yradius)));
00321
00322 the_end:
00323 if (TIMES) TIMING(T_EXIT);
00324 return(ampl);
00325 }