Changeset 19345 for trunk/psModules/src/imcombine/pmStackReject.c
- Timestamp:
- Sep 3, 2008, 12:22:04 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/imcombine/pmStackReject.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmStackReject.c
r19282 r19345 8 8 9 9 #include "pmSubtraction.h" 10 #include "pmSubtractionThreads.h" 10 11 #include "pmSubtractionKernels.h" 11 12 … … 13 14 14 15 //#define TESTING // Testing output 16 17 // Mask values 18 typedef enum { 19 PM_STACK_MASK_BAD = 0x01, // Bad pixel 20 PM_STACK_MASK_CONVOLVE = 0x02, // Touching a bad pixel 21 } pmStackMask; 22 23 static bool threaded = false; // Running threaded? 24 25 26 // Grow the rejection mask 27 static inline bool stackRejectGrow(psImage *target, // Target mask image (product) 28 psImage *source, // Source mask image (to be grown) 29 const pmSubtractionKernels *kernels, // Subtraction kernels 30 int numCols, int numRows, // Size of image 31 int xMin, int xMax, int yMin, int yMax, // Bounds of convolution 32 float poorFrac // Fraction for "poor" 33 ) 34 { 35 int size = kernels->size; // Half-size of convolution kernel 36 psImage *polyValues = p_pmSubtractionPolynomialFromCoords(NULL, kernels, numCols, numRows, 37 xMin + size + 1, yMin + size + 1); // Polynomial 38 int box = p_pmSubtractionBadRadius(NULL, kernels, polyValues, false, poorFrac); // Radius of bad box 39 psFree(polyValues); 40 41 if (box > 0) { 42 // Convolve a subimage, then stick it in the target 43 if (threaded) { 44 psMutexLock(source); 45 } 46 psImage *mask = psImageSubset(source, psRegionSet(xMin - box, xMax + box, 47 yMin - box, yMax + box)); // Mask to convolve 48 if (threaded) { 49 psMutexUnlock(source); 50 } 51 psImage *convolved = psImageConvolveMask(NULL, mask, PM_STACK_MASK_BAD, PM_STACK_MASK_CONVOLVE, 52 -box, box, -box, box); // Convolved mask 53 if (threaded) { 54 psMutexLock(source); 55 } 56 psFree(mask); 57 if (threaded) { 58 psMutexUnlock(source); 59 } 60 61 int numBytes = (xMax - xMin) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK); // Number of bytes to copy 62 psAssert(convolved->numCols - 2 * box == xMax - xMin, "Bad number of columns"); 63 psAssert(convolved->numRows - 2 * box == yMax - yMin, "Bad number of rows"); 64 65 for (int yTarget = yMin, ySource = box; yTarget < yMax; yTarget++, ySource++) { 66 memcpy(&target->data.PS_TYPE_MASK_DATA[yTarget][xMin], 67 &convolved->data.PS_TYPE_MASK_DATA[ySource][box], numBytes); 68 } 69 psFree(convolved); 70 } 71 return true; 72 } 73 74 // Thread entry for stackRejectGrow 75 static bool stackRejectGrowThread(psThreadJob *job // Job to execute 76 ) 77 { 78 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 79 80 psArray *args = job->args; // Job arguments 81 psImage *target = args->data[0]; // Target mask image 82 psImage *source = args->data[1]; // Source mask image 83 const pmSubtractionKernels *kernels = args->data[2]; // Subtraction kernels 84 int numCols = PS_SCALAR_VALUE(args->data[3], S32); // Number of columns 85 int numRows = PS_SCALAR_VALUE(args->data[4], S32); // Number of rows 86 int xMin = PS_SCALAR_VALUE(args->data[5], S32); // Minimum x value 87 int xMax = PS_SCALAR_VALUE(args->data[6], S32); // Maximum x value 88 int yMin = PS_SCALAR_VALUE(args->data[7], S32); // Minimum y value 89 int yMax = PS_SCALAR_VALUE(args->data[8], S32); // Maximum y value 90 float poorFrac = PS_SCALAR_VALUE(args->data[9], F32); // Fraction for "poor" 91 92 return stackRejectGrow(target, source, kernels, numCols, numRows, xMin, xMax, yMin, yMax, poorFrac); 93 } 94 95 bool pmStackRejectThreadsInit(void) 96 { 97 if (threaded) { 98 psAbort("Already running threaded."); 99 } 100 threaded = true; 101 102 if (!pmSubtractionThreaded()) { 103 pmSubtractionThreadsInit(NULL, NULL); 104 } 105 106 { 107 psThreadTask *task = psThreadTaskAlloc("PSMODULES_STACK_REJECT_GROW", 10); 108 task->function = &stackRejectGrowThread; 109 psThreadTaskAdd(task); 110 psFree(task); 111 } 112 113 return true; 114 } 15 115 16 116 … … 52 152 pmReadout *inRO = pmReadoutAlloc(NULL); // Readout with input image 53 153 inRO->image = image; 154 if (threaded) { 155 psMutexInit(image); 156 } 54 157 for (int i = 0; i < numRegions; i++) { 55 158 psRegion *region = subRegions->data[i]; // Region of interest … … 70 173 float yNorm = (region->y0 + 0.5 * (region->y1 - region->y0) - kernels->numRows/2.0) / 71 174 (float)kernels->numRows; 72 psImage * image= pmSubtractionKernelImage(kernels, xNorm, yNorm, false);73 if (! image) {175 psImage *kernel = pmSubtractionKernelImage(kernels, xNorm, yNorm, false); 176 if (!kernel) { 74 177 psError(PS_ERR_UNKNOWN, false, "Unable to generate kernel image."); 75 178 psFree(convRO); … … 78 181 } 79 182 float sum = 0.0; 80 for (int y = 0; y < image->numRows; y++) {81 for (int x = 0; x < image->numCols; x++) {82 sum += image->data.F32[y][x];183 for (int y = 0; y < kernel->numRows; y++) { 184 for (int x = 0; x < kernel->numCols; x++) { 185 sum += kernel->data.F32[y][x]; 83 186 } 84 187 } 85 psFree( image);188 psFree(kernel); 86 189 87 190 // Range for normalisation … … 97 200 } 98 201 } 202 if (threaded) { 203 psMutexDestroy(image); 204 } 99 205 psFree(inRO); 100 206 psImage *convolved = psMemIncrRefCounter(convRO->image); … … 123 229 } 124 230 } 125 psFree(convolved);126 231 127 232 // Now, grow the mask to include everything that touches a bad pixel in the convolution 128 // Mask values: 129 // 0x0f: we think this is bad 130 // 0xf0: this is within the convolution kernel of a bad pixel 131 mask = psPixelsToMask(NULL, bad, psRegionSet(0, numCols - 1, 0, numRows - 1), 0x0f); 233 psImage *source = psPixelsToMask(NULL, bad, psRegionSet(0, numCols - 1, 0, numRows - 1), 234 PM_STACK_MASK_BAD); // Mask image to grow 235 psImage *target = psImageRecycle(convolved, numCols, numRows, PS_TYPE_U8); // Grown image 236 if (threaded) { 237 psMutexInit(source); 238 } 132 239 for (int i = 0; i < subRegions->n; i++) { 133 240 psRegion *region = subRegions->data[i]; // Subtraction region … … 141 248 int yMin = PS_MAX(region->y0, size), yMax = PS_MIN(region->y1, numRows - size); 142 249 143 psImage *polyValues = NULL; // Pre-calculated polynomial values144 250 for (int j = yMin; j < yMax; j += fullSize) { 145 251 int ySubMax = PS_MIN(j + fullSize, yMax); // Range for subregion of interest … … 147 253 int xSubMax = PS_MIN(i + fullSize, xMax); // Range for subregion of interest 148 254 149 polyValues = p_pmSubtractionPolynomialFromCoords(polyValues, kernels, numCols, numRows, 150 i + size + 1, j + size + 1); 151 int box = p_pmSubtractionBadRadius(NULL, kernels, polyValues, 152 false, poorFrac); // Radius of bad box 153 if (box > 0) { 154 // Convolve a subimage, then stick it in the original 155 psImage *subMask = psImageSubset(mask, psRegionSet(i - box, xSubMax + box, 156 j - box, ySubMax + box)); // Subimage 157 psImage *convolved = psImageConvolveMask(NULL, subMask, 0x0f, 0xf0, 158 -box, box, -box, box); // Convolved mask 159 psFree(subMask); 160 161 int numBytes = (xSubMax - i) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK); // Number of bytes to copy 162 psAssert(convolved->numCols - 2 * box == xSubMax - i, "Bad number of columns"); 163 psAssert(convolved->numRows - 2 * box == ySubMax - j, "Bad number of rows"); 164 165 for (int yTarget = j, ySource = box; yTarget < ySubMax; yTarget++, ySource++) { 166 memcpy(&mask->data.PS_TYPE_MASK_DATA[yTarget][i], 167 &convolved->data.PS_TYPE_MASK_DATA[ySource][box], numBytes); 255 if (threaded) { 256 psThreadJob *job = psThreadJobAlloc("PSMODULES_STACK_REJECT_GROW"); // Job to execute 257 psArray *args = job->args; // Job arguments 258 psArrayAdd(args, 1, target); 259 psMutexLock(source); 260 psArrayAdd(args, 1, source); 261 psMutexUnlock(source); 262 psArrayAdd(args, 1, kernels); 263 PS_ARRAY_ADD_SCALAR(args, numCols, PS_TYPE_S32); 264 PS_ARRAY_ADD_SCALAR(args, numRows, PS_TYPE_S32); 265 PS_ARRAY_ADD_SCALAR(args, i, PS_TYPE_S32); 266 PS_ARRAY_ADD_SCALAR(args, xSubMax, PS_TYPE_S32); 267 PS_ARRAY_ADD_SCALAR(args, j, PS_TYPE_S32); 268 PS_ARRAY_ADD_SCALAR(args, ySubMax, PS_TYPE_S32); 269 PS_ARRAY_ADD_SCALAR(args, poorFrac, PS_TYPE_F32); 270 if (!psThreadJobAddPending(job)) { 271 psFree(job); 272 psFree(source); 273 psFree(target); 274 return false; 168 275 } 169 psFree(convolved); 276 psFree(job); 277 } else if (!stackRejectGrow(target, source, kernels, numCols, numRows, 278 i, xSubMax, j, ySubMax, poorFrac)) { 279 psError(PS_ERR_UNKNOWN, false, "Unable to grow bad pixels."); 280 psFree(source); 281 psFree(target); 282 return NULL; 170 283 } 171 284 } 172 285 } 173 psFree(polyValues); 174 } 175 bad = psPixelsFromMask(bad, mask, 0xff); 286 } 287 288 if (!psThreadPoolWait(false)) { 289 psError(PS_ERR_UNKNOWN, false, "Unable to grow bad pixels."); 290 psFree(source); 291 psFree(target); 292 return NULL; 293 } 294 295 if (threaded) { 296 psMutexDestroy(source); 297 } 298 psFree(source); 299 bad = psPixelsFromMask(bad, target, 0xff); 176 300 177 301 return bad;
Note:
See TracChangeset
for help on using the changeset viewer.
