IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 10957


Ignore:
Timestamp:
Jan 7, 2007, 3:28:00 PM (20 years ago)
Author:
eugene
Message:

added local linear map

Location:
trunk/pswarp/src
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/pswarp/src/Makefile.am

    r10954 r10957  
    1818pswarpDefine.c             \
    1919pswarpErrorCodes.c         \
     20pswarpMapGrid.c            \
     21pswarpMatchRange.c         \
    2022pswarpParseCamera.c        \
    2123pswarpTransformReadout.c   \
     24pswarpTransformReadout_Opt.c \
    2225pswarpVersion.c           
    2326
  • trunk/pswarp/src/pswarp.h

    r10954 r10957  
    1313# define PSWARP_RECIPE "PSWARP" // Name of the recipe to use
    1414
     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
    1517typedef 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;
    1822} pswarpMap;
    1923
     24// the pswarpMapGrid carries a collection of pswarpMag structures representing the
     25// local value of the pswarpMap at different locations in the image.
    2026typedef 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
    2431} pswarpMapGrid;
    2532
     
    3138void pswarpCleanup (pmConfig *config);
    3239bool pswarpTransformReadout (pmReadout *output, pmReadout *input, pmConfig *config);
     40bool pswarpTransformReadout_Opt (pmReadout *output, pmReadout *input, pmConfig *config);
    3341
     42bool pswarpMatchRange (int *minX, int *minY, int *maxX, int *maxY, pmReadout *dest, pmReadout *src);
     43
     44pswarpMap *pswarpMapAlloc ();
     45pswarpMapGrid *pswarpMapGridAlloc (int Nx, int Ny);
     46
     47pswarpMapGrid *pswarpMapGridFromImage (pmReadout *dest, pmReadout *src, int nXpix, int nYpix);
     48bool pswarpMapGridSetGrid (pswarpMapGrid *grid, int ix, int iy, int *gridX, int *gridY);
     49bool pswarpMapGridNextGrid (pswarpMapGrid *grid, int gridX, int gridY, int *nextX, int *nextY);
     50double pswarpMapGridMaxError (pswarpMapGrid *grid);
     51bool pswarpMapApply (double *outX, double *outY, pswarpMap *map, double inX, double inY);
     52bool pswarpMapSetLocalModel (pswarpMap *map, pmReadout *dest, pmReadout *src, int ix, int iy);
  • trunk/pswarp/src/pswarpMapGrid.c

    r10954 r10957  
    11# include "pswarp.h"
    22
    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
     5pswarpMapGrid *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
     28bool 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
     35bool 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
     43double 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
     64bool 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
     73bool 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
     151static void pswarpMapFree (pswarpMap *map) {
    4152  return;
    5153}
     
    13161}
    14162
     163static 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
     178pswarpMapGrid *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;
    15195 
     196  return grid;
     197}
     198
  • trunk/pswarp/src/pswarpTransformReadout.c

    r10954 r10957  
    3535        for (int x = 0; x < outNx; x++) {
    3636            // 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;
    3938
    40                 // XXX double check this 1/2 pixel offset
    41                 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;
    4342
    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);
    4746               
    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);
    5150
    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?
    7355        }
    74     } // Iterating over output pixels
    75 
     56    }
    7657    return true;
    7758}
    7859
    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  
    11# include "pswarp.h"
    22
    3 bool pswarpTransformReadout (pmReadout *output, pmReadout *input, pmConfig *config) {
     3// NOTE: in this function, the coordinates are transformed from the OUTPUT to the INPUT
     4bool 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;
    49
    510    // XXX this implementation currently ignores the use of the region
    611    psImage *region = NULL;
    7     pmCell *cell = NULL;
    812
    913    // 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);
    1415
    1516    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;
    3018    psF32 **outData = output->image->data.F32;
    31     psImage *inImage = input->image;
    3219
    3320    // we might want to do the rectangular regions outside of the selection independently
     
    3724    pswarpMatchRange (&minX, &minY, &maxX, &maxY, input, output);
    3825
     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
    3936    // 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
    4250            // 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;
    4552
    46                 // XXX double check this 1/2 pixel offset
    47                 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);
    4956
    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);
    8061        }
    81     } // Iterating over output pixels
    82 
     62    }
    8363    return true;
    8464}
    8565
     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
    8679   
Note: See TracChangeset for help on using the changeset viewer.