IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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

Running fast now. Only optimisation tweaks to be made now.

File:
1 edited

Legend:

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

    r2764 r2783  
    2626    for (int i = 0; i < num; i++) {
    2727        if (! masks->data.U8[i]) {
    28             sum += values->data.F32[i] / SQUARE(errors->data.F32[i]);
    29             weights += 1.0 / SQUARE(errors->data.F32[i]);
     28            // "error" here is the variance
     29            sum += values->data.F32[i] / errors->data.F32[i];
     30            weights += 1.0 / errors->data.F32[i];
    3031        }
    3132    }
     
    5354
    5455
    55 psImage *stacCombine(psArray *images,   // Array of transformed images
    56                      psArray *errors,   // Array of transformed error images
    57                      int nReject,       // Number of rejection iterations
    58                      psArray **rejected, // Array of rejection masks
    59                      stacConfig *config // Configuration
     56
     57bool stacCombine(psImage **combined,    // The combined image for output
     58                 psArray **rejected,    // Array of rejection masks
     59                 psArray *images,       // Array of transformed images
     60                 psArray *errors,       // Array of transformed error images
     61                 int nReject,           // Number of rejection iterations
     62                 psImage *region,       // Region to combine
     63                 stacConfig *config     // Configuration
    6064    )
    6165{
     
    7680                    "Image size mismatch on error image %d\nExpected %dx%d, got %dx%d\n",
    7781                    i, numCols, numRows, image->numCols, image->numRows);
    78             return NULL;
     82            return false;
    7983        }
    8084        if ((error->numCols != numCols) || (error->numRows != numRows)) {
     
    8286                    "Image size mismatch on error image %d\nExpected %dx%d, got %dx%d\n",
    8387                    i, numCols, numRows, error->numCols, error->numRows);
    84             return NULL;
    85         }
     88            return false;
     89        }
     90    }
     91
     92    // Check combined image
     93    if (*combined == NULL) {
     94        *combined = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Combined image
     95    } else if (((*combined)->numRows != numRows) || ((*combined)->numCols != numCols)) {
     96        psError("stac.combine", "Size of combined image (%dx%d) does not match inputs (%dx%d)\n",
     97                (*combined)->numCols, (*combined)->numRows, numCols, numRows);
     98        return false;
     99    }
     100
     101    // Check area of interest
     102    if (region && ((region->numRows != numRows) || (region->numCols != numCols))) {
     103        psError("stac.combine", "Size of area of interest (%dx%d) does not match inputs (%dx%d)\n",
     104                region->numCols, region->numRows, numCols, numRows);
     105        return false;
    86106    }
    87107
    88108    psTrace("stac.combine", 1, "Combining images....\n");
    89     psTrace("stac.combine", 3, "Saturation: %f Bad: %f\n", saturated, bad);
    90109
    91110    psVector *pixels = psVectorAlloc(nImages, PS_TYPE_F32); // Will hold the pixels in the statistics step
    92111    psVector *deltas = psVectorAlloc(nImages, PS_TYPE_F32); // Will hold the errors in the statistics step
    93     psVector *mask = psVectorAlloc(nImages, PS_TYPE_U8); // Mask bad pixels
    94     psImage *combined = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Combined image
    95 
     112    psVector *mask = psVectorAlloc(nImages, PS_TYPE_U8); // Will hold the mask in the statistics step
    96113
    97114    // Set up rejection masks
     
    105122            return NULL;
    106123        }
     124
     125        // Create and initialise rejection masks
    107126        for (int i = 0; i < nImages; i++) {
    108             (*rejected)->data[i] = psImageAlloc(numCols, numRows, PS_TYPE_U8); // Create rejection mask
    109             // Zero out the mask
     127            (*rejected)->data[i] = psImageAlloc(numCols, numRows, PS_TYPE_U8);
    110128            for (int r = 0; r < numRows; r++) {
    111129                for (int c = 0; c < numCols; c++) {
     
    124142    for (int y = 0; y < numRows; y++) {
    125143        for (int x = 0; x < numCols; x++) {
     144
     145            // Only combine those pixels requested
     146            if (!region || (region && region->data.U8[y][x])) {
    126147           
    127             // Export pixels into the vector and get stats
    128             for (int i = 0; i < nImages; i++) {
    129                 float pixel = ((psImage*)images->data[i])->data.F32[y][x];
    130                 float delta = ((psImage*)errors->data[i])->data.F32[y][x];
    131                 pixels->data.F32[i] = pixel;
    132                 deltas->data.F32[i] = delta;
    133                 if ((pixel >= saturated) || (pixel <= bad) || (! isfinite(pixel)) || (! isfinite(delta))) {
    134                     mask->data.U8[i] = (psU8)1; // Don't use!
    135                 } else {
    136                     mask->data.U8[i] = (psU8)0; // Use.
    137                 }
    138             }
     148                // Export pixels into the vector and get stats
     149                for (int i = 0; i < nImages; i++) {
     150                    float pixel = ((psImage*)images->data[i])->data.F32[y][x];
     151                    float delta = ((psImage*)errors->data[i])->data.F32[y][x]; // This is the variance!
     152                    pixels->data.F32[i] = pixel;
     153                    deltas->data.F32[i] = delta;
     154                    if ((pixel >= saturated) || (pixel <= bad) || (! isfinite(pixel)) || (! isfinite(delta))) {
     155                        mask->data.U8[i] = (psU8)1; // Don't use!
     156                    } else {
     157                        mask->data.U8[i] = (psU8)0; // Use.
     158                    }
     159                }
    139160           
    140             float average = stacCombineMean(pixels, deltas, mask); // Combined value
     161                float average = stacCombineMean(pixels, deltas, mask); // Combined value
    141162
    142163#ifdef TESTING
    143             // Calculate chi^2
    144             chi2->data.F32[y][x] = 0.0;
    145             int numGoodPix = 0;
    146             for (int i = 0; i < nImages; i++) {
    147                 if (! mask->data.U8[i]) {
    148                     chi2->data.F32[y][x] += SQUARE((pixels->data.F32[i] - average) / deltas->data.F32[i]);
    149                     numGoodPix++;
    150                 }
    151             }
    152             chi2->data.F32[y][x] /= (float)numGoodPix;
    153 #endif
     164                // Calculate chi^2
     165                chi2->data.F32[y][x] = 0.0;
     166                int numGoodPix = 0;
     167                for (int i = 0; i < nImages; i++) {
     168                    if (! mask->data.U8[i]) {
     169                        chi2->data.F32[y][x] += SQUARE(pixels->data.F32[i] - average) / deltas->data.F32[i];
     170                        numGoodPix++;
     171                    }
     172                }
     173                chi2->data.F32[y][x] /= (float)numGoodPix;
     174#endif
     175               
     176                // Rejection iterations
     177                bool keepGoing = true;  // Keep going with rejection?
     178                for (int rejNum = 0; (rejNum < nReject) && keepGoing; rejNum++) {
     179                    float max = 0.0;    // Maximum deviation
     180                    int maxIndex = -1;  // Index of the maximum deviation
     181                    for (int i = 0; i < nImages; i++) {
     182                        if (!mask->data.U8[i] &&
     183                            ((pixels->data.F32[i] - average) / sqrtf(deltas->data.F32[i]) > max)) {
     184                            max = (pixels->data.F32[i] - average) / sqrtf(deltas->data.F32[i]);
     185                            maxIndex = i;
     186                        }
     187                    }
     188                    // Reject the pixel with the maximum deviation
     189                    if (max > reject) {
     190                        mask->data.U8[maxIndex] = 1;
     191                        ((psImage*)((*rejected)->data[maxIndex]))->data.U8[y][x] += 1;
     192                        // Re-do combination following rejection
     193                        average = stacCombineMean(pixels, deltas, mask);
     194                    } else {
     195                        keepGoing = false;
     196                    }
     197                }
    154198           
    155             // Rejection iterations
    156             bool keepGoing = true;      // Keep going with rejection?
    157             for (int rejNum = 0; (rejNum < nReject) && keepGoing; rejNum++) {
    158                 float max = 0.0;        // Maximum deviation
    159                 int maxIndex = -1;      // Index of the maximum deviation
    160                 for (int i = 0; i < nImages; i++) {
    161                     if (!mask->data.U8[i] && ((pixels->data.F32[i] - average) / deltas->data.F32[i] > max)) {
    162                         max = (pixels->data.F32[i] - average) / deltas->data.F32[i];
    163                         maxIndex = i;
    164                     }
    165                 }
    166                 // Reject the pixel with the maximum deviation
    167                 if (max > reject) {
    168                     mask->data.U8[maxIndex] = 1;
    169                     ((psImage*)((*rejected)->data[maxIndex]))->data.U8[y][x] += 1.0;
    170                     // Re-do combination following rejection
    171                     average = stacCombineMean(pixels, deltas, mask);
    172                 } else {
    173                     keepGoing = false;
    174                 }
    175             }
    176            
    177             combined->data.F32[y][x] = average;
     199                (*combined)->data.F32[y][x] = average;
     200
     201            } // Pixels of interest
     202
    178203        }
    179204    } // Iterating over output pixels
Note: See TracChangeset for help on using the changeset viewer.