Changeset 2783 for trunk/stac/src/stacCombine.c
- Timestamp:
- Dec 21, 2004, 4:07:04 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/stac/src/stacCombine.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/stac/src/stacCombine.c
r2764 r2783 26 26 for (int i = 0; i < num; i++) { 27 27 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]; 30 31 } 31 32 } … … 53 54 54 55 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 57 bool 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 60 64 ) 61 65 { … … 76 80 "Image size mismatch on error image %d\nExpected %dx%d, got %dx%d\n", 77 81 i, numCols, numRows, image->numCols, image->numRows); 78 return NULL;82 return false; 79 83 } 80 84 if ((error->numCols != numCols) || (error->numRows != numRows)) { … … 82 86 "Image size mismatch on error image %d\nExpected %dx%d, got %dx%d\n", 83 87 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; 86 106 } 87 107 88 108 psTrace("stac.combine", 1, "Combining images....\n"); 89 psTrace("stac.combine", 3, "Saturation: %f Bad: %f\n", saturated, bad);90 109 91 110 psVector *pixels = psVectorAlloc(nImages, PS_TYPE_F32); // Will hold the pixels in the statistics step 92 111 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 96 113 97 114 // Set up rejection masks … … 105 122 return NULL; 106 123 } 124 125 // Create and initialise rejection masks 107 126 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); 110 128 for (int r = 0; r < numRows; r++) { 111 129 for (int c = 0; c < numCols; c++) { … … 124 142 for (int y = 0; y < numRows; y++) { 125 143 for (int x = 0; x < numCols; x++) { 144 145 // Only combine those pixels requested 146 if (!region || (region && region->data.U8[y][x])) { 126 147 127 // Export pixels into the vector and get stats128 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 } 139 160 140 float average = stacCombineMean(pixels, deltas, mask); // Combined value161 float average = stacCombineMean(pixels, deltas, mask); // Combined value 141 162 142 163 #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 } 154 198 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 178 203 } 179 204 } // Iterating over output pixels
Note:
See TracChangeset
for help on using the changeset viewer.
