IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 7, 2005, 4:04:22 PM (21 years ago)
Author:
Paul Price
Message:

Using autoconf; some bug fixes to the polynomial order

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/stac/src/stacInvertMaps.c

    r5743 r5745  
    99
    1010psArray *stacInvertMaps(const psArray *maps, // Array of maps to invert
    11                         int outnx, int outny // Size of output image
     11                        int outnx, int outny // Size of output image
    1212    )
    1313{
    14     int nMaps = maps->n;                // Number of maps
     14    int nMaps = maps->n;                // Number of maps
    1515    psArray *inverted = psArrayAlloc(nMaps); // Array of inverted maps for output
    1616
     
    2323    for (int mapNum = 0; mapNum < nMaps; mapNum++) {
    2424
    25         psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[mapNum]; // Uninverted map
    26         // Check input
    27         assert(oldMap->x->nX == oldMap->x->nY && oldMap->y->nX == oldMap->y->nY &&
    28                oldMap->x->nX == oldMap->y->nX);
    29         int order = oldMap->x->nX + 1;  // Polynomial order
    30         psTrace("stac.invertMaps", 4, "Generating order %d polynomial inverse transformation.\n", order);
    31         psPlaneTransform *newMap = psPlaneTransformAlloc(order + 1, order + 1); // Inverted map
    32 
    33         // Create fake polynomial to use in evaluation
    34         psPolynomial2D *fakePoly = psPolynomial2DAlloc(order, order, PS_POLYNOMIAL_ORD);
    35         for (int i = 0; i < order; i++) {
    36             for (int j = 0; j < order; j++) {
    37                 fakePoly->coeff[i][j] = 1.0; // Set all coeffecients to 1
    38                 fakePoly->mask[i][j] = 1; // Mask all coefficients; unmask to evaluate
    39             }
    40         }
    41 
    42         // A grid of xin,yin --> xout,yout
    43         psVector *xIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
    44         psVector *yIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
    45         psVector *xOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
    46         psVector *yOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
    47 
    48         // Create grid of points
    49         for (int yint = 0; yint < NUM_GRID; yint++) {
    50             inCoord->y = (float)(yint * outny) / (float)(NUM_GRID - 1);
    51             for (int xint = 0; xint < NUM_GRID; xint++) {
    52                 inCoord->x = (float)(xint * outnx) / (float)(NUM_GRID - 1);
    53 
    54                 (void)psPlaneTransformApply(outCoord, oldMap, inCoord);
    55 
    56                 xOut->data.F32[yint*NUM_GRID + xint] = inCoord->x;
    57                 yOut->data.F32[yint*NUM_GRID + xint] = inCoord->y;
    58                 xIn->data.F32[yint*NUM_GRID + xint] = outCoord->x;
    59                 yIn->data.F32[yint*NUM_GRID + xint] = outCoord->y;
    60             }
    61         }
    62 
    63         // Initialise the matrix and vectors
    64         int nCoeff = order * (order + 1) / 2; // Number of polynomial coefficients
    65         psImage *matrix = psImageAlloc(nCoeff, nCoeff, PS_TYPE_F64); // Matrix for solution
    66         psVector *xVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in x
    67         psVector *yVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in y
    68         for (int i = 0; i < nCoeff; i++) {
    69             for (int j = 0; j < nCoeff; j++) {
    70                 matrix->data.F64[i][j] = 0.0;
    71             }
    72             xVector->data.F64[i] = 0.0;
    73             yVector->data.F64[i] = 0.0;
    74         }
    75 
    76         // Iterate over the grid points
    77         for (int g = 0; g < NUM_GRID*NUM_GRID; g++) {
    78 
    79             // Iterate over the polynomial coefficients, accumulating the matrix and vectors
    80             for (int i = 0, ijIndex = 0; i < order; i++) {
    81                 for (int j = 0; j < order - i; j++, ijIndex++) {
    82 
    83                     fakePoly->mask[i][j] = 0;
    84                     double ijPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]);
    85                     fakePoly->mask[i][j] = 1;
    86 
    87                     for (int m = 0, mnIndex = 0; m < order; m++) {
    88                         for (int n = 0; n < order - m; n++, mnIndex++) {
    89                            
    90                             fakePoly->mask[m][n] = 0;
    91                             double mnPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]);
    92                             fakePoly->mask[m][n] = 1;
    93 
    94                             matrix->data.F64[ijIndex][mnIndex] += ijPoly * mnPoly;
    95                         }
    96                     }
    97                    
    98                     xVector->data.F64[ijIndex] += ijPoly * (double)xOut->data.F32[g];
    99                     yVector->data.F64[ijIndex] += ijPoly * (double)yOut->data.F32[g];
    100                 }
    101             } // Iterating over coefficients
    102         } // Iterating over grid points
    103 
    104         // Solution via LU Decomposition
    105         psVector *permutation = psVectorAlloc(nCoeff, PS_TYPE_F64); // Permutation vector for LU Decomposition
    106         psImage *luMatrix = psMatrixLUD(NULL, &permutation, matrix); // LU decomposed matrix
    107         psVector *xSolution = psMatrixLUSolve(NULL, luMatrix, xVector, permutation); // Solution in x
    108         psVector *ySolution = psMatrixLUSolve(NULL, luMatrix, yVector, permutation); // Solution in y
    109 
    110         // Stuff coefficients into transformation
    111         for (int i = 0, ijIndex = 0; i < order; i++) {
    112             for (int j = 0; j < order - i; j++, ijIndex++) {
    113                 newMap->x->coeff[i][j] = xSolution->data.F64[ijIndex];
    114                 newMap->y->coeff[i][j] = ySolution->data.F64[ijIndex];
    115             }
    116         }
    117         inverted->data[mapNum] = newMap;
     25        psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[mapNum]; // Uninverted map
     26        // Check input
     27        assert(oldMap->x->nX == oldMap->x->nY && oldMap->y->nX == oldMap->y->nY &&
     28               oldMap->x->nX == oldMap->y->nX);
     29        int order = oldMap->x->nX;      // Polynomial order
     30        psTrace("stac.invertMaps", 4, "Generating order %d polynomial inverse transformation.\n", order);
     31        psPlaneTransform *newMap = psPlaneTransformAlloc(order, order); // Inverted map
     32
     33        // Create fake polynomial to use in evaluation
     34        psPolynomial2D *fakePoly = psPolynomial2DAlloc(order, order, PS_POLYNOMIAL_ORD);
     35        for (int i = 0; i <= order; i++) {
     36            for (int j = 0; j <= order; j++) {
     37                fakePoly->coeff[i][j] = 1.0; // Set all coeffecients to 1
     38                fakePoly->mask[i][j] = 1; // Mask all coefficients; unmask to evaluate
     39            }
     40        }
     41
     42        // A grid of xin,yin --> xout,yout
     43        psVector *xIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
     44        psVector *yIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
     45        psVector *xOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
     46        psVector *yOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);
     47
     48        // Create grid of points
     49        for (int yint = 0; yint < NUM_GRID; yint++) {
     50            inCoord->y = (float)(yint * outny) / (float)(NUM_GRID - 1);
     51            for (int xint = 0; xint < NUM_GRID; xint++) {
     52                inCoord->x = (float)(xint * outnx) / (float)(NUM_GRID - 1);
     53
     54                (void)psPlaneTransformApply(outCoord, oldMap, inCoord);
     55
     56                xOut->data.F32[yint*NUM_GRID + xint] = inCoord->x;
     57                yOut->data.F32[yint*NUM_GRID + xint] = inCoord->y;
     58                xIn->data.F32[yint*NUM_GRID + xint] = outCoord->x;
     59                yIn->data.F32[yint*NUM_GRID + xint] = outCoord->y;
     60            }
     61        }
     62
     63        // Initialise the matrix and vectors
     64        int nCoeff = (order + 1) * (order + 2) / 2; // Number of polynomial coefficients
     65        psImage *matrix = psImageAlloc(nCoeff, nCoeff, PS_TYPE_F64); // Matrix for solution
     66        psVector *xVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in x
     67        psVector *yVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in y
     68        for (int i = 0; i < nCoeff; i++) {
     69            for (int j = 0; j < nCoeff; j++) {
     70                matrix->data.F64[i][j] = 0.0;
     71            }
     72            xVector->data.F64[i] = 0.0;
     73            yVector->data.F64[i] = 0.0;
     74        }
     75
     76        // Iterate over the grid points
     77        for (int g = 0; g < NUM_GRID*NUM_GRID; g++) {
     78
     79            // Iterate over the polynomial coefficients, accumulating the matrix and vectors
     80            for (int i = 0, ijIndex = 0; i <= order; i++) {
     81                for (int j = 0; j <= order - i; j++, ijIndex++) {
     82
     83                    fakePoly->mask[i][j] = 0;
     84                    double ijPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]);
     85                    fakePoly->mask[i][j] = 1;
     86
     87                    for (int m = 0, mnIndex = 0; m <= order; m++) {
     88                        for (int n = 0; n <= order - m; n++, mnIndex++) {
     89
     90                            fakePoly->mask[m][n] = 0;
     91                            double mnPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]);
     92                            fakePoly->mask[m][n] = 1;
     93
     94                            matrix->data.F64[ijIndex][mnIndex] += ijPoly * mnPoly;
     95                        }
     96                    }
     97
     98                    xVector->data.F64[ijIndex] += ijPoly * (double)xOut->data.F32[g];
     99                    yVector->data.F64[ijIndex] += ijPoly * (double)yOut->data.F32[g];
     100                }
     101            } // Iterating over coefficients
     102        } // Iterating over grid points
     103
     104        // Solution via LU Decomposition
     105        psVector *permutation = psVectorAlloc(nCoeff, PS_TYPE_F64); // Permutation vector for LU Decomposition
     106        psImage *luMatrix = psMatrixLUD(NULL, &permutation, matrix); // LU decomposed matrix
     107        psVector *xSolution = psMatrixLUSolve(NULL, luMatrix, xVector, permutation); // Solution in x
     108        psVector *ySolution = psMatrixLUSolve(NULL, luMatrix, yVector, permutation); // Solution in y
     109
     110        // Stuff coefficients into transformation
     111        for (int i = 0, ijIndex = 0; i <= order; i++) {
     112            for (int j = 0; j <= order - i; j++, ijIndex++) {
     113                newMap->x->coeff[i][j] = xSolution->data.F64[ijIndex];
     114                newMap->y->coeff[i][j] = ySolution->data.F64[ijIndex];
     115            }
     116        }
     117        inverted->data[mapNum] = newMap;
    118118
    119119#ifdef TESTING
    120         // Print x coefficients
    121         psTrace("stac.invertMaps", 7, "x' = \n");
    122         for (int i = 0; i < order; i++) {
    123             for (int j = 0; j < order - i; j++) {
    124                 psTrace("stac.invertMaps", 7, "      %f x^%d y^%d\n", newMap->x->coeff[i][j], i, j);
    125             }
    126         }
    127         // Print y coefficients
    128         psTrace("stac.invertMaps", 7, "y' = \n");
    129         for (int i = 0; i < order; i++) {
    130             for (int j = 0; j < order - i; j++) {
    131                 psTrace("stac.invertMaps", 7, "      %f x^%d y^%d\n", newMap->y->coeff[i][j], i, j);
    132             }
    133         }
     120        // Print x coefficients
     121        psTrace("stac.invertMaps", 7, "x' = \n");
     122        for (int i = 0; i <= order; i++) {
     123            for (int j = 0; j <= order - i; j++) {
     124                psTrace("stac.invertMaps", 7, "      %f x^%d y^%d\n", newMap->x->coeff[i][j], i, j);
     125            }
     126        }
     127        // Print y coefficients
     128        psTrace("stac.invertMaps", 7, "y' = \n");
     129        for (int i = 0; i <= order; i++) {
     130            for (int j = 0; j <= order - i; j++) {
     131                psTrace("stac.invertMaps", 7, "      %f x^%d y^%d\n", newMap->y->coeff[i][j], i, j);
     132            }
     133        }
    134134#endif
    135135
    136136#ifdef TESTING
    137         // Go forward then backward
    138         double x = 123.4;
    139         double y = 432.1;
    140         psPlane *oldCoords = psAlloc(sizeof(psPlane));
    141         oldCoords->x = x;
    142         oldCoords->y = y;
    143         psPlane *newCoords = psPlaneTransformApply(NULL, oldMap, oldCoords);
    144         psTrace("stac.invertMaps.test", 5, "%f,%f --> %f,%f\n", x, y, newCoords->x, newCoords->y);
    145         (void)psPlaneTransformApply(oldCoords, newMap, newCoords);
    146         psTrace("stac.invertMaps.test", 5, "--------> %f,%f\n", oldCoords->x, oldCoords->y);
    147         psFree(newCoords);
    148         psFree(oldCoords);
     137        // Go forward then backward
     138        double x = 123.4;
     139        double y = 432.1;
     140        psPlane *oldCoords = psAlloc(sizeof(psPlane));
     141        oldCoords->x = x;
     142        oldCoords->y = y;
     143        psPlane *newCoords = psPlaneTransformApply(NULL, oldMap, oldCoords);
     144        psTrace("stac.invertMaps.test", 5, "%f,%f --> %f,%f\n", x, y, newCoords->x, newCoords->y);
     145        (void)psPlaneTransformApply(oldCoords, newMap, newCoords);
     146        psTrace("stac.invertMaps.test", 5, "--------> %f,%f\n", oldCoords->x, oldCoords->y);
     147        psFree(newCoords);
     148        psFree(oldCoords);
    149149#endif
    150150
    151         psFree(permutation);
    152         psFree(luMatrix);
    153         psFree(matrix);
    154         psFree(xVector);
    155         psFree(yVector);
    156         psFree(xSolution);
    157         psFree(ySolution);
    158         psFree(fakePoly);
    159         psFree(xIn);
    160         psFree(yIn);
    161         psFree(xOut);
    162         psFree(yOut);
     151        psFree(permutation);
     152        psFree(luMatrix);
     153        psFree(matrix);
     154        psFree(xVector);
     155        psFree(yVector);
     156        psFree(xSolution);
     157        psFree(ySolution);
     158        psFree(fakePoly);
     159        psFree(xIn);
     160        psFree(yIn);
     161        psFree(xOut);
     162        psFree(yOut);
    163163    }
    164164
    165165    psFree(inCoord);
    166166    psFree(outCoord);
    167                
     167
    168168
    169169#if 0
    170         // Can't handle higher order than linear yet
    171         assert(((psPlaneTransform*)maps->data[i])->x->nX == 2 &&
    172                ((psPlaneTransform*)maps->data[i])->x->nY == 2 &&
    173                ((psPlaneTransform*)maps->data[i])->y->nX == 2 &&
    174                ((psPlaneTransform*)maps->data[i])->y->nY == 2);
    175         psPlaneTransform *newMap = psPlaneTransformAlloc(2, 2); // Inverted map
    176         psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[i]; // Uninverted map
    177 
    178         // Now, simply do a 2x2 matrix inversion
    179 
    180         double a = oldMap->x->coeff[1][0];
    181         double b = oldMap->x->coeff[0][1];
    182         double c = oldMap->y->coeff[1][0];
    183         double d = oldMap->y->coeff[0][1];
    184         double e = oldMap->x->coeff[0][0];
    185         double f = oldMap->y->coeff[0][0];
    186 
    187         double invDet = 1.0 / (a * d - b * c); // Inverse of the determinant
    188 
    189         // Not entirely sure why this works, but it appears to do so.......................................
    190         newMap->x->coeff[1][0] = invDet * a;
    191         newMap->x->coeff[0][1] = - invDet * b;
    192         newMap->y->coeff[1][0] = - invDet * c;
    193         newMap->y->coeff[0][1] = invDet * d;
    194 
    195         newMap->x->coeff[0][0] = - invDet * (d * e + c * f);
    196         newMap->y->coeff[0][0] = - invDet * (b * e + a * f);
     170        // Can't handle higher order than linear yet
     171        assert(((psPlaneTransform*)maps->data[i])->x->nX == 2 &&
     172               ((psPlaneTransform*)maps->data[i])->x->nY == 2 &&
     173               ((psPlaneTransform*)maps->data[i])->y->nX == 2 &&
     174               ((psPlaneTransform*)maps->data[i])->y->nY == 2);
     175        psPlaneTransform *newMap = psPlaneTransformAlloc(2, 2); // Inverted map
     176        psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[i]; // Uninverted map
     177
     178        // Now, simply do a 2x2 matrix inversion
     179
     180        double a = oldMap->x->coeff[1][0];
     181        double b = oldMap->x->coeff[0][1];
     182        double c = oldMap->y->coeff[1][0];
     183        double d = oldMap->y->coeff[0][1];
     184        double e = oldMap->x->coeff[0][0];
     185        double f = oldMap->y->coeff[0][0];
     186
     187        double invDet = 1.0 / (a * d - b * c); // Inverse of the determinant
     188
     189        // Not entirely sure why this works, but it appears to do so.......................................
     190        newMap->x->coeff[1][0] = invDet * a;
     191        newMap->x->coeff[0][1] = - invDet * b;
     192        newMap->y->coeff[1][0] = - invDet * c;
     193        newMap->y->coeff[0][1] = invDet * d;
     194
     195        newMap->x->coeff[0][0] = - invDet * (d * e + c * f);
     196        newMap->y->coeff[0][0] = - invDet * (b * e + a * f);
    197197#endif
    198198
Note: See TracChangeset for help on using the changeset viewer.