Changeset 19282 for trunk/psModules/src/imcombine/pmStackReject.c
- Timestamp:
- Aug 28, 2008, 6:04:19 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
r19164 r19282 4 4 5 5 #include <stdio.h> 6 #include <string.h> 6 7 #include <pslib.h> 7 8 … … 14 15 15 16 16 psPixels *pmStackReject(const psPixels *in, const psRegion *valid, float threshold,17 const psArray *subRegions, const psArray * kernels)17 psPixels *pmStackReject(const psPixels *in, int numCols, int numRows, float threshold, float poorFrac, 18 const psArray *subRegions, const psArray *subKernels) 18 19 { 19 20 PS_ASSERT_PIXELS_NON_NULL(in, NULL); … … 21 22 PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(threshold, 1.0, NULL); 22 23 PS_ASSERT_ARRAY_NON_NULL(subRegions, NULL); 23 PS_ASSERT_ARRAY_NON_NULL( kernels, NULL);24 PS_ASSERT_ARRAYS_SIZE_EQUAL(subRegions, kernels, NULL);24 PS_ASSERT_ARRAY_NON_NULL(subKernels, NULL); 25 PS_ASSERT_ARRAYS_SIZE_EQUAL(subRegions, subKernels, NULL); 25 26 26 27 // Trivial case … … 29 30 } 30 31 31 // Get the original image size 32 int numRegions = subRegions->n; // Number of regions 33 int numCols = 0, numRows = 0; // Size of original image 34 int minCols = INT_MAX, minRows = INT_MAX; // Minimum coordinate for image 32 // Check consistency of kernels 33 int numRegions = subRegions->n; // Number of regions 35 34 int size = 0; // Size of kernel 36 35 for (int i = 0; i < numRegions; i++) { 37 psRegion *subRegion = subRegions->data[i]; // Region of interest 38 if (subRegion->x0 < minCols) { 39 minCols = subRegion->x0; 40 } 41 if (subRegion->y0 < minRows) { 42 minRows = subRegion->y0; 43 } 44 if (subRegion->x1 > numCols) { 45 numCols = subRegion->x1; 46 } 47 if (subRegion->y1 > numRows) { 48 numRows = subRegion->y1; 49 } 50 51 pmSubtractionKernels *kernel = kernels->data[i]; // Kernel of interest 36 pmSubtractionKernels *kernels = subKernels->data[i]; // Kernel of interest 52 37 if (size == 0) { 53 size = kernel ->size;54 } else if (kernel ->size != size) {38 size = kernels->size; 39 } else if (kernels->size != size) { 55 40 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Kernel sizes are not identical: %d vs %d", 56 size, kernel ->size);41 size, kernels->size); 57 42 return NULL; 58 43 } 59 44 } 60 45 61 // Adjust the size for the size of the subimage 62 if (valid) { 63 minCols = PS_MAX(valid->x0, minCols); 64 minRows = PS_MAX(valid->y0, minRows); 65 numCols = PS_MIN(valid->x1, numCols); 66 numRows = PS_MIN(valid->y1, numRows); 67 } 68 psTrace("psModules.imcombine", 1, "Rejecting [%d:%d,%d:%d]\n", minCols, numCols, minRows, numRows); 69 70 psImage *mask = psPixelsToMask(NULL, in, psRegionSet(minCols, numCols - 1, minRows, numRows - 1), 71 0x01); // Mask 46 psImage *mask = psPixelsToMask(NULL, in, psRegionSet(0, numCols - 1, 0, numRows - 1), 0x01); // Mask 72 47 psImage *image = psImageCopy(NULL, mask, PS_TYPE_F32); // Floating-point version, so we can convolve 73 48 psFree(mask); … … 77 52 pmReadout *inRO = pmReadoutAlloc(NULL); // Readout with input image 78 53 inRO->image = image; 79 inRO->col0 = minCols;80 inRO->row0 = minRows;81 54 for (int i = 0; i < numRegions; i++) { 82 55 psRegion *region = subRegions->data[i]; // Region of interest 83 if (valid && (region->x0 > valid->x1 || region->x1 < valid->x0 || 84 region->y0 > valid->y1 || region->y1 < valid->y0)) { 85 // Region is outside of our sub-image 86 continue; 87 } 88 pmSubtractionKernels *kernel = kernels->data[i]; // Kernel of interest 89 if (!pmSubtractionConvolve(convRO, NULL, inRO, NULL, NULL, 0, 0, 1.0, region, kernel, false, true)) { 56 pmSubtractionKernels *kernels = subKernels->data[i]; // Kernel of interest 57 if (!pmSubtractionConvolve(convRO, NULL, inRO, NULL, NULL, 0, 0, 1.0, region, kernels, false, true)) { 90 58 psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask image in region %d.", i); 91 59 psFree(convRO); … … 98 66 99 67 // Image of the kernel at the centre of the region 100 float xNorm = (region->x0 + 0.5 * (region->x1 - region->x0) - kernel ->numCols/2.0) /101 (float)kernel ->numCols;102 float yNorm = (region->y0 + 0.5 * (region->y1 - region->y0) - kernel ->numRows/2.0) /103 (float)kernel ->numRows;104 psImage *image = pmSubtractionKernelImage(kernel , xNorm, yNorm, false);68 float xNorm = (region->x0 + 0.5 * (region->x1 - region->x0) - kernels->numCols/2.0) / 69 (float)kernels->numCols; 70 float yNorm = (region->y0 + 0.5 * (region->y1 - region->y0) - kernels->numRows/2.0) / 71 (float)kernels->numRows; 72 psImage *image = pmSubtractionKernelImage(kernels, xNorm, yNorm, false); 105 73 if (!image) { 106 74 psError(PS_ERR_UNKNOWN, false, "Unable to generate kernel image."); … … 118 86 119 87 // Range for normalisation 120 int yMin = PS_MAX(minRows, region->y0) - inRO->row0; 121 int yMax = PS_MIN(numRows - 1, region->y1) - inRO->row0; 122 int xMin = PS_MAX(minCols, region->x0) - inRO->col0; 123 int xMax = PS_MIN(numCols - 1, region->x1) - inRO->col0; 88 int xMin = PS_MAX(0, region->x0), xMax = PS_MIN(numCols - 1, region->x1); 89 int yMin = PS_MAX(0, region->y0), yMax = PS_MIN(numRows - 1, region->y1); 124 90 psTrace("psModules.imcombine", 2, "Normalising convolved mask image by %f over %d:%d,%d:%d\n", 125 91 sum, xMin, xMax, yMin, yMax); 92 sum = 1.0 / sum; 126 93 for (int y = yMin; y <= yMax; y++) { 127 94 for (int x = xMin; x <= xMax; x++) { 128 convRO->image->data.F32[y][x] /= sum;95 convRO->image->data.F32[y][x] *= sum; 129 96 } 130 97 } … … 152 119 for (int x = size; x < convolved->numCols - size; x++) { 153 120 if (convolved->data.F32[y][x] > threshold) { 154 // Pixel coordinates in "bad" correspond to the full image 155 bad = psPixelsAdd(bad, PIXEL_LIST_BUFFER, x + minCols, y + minRows); 121 bad = psPixelsAdd(bad, bad->nalloc, x, y); 156 122 } 157 123 } … … 160 126 161 127 // Now, grow the mask to include everything that touches a bad pixel in the convolution 162 int x0 = minCols, y0 = minRows; // Offset for mask image 163 mask = psPixelsToMask(NULL, bad, psRegionSet(x0, numCols - 1, y0, numRows - 1), 0xff); 164 for (int i = 0; i < bad->n; i++) { 165 int xPix = bad->data[i].x - x0, yPix = bad->data[i].y - y0; // Coordinates in frame of mask image 166 // Convolution limits 167 int xMin = PS_MAX(xPix - size, 0); 168 int xMax = PS_MIN(xPix + size, mask->numCols - 1); 169 int yMin = PS_MAX(yPix - size, 0); 170 int yMax = PS_MIN(yPix + size, mask->numRows - 1); 171 for (int y = yMin; y <= yMax; y++) { 172 for (int x = xMin; x <= xMax; x++) { 173 assert(x < mask->numCols && y < mask->numRows); 174 mask->data.PS_TYPE_MASK_DATA[y][x] = 0xff; 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); 132 for (int i = 0; i < subRegions->n; i++) { 133 psRegion *region = subRegions->data[i]; // Subtraction region 134 pmSubtractionKernels *kernels = subKernels->data[i]; // Subtraction kernel 135 136 int size = kernels->size; // Half-size of kernel 137 int fullSize = 2 * size + 1; // Full size of kernel 138 139 // Get region for convolution: [xMin:xMax,yMin:yMax] 140 int xMin = PS_MAX(region->x0, size), xMax = PS_MIN(region->x1, numCols - size); 141 int yMin = PS_MAX(region->y0, size), yMax = PS_MIN(region->y1, numRows - size); 142 143 psImage *polyValues = NULL; // Pre-calculated polynomial values 144 for (int j = yMin; j < yMax; j += fullSize) { 145 int ySubMax = PS_MIN(j + fullSize, yMax); // Range for subregion of interest 146 for (int i = xMin; i < xMax; i += fullSize) { 147 int xSubMax = PS_MIN(i + fullSize, xMax); // Range for subregion of interest 148 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); 168 } 169 psFree(convolved); 170 } 175 171 } 176 172 } 173 psFree(polyValues); 177 174 } 178 175 bad = psPixelsFromMask(bad, mask, 0xff); 179 psFree(mask);180 181 // Convert coordinates to frame of original image182 for (int i = 0; i < bad->n; i++) {183 int x = bad->data[i].x + x0;184 int y = bad->data[i].y + y0;185 if (x < 0 || x >= numCols || y < 0 || y >= numRows) {186 psWarning("Bad pixel coordinate %d: %d,%d --- ignored.",187 i, x, y);188 continue;189 }190 bad->data[i].x = x;191 bad->data[i].y = y;192 }193 176 194 177 return bad;
Note:
See TracChangeset
for help on using the changeset viewer.
