IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 24, 2009, 8:40:34 AM (17 years ago)
Author:
eugene
Message:

various petrosian / radial profile analysis improvements

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715/psphot/src/psphotRadialProfileByAngle.c

    r25128 r25178  
    44// separations
    55
    6 // XXX choices for rMax and Nsec?
     6float psphotMeanSectorValue (psImage *image, int x, int y, float dL, float dW, float theta);
     7psVector *psphotBoxValues (psImage *image, float x0, float y0, float dL, float dW, float theta);
     8psVector *psphotLineValues (psImage *image, double x1, double y1, double x2, double y2, int dW);
     9psVector *psphotLineValuesBresen (psImage *image, int X1, int Y1, int X2, int Y2, int dW, int swapcoords);
    710
    811bool psphotRadialProfilesByAngles (pmPetrosian *petrosian, pmSource *source, int Nsec, float Rmax) {
     
    2831        psVector *flux   = psVectorAllocEmpty(Rmax, PS_TYPE_F32);
    2932
    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) {
    3339
    3440            float Xo = source->peak->xf + 0.5;
     
    3844            float x = r * cos (theta) + Xo;
    3945            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
    5262            psVectorAppend (radius, r);
    5363            psVectorAppend (flux, value);
     64            continue;
     65           
     66        badvalue:
     67            psVectorAppend (radius, r);
     68            psVectorAppend (flux, NAN);
    5469        }
    5570
     
    103118    return true;
    104119}
     120
     121float 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
     136psVector *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 */
     154psVector *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 */
     186psVector *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.