Changeset 10957
- Timestamp:
- Jan 7, 2007, 3:28:00 PM (20 years ago)
- Location:
- trunk/pswarp/src
- Files:
-
- 1 added
- 5 edited
-
Makefile.am (modified) (1 diff)
-
pswarp.h (modified) (2 diffs)
-
pswarpMapGrid.c (modified) (2 diffs)
-
pswarpMatchRange.c (added)
-
pswarpTransformReadout.c (modified) (1 diff)
-
pswarpTransformReadout_Opt.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/pswarp/src/Makefile.am
r10954 r10957 18 18 pswarpDefine.c \ 19 19 pswarpErrorCodes.c \ 20 pswarpMapGrid.c \ 21 pswarpMatchRange.c \ 20 22 pswarpParseCamera.c \ 21 23 pswarpTransformReadout.c \ 24 pswarpTransformReadout_Opt.c \ 22 25 pswarpVersion.c 23 26 -
trunk/pswarp/src/pswarp.h
r10954 r10957 13 13 # define PSWARP_RECIPE "PSWARP" // Name of the recipe to use 14 14 15 // a single pswarpMap converts coordinates from one image to a second image 16 // the linear model is only valid over a limited range of pixels 15 17 typedef struct { 16 double Xo, Xx, Xy; 17 double Yo, Yx, Yy; 18 double Xo, Xx, Xy; 19 double Yo, Yx, Yy; 20 int xo; 21 int yo; 18 22 } pswarpMap; 19 23 24 // the pswarpMapGrid carries a collection of pswarpMag structures representing the 25 // local value of the pswarpMap at different locations in the image. 20 26 typedef struct { 21 pswarpMap **grid; 22 int Nx, Ny; 23 int nXpix, nYpix; 27 pswarpMap ***maps; 28 int nXpts, nYpts; // number of x,y samples in the grid 29 int nXpix, nYpix; // x,y spacing in src image pixels of grid samples 30 int xMin, yMin; // coordinate of first grid sample 24 31 } pswarpMapGrid; 25 32 … … 31 38 void pswarpCleanup (pmConfig *config); 32 39 bool pswarpTransformReadout (pmReadout *output, pmReadout *input, pmConfig *config); 40 bool pswarpTransformReadout_Opt (pmReadout *output, pmReadout *input, pmConfig *config); 33 41 42 bool pswarpMatchRange (int *minX, int *minY, int *maxX, int *maxY, pmReadout *dest, pmReadout *src); 43 44 pswarpMap *pswarpMapAlloc (); 45 pswarpMapGrid *pswarpMapGridAlloc (int Nx, int Ny); 46 47 pswarpMapGrid *pswarpMapGridFromImage (pmReadout *dest, pmReadout *src, int nXpix, int nYpix); 48 bool pswarpMapGridSetGrid (pswarpMapGrid *grid, int ix, int iy, int *gridX, int *gridY); 49 bool pswarpMapGridNextGrid (pswarpMapGrid *grid, int gridX, int gridY, int *nextX, int *nextY); 50 double pswarpMapGridMaxError (pswarpMapGrid *grid); 51 bool pswarpMapApply (double *outX, double *outY, pswarpMap *map, double inX, double inY); 52 bool pswarpMapSetLocalModel (pswarpMap *map, pmReadout *dest, pmReadout *src, int ix, int iy); -
trunk/pswarp/src/pswarpMapGrid.c
r10954 r10957 1 1 # include "pswarp.h" 2 2 3 static pswarpMapFree (pswarpMap *map) { 3 // construct a grid with superpixel spacing of nXpix, nYpix 4 // XXX for the moment, ignore readout->cell->chip offsets 5 pswarpMapGrid *pswarpMapGridFromImage (pmReadout *dest, pmReadout *src, int nXpix, int nYpix) { 6 7 // split the difference of the remainder 8 int xMin = 0.5*(src->image->numCols % nXpix); 9 int yMin = 0.5*(src->image->numRows % nYpix); 10 11 pswarpMapGrid *grid = pswarpMapGridAlloc (src->image->numCols / nXpix, src->image->numRows / nYpix); 12 13 int ni = 0; 14 int nj = 0; 15 for (int i = xMin; i < src->image->numCols; i += nXpix, ni++) { 16 for (int j = yMin; j < src->image->numRows; j += nYpix, nj++) { 17 pswarpMapSetLocalModel (grid->maps[ni][nj], dest, src, i, j); 18 } 19 } 20 21 grid->nXpix = nXpix; 22 grid->nYpix = nYpix; 23 grid->xMin = xMin; 24 grid->yMin = yMin; 25 return grid; 26 } 27 28 bool pswarpMapGridSetGrid (pswarpMapGrid *grid, int ix, int iy, int *gridX, int *gridY) { 29 30 *gridX = (ix - grid->xMin + 0.5*grid->nXpix) / grid->nXpix; 31 *gridY = (iy - grid->yMin + 0.5*grid->nYpix) / grid->nYpix; 32 return true; 33 } 34 35 bool pswarpMapGridNextGrid (pswarpMapGrid *grid, int gridX, int gridY, int *nextX, int *nextY) { 36 37 *nextX = gridX*grid->nXpix + grid->xMin + 0.5*grid->nXpix; 38 *nextY = gridY*grid->nYpix + grid->yMin + 0.5*grid->nYpix; 39 return true; 40 } 41 42 // measure the max error accumulated in appling one grid point to its neighbors 43 double pswarpMapGridMaxError (pswarpMapGrid *grid) { 44 45 double xRaw, yRaw; 46 double xRef, yRef; 47 double maxError = 0; 48 49 for (int i = 0; i < grid->nXpts - 1; i++) { 50 for (int j = 0; j < grid->nYpts - 1; j++) { 51 52 // measure the output coordinates for the next grid position using the current grid map 53 // compare with the coordinates measured using the next grid map 54 pswarpMapApply (&xRaw, &yRaw, grid->maps[i][j], grid->maps[i][j]->xo + grid->nXpix, grid->maps[i][j]->yo); 55 pswarpMapApply (&xRef, &yRef, grid->maps[i+1][j], grid->maps[i][j]->xo + grid->nXpix, grid->maps[i][j]->yo); 56 57 double posError = hypot (xRaw-xRef, yRaw-yRef); 58 maxError = PS_MAX (maxError, posError); 59 } 60 } 61 return maxError; 62 } 63 64 bool pswarpMapApply (double *outX, double *outY, pswarpMap *map, double inX, double inY) { 65 66 *outX = map->Xo + map->Xx*inX + map->Xy*inY; 67 *outY = map->Yo + map->Yx*inX + map->Yy*inY; 68 69 return true; 70 } 71 72 // determine the map for the given pixel from src to dest. pixel is in src coords 73 bool pswarpMapSetLocalModel (pswarpMap *map, pmReadout *dest, pmReadout *src, int ix, int iy) { 74 75 pmCell *cell = NULL; 76 77 cell = src->parent; 78 pmChip *chipSrc = cell->parent; 79 pmFPA *fpaSrc = chipSrc->parent; 80 81 cell = dest->parent; 82 pmChip *chipDest = cell->parent; 83 pmFPA *fpaDest = chipDest->parent; 84 85 // XXX save these as static for speed? 86 psPlane *offset = psPlaneAlloc(); 87 88 psPlane *FP = psPlaneAlloc(); 89 psPlane *TP = psPlaneAlloc(); 90 psSphere *sky = psSphereAlloc(); 91 92 psPlane *V00 = psPlaneAlloc(); 93 psPlane *V10 = psPlaneAlloc(); 94 psPlane *V01 = psPlaneAlloc(); 95 96 // XXX need to include readout->cell->chip offsets 97 98 // V(0,0) position 99 offset->x = ix; 100 offset->y = iy; 101 psPlaneTransformApply(FP, chipSrc->toFPA, offset); 102 psPlaneTransformApply (TP, fpaSrc->toTPA, FP); 103 psDeproject (sky, TP, fpaSrc->toSky); 104 psProject (TP, sky, fpaDest->toSky); 105 psPlaneTransformApply (FP, fpaDest->fromTPA, TP); 106 psPlaneTransformApply (V00, chipDest->fromFPA, FP); 107 108 // V(1,0) position 109 offset->x = ix + 1; 110 offset->y = iy; 111 psPlaneTransformApply(FP, chipSrc->toFPA, offset); 112 psPlaneTransformApply (TP, fpaSrc->toTPA, FP); 113 psDeproject (sky, TP, fpaSrc->toSky); 114 psProject (TP, sky, fpaDest->toSky); 115 psPlaneTransformApply (FP, fpaDest->fromTPA, TP); 116 psPlaneTransformApply (V10, chipDest->fromFPA, FP); 117 118 // V(0,1) position 119 offset->x = ix; 120 offset->y = iy + 1; 121 psPlaneTransformApply(FP, chipSrc->toFPA, offset); 122 psPlaneTransformApply (TP, fpaSrc->toTPA, FP); 123 psDeproject (sky, TP, fpaSrc->toSky); 124 psProject (TP, sky, fpaDest->toSky); 125 psPlaneTransformApply (FP, fpaDest->fromTPA, TP); 126 psPlaneTransformApply (V01, chipDest->fromFPA, FP); 127 128 map->Xx = V10->x - V00->x; 129 map->Xy = V01->x - V00->x; 130 map->Xo = V00->x + map->Xx*ix + map->Xy*iy; 131 132 map->Yx = V10->y - V00->y; 133 map->Yy = V01->y - V00->y; 134 map->Yo = V00->y + map->Yx*ix + map->Yy*iy; 135 136 map->xo = ix; 137 map->yo = iy; 138 139 psFree (offset); 140 psFree (FP); 141 psFree (TP); 142 psFree (sky); 143 144 psFree (V00); 145 psFree (V10); 146 psFree (V01); 147 148 return true; 149 } 150 151 static void pswarpMapFree (pswarpMap *map) { 4 152 return; 5 153 } … … 13 161 } 14 162 163 static void pswarpMapGridFree (pswarpMapGrid *grid) { 164 165 if (grid == NULL) return; 166 if (grid->maps == NULL) return; 167 168 for (int i = 0; i < grid->nXpts; i++) { 169 for (int j = 0; j < grid->nYpts; j++) { 170 psFree (grid->maps[i][j]); 171 } 172 psFree (grid->maps[i]); 173 } 174 psFree (grid->maps); 175 return; 176 } 177 178 pswarpMapGrid *pswarpMapGridAlloc (int nXpts, int nYpts) { 179 180 pswarpMapGrid *grid = (pswarpMapGrid *) psAlloc (sizeof(pswarpMapGrid)); 181 psMemSetDeallocator(grid, (psFreeFunc) pswarpMapGridFree); 182 183 grid->maps = psAlloc (nXpts*sizeof(void **)); 184 for (int i = 0; i < nXpts; i++) { 185 grid->maps[i] = psAlloc (nYpts*sizeof(void *)); 186 for (int j = 0; j < nYpts; j++) { 187 grid->maps[i][j] = pswarpMapAlloc(); 188 } 189 } 190 grid->nXpts = nXpts; 191 grid->nYpts = nYpts; 192 193 grid->nXpix = 0; 194 grid->nYpix = 0; 15 195 196 return grid; 197 } 198 -
trunk/pswarp/src/pswarpTransformReadout.c
r10954 r10957 35 35 for (int x = 0; x < outNx; x++) { 36 36 // Only transform those pixels requested 37 if (!region || (region && region->data.U8[y][x])) { 38 // Transform! 37 if (region && region->data.U8[y][x]) continue; 39 38 40 // XXX double check this 1/2 pixel offset41 outPix->x = (double)x + 0.5;42 outPix->y = (double)y + 0.5;39 // XXX double check this 1/2 pixel offset 40 outPix->x = (double)x + 0.5; 41 outPix->y = (double)y + 0.5; 43 42 44 psPlaneTransformApply(FP, chipOutput->toFPA, outPix);45 psPlaneTransformApply (TP, fpaOutput->toTPA, FP);46 psDeproject (sky, TP, fpaOutput->toSky);43 psPlaneTransformApply(FP, chipOutput->toFPA, outPix); 44 psPlaneTransformApply (TP, fpaOutput->toTPA, FP); 45 psDeproject (sky, TP, fpaOutput->toSky); 47 46 48 psProject (TP, sky, fpaInput->toSky);49 psPlaneTransformApply (FP, fpaInput->fromTPA, TP);50 psPlaneTransformApply (inPix, chipInput->fromFPA, FP);47 psProject (TP, sky, fpaInput->toSky); 48 psPlaneTransformApply (FP, fpaInput->fromTPA, TP); 49 psPlaneTransformApply (inPix, chipInput->fromFPA, FP); 51 50 52 // XXX get interpolation method from the recipe 53 outData[y][x] = (psF32)psImagePixelInterpolate(inImage, inPix->x, inPix->y, NULL, 1, NAN, PS_INTERPOLATE_BILINEAR); 54 // modify zero and scale? 55 56 // outData[y][x] = (psF32)psImagePixelInterpolate(inImage, inPix->x, inPix->y, mask, 1, NAN, PS_INTERPOLATE_BILINEAR); 57 58 # if (0) 59 if (error) { 60 // Error is actually the variance 61 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error, 62 detector->x, 63 detector->y, 64 mask, 1, NAN); 65 } 66 if (error) { 67 outError->data.F32[y][x] = outError->data.F32[y][x] / SQUARE(scale); 68 } 69 # endif 70 71 } // Pixels of interest 72 51 // XXX get interpolation method from the recipe 52 outData[y][x] = (psF32)psImagePixelInterpolate(inImage, inPix->x, inPix->y, NULL, 1, NAN, PS_INTERPOLATE_BILINEAR); 53 // outData[y][x] = (psF32)psImagePixelInterpolate(inImage, inPix->x, inPix->y, mask, 1, NAN, PS_INTERPOLATE_BILINEAR); 54 // modify zero and scale? 73 55 } 74 } // Iterating over output pixels 75 56 } 76 57 return true; 77 58 } 78 59 79 60 # if (0) 61 if (error) { 62 // Error is actually the variance 63 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error, 64 detector->x, 65 detector->y, 66 mask, 1, NAN); 67 } 68 if (error) { 69 outError->data.F32[y][x] = outError->data.F32[y][x] / SQUARE(scale); 70 } 71 # endif -
trunk/pswarp/src/pswarpTransformReadout_Opt.c
r10954 r10957 1 1 # include "pswarp.h" 2 2 3 bool pswarpTransformReadout (pmReadout *output, pmReadout *input, pmConfig *config) { 3 // NOTE: in this function, the coordinates are transformed from the OUTPUT to the INPUT 4 bool pswarpTransformReadout_Opt (pmReadout *output, pmReadout *input, pmConfig *config) { 5 6 int minX, minY, maxX, maxY; 7 int gridX, gridY, nextGridX, nextGridY; 8 pswarpMap *map = NULL; 4 9 5 10 // XXX this implementation currently ignores the use of the region 6 11 psImage *region = NULL; 7 pmCell *cell = NULL;8 12 9 13 // select the current recipe 10 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 11 12 int outNx = output->image->numCols; 13 int outNy = output->image->numRows; 14 // psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 14 15 15 16 psPlane *inPix = psPlaneAlloc(); // Coordinates on the input detector 16 psPlane *outPix = psPlaneAlloc(); // Coordinates on the output detector 17 18 psPlane *FP = psPlaneAlloc(); // Coordinates on the focal plane 19 psPlane *TP = psPlaneAlloc(); // Coordinates on the tangent plane 20 psSphere *sky = psSphereAlloc(); // Coordinates on the sky 21 22 cell = input->parent; 23 pmChip *chipInput = cell->parent; 24 pmFPA *fpaInput = chipInput->parent; 25 26 cell = output->parent; 27 pmChip *chipOutput = cell->parent; 28 pmFPA *fpaOutput = chipOutput->parent; 29 17 psImage *inImage = input->image; 30 18 psF32 **outData = output->image->data.F32; 31 psImage *inImage = input->image;32 19 33 20 // we might want to do the rectangular regions outside of the selection independently … … 37 24 pswarpMatchRange (&minX, &minY, &maxX, &maxY, input, output); 38 25 26 pswarpMapGrid *grid = pswarpMapGridFromImage (input, output, 128, 128); 27 28 // XXX need to modify the grid based on this result and force the maxError < XXX 29 double maxError = pswarpMapGridMaxError (grid); 30 fprintf (stderr, "maximum error using this grid sampling: %f\n", maxError); 31 32 pswarpMapGridSetGrid (grid, minX, minY, &gridX, &gridY); 33 pswarpMapGridNextGrid (grid, gridX, gridY, &nextGridX, &nextGridY); 34 map = grid->maps[gridX][gridY]; 35 39 36 // Iterate over the output image pixels 40 for (int y = 0; y < outNy; y++) { 41 for (int x = 0; x < outNx; x++) { 37 for (int y = minY; y < maxY; y++) { 38 if (y >= nextGridY) { 39 gridY ++; 40 pswarpMapGridNextGrid (grid, gridX, gridY, &nextGridX, &nextGridY); 41 map = grid->maps[gridX][gridY]; 42 } 43 for (int x = minX; x < maxX; x++) { 44 if (x >= nextGridX) { 45 gridX ++; 46 pswarpMapGridNextGrid (grid, gridX, gridY, &nextGridX, &nextGridY); 47 map = grid->maps[gridX][gridY]; 48 } 49 42 50 // Only transform those pixels requested 43 if (!region || (region && region->data.U8[y][x])) { 44 // Transform! 51 if (region && region->data.U8[y][x]) continue; 45 52 46 // XXX double check this 1/2 pixel offset47 outPix->x = (double)x + 0.5;48 outPix->y = (double)y + 0.5;53 // XXX double check this 1/2 pixel offset 54 // XXX subtract 0.5,0.5 from result? 55 pswarpMapApply (&inPix->x, &inPix->y, map, x + 0.5, y + 0.5); 49 56 50 psPlaneTransformApply(FP, chipOutput->toFPA, outPix); 51 psPlaneTransformApply (TP, fpaOutput->toTPA, FP); 52 psDeproject (sky, TP, fpaOutput->toSky); 53 54 psProject (TP, sky, fpaInput->toSky); 55 psPlaneTransformApply (FP, fpaInput->fromTPA, TP); 56 psPlaneTransformApply (inPix, chipInput->fromFPA, FP); 57 58 // XXX get interpolation method from the recipe 59 outImage->data.F32[y][x] = (psF32)psImagePixelInterpolate(image, inPix->x, inPix->y, mask, 1, NAN, PS_INTERPOLATE_BILINEAR); 60 61 # if (0) 62 if (error) { 63 // Error is actually the variance 64 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error, 65 detector->x, 66 detector->y, 67 mask, 1, NAN); 68 } 69 # endif 70 71 outImage->data.F32[y][x] = (outImage->data.F32[y][x] - offset) / scale; 72 # if (0) 73 if (error) { 74 outError->data.F32[y][x] = outError->data.F32[y][x] / SQUARE(scale); 75 } 76 # endif 77 78 } // Pixels of interest 79 57 // XXX get interpolation method from the recipe 58 // XXX include mask 59 // XXX apply scale and offset? 60 outData[y][x] = (psF32)psImagePixelInterpolate(inImage, inPix->x, inPix->y, NULL, 1, NAN, PS_INTERPOLATE_BILINEAR); 80 61 } 81 } // Iterating over output pixels 82 62 } 83 63 return true; 84 64 } 85 65 66 # if (0) 67 if (error) { 68 // Error is actually the variance 69 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error, 70 detector->x, 71 detector->y, 72 mask, 1, NAN); 73 } 74 if (error) { 75 outError->data.F32[y][x] = outError->data.F32[y][x] / SQUARE(scale); 76 } 77 # endif 78 86 79
Note:
See TracChangeset
for help on using the changeset viewer.
