Changeset 2783
- Timestamp:
- Dec 21, 2004, 4:07:04 PM (22 years ago)
- Location:
- trunk/stac/src
- Files:
-
- 6 edited
-
stac.c (modified) (8 diffs)
-
stac.h (modified) (3 diffs)
-
stacAreaOfInterest.c (modified) (1 diff)
-
stacCombine.c (modified) (6 diffs)
-
stacConfig.c (modified) (5 diffs)
-
stacTransform.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/stac/src/stac.c
r2764 r2783 36 36 psTraceSetLevel("stac.rejection",10); 37 37 psTraceSetLevel("stac.time",10); 38 38 psTraceSetLevel("stac.area",10); 39 39 40 40 // Set logging level … … 50 50 psArray *maps = stacReadMaps(config); 51 51 52 psTrace("stac.time", 1, "I/O completed at %f seconds\n", getTime() - startTime); 53 52 54 // Invert maps 53 55 psArray *inverseMaps = stacInvertMaps(maps); … … 57 59 58 60 // Transform inputs and errors 61 psArray *transformed = NULL; 59 62 psArray *transformedErrors = NULL; 60 psArray *transformed = stacTransform(inputs, inverseMaps, errors, &transformedErrors, NULL, config);63 (void)stacTransform(&transformed, &transformedErrors, inputs, inverseMaps, errors, NULL, NULL, config); 61 64 62 65 psTrace("stac.time",1,"Transformation completed at %f seconds\n", getTime() - startTime); … … 64 67 // Combine with rejection 65 68 psArray *rejected = NULL; 66 psImage *combined = stacCombine(transformed, transformedErrors, 2, &rejected, config); 69 psImage *combined = NULL; 70 (void)stacCombine(&combined, &rejected, transformed, transformedErrors, config->nReject, NULL, config); 71 72 psTrace("stac.time",1,"First combination completed at %f seconds\n", getTime() - startTime); 67 73 68 74 #ifdef TESTING … … 75 81 psArray *regions = psArrayAlloc(inputs->n); // Array of images denoting regions of interest 76 82 for (int i = 0; i < inputs->n; i++) { 77 fprintf(stderr, "Finding area of interest for image %d\n", i);78 83 regions->data[i] = stacAreaOfInterest(rejected->data[i], inverseMaps->data[i], 79 84 ((psImage*)(inputs->data[i]))->numCols, … … 89 94 psArray *rejectedSource = stacRejection(inputs, rejected, regions, maps, inverseMaps, config); 90 95 91 // Redo transformation with the mask 92 psFree(transformed); 93 psFree(transformedErrors); 94 psArray *transformedErrorsNew = NULL; 95 psArray *transformedNew = stacTransform(inputs, inverseMaps, errors, &transformedErrorsNew, 96 rejectedSource, config); 96 // Get regions of interest in the output frame 97 psImage *combineRegion = psImageAlloc(config->outnx, config->outny, PS_TYPE_U8); 98 for (int y = 0; y < config->outny; y++) { 99 for (int x = 0; x < config->outnx; x++) { 100 combineRegion->data.U8[y][x] = 0; 101 } 102 } 103 for (int i = 0; i < inputs->n; i++) { 104 psImage *region = stacAreaOfInterest(rejectedSource->data[i], maps->data[i], config->outnx, 105 config->outny); 106 psBinaryOp(combineRegion, combineRegion, "+", region); 107 psFree(region); 108 } 109 110 // Redo transformation with the masks 111 (void)stacTransform(&transformed, &transformedErrors, inputs, inverseMaps, errors, rejectedSource, 112 combineRegion, config); 97 113 98 114 // Combine the newly-transformed CR-free images, no rejection 99 psFree(combined);100 115 psFree(rejected); 101 116 rejected = NULL; 102 combined = stacCombine(transformedNew, transformedErrorsNew, 0, &rejected, config);117 (void)stacCombine(&combined, &rejected, transformed, transformedErrors, 0, combineRegion, config); 103 118 104 119 // Write output image … … 107 122 // Free everything I've used 108 123 stacConfigFree(config); 124 psFree(combineRegion); 109 125 psFree(regions); 110 126 psFree(inputs); … … 113 129 psFree(errors); 114 130 psFree(transformedErrors); 115 psFree(transformed New);131 psFree(transformed); 116 132 psFree(rejectedSource); 117 133 psFree(combined); 118 134 119 psTrace("stac.time",1," Combination completed at %f seconds\n", getTime() - startTime);135 psTrace("stac.time",1,"Final combination completed at %f seconds\n", getTime() - startTime); 120 136 121 137 // Check memory for leaks, corruption -
trunk/stac/src/stac.h
r2764 r2783 28 28 // considered bad 29 29 float grad; // Multiplier of the gradient 30 int nReject; // Number of rejection iterations 30 31 } stacConfig; 31 32 … … 67 68 // stacTransform.c 68 69 69 // Transform input images 70 psArray *stacTransform(const psArray *images, // Array of images to be transformed 71 const psArray *maps, // Array of polynomials that do the transformation 72 const psArray *errors, // Array of error images 73 psArray **outErrors, // Array of output errors 74 const psArray *masks, // Masks of input images 75 const stacConfig *config // Configuration 70 // Transform input images, return success 71 bool stacTransform(psArray **outputs, // Transformed images for output 72 psArray **outErrors, // Transformed error images for output 73 const psArray *images, // Array of images to be transformed 74 const psArray *maps, // Array of polynomials that do the transformation 75 const psArray *errors, // Array of error images to be transformed 76 const psArray *masks, // Masks of input images 77 const psImage *region, // Region of interest for transformation 78 const stacConfig *config // Configuration 76 79 ); 77 80 … … 110 113 111 114 // Combine the transformed images 112 psImage *stacCombine(psArray *images, // Array of transformed images 113 psArray *errors, // Array of transformed error images 114 int nReject, // Number of rejection iterations 115 psArray **rejected, // Array of rejection masks 116 stacConfig *config // Configuration 115 bool stacCombine(psImage **combined, // The combined image for output 116 psArray **rejected, // Array of rejection masks 117 psArray *images, // Array of transformed images 118 psArray *errors, // Array of transformed error images 119 int nReject, // Number of rejection iterations 120 psImage *region, // Region to combine 121 stacConfig *config // Configuration 117 122 ); 118 123 -
trunk/stac/src/stacAreaOfInterest.c
r2764 r2783 89 89 } 90 90 91 psTrace("stac.area", 3, "Finding area of interest....\n"); 92 93 91 94 // Coordinates for the transformations 92 95 psPlane *inFrame = psAlloc(sizeof(psPlane)); -
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 -
trunk/stac/src/stacConfig.c
r2711 r2783 9 9 { 10 10 fprintf (stderr, "STAC: Simultaneous Telescope Array Combination\n" 11 "Usage: %s [-h] [-v] [-g GAIN] [-r RN] [-o NX NY] [-s SAT] [-b BAD] [-k REJ] [- k FRAC] [-G GRAD] OUT IN1 IN2...\n"11 "Usage: %s [-h] [-v] [-g GAIN] [-r RN] [-o NX NY] [-s SAT] [-b BAD] [-k REJ] [-n NREJECT] [-k FRAC] [-G GRAD] OUT IN1 IN2...\n" 12 12 "where\n" 13 13 "\t-h Help (this info)\n" … … 19 19 "\t-b BAD Bad level (0)\n" 20 20 "\t-k REJ Rejection level (k-sigma; 3.5)\n" 21 "\t-n NREJECT Number of rejection iterations (2)\n" 21 22 "\t-f FRAC Fraction of pixel to be marked before considered bad (0.5)\n" 22 23 "\t-d GRAD Gradient threshold for pixel to be marked (0.0)\n" … … 45 46 config->frac = 0.5; 46 47 config->grad = 0.4; 48 config->nReject = 2; 47 49 48 50 return config; … … 74 76 75 77 /* Parse command-line arguments using getopt */ 76 while ((opt = getopt(argc, argv, "hvg:r:o:s:b:k: f:G:")) != -1) {78 while ((opt = getopt(argc, argv, "hvg:r:o:s:b:k:n:f:G:")) != -1) { 77 79 switch (opt) { 78 80 case 'h': … … 115 117 case 'k': 116 118 if (sscanf(optarg, "%f", &config->reject) != 1) { 119 help(programName); 120 } 121 break; 122 case 'n': 123 if (sscanf(optarg, "%d", &config->nReject) != 1) { 117 124 help(programName); 118 125 } -
trunk/stac/src/stacTransform.c
r2751 r2783 105 105 106 106 107 psArray *stacTransform(const psArray *images, // Array of images to be transformed 108 const psArray *maps, // Array of polynomials that do the transformation 109 const psArray *errors, // Array of error images to be transformed 110 psArray **outErrors, // Transformed error images for output 111 const psArray *masks, // Masks of input images 112 const stacConfig *config // Configuration 107 bool stacTransform(psArray **outputs, // Transformed images for output 108 psArray **outErrors, // Transformed error images for output 109 const psArray *images, // Array of images to be transformed 110 const psArray *maps, // Array of polynomials that do the transformation 111 const psArray *errors, // Array of error images to be transformed 112 const psArray *masks, // Masks of input images 113 const psImage *region, // Region of interest for transformation 114 const stacConfig *config // Configuration 113 115 ) 114 116 { … … 121 123 psError("stac.transform", "Number of maps (%d) does not match number of images (%d).\n", 122 124 maps->n, images->n); 123 return NULL;125 return false; 124 126 } 125 127 if (errors && (images->n != errors->n)) { 126 128 psError("stac.transform", "Number of error images (%d) does not match number of images (%d).\n", 127 129 errors->n, images->n); 128 return NULL; 129 } 130 130 return false; 131 } 132 133 // Allocate the output images if required, otherwise check the number 134 if (*outputs == NULL) { 135 *outputs = psArrayAlloc(nImages); 136 psTrace("stac.transform", 5, "Allocating space for transformed images, %dx%d\n", nx, ny); 137 for (int i = 0; i < nImages; i++) { 138 (*outputs)->data[i] = psImageAlloc(nx, ny, PS_TYPE_F32); 139 } 140 } else if ((*outputs)->n != nImages) { 141 psError("stac.transform", "Number of output images (%d) does not match number of input images " 142 "(%d).\n", (*outputs)->n, nImages); 143 return false; 144 } 145 146 // Allocate the output error images, if required, otherwise check the number 131 147 if (errors && (*outErrors == NULL)) { 132 // Allocate the output error images, if required133 148 *outErrors = psArrayAlloc(errors->n); 149 psTrace("stac.transform", 5, "Allocating space for transformed error images, %dx%d\n", nx, ny); 150 for (int i = 0; i < nImages; i++) { 151 (*outErrors)->data[i] = psImageAlloc(nx, ny, PS_TYPE_F32); 152 } 134 153 } else if (errors->n != (*outErrors)->n) { 135 154 psError("stac.transform", "Number of error output images (%d) does not match number of input" 136 155 "images (%d).\n", (*outErrors)->n, errors->n); 137 return NULL; 138 } 139 156 return false; 157 } 158 159 // Check the masks, if specified 140 160 if (masks != NULL) { 141 161 if (masks->n != nImages) { 142 162 psError("stac.transform", "Number of masks (%d) does not match number of input images (%d).\n", 143 163 masks->n, nImages); 144 return NULL;164 return false; 145 165 } 146 166 for (int i = 0; i < nImages; i++) { … … 151 171 "Size of input mask (%dx%d) does not match that of input image (%dx%d).\n", 152 172 mask->numCols, mask->numRows, image->numCols, image->numRows); 153 return NULL;173 return false; 154 174 } 155 175 } 156 176 } 157 177 158 // Arrays of images for return159 psArray *outImages = psArrayAlloc(nImages); // Output images160 178 161 179 // Stuff for the transformations 162 180 psPlane *detector = psAlloc(sizeof(psPlane)); // Coordinates on the detector 163 181 psPlane *sky = psAlloc(sizeof(psPlane)); // Coordinates on the sky 182 164 183 165 184 // Iterate over the images … … 171 190 psPlaneTransform *map = maps->data[n]; // The map 172 191 psImage *error = errors->data[n]; // The error image 173 174 // Initialise the output images 175 psImage *outImage = psImageAlloc(nx, ny, PS_TYPE_F32); 176 psImage *outError = psImageAlloc(nx, ny, PS_TYPE_F32); 177 psTrace("stac.transform", 5, "Allocating space for transformed image, %dx%d\n", nx, ny); 192 psImage *outImage = (*outputs)->data[n]; // The output image 193 psImage *outError = (*outErrors)->data[n]; // The output error image 178 194 179 195 #if 0 … … 193 209 } 194 210 195 #if 0196 // Calculate scales; could be adapted for higher order than linear by moving this into the197 // pixel-dependent section and calculating derivatives198 double xscale = 0.5*sqrt(SQUARE(map->x->coeff[0][1]) + SQUARE(map->x->coeff[1][0]));199 double yscale = 0.5*sqrt(SQUARE(map->y->coeff[0][1]) + SQUARE(map->y->coeff[1][0]));200 double areascale = 0.25 / xscale / yscale;201 #endif202 203 211 // Iterate over the output image pixels 204 212 for (int y = 0; y < ny; y++) { 205 213 for (int x = 0; x < nx; x++) { 206 // Transform! 207 sky->x = (double)x + 0.5; 208 sky->y = (double)y + 0.5; 209 (void)psPlaneTransformApply(detector, map, sky); 210 211 // Change PS_INTERPOLATE_BILINEAR to best available technique. 212 outImage->data.F32[y][x] = (psF32)psImagePixelInterpolate(image, detector->x + 0.5, 213 detector->y + 0.5, mask, 1, 0.0, 214 PS_INTERPOLATE_BILINEAR); 215 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error, 216 detector->x + 0.5, 217 detector->y + 0.5, 218 mask, 1, 0.0); 219 outError->data.F32[y][x] = sqrtf(outError->data.F32[y][x]); 214 215 // Only transform those pixels requested 216 if (!region || (region && region->data.U8[y][x])) { 217 // Transform! 218 sky->x = (double)x + 0.5; 219 sky->y = (double)y + 0.5; 220 (void)psPlaneTransformApply(detector, map, sky); 221 222 // Change PS_INTERPOLATE_BILINEAR to best available technique. 223 outImage->data.F32[y][x] = (psF32)psImagePixelInterpolate(image, detector->x + 0.5, 224 detector->y + 0.5, mask, 1, 0.0, 225 PS_INTERPOLATE_BILINEAR); 226 // Error is actually the variance 227 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error, 228 detector->x + 0.5, 229 detector->y + 0.5, 230 mask, 1, 0.0); 231 } // Pixels of interest 232 220 233 } 221 234 } // Iterating over output pixels … … 233 246 #endif 234 247 235 // Plug the new images into arrays236 outImages->data[n] = outImage;237 (*outErrors)->data[n] = outError;238 239 248 } // Iterating over images 240 249 … … 243 252 psFree(sky); 244 253 245 return outImages;254 return true; 246 255 } 247 256
Note:
See TracChangeset
for help on using the changeset viewer.
