(file) Return to imageinterp.c CVS log (file) (dir) Up to [Development] / JSOC / proj / globalhs / apps

  1 tplarson 1.1 
  2              /*
  3               *  imageinterp (modified from obs2helio)                       
  4               *
  5               *  Purpose:
  6               *     Interpolate CCD data to estimate value that would
  7               *     be obtained at specified equal incrememts of heliographic
  8               *     longitude and sine of latitude.
  9               *
 10               *  Description:
 11               *
 12               *     Employs bi-linear or cubic convolution interpolation to map a
 13               *     portion of the solar disk to a rectangular array "cols" by "rows" in
 14               *     width and height respectively.
 15               *
 16               *  Reference:
 17               *
 18               *     Green, Robin M. "Spherical Astronomy," Cambridge University
 19               *     Press, Cambridge, 1985.
 20               *
 21               *  Responsible:  Kay Leibrand                   KLeibrand@solar.Stanford.EDU
 22 tplarson 1.1  *
 23               *  Restrictions:
 24               *     The number of output map rows must be even.
 25               *     The number of output map columns must be less than MAXCOLS.
 26               *     Assumes orientation is a 4 character string with one of the following
 27               *     8 legal values: SESW SENE SWSE SWNW NWNE NWSW NENW NESE 
 28               *
 29               *  Bugs:
 30               *     Possible division by 0 
 31               *
 32               *  Planned updates:
 33               *     Optimize.
 34               *
 35               *  Revision history is at end of file.
 36               */
 37              
 38              #include <math.h>
 39 tplarson 1.4 #include "projection.h"
 40 tplarson 1.1 
 41 tplarson 1.4 char *cvsinfo_imageinterp = "cvsinfo: $Header: imageinterp.c,v $";
 42 tplarson 1.1 
 43              const int kMaxCols = 8192;
 44              const double kOmegaCarr = (360 /  27.27527); /* degrees/day - synodic Carrington rotation rate */
 45              const double kRadsPerDegree = M_PI/180.;
 46              
 47              static void Ccker(double *u, double s);
 48              static double Ccintd(double *f, int nx, int ny, double x, double y);
 49              static double Linintd(double *f, int nx, int ny, double x, double y);
 50              static void Distort(double x, 
 51              		    double y, 
 52              		    double rsun, 
 53              		    int sign, 
 54              		    double *xd, 
 55              		    double *yd, 
 56 tplarson 1.4 		    const LIBPROJECTION_Dist_t *distpars);
 57 tplarson 1.1 
 58              /* Calculate the interpolation kernel. */
 59              void Ccker(double *u, double s)
 60              {
 61                 double s2, s3;
 62                   
 63                 s2= s * s;
 64                 s3= s2 * s;
 65                 u[0] = s2 - 0.5 * (s3 + s);
 66                 u[1] = 1.5*s3 - 2.5*s2 + 1.0;
 67                 u[2] = -1.5*s3 + 2.0*s2 + 0.5*s;
 68                 u[3] = 0.5 * (s3 - s2);
 69              }
 70              
 71              /* Cubic convolution interpolation */
 72              /*
 73               *  Cubic convolution interpolation, based on GONG software, received Apr-88
 74               *  Interpolation by cubic convolution in 2 dimensions with 32-bit double data
 75               *
 76               *  Reference:
 77               *    R.G. Keys in IEEE Trans. Acoustics, Speech, and Signal Processing, 
 78 tplarson 1.1  *    Vol. 29, 1981, pp. 1153-1160.
 79               *
 80               *  Usage:
 81               *    double ccintd (double *f, int nx, int ny, double x, double y)
 82               *
 83               *  Bugs:
 84               *    Currently interpolation within one pixel of edge is not
 85               *      implemented.  If x or y is in this range or off the picture, the
 86               *      function value returned is zero.
 87               *    Only works for double data.
 88               */
 89              double Ccintd(double *f, int nx, int ny, double x, double y)
 90              {
 91                 double  ux[4], uy[4];
 92                 /* Sum changed to double to speed up things */
 93                 double sum;
 94              
 95                 int ix, iy, ix1, iy1, i, j;
 96                   
 97                 if (x < 1. || x >= (double)(nx-2) ||
 98                     y < 1. || y >= (double)(ny-2))
 99 tplarson 1.1      return 0.0;
100                   
101                 ix = (int)x;
102                 iy = (int)y;
103                 Ccker(ux,  x - (double)ix);
104                 Ccker(uy,  y - (double)iy);
105                   
106                 ix1 = ix - 1;
107                 iy1 = iy - 1;
108                 sum = 0.;
109                 for (i = 0; i < 4; i++)
110                   for (j = 0; j < 4; j++)
111                     sum = sum + f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
112                 return sum;
113              }
114              
115              /*
116               *  Bilinear interpolation, based on pipeLNU remap.
117               *
118               *  Reference: 
119               *     Abramowitz, Milton, and Stegun, Irene, "Handbook of Mathematical
120 tplarson 1.1  *     Functions," Dover Publications, New York, 1964.
121               *
122               *  Usage:
123               *    double linintd (double *f, int nx, int ny, double x, double y)
124               *
125               *  Bugs:
126               *    Only works for double data.
127               */
128              
129              double Linintd(double *f, int nx, int ny, double x, double y) 
130              {
131                 double p0, p1, q0, q1;          /* weights                              */
132                 int ilow, jlow;   /* selected CCD pixels                  */
133                 double *fptr;                    /* input array temp                     */
134                 double u;                        
135                   
136                 ilow = (int)floor(x);
137                 jlow = (int)floor(y);
138                 if (ilow < 0) ilow = 0;
139                 if (ilow+1 >= nx) ilow -= 1;
140                 if (jlow < 0) jlow = 0;
141 tplarson 1.1    if (jlow+1 >= ny) jlow -= 1;
142                 p1 = x - ilow;
143                 p0 = 1.0 - p1;
144                 q1 = y - jlow;
145                 q0 = 1.0 - q1;
146                   
147                 /* Bilinear interpolation from four data points. */
148                 u = 0.0;
149                 fptr = f + jlow*nx + ilow;
150                 u += p0 * q0 * *fptr++;
151                 u += p1 * q0 * *fptr;
152                 fptr += nx - 1;
153                 u += p0 * q1 * *fptr++;
154                 u += p1 * q1 * *fptr;
155                 return u;
156              }
157              
158              
159              int SetDistort(int dist, 
160              	       double cubic, 
161              	       double alpha, 
162 tplarson 1.1 	       double beta, 
163              	       double feff,
164 tplarson 1.4  	       LIBPROJECTION_Dist_t *dOut)
165 tplarson 1.1 {
166                 int error = 0;
167              
168                 if (dOut != NULL)
169                 {
170                    int status = 0;
171              
172                    dOut->disttype = dist;
173              
174                    /* disttype == 0 is 'no distortion' and is not an error */
175                    if (dOut->disttype != 0)
176                    {
177              	 if (dOut->disttype == 1) 
178              	 { 
179              	    /* FD */
180              	    dOut->xc = 511.5;
181              	    dOut->yc = 511.5;
182              	    dOut->scale = 1.0;
183              	 }
184              	 else if (dOut->disttype == 2)
185              	 { 
186 tplarson 1.1 	    /* vw */
187              	    dOut->xc = 95.1;
188              	    dOut->yc = 95.1;
189              	    dOut->scale = 5.0;
190              	 }
191              	 else 
192              	 {
193              	    error = 1;
194              	 }
195              
196              	 if (!error)
197              	 {
198              	    dOut->feff = feff;
199              	    dOut->alpha = alpha * kRadsPerDegree;
200              	    beta *= kRadsPerDegree;
201              	    dOut->cosbeta = cos(beta);
202              	    dOut->sinbeta = sin(beta);
203              	    dOut->cdist = cubic;
204              
205              	    if (status != CMDPARAMS_SUCCESS)
206              	    {
207 tplarson 1.1 	       error = 1;
208              	    }
209              
210              	 }
211              
212                    } /* disttype != 0*/
213                 }
214                 else
215                 {
216                    error = 1;
217                 }
218              
219                 return error;
220              }
221              
222              
223              void Distort(double x, 
224              	     double y, 
225              	     double rsun, 
226              	     int sign, 
227              	     double *xd, 
228 tplarson 1.1 	     double *yd, 
229 tplarson 1.4 	     const LIBPROJECTION_Dist_t *distpars)
230 tplarson 1.1 {
231                 /*
232                   For sign=+1 transforms ideal coordinates (x,y) to distorted
233                   coordinates (xd,yd). rsun needed to correct for scale error.
234                   For sign=-1 ideal and distorted coordinates are swapped.
235                   Units are pixels from lower left corner.
236                   Adapted from /home/schou/calib/dist/distort.pro
237                   Note that rsun must be passed in FD pixels!
238                 */
239                   
240                 double xx,yy,xxl,yyl,x0,y0,x00,y00,x0l,y0l,epsx,epsy,rdist;
241                   
242                 if (distpars->disttype == 0) 
243                 {
244                    *xd=x;
245                    *yd=y;
246                    return;
247                 }
248                 /* Convert fo FD pixel scale*/
249              
250                   rsun=rsun*distpars->scale;
251 tplarson 1.1 
252                 /* Don't do anyway since rsun already corrected. Don't get me started... */
253                 /* above comment no longer applies, rsun is now untouched in o2helio (v2helio) */  
254                   
255                 /* Shift zero point to nominal image center and convert to FD pixel scale */
256                   
257                 x00=distpars->scale*(x-distpars->xc);
258                 y00=distpars->scale*(y-distpars->yc);
259                   
260                 /* Radial distortion */
261                   
262                 rdist=distpars->cdist*(x00*x00+y00*y00-rsun*rsun);
263                   
264                 x0=x00+rdist*x00;
265                 y0=y00+rdist*y00;
266                   
267                 /* Distortion due to CCD tilt */
268                   
269                 /* First rotate coordinate system */
270                 x0l=x0*distpars->cosbeta+y0*distpars->sinbeta;
271                 y0l=-x0*distpars->sinbeta+y0*distpars->cosbeta;
272 tplarson 1.1      
273                 /* Apply distortion */
274                 xxl=x0l*(1.-distpars->alpha*distpars->alpha/4.+y0l/distpars->feff*distpars->alpha);
275                 yyl=y0l*(1.+distpars->alpha*distpars->alpha/4.+y0l/distpars->feff*distpars->alpha) - 
276                   rsun*rsun/distpars->feff*distpars->alpha;
277                   
278                 /* Rotate coordinates back */
279                 xx=xxl*distpars->cosbeta-yyl*distpars->sinbeta;
280                 yy=xxl*distpars->sinbeta+yyl*distpars->cosbeta;
281                   
282                 /* Total distortion */
283                   
284                 epsx=xx-x00;
285                 epsy=yy-y00;
286                   
287                 /* Return distorted values. Cheating with inverse transform. */
288                   
289                 *xd=x+sign*epsx/distpars->scale;
290                 *yd=y+sign*epsy/distpars->scale;
291              }
292              
293 tplarson 1.1 
294              int imageinterp(
295                      float *V,  /* input velocity array    */
296                      /* assumed declared V[ypixels][xpixels]  */
297                      float *U,  /* output projected array   */
298                      
299 tplarson 1.2         int xpixels, /* x width of input array */
300                      int ypixels, /* y width of input array */
301                      double   x0, /* x pixel address of disk center		*/
302                      double   y0, /* y pixel address of disk center		*/
303                      double   P,  /* angle between CCD y-axis and solar vertical */
304                                   /* positive to the east (CCW) */
305 tplarson 1.1         double   rsun,  /* pixels */
306 tplarson 1.3         double   Rmax, /* maximum disk radius to use (e.g. 0.95)	*/
307                      int      NaN_beyond_rmax,
308 tplarson 1.1         int interpolation, /* option */
309                      int cols,  /* width of output array   */
310                      int rows,  /* height of output array   */
311                      double   vsign,
312 tplarson 1.4         const LIBPROJECTION_Dist_t *distpars)
313 tplarson 1.1 {
314                   
315                 float u;   /* output temp    */
316                 double x, y;   /* CCD location of desired point */
317                 int row, col;   /* index into output array  */
318                 int rowoffset;
319 tplarson 1.3    double xratio, yratio, Rmax2;
320 tplarson 1.1 
321                 long i;
322                 double *vdp;
323                 float *vp;
324 tplarson 1.2    double xtmp, ytmp;
325 tplarson 1.1      
326                 double *VD;
327                 VD=(double *)(malloc(xpixels*ypixels*sizeof(double)));
328                 vdp=VD;
329                 vp=V;
330                 for (i=0;i<xpixels*ypixels;i++) *vdp++=(double)*vp++;
331 tplarson 1.3 
332                 Rmax2 = Rmax*Rmax*rsun*rsun;
333 tplarson 1.1      
334                 if (cols > kMaxCols) 
335                 {
336 tplarson 1.4       return kLIBPROJECTION_DimensionMismatch;
337 tplarson 1.1    }
338              
339                   
340 tplarson 1.4    if (interpolation != kLIBPROJECTION_InterCubic && interpolation != kLIBPROJECTION_InterBilinear) 
341 tplarson 1.1    {     
342 tplarson 1.4       return kLIBPROJECTION_UnsupportedInterp;
343 tplarson 1.1    }
344              
345                 xratio=(double)xpixels/cols;
346                 yratio=(double)ypixels/rows;
347                   
348                 for (row = 0; row < rows; row++) {
349               
350                    rowoffset = row*cols;
351                
352                    for (col = 0; col < cols; col++) {
353              
354 tplarson 1.3          xtmp = (col + 0.5)*xratio - 0.5 - x0;
355                       ytmp = (row + 0.5)*yratio - 0.5 - y0;
356                       if ((xtmp*xtmp + ytmp*ytmp) >= Rmax2)
357                       {
358                         *(U + rowoffset + col) = (NaN_beyond_rmax) ? DRMS_MISSING_FLOAT : (float)0.0;
359                         continue;
360                       }
361                       x= x0 + xtmp*cos(P) - ytmp*sin(P);
362                       y= y0 + xtmp*sin(P) + ytmp*cos(P);
363 tplarson 1.1 
364                       Distort(x, y, rsun, +1, &x, &y, distpars);
365              
366 tplarson 1.4          if (interpolation == kLIBPROJECTION_InterCubic) 
367 tplarson 1.1          {
368                          u = (float)(vsign * Ccintd (VD,xpixels,ypixels,x,y));
369                       }
370 tplarson 1.4          else if (interpolation == kLIBPROJECTION_InterBilinear) 
371 tplarson 1.1          {
372                          u = (float)(vsign * Linintd (VD,xpixels,ypixels,x,y));
373                       }
374              
375                       *(U + rowoffset + col) = u;
376                    }
377                 }
378                 free(VD);
379 tplarson 1.4    return kLIBPROJECTION_Success;
380 tplarson 1.1 }

Karen Tian
Powered by
ViewCVS 0.9.4