- Timestamp:
- Aug 24, 2009, 8:40:34 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20090715/psphot/src/psphotRadialProfileByAngle.c
r25128 r25178 4 4 // separations 5 5 6 // XXX choices for rMax and Nsec? 6 float psphotMeanSectorValue (psImage *image, int x, int y, float dL, float dW, float theta); 7 psVector *psphotBoxValues (psImage *image, float x0, float y0, float dL, float dW, float theta); 8 psVector *psphotLineValues (psImage *image, double x1, double y1, double x2, double y2, int dW); 9 psVector *psphotLineValuesBresen (psImage *image, int X1, int Y1, int X2, int Y2, int dW, int swapcoords); 7 10 8 11 bool psphotRadialProfilesByAngles (pmPetrosian *petrosian, pmSource *source, int Nsec, float Rmax) { … … 28 31 psVector *flux = psVectorAllocEmpty(Rmax, PS_TYPE_F32); 29 32 30 // start at Xo,Yo and find the x,y locations for r_i, theta where r_i increments by 1 pixel 31 // XXX at large radii ( > 10-15) use stats in a patch rather than sub-pixel interpolation 32 for (float r = 0; r < Rmax; r += 1.0) { 33 // Start at Xo,Yo and find the x,y locations for r_i, theta where r_i initially 34 // increments by 1 pixel. At large radii (r*dtheta > 2) use stats in a box rather than 35 // sub-pixel interpolation 36 37 int dR = 1.0; 38 for (float r = 0; r < Rmax; r += dR) { 33 39 34 40 float Xo = source->peak->xf + 0.5; … … 38 44 float x = r * cos (theta) + Xo; 39 45 float y = r * sin (theta) + Yo; 40 41 if (x < 0) continue; 42 if (y < 0) continue; 43 if (x >= source->pixels->parent->numCols) continue; 44 if (y >= source->pixels->parent->numRows) continue; 45 46 // value is NAN if we run off the image 47 float value = psImageInterpolatePixelBilinear(x, y, source->pixels); 48 49 // keep the nan values so all vectors are matched 50 // if (isnan(value)) continue; 51 46 dR = 2*(int)(0.5*r*sin(dtheta)) + 1; 47 48 if (x < 0) goto badvalue; 49 if (y < 0) goto badvalue; 50 if (x >= source->pixels->parent->numCols) goto badvalue; 51 if (y >= source->pixels->parent->numRows) goto badvalue; 52 53 float value = NAN; 54 if (dR < 2) { 55 // value is NAN if we run off the image 56 value = psImageInterpolatePixelBilinear(x, y, source->pixels); 57 } else { 58 value = psphotMeanSectorValue(source->pixels, x, y, dR, dR, theta); 59 } 60 61 // keep the all values (even NAN) so all vectors are matched in length 52 62 psVectorAppend (radius, r); 53 63 psVectorAppend (flux, value); 64 continue; 65 66 badvalue: 67 psVectorAppend (radius, r); 68 psVectorAppend (flux, NAN); 54 69 } 55 70 … … 103 118 return true; 104 119 } 120 121 float psphotMeanSectorValue (psImage *image, int x, int y, float dL, float dW, float theta) { 122 123 psVector *values = psphotBoxValues (image, x, y, dL, dW, theta); 124 125 psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN); 126 psVectorStats (stats, values, NULL, NULL, 0); 127 128 float value = stats->sampleMedian; 129 130 psFree (stats); 131 psFree (values); 132 133 return value; 134 } 135 136 psVector *psphotBoxValues (psImage *image, float x0, float y0, float dL, float dW, float theta) { 137 138 // extract pixels from a series of lines (from -0.5*dW to +0.5*dW) of length dL, 139 // centered on x0, y0 in parent pixel coordinates (not pixel indicies) 140 141 float xs = x0 - image->col0 - 0.5*dL*cos(theta); 142 float ys = y0 - image->row0 - 0.5*dL*sin(theta); 143 144 float xe = xs + 0.5*dL*cos(theta); 145 float ye = ys + 0.5*dL*sin(theta); 146 147 psVector *values = psphotLineValues (image, xs, ys, xe, ye, (int) dW); 148 return values; 149 } 150 151 /** 152 * identify the quadrant and draw the correct line 153 */ 154 psVector *psphotLineValues (psImage *image, double x1, double y1, double x2, double y2, int dW) { 155 156 int FlipDirect, FlipCoords; 157 int X1, Y1, X2, Y2, dX, dY; 158 159 /* rather than draw the line from float positions, we find the closest 160 integer end-points and draw the line between those pixels */ 161 162 X1 = ROUND(x1); 163 Y1 = ROUND(y1); 164 X2 = ROUND(x2); 165 Y2 = ROUND(y2); 166 167 dX = X2 - X1; 168 dY = Y2 - Y1; 169 170 FlipCoords = (abs(dX) < abs(dY)); 171 FlipDirect = FlipCoords ? (y1 > y2) : (x1 > x2); 172 173 psVector *values = NULL; 174 if (!FlipDirect && !FlipCoords) values = psphotLineValuesBresen (image, X1, Y1, X2, Y2, dW, FALSE); 175 if ( FlipDirect && !FlipCoords) values = psphotLineValuesBresen (image, X2, Y2, X1, Y1, dW, FALSE); 176 if (!FlipDirect && FlipCoords) values = psphotLineValuesBresen (image, Y1, X1, Y2, X2, dW, TRUE); 177 if ( FlipDirect && FlipCoords) values = psphotLineValuesBresen (image, Y2, X2, Y1, X1, dW, TRUE); 178 179 return values; 180 } 181 182 /** 183 * use the Bresenham line drawing technique 184 * integer-only Bresenham line-draw version which is fast 185 */ 186 psVector *psphotLineValuesBresen (psImage *image, int X1, int Y1, int X2, int Y2, int dW, int swapcoords) { 187 188 int X, Y, dX, dY; 189 int e, e2; 190 191 psVector *values = psVectorAllocEmpty(100, PS_TYPE_F32); 192 193 dX = X2 - X1; 194 dY = Y2 - Y1; 195 196 Y = Y1; 197 e = 0; 198 for (X = X1; X <= X2; X++) { 199 if (X > 0) { 200 if (swapcoords) { 201 if (X >= image->numRows) continue; 202 for (int y = Y - dW; y <= Y + dW; y++) { 203 if (y < 0) continue; 204 if (y >= image->numCols) continue; 205 psVectorAppend(values, image->data.F32[X][y]); 206 } 207 } else { 208 if (X >= image->numCols) continue; 209 for (int y = Y - dW; y <= Y + dW; y++) { 210 if (y < 0) continue; 211 if (y >= image->numRows) continue; 212 psVectorAppend(values, image->data.F32[y][X]); 213 } 214 } 215 } 216 e += dY; 217 e2 = 2 * e; 218 if (e2 > dX) { 219 Y++; 220 e -= dX; 221 } 222 if (e2 < -dX) { 223 Y--; 224 e += dX; 225 } 226 } 227 return values; 228 } 229
Note:
See TracChangeset
for help on using the changeset viewer.
