Changeset 31014
- Timestamp:
- Mar 23, 2011, 8:52:13 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110213/psLib/src/imageops/psImageBackground.c
r30981 r31014 100 100 // This is not optimal, since there may be a large masked fraction that leaves us with few good pixels. 101 101 // In that case, you should have set Nsubset....... 102 // 2011/03/16 - MWV: Fixed double-sampling of sky pixels. 103 // The pick-a-random-pixel-at-a-time approach doesn't work well when Npixels is close to Nsubset 104 // If Nsubset is 0.8*Npixels, then we will get lots of pixels double-counted 105 // This is correct on average, but isn't the optimal way to estimate the sky level 106 // I suggest instead the following approach: 107 // 1) Calculate a random ordering of the pixels 108 // 2) Go through this ordering up to Nsubset to select pixels 109 psVector *frndPixelOrder = psVectorAlloc(Npixels, PS_TYPE_F32); 110 for (long i = 0; i < Npixels; i++) { 111 frndPixelOrder->data.F32[i] = psRandomUniform(rng); 112 } 113 // Now sort the array so that we end up with a list of the pixels in random order 114 psVector *frndSortedPixelOrder = psVectorSortIndex(NULL, frndPixelOrder); 115 // Now loop in our new sorted order; 116 // Note that it's the number of good samples found, "n", that will generally terminate the loop 117 for (long i = 0; n < Nsubset && i < Npixels; i++) { 118 int pixel = frndSortedPixelOrder->data.S32[i]; 119 int ix = pixel % nx; 120 int iy = pixel / nx; 121 122 if (bad->data.U8[iy][ix]) { 123 continue; 124 } 125 126 float value = image->data.F32[iy][ix]; 127 // 2011/03/16 - MWV: Keep a running overall min and max 128 min = PS_MIN(value, min); 129 max = PS_MAX(value, max); 130 values->data.F32[n] = value; 131 n++; 102 103 // 2011/03/22 - MWV: On prompting from Gene, changed the sampling so that it doesn't build and then sort 104 // a huge array when Nsubset << Npixel. 105 // O(Npixel) log(Npixel) is unnecessarily painful when Npixel=38 million (one skycell) 106 // but we only needed Nsubset pixels and Nsubset << Npixel. 107 108 // It also perhaps partially defeats any gain of taking only subsamples if we're sorting the array. 109 // I should do some performance tests on this anyway. 110 111 // If our chance of collision is low and the gain from not sorting the array is likely to be high, 112 // then just pick randomnly 113 // Note that we're guaranteeing Nsubset pixels returned here (up to the limit of Npixels) 114 if (Nsubset < 0.1 * Npixels) { 115 for (long i = 0; n < Nsubset && i < Npixels; i++) { 116 float frnd = psRandomUniform(rng); 117 int pixel = Npixels * frnd; 118 int ix = pixel % nx; 119 int iy = pixel / nx; 120 121 if (bad->data.U8[iy][ix]) { 122 continue; 123 } 124 125 float value = image->data.F32[iy][ix]; 126 min = PS_MIN(value, min); 127 max = PS_MAX(value, max); 128 values->data.F32[n] = value; 129 n++; 130 } 131 } else { 132 // 2011/03/16 - MWV: Fixed double-sampling of sky pixels. 133 // The pick-a-random-pixel-at-a-time approach doesn't work well when Npixels is close to Nsubset 134 // If Nsubset is 0.8*Npixels, then we will get lots of pixels double-counted 135 // This is correct on average, but isn't the optimal way to estimate the sky level 136 // Instead we take the following approach: 137 // 1) Calculate a random ordering of the pixels 138 // 2) Go through this ordering up to Nsubset to select pixels 139 // This is O(n log(n)) 140 psVector *frndPixelOrder = psVectorAlloc(Npixels, PS_TYPE_F32); 141 for (long i = 0; i < Npixels; i++) { 142 frndPixelOrder->data.F32[i] = psRandomUniform(rng); 143 } 144 // Now sort the array so that we end up with a list of the pixels in random order 145 psVector *frndSortedPixelOrder = psVectorSortIndex(NULL, frndPixelOrder); 146 // Now loop in our new sorted order; 147 // Note that it's the number of good samples found, "n", that will generally terminate the loop 148 for (long i = 0; n < Nsubset && i < Npixels; i++) { 149 int pixel = frndSortedPixelOrder->data.S32[i]; 150 int ix = pixel % nx; 151 int iy = pixel / nx; 152 153 if (bad->data.U8[iy][ix]) { 154 continue; 155 } 156 157 float value = image->data.F32[iy][ix]; 158 min = PS_MIN(value, min); 159 max = PS_MAX(value, max); 160 values->data.F32[n] = value; 161 n++; 162 } 132 163 } 133 164 }
Note:
See TracChangeset
for help on using the changeset viewer.
