Changeset 14726
- Timestamp:
- Sep 3, 2007, 10:29:07 AM (19 years ago)
- Location:
- branches/eam_branch_20070830/psLib
- Files:
-
- 3 edited
-
src/imageops/psImageMap.c (modified) (6 diffs)
-
src/imageops/psImagePixelInterpolate.c (modified) (3 diffs)
-
test/imageops/tap_psImageMap.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branch_20070830/psLib/src/imageops/psImageMap.c
r14725 r14726 7 7 * @author Eugene Magnier, IfA 8 8 * 9 * @version $Revision: 1.1.2. 3$ $Name: not supported by cvs2svn $10 * @date $Date: 2007-09-0 2 20:29:50$9 * @version $Revision: 1.1.2.4 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2007-09-03 20:29:07 $ 11 11 * 12 12 * Copyright 2007 Institute for Astronomy, University of Hawaii … … 63 63 64 64 psImage *mask = psImageAlloc (map->map->numCols, map->map->numRows, PS_TYPE_MASK); 65 psImage *xCoord = psImageAlloc (map->map->numCols, map->map->numRows, PS_TYPE_F32); 66 psImage *yCoord = psImageAlloc (map->map->numCols, map->map->numRows, PS_TYPE_F32); 65 67 66 68 // accumulate the values for each map pixel 67 69 68 // we can do this by accumulating a sub-vectorfor each cell69 psArray * vectors = psArrayAlloc (map->map->numCols*map->map->numRows);70 for (int i = 0; i < vectors->n; i++) {71 vectors->data[i] = psVectorAllocEmpty (4, PS_TYPE_F32);70 // we can do this by accumulating a vector of pixel indexes for each cell 71 psArray *pixelSets = psArrayAlloc (map->map->numCols*map->map->numRows); 72 for (int i = 0; i < pixelsSets->n; i++) { 73 pixelSets->data[i] = psVectorAllocEmpty (4, PS_TYPE_S32); 72 74 } 73 75 // associate each value with a cell 74 76 for (int i = 0; i < x->n; i++) { 75 77 // XXX use the psImageUnbin command to convert from x,y, to xRuff,yRuff? 76 78 int xRuff = x->data.F32[i] / map->binning->nXbin; 77 79 int yRuff = y->data.F32[i] / map->binning->nYbin; … … 79 81 int bin = xRuff + yRuff*map->map->numCols; 80 82 81 psVector * vector = vectors->data[bin];82 vector->data.F32[vector->n] = f->data.F32[i];83 psVector *pixels = pixelSets->data[bin]; 84 pixels->data.S32[pixels->n] = i; 83 85 psVectorExtend (vector, 4, 1); 84 86 } 85 87 88 // accumulate the x,y coords for each point to calculate the mean position. 86 89 int Nx = map->map->numCols; 87 90 int Ny = map->map->numRows; … … 89 92 for (int ix = 0; ix < Nx; ix++) { 90 93 91 // select the vector 92 psVector *vector = vectors->data[ix + iy*Nx]; 94 // select the vector. use psImageUnbin command to convert xRuff,yRuff to 95 // xFine,yFine 96 psVector *pixels = pixelSets->data[ix + iy*Nx]; 97 98 psVector xCell = psVectorAlloc (pixels->n, PS_TYPE_F32); 99 psVector yCell = psVectorAlloc (pixels->n, PS_TYPE_F32); 100 psVector fCell = psVectorAlloc (pixels->n, PS_TYPE_F32); 101 102 for (int i = 0; i < pixels->n; i++) { 103 bin = pixels->data.S32[i]; 104 xCell->data.F32[i] = x->data.F32[bin]; 105 yCell->data.F32[i] = y->data.F32[bin]; 106 fCell->data.F32[i] = f->data.F32[bin]; 107 } 93 108 94 109 // reset the stats to avoid contamination from the previous loop … … 96 111 97 112 // get the value 98 if (psVectorStats (map->stats, vector, NULL, NULL, 0)) { 113 // XXX need to supply a mask and skip the masked pixels when calculating the centroid 114 // this will not in general be properly weighted... 115 if (psVectorStats (map->stats, fCell, NULL, NULL, 0)) { 99 116 mask->data.U8[iy][ix] = 0; 100 117 // XXX ensure only one option is selected, or save both position and width 101 118 map->map->data.F32[iy][ix] = psStatsGetValue (map->stats, map->stats->options); 119 120 // calculate the mean position and save: 121 psVectorStats (meanStat, xCell, NULL, NULL, 0); 122 xCoord->data.F32[iy][ix] = psStatsGetValue (meanStat, meanStat->options); 123 psVectorStats (meanStat, yCell, NULL, NULL, 0); 124 yCoord->data.F32[iy][ix] = psStatsGetValue (meanStat, meanStat->options); 102 125 } else { 103 126 mask->data.U8[iy][ix] = 1; 104 127 } 128 129 psFree (xCell); 130 psFree (yCell); 131 psFree (fCell); 105 132 } 106 133 } 134 135 // at this point, for each map pixel, we have (f,x,y), or the pixel is masked. 107 136 108 137 psImage *state = psImagePixelInterpolateState (&map->nBad, &map->nPoor, mask, 0xff); … … 112 141 } 113 142 143 // fit the valid pixels to (0,1,2) order polynomials, interpolate values to the pixel center 144 // XXX I need to be careful about the pixel coordinates: center is 0,0 or 0.5, 0.5? 145 psImagePixelInterpolateCenters (map->map, xCoord, yCoord, state, mask, 0xff); 146 psFree (xCoord); 147 psFree (yCoord); 148 114 149 psImagePixelInterpolatePoor (map->map, state, mask, 0xff); 150 115 151 return true; 116 152 } -
branches/eam_branch_20070830/psLib/src/imageops/psImagePixelInterpolate.c
r14725 r14726 11 11 * @author Eugene Magnier, IfA 12 12 * 13 * @version $Revision: 1.1.2. 4$ $Name: not supported by cvs2svn $14 * @date $Date: 2007-09-0 2 20:29:50$13 * @version $Revision: 1.1.2.5 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2007-09-03 20:29:07 $ 15 15 * 16 16 * Copyright 2007 Institute for Astronomy, University of Hawaii … … 163 163 break; } 164 164 165 // XXX should I use 1 1D polynomial fitting all unmasked pixels in the 3x3 grid? 166 // XXX that would automatically extend to regions where only 2 pixels are valid... 165 167 case PS_IMAGE_INTERPOLATE_LL: { 166 168 // fit a plane to the 3 pixels at (0,1),(1,0),(1,1), extend to pixel at (0,0) … … 196 198 return true; 197 199 } 198 199 200 201 // interpolate the good pixels to their true centers 202 bool psImagePixelInterpolateCenter (psImage *value, psImage *xCoord, psImage *yCoord, psImage *state, psImage *mask, psMaskType maskVal) { 203 204 assert (value->numCols == state->numCols); 205 assert (value->numRows == state->numRows); 206 assert (value->numCols == mask->numCols); 207 assert (value->numRows == mask->numRows); 208 209 psImage *output = psImageAlloc (value->numCols, value->numRows, PS_TYPE_F32); 210 211 // allocate the vectors for the 2nd order fit below 212 psVector *f = psVectorAlloc (9, PS_TYPE_F32); 213 // XXX if we add the weight above, include df 214 // psVector *df = psVectorAlloc (9, PS_TYPE_F32); 215 psVector *x = psVectorAlloc (9, PS_TYPE_F32); 216 psVector *y = psVectorAlloc (9, PS_TYPE_F32); 217 218 // allocate a 2D polynomial to fit a quadratic to the valid neighbor pixels. 219 psPolynomial2D *poly2D = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, 2, 2); 220 poly2D->mask[2][2] = 1; 221 poly2D->mask[2][1] = 1; 222 poly2D->mask[1][2] = 1; 223 224 // allocate a 2D polynomial to fit a plane to the valid neighbor pixels. 225 psPolynomial2D *poly1D = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, 1, 1); 226 poly2D->mask[1][1] = 1; 227 228 for (int iy = 0; iy < state->numRows; iy++) { 229 for (int ix = 0; ix < state->numCols; ix++) { 230 231 switch (state->data.S32[iy][ix]) { 232 case PS_IMAGE_INTERPOLATE_GOOD2: { 233 // XXX is there a fit-image-region function? 234 int n = 0; 235 for (int jy = -1; jy <= +1; jy++) { 236 // skip invalid pixels 237 if (jy + iy < 0) { continue; } 238 if (jy + iy >= value->numRows) { continue; } 239 for (int jx = -1; jx <= +1; jx++) { 240 // skip invalid pixels 241 if (jx + ix < 0) { continue; } 242 if (jx + ix >= value->numCols) { continue; } 243 // skip masked pixels 244 if (mask->data.PS_TYPE_MASK_DATA[iy+jy][ix+jx] & maskVal) { continue; } 245 x->data.F32[n] = xCoord->data.F32[iy+jy][ix+jx]; 246 y->data.F32[n] = yCoord->data.F32[iy+jy][ix+jx]; 247 f->data.F32[n] = value->data.F32[iy+jy][ix+jx]; 248 // df->data.F32[n] = weight->data.F32[iy+jy][ix+jx]; 249 n++; 250 } 251 } 252 // set vector lengths here 253 x->n = n; 254 y->n = n; 255 f->n = n; 256 // df->n = n; 257 // psVectorFitPolynomial2D (poly, NULL, 0xff, f, df, x, y); 258 psVectorFitPolynomial2D (poly2D, NULL, 0xff, f, NULL, x, y); 259 // apply the fitted quadratic to get the poor pixel value 260 output->data.F32[iy][ix] = psPolynomial2DEval (poly2D, ix, iy); 261 break; } 262 263 case PS_IMAGE_INTERPOLATE_GOOD1: { 264 // XXX is there a fit-image-region function? 265 int n = 0; 266 for (int jy = -1; jy <= +1; jy++) { 267 // skip invalid pixels 268 if (jy + iy < 0) { continue; } 269 if (jy + iy >= value->numRows) { continue; } 270 for (int jx = -1; jx <= +1; jx++) { 271 // skip invalid pixels 272 if (jx + ix < 0) { continue; } 273 if (jx + ix >= value->numCols) { continue; } 274 // skip masked pixels 275 if (mask->data.PS_TYPE_MASK_DATA[iy+jy][ix+jx] & maskVal) { continue; } 276 x->data.F32[n] = xCoord->data.F32[iy+jy][ix+jx]; 277 y->data.F32[n] = yCoord->data.F32[iy+jy][ix+jx]; 278 f->data.F32[n] = value->data.F32[iy+jy][ix+jx]; 279 // df->data.F32[n] = weight->data.F32[iy+jy][ix+jx]; 280 n++; 281 } 282 } 283 // set vector lengths here 284 x->n = n; 285 y->n = n; 286 f->n = n; 287 // df->n = n; 288 // psVectorFitPolynomial2D (poly1D, NULL, 0xff, f, df, x, y); 289 psVectorFitPolynomial2D (poly1D, NULL, 0xff, f, NULL, x, y); 290 // apply the fitted quadratic to get the poor pixel value 291 output->data.F32[iy][ix] = psPolynomial2DEval (poly1D, ix, iy); 292 break; } 293 294 case PS_IMAGE_INTERPOLATE_GOOD0: { 295 output->data.F32[iy][ix] = value->data.F32[iy+jy][ix+jx]; 296 break; } 297 298 default: 299 psAbort("impossible case in __func__"); 300 } 301 } 302 } 303 304 for (int iy = 0; iy < value->numRows; iy++) { 305 for (int ix = 0; ix < value->numCols; ix++) { 306 if (mask->data.PS_TYPE_MASK_DATA[iy][ix] & maskVal) { continue; } 307 value->data.F32[iy][ix] = output->data.F32[iy][ix]; 308 } 309 } 310 311 psFree (x); 312 psFree (y); 313 psFree (f); 314 315 psFree (poly2D); 316 psFree (poly1D); 317 318 psFree (output); 319 return true; 320 } -
branches/eam_branch_20070830/psLib/test/imageops/tap_psImageMap.c
r14725 r14726 92 92 93 93 // make a model for a well-sampled field of a non-polynomial function (f = (a(x-xo)^2 + b(y-yo)^2)^-1) 94 { 95 // function is defined over the range 0-1000, 0-1000 96 psImageBinning *binning = psImageBinningAlloc(); 97 binning->nXfine = 1000; 98 binning->nYfine = 1000; 99 binning->nXruff = 5; 100 binning->nYruff = 5; 101 102 // generate a grid of test data points 103 psVector *x = psVectorAllocEmpty (100, PS_TYPE_F32); 104 psVector *y = psVectorAllocEmpty (100, PS_TYPE_F32); 105 psVector *f = psVectorAllocEmpty (100, PS_TYPE_F32); 106 107 for (int ix = 0; ix < 1000; ix += 10) { 108 for (int iy = 0; iy < 1000; iy += 10) { 109 x->data.F32[x->n] = ix; 110 y->data.F32[y->n] = iy; 111 f->data.F32[f->n] = C00 / (C10*PS_SQR(ix-500) + C01*PS_SQR(iy-500) + 0.1); 112 psVectorExtend (x, 100, 1); 113 psVectorExtend (y, 100, 1); 114 psVectorExtend (f, 100, 1); 115 } 116 } 117 118 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 119 120 // scale defines both field and map image sizes (nXfine, nXruff) 121 psImageMap *map = psImageMapAlloc (NULL, binning, stats); 122 123 // allocate a map, but we have no field image to supply 124 // XXX this function needs to correct for the mean superpixel position 125 // which is sampled... 126 psImageMapGenerate (map, x, y, f, 0.1); 127 psFree (binning); 128 129 fprintf (stderr, "nGood: %d\n", map->nGood); 130 fprintf (stderr, "nPoor: %d\n", map->nPoor); 131 fprintf (stderr, "nBad: %d\n", map->nBad); 132 133 SaveImage (NULL, map->map, "map.fits"); 134 135 psImage *field = psImageAlloc(1000, 1000, PS_TYPE_F32); 136 for (int ix = 0; ix < 1000; ix++) { 137 for (int iy = 0; iy < 1000; iy++) { 138 field->data.F32[iy][ix] = C00 / (C10*PS_SQR(ix-500) + C01*PS_SQR(iy-500) + 0.1); 139 } 140 } 141 SaveImage (NULL, field, "field.fits"); 142 143 // measure difference between model (map) and data (field) 144 for (int ix = 0; ix < map->map->numCols; ix++) { 145 for (int iy = 0; iy < map->map->numRows; iy++) { 146 147 int xo = (ix + 0.5)*map->binning->nXbin; 148 int yo = (iy + 0.5)*map->binning->nYbin; 149 float df = field->data.F32[yo][xo] - map->map->data.F32[iy][ix]; 150 fprintf (stderr, "%d %d -> %d %d : %f = %f - %f\n", ix, iy, xo, yo, df, field->data.F32[yo][xo], map->map->data.F32[iy][ix]); 151 } 152 } 153 } 94 154 95 155 // make a model for a poorly-sampled field of a non-polynomial function (f = (a(x-xo)^2 + b(y-yo)^2)^-1)
Note:
See TracChangeset
for help on using the changeset viewer.
