Changeset 6399
- Timestamp:
- Feb 9, 2006, 9:40:40 AM (20 years ago)
- Location:
- trunk/psphot/src
- Files:
-
- 1 added
- 4 edited
-
Makefile.am (modified) (1 diff)
-
psphot.h (modified) (1 diff)
-
psphotCleanup.c (added)
-
psphotImageMedian.c (modified) (2 diffs)
-
psphotReadout.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/Makefile.am
r6379 r6399 39 39 psphotMagnitudes.c \ 40 40 psphotRadiusChecks.c \ 41 psphotImageMedian.c \ 41 42 psLine.c \ 42 43 psSparse.c \ -
trunk/psphot/src/psphot.h
r6379 r6399 39 39 pmPSF *psphotChoosePSF (psMetadata *config, psArray *sources, psStats *sky); 40 40 void psphotOutput (pmReadout *readout, psMetadata *arguments); 41 psImage *psphotImageMedian (pmReadout *readout, psMetadata *config, psStats *sky); 41 42 42 43 // optional object analysis steps -
trunk/psphot/src/psphotImageMedian.c
r6324 r6399 1 1 # include "psphot.h" 2 double psImageClippedStats (psImage *image, psImage *mask, psU8 maskValue, double fmin, double fmax); 3 void fsort (float *value, int N); 4 5 // random number seed to select a fraction of the image pixels 6 static psRandom *rnd; 7 8 // use no more than MAX_SAMPLE_PIXELS pixels for each median box 9 static int MAX_SAMPLE_PIXELS; 2 10 3 11 // generate the median in NxN boxes, clipping heavily 4 // build a 2D clipped spline to the data (toss out the outliers? 5 12 // linear interpolation to generate full-scale model 6 13 psImage *psphotImageMedian (pmReadout *readout, psMetadata *config, psStats *sky) 7 14 { 8 15 bool status; 9 16 psRegion region; 17 18 rnd = psRandomAlloc (PS_RANDOM_TAUS, 0); 19 MAX_SAMPLE_PIXELS = psMetadataLookupF32 (&status, config, "IMSTATS_NPIX"); 20 if (!status) MAX_SAMPLE_PIXELS = 1000; 10 21 11 22 // fit background to subset of image points within 3 sigma of sky 12 23 psTimerStart ("psphot"); 13 psRandom *rnd = psRandomAlloc (PS_RANDOM_TAUS, 0);14 24 15 25 psImage *image = readout->image; 16 26 psImage *mask = readout->mask; 17 27 18 bool status = false; 19 int Nx = image->numCols + image->col0; 20 int Ny = image->numRows + image->row0; 21 int xbin = psMetadataLookupS32 (&status, config, "BACKGROUND_XBIN"); 22 if (!status) {xbin = 64;} 23 int ybin = psMetadataLookupS32 (&status, config, "BACKGROUND_YBIN"); 24 if (!status) {ybin = 64;} 25 26 // we slide the box in half-steps from -0.5 off the left edge to +0.5 off the right edge 27 int nx = 2 + 2 * Nx / xbin; 28 int ny = 2 + 2 * Ny / ybin; 29 30 psStats *stats = psStatsAlloc (PS_STATS_CLIPPED_MEAN, PS_STATS_CLIPPED_STDEV); 31 psImage *medimage = psImageAlloc (nx, ny, PS_TYPE_F32); 32 33 psVector *xval = psVectorAlloc (nx, PS_TYPE_F32); 34 psVector *yval = psVectorAlloc (ny, PS_TYPE_F32); 28 // dimensions of input & output image 29 int Nx = image->numCols; 30 int Ny = image->numRows; 31 32 // scaling factor 33 int DX = psMetadataLookupS32 (&status, config, "BACKGROUND_XBIN"); 34 if (!status) {DX = 64;} 35 int DY = psMetadataLookupS32 (&status, config, "BACKGROUND_YBIN"); 36 if (!status) {DY = 64;} 37 38 // overhang : we will balance this evenly 39 int dx = (Nx % DX) / 2; 40 int dy = (Ny % DY) / 2; 41 42 // dimensions of binned image 43 int nx = (Nx % DX) ? (int)(Nx / DX) + 1 : Nx / DX; 44 int ny = (Ny % DY) ? (int)(Ny / DY) + 1 : Ny / DY; 45 46 // psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 47 psImage *model = psImageAlloc (nx, ny, PS_TYPE_F32); 35 48 36 49 // measure clipped median for subimages 37 for (int iy = -1; iy < ny - 1; iy++) { 38 for (int ix = -1; ix < nx - 1; ix++) { 39 int sx = 0.5*ix*xbin; 40 int sy = 0.5*iy*ybin; 41 region = psRegionSet (sx, sx + xbin, sy, sy + ybin); 42 region = psRegionForImage (readout->image, region); 43 psImage *subset = psImageSubset (readout->image, region); 44 stats = psImageStats (stats, subset); 45 46 // XXX filter these on the clippedStdev? 47 medimage->data.F32[iy][ix] = stats->clippedMean; 48 49 } 50 } 51 for (int ix = -1; ix < nx - 1; ix++) { 52 xval->data.F32[ix] = 0.5*ix*xbin + 0.5*xbin; 53 } 54 for (int iy = -1; iy < ny - 1; iy++) { 55 yval->data.F32[iy] = 0.5*iy*ybin + 0.5*ybin; 56 } 57 58 // x-dir / y-dir 59 psImage *devimage = psImageFitSpline (medimage, true); 60 psImage *background = psImageEvalSpline (medimage, devimage, xval, yval, Nx, Ny); 61 62 // this is a very inefficient way to evaluate the function.. 63 // lame, temporary step to zero masked pixels 50 for (int iy = 0; iy < ny; iy++) { 51 for (int ix = 0; ix < nx; ix++) { 52 // sx, sy are in parent coords 53 int sx = ix*DX - dx + image->col0; 54 int sy = iy*DY - dy + image->row0; 55 region = psRegionSet (sx, sx + 2*DX, sy, sy + 2*DY); 56 region = psRegionForImage (image, region); 57 psImage *subset = psImageSubset (image, region); 58 psImage *submask = psImageSubset (mask, region); 59 60 model->data.F32[iy][ix] = psImageClippedStats (subset, submask, 0xff, 0.25, 0.50); 61 62 psFree (subset); 63 psFree (submask); 64 65 // XXX psImageStats is still very inefficient and poorly coded... 66 // stats = psImageStats (stats, subset, maskset, 0xff); 67 // model->data.F32[iy][ix] = stats->clippedMean; 68 } 69 } 70 psLogMsg ("psphot", 3, "build median image: %f sec\n", psTimerMark ("psphot")); 71 72 // linear interpolation to full-scale 73 74 psImage *background = psImageAlloc (Nx, Ny, PS_TYPE_F32); 75 76 // XXX this code skips the initial pixels 77 for (int Iy = 0; Iy < ny-1; Iy ++) { 78 for (int Ix = 0; Ix < nx-1; Ix ++) { 79 80 float V00 = model->data.F32[Iy+0][Ix+0]; 81 float V01 = model->data.F32[Iy+0][Ix+1]; 82 float V10 = model->data.F32[Iy+1][Ix+0]; 83 float V11 = model->data.F32[Iy+1][Ix+1]; 84 85 // a single binned pixel quad 86 // (Xs,Ys) : (Xe,Ye) : binned pixel centers in unbinned coords 87 // corresponding to (Ix,Iy), (Ix+1,Iy+1) 88 int Xs = (Ix + 1)*DX - dx; 89 int Ys = (Iy + 1)*DY - dy; 90 int Xe = Xs + DX; 91 int Ye = Ys + DY; 92 93 for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) { 94 float Vxs = (V10 - V00)*(iy - Ys) / DY + V00; 95 float Vxe = (V11 - V01)*(iy - Ys) / DY + V01; 96 float dV = (Vxe - Vxs) / DX; 97 float V = Vxs; 98 for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) { 99 background->data.F32[iy][ix] = V; 100 V += dV; 101 } 102 } 103 } 104 } 105 106 // side pixels 107 int Xs = DX - dx; 108 int Xe = nx*DX - dx; 109 for (int Iy = 0; Iy < ny - 1; Iy++) { 110 111 int Ys = (Iy + 1)*DY - dy; 112 int Ye = Ys + DY; 113 114 // leading edge 115 float V0 = model->data.F32[Iy+0][0]; 116 float V1 = model->data.F32[Iy+1][0]; 117 float dV = (V1 - V0) / DY; 118 float V = V0; 119 for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) { 120 for (int ix = 0; ix < Xs; ix++) { 121 background->data.F32[iy][ix] = V; 122 } 123 V += dV; 124 } 125 126 // trailing edge 127 V0 = model->data.F32[Iy+0][nx-1]; 128 V1 = model->data.F32[Iy+1][nx-1]; 129 dV = (V1 - V0) / DY; 130 V = V0; 131 for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) { 132 for (int ix = Xe; ix < Nx; ix++) { 133 background->data.F32[iy][ix] = V; 134 } 135 V += dV; 136 } 137 } 138 139 // top and bottom pixels 140 int Ys = DY - dy; 141 int Ye = ny*DY - dy; 142 for (int Ix = 0; Ix < nx - 1; Ix++) { 143 144 int Xs = (Ix + 1)*DX - dx; 145 int Xe = Xs + DX; 146 147 // top edge 148 float V0 = model->data.F32[0][Ix+0]; 149 float V1 = model->data.F32[0][Ix+1]; 150 float dV = (V1 - V0) / DX; 151 for (int iy = 0; iy < Ys; iy++) { 152 float V = V0; 153 for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) { 154 background->data.F32[iy][ix] = V; 155 V += dV; 156 } 157 } 158 159 // bottom edge 160 V0 = model->data.F32[ny-1][Ix+0]; 161 V1 = model->data.F32[ny-1][Ix+1]; 162 dV = (V1 - V0) / DX; 163 for (int iy = Ye; iy < Ny; iy++) { 164 float V = V0; 165 for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) { 166 background->data.F32[iy][ix] = V; 167 V += dV; 168 } 169 } 170 } 171 172 // the four corners 173 { 174 float V; 175 // 0,0 176 V = model->data.F32[0][0]; 177 for (int iy = 0; iy < DY - dy; iy++) { 178 for (int ix = 0; ix < DX - dx; ix++) { 179 background->data.F32[iy][ix] = V; 180 } 181 } 182 // Nx,0 183 V = model->data.F32[0][nx-1]; 184 for (int iy = 0; iy < DY - dy; iy++) { 185 for (int ix = nx*DX - dx; ix < Nx; ix++) { 186 background->data.F32[iy][ix] = V; 187 } 188 } 189 // 0,Ny 190 V = model->data.F32[ny-1][0]; 191 for (int iy = ny*DY - dy; iy < Ny; iy++) { 192 for (int ix = 0; ix < DX - dx; ix++) { 193 background->data.F32[iy][ix] = V; 194 } 195 } 196 // Nx,Ny 197 V = model->data.F32[nx-1][ny-1]; 198 for (int iy = ny*DY - dy; iy < Ny; iy++) { 199 for (int ix = nx*DX - dx; ix < Nx; ix++) { 200 background->data.F32[iy][ix] = V; 201 } 202 } 203 } 204 psLogMsg ("psphot", 3, "build resampled image: %f sec\n", psTimerMark ("psphot")); 205 206 // subtract the background model 64 207 for (int j = 0; j < image->numRows; j++) { 65 208 for (int i = 0; i < image->numCols; i++) { … … 69 212 } 70 213 } 71 psFree (medimage); 72 psFree (devimage); 73 psFree (rnd); // XXX should this be made available at a higher level? 74 75 psLogMsg ("psphot", 3, "fit background model: %f sec\n", psTimerMark ("psphot")); 214 psLogMsg ("psphot", 3, "subtracted background model: %f sec\n", psTimerMark ("psphot")); 215 psFree (rnd); 76 216 return (background); 77 217 } 218 219 double psImageClippedStats (psImage *image, psImage *mask, psU8 maskValue, double fmin, double fmax) { 220 221 double value; 222 int nx = image->numCols; 223 int ny = image->numRows; 224 225 if (nx*ny <= 0) return 0.0; 226 227 int Nsubset = PS_MIN (MAX_SAMPLE_PIXELS, nx*ny); 228 int Npixels = nx*ny; 229 230 psVector *values = psVectorAlloc (Nsubset, PS_TYPE_F32); 231 232 float min = values->data.F32[0]; 233 float max = values->data.F32[0]; 234 235 int n = 0; 236 for (int i = 0; i < Nsubset; i++) { 237 double frnd = psRandomUniform (rnd); 238 int pixel = Npixels * frnd; 239 int ix = pixel % nx; 240 int iy = pixel / nx; 241 242 if (mask->data.U8[iy][ix] & maskValue) continue; 243 244 value = image->data.F32[iy][ix]; 245 min = PS_MIN (value, min); 246 max = PS_MIN (value, max); 247 values->data.F32[n] = value; 248 n++; 249 } 250 values->n = n; 251 252 int imin = fmin * n; 253 int imax = fmax * n; 254 int npts = imax - imin + 1; 255 256 fsort (values->data.F32, n); 257 258 value = 0; 259 for (int i = imin; (i <= imax) && (i < n); i++) { 260 value += values->data.F32[i]; 261 } 262 value = value / npts; 263 264 psFree (values); 265 return value; 266 } 267 268 void fsort (float *value, int N) { 269 270 int l,j,ir,i; 271 float temp; 272 273 if (N < 2) return; 274 l = N >> 1; 275 ir = N - 1; 276 for (;;) { 277 if (l > 0) { 278 temp = value[--l]; 279 } 280 else { 281 temp = value[ir]; 282 value[ir] = value[0]; 283 if (--ir == 0) { 284 value[0] = temp; 285 return; 286 } 287 } 288 i = l; 289 j = (l << 1) + 1; 290 while (j <= ir) { 291 if (j < ir && value[j] < value[j+1]) ++j; 292 if (temp < value[j]) { 293 value[i]=value[j]; 294 j += (i=j) + 1; 295 } 296 else j = ir + 1; 297 } 298 value[i] = temp; 299 } 300 } 301 -
trunk/psphot/src/psphotReadout.c
r6379 r6399 11 11 psPolynomial2D *model = NULL; 12 12 13 psphotSaveImage (NULL, readout->mask, "mask.fits"); 14 psphotSaveImage (NULL, readout->image, "image.fits"); 15 psphotSaveImage (NULL, readout->weight, "weight.fits"); 13 psphotImageMedian (readout, config, sky); 16 14 17 15 // measure image stats for initial guess
Note:
See TracChangeset
for help on using the changeset viewer.
