IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 13236


Ignore:
Timestamp:
May 4, 2007, 6:40:14 AM (19 years ago)
Author:
rhl
Message:

Worked on pmFootprints; added pmFindFootprintAtPoint

Location:
trunk/psphot/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/pmFootprint.c

    r13007 r13236  
    3434}
    3535
     36//
     37// Sort pmSpans by y, then x0, then x1
     38//
     39int pmSpanSortByYX(const void **a, const void **b) {
     40    const pmSpan *sa = *(const pmSpan **)a;
     41    const pmSpan *sb = *(const pmSpan **)b;
     42
     43    if (sa->y < sb->y) {
     44        return -1;
     45    } else if (sa->y == sb->y) {
     46        if (sa->x0 < sb->x0) {
     47            return -1;
     48        } else if (sa->x0 == sb->x0) {
     49            if (sa->x1 < sb->x1) {
     50                return -1;
     51            } else if (sa->x1 == sb->x1) {
     52                return 0;
     53            } else {
     54                return 1;
     55            }
     56        } else {
     57            return 1;
     58        }
     59    } else {
     60        return 1;
     61    }
     62}
     63
    3664/************************************************************************************************************/
    3765
     
    6391    psMemSetDeallocator(footprint, (psFreeFunc) footprintFree);
    6492
     93    footprint->normalized = false;
     94
    6595    assert(nspan >= 0);
    6696    footprint->npix = 0;
    67     footprint->nspan = nspan;
    6897    footprint->spans = psArrayAllocEmpty(nspan);
    6998    footprint->peaks = psArrayAlloc(0);
     
    90119}
    91120
     121pmFootprint *pmFootprintNormalize(pmFootprint *fp) {
     122    if (fp != NULL && !fp->normalized) {
     123        fp->peaks = psArraySort(fp->peaks, pmPeakSortBySN);
     124        fp->normalized = true;
     125    }
     126
     127    return fp;
     128}
     129
    92130//
    93 // Add a span to a footprint, returning the number of pixels in the footprint
     131// Add a span to a footprint, returning the new span
    94132//
    95 static int pmFootprintAddSpan(pmFootprint *fp,  // the footprint to add to
    96                               const int y,      // row to add
    97                               int x0,           // range of
    98                               int x1) {         //          columns
     133static pmSpan *pmFootprintAddSpan(pmFootprint *fp,      // the footprint to add to
     134                                  const int y, // row to add
     135                                  int x0,      // range of
     136                                  int x1) {    //          columns
    99137
    100138    if (x1 < x0) {
     
    110148    fp->npix += x1 - x0 + 1;
    111149
    112     if (fp->nspan == 1) {
     150    if (fp->spans->n == 1) {
    113151        fp->bbox.x0 = x0;
    114152        fp->bbox.x1 = x1;
     
    122160    }
    123161
    124     return fp->npix;
     162    return sp;
    125163}
    126164
    127165void pmFootprintSetBBox(pmFootprint *fp) {
    128166    assert (fp != NULL);
    129     if (fp->nspan == 0) {
     167    if (fp->spans->n == 0) {
    130168        return;
    131169    }
     
    154192   assert (fp != NULL);
    155193   int npix = 0;
    156    for (int i = 0; i < fp->nspan; i++) {
     194   for (int i = 0; i < fp->spans->n; i++) {
    157195       pmSpan *span = fp->spans->data[i];
    158196       npix += span->x1 - span->x0 + 1;
     
    215253                 const int npixMin)     // minimum number of pixels in an acceptable pmFootprint
    216254{
    217    int *aliases;                        /* aliases for object IDs */
    218    int *id_s;                           /* storage for id[cp] */
    219    int *idc, *idp;                      /* object IDs in current/previous row*/
    220255   int i0;                              /* initial value of i */
    221256   int id;                              /* object ID */
     
    224259   int nobj = 0;                        /* number of objects found */
    225260   int x0 = 0;                          /* unpacked from a WSPAN */
    226    int size_aliases = 0;                /* size of aliases[] array */
    227    int size_spans = 0;                  /* size of spans[] array */
    228    WSPAN *spans;                        /* row:x0,x1 for objects */
    229261   int *tmp;                            /* used in swapping idc/idp */
    230262
     
    251283 * refer to idp[-1] and idp[numCols], hence the (numCols + 2)
    252284 */
    253    id_s = psAlloc(2*(numCols + 2)*sizeof(int));
     285   int *id_s = psAlloc(2*(numCols + 2)*sizeof(int));
    254286   memset(id_s, '\0', 2*(numCols + 2)*sizeof(int)); assert(id_s[0] == 0);
    255    idc = id_s + 1; idp = idc + (numCols + 2);
    256 
    257    size_aliases = 1 + numRows/20;
    258    aliases = psAlloc(size_aliases*sizeof(int));
    259 
    260    size_spans = 1 + numRows/20;
    261    spans = psAlloc(size_spans*sizeof(WSPAN));
     287   int *idc = id_s + 1;                 // object IDs in current/
     288   int *idp = idc + (numCols + 2);      //                       previous row
     289
     290   int size_aliases = 1 + numRows/20;   // size of aliases[] array
     291   int *aliases = psAlloc(size_aliases*sizeof(int)); // aliases for object IDs
     292
     293   int size_spans = 1 + numRows/20;     // size of spans[] array
     294   WSPAN *spans = psAlloc(size_spans*sizeof(WSPAN)); // row:x0,x1 for objects
    262295/*
    263296 * Go through image identifying objects
     
    273306      in_span = 0;                      /* not in a span */
    274307      for (j = 0; j < numCols; j++) {
    275           double pixVal = F32 ? imgRowF32[j] : imgRowS32[j];
     308         double pixVal = F32 ? imgRowF32[j] : imgRowS32[j];
    276309         if (pixVal < threshold) {
    277310            if (in_span) {
     
    395428/************************************************************************************************************/
    396429/*
    397  * Worker routine for the pmSetFootprintArrayIds (and pmMergeFootprintArrays)
    398  */
     430 * A data structure to hold the starting point for a search for pixels above threshold,
     431 * used by pmFindFootprintAtPoint
     432 *
     433 * We don't want to find this span again --- it's already part of the footprint ---
     434 * so we set the pixels in the image to as small a value as we can.  N.b. We may want
     435 * to reconsider this when dealing with difference images
     436 */
     437typedef enum {PM_SSPAN_DOWN = 0,        // scan down from this span
     438              PM_SSPAN_UP,              // scan up from this span
     439              PM_SSPAN_RESTART,         // restart scanning from this span
     440              PM_SSPAN_DONE             // this span is processed
     441} PM_SSPAN_DIR;                         // How to continue searching
     442
     443typedef struct {
     444    const pmSpan *span;                 // save the pixel range
     445    PM_SSPAN_DIR direction;             // How to continue searching
     446    // private
     447    int nbyte;                          // number of bytes saved
     448    void *data;                         // saved data
     449    void *data_home;                    // where the data was saved from
     450} Startspan;
     451
     452static void startspanFree(Startspan *sspan) {
     453    if (sspan->nbyte > 0) {
     454        memcpy(sspan->data_home, sspan->data, sspan->nbyte); // restore image's pixels to their pristine state
     455    }
     456
     457    psFree(sspan->data);
     458    psFree((void *)sspan->span);
     459}
     460
     461static Startspan *
     462StartspanAlloc(const pmSpan *span, // The span in question
     463               psImage *img,// the data wherein lives the span
     464               const PM_SSPAN_DIR dir   // Should we continue searching towards the top of the image?
     465    ) {
     466    Startspan *sspan = psAlloc(sizeof(Startspan));
     467    psMemSetDeallocator(sspan, (psFreeFunc)startspanFree);
     468
     469    sspan->span = psMemIncrRefCounter((void *)span);
     470    sspan->direction = dir;
     471   
     472    if (img == NULL) {                  // nothing to save
     473        sspan->nbyte = 0;
     474        sspan->data_home = sspan->data = NULL;
     475
     476        return sspan;
     477    }
     478    //
     479    // Save the pixels, and set the image to a -ve large value
     480    //   
     481    sspan->nbyte = (span->x1 - span->x0 + 1)*PSELEMTYPE_SIZEOF(img->type.type);
     482    sspan->data = psAlloc(sspan->nbyte);
     483
     484    switch (img->type.type) {
     485      case PS_TYPE_F32:
     486        sspan->data_home = &img->data.F32[span->y - img->row0][span->x0 - img->col0];
     487        memcpy(sspan->data, sspan->data_home, sspan->nbyte);
     488
     489        for (int i = 0; i <= span->x1 - span->x0; i++) {
     490            ((psF32 *)sspan->data_home)[i] = PS_MIN_F32;
     491        }
     492        break;
     493      case PS_TYPE_S32:
     494        sspan->data_home = &img->data.S32[span->y - img->row0][span->x0 - img->col0];
     495        memcpy(sspan->data, sspan->data_home, sspan->nbyte);
     496       
     497        for (int i = 0; i <= span->x1 - span->x0; i++) {
     498            ((psS32 *)sspan->data_home)[i] = PS_MIN_S32;
     499        }
     500        break;
     501      default:
     502        psAbort("Unsupported image type %d\n", img->type.type);
     503    }
     504
     505    return sspan;
     506}
     507
     508//
     509// Add a new Startspan to an array of Startspans
     510//
     511static void add_startspan(psArray *startspans, // the saved Startspans
     512                          const pmSpan *sp, // the span in question
     513                          const psImage *img, // image to save/restore (or NULL)
     514                          const PM_SSPAN_DIR dir) { // the desired direction to search
     515    if (dir == PM_SSPAN_RESTART) {
     516        add_startspan(startspans, sp, img,  PM_SSPAN_UP);
     517        add_startspan(startspans, sp, NULL, PM_SSPAN_DOWN);
     518    } else {
     519        Startspan *sspan = StartspanAlloc(sp, (psImage *)img, dir);
     520        psArrayAdd(startspans, 1, sspan);
     521        psFree(sspan);                  // as it's now owned by startspans
     522    }
     523}
     524
     525/************************************************************************************************************/
     526/*
     527 * Search the image for pixels above threshold, starting at a single Startspan.
     528 * We search the array looking for one to process; it'd be better to move the
     529 * ones that we're done with to the end, but it probably isn't worth it for
     530 * the anticipated uses of this routine.
     531 *
     532 * This is the guts of pmFindFootprintAtPoint
     533 */
     534static bool do_startspan(pmFootprint *fp, // the footprint that we're building
     535                         const psImage *img, // the psImage we're working on
     536                         const float threshold, // Threshold
     537                         psArray *startspans) { // specify which span to process next
     538    bool F32 = false;                   // is this an F32 image?
     539    if (img->type.type == PS_TYPE_F32) {
     540        F32 = true;
     541    } else if (img->type.type == PS_TYPE_S32) {
     542        F32 = false;
     543    } else {                            // N.b. You can't trivially add more cases here; F32 is just a bool
     544        psError(PS_ERR_UNKNOWN, true, "Unsupported psImage type: %d", img->type.type);
     545        return NULL;
     546    }
     547
     548    psF32 *imgRowF32 = NULL;            // row pointer if F32
     549    psS32 *imgRowS32 = NULL;            //  "   "   "  "  !F32
     550   
     551    const int row0 = img->row0;
     552    const int col0 = img->col0;
     553    const int numRows = img->numRows;
     554    const int numCols = img->numCols;
     555   
     556    /********************************************************************************************************/
     557   
     558    Startspan *sspan = NULL;
     559    for (int i = 0; i < startspans->n; i++) {
     560        sspan = startspans->data[i];
     561        if (sspan->direction != PM_SSPAN_DONE) {
     562            break;
     563        }
     564    }
     565    if (sspan == NULL || sspan->direction == PM_SSPAN_DONE) { // no more Startspans to process
     566        return false;
     567    }
     568    /*
     569     * Work
     570     */
     571    const PM_SSPAN_DIR dir = sspan->direction;
     572    /*
     573     * Set initial span to the startspan
     574     */
     575    int x0 = sspan->span->x0 - col0, x1 = sspan->span->x1 - col0;
     576    /*
     577     * Go through image identifying objects
     578     */
     579    int nx0, nx1 = -1;                  // new values of x0, x1
     580    const int di = (dir == PM_SSPAN_UP) ? 1 : -1; // how much i changes to get to the next row
     581    for (int i = sspan->span->y -row0 + di; i < numRows && i >= 0; i += di) {
     582        imgRowF32 = img->data.F32[i];   // only one of
     583        imgRowS32 = img->data.S32[i];   //      these is valid!
     584        //
     585        // Search left from the pixel diagonally to the left of (i - di, x0). If there's
     586        // a connected span there it may need to grow up and/or down, so push it onto
     587        // the stack for later consideration
     588        //
     589        nx0 = -1;
     590        for (int j = x0 - 1; j >= -1; j--) {
     591            double pixVal = (j < 0) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]);
     592            if (pixVal < threshold) {
     593                if (j < x0 - 1) {       // we found some pixels above threshold
     594                    nx0 = j + 1;
     595                }
     596                break;
     597            }
     598        }
     599
     600        if (nx0 < 0) {                  // no span to the left
     601            nx1 = x0 - 1;               // we're going to resume searching at nx1 + 1
     602        } else {
     603            //
     604            // Search right in leftmost span
     605            //
     606            //nx1 = 0;                  // make gcc happy
     607            for (int j = nx0 + 1; j <= numCols; j++) {
     608                double pixVal = (j >= numCols) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]);
     609                if (pixVal < threshold) {
     610                    nx1 = j - 1;
     611                    break;
     612                }
     613            }
     614           
     615            const pmSpan *sp = pmFootprintAddSpan(fp, i + row0, nx0 + col0, nx1 + col0);
     616           
     617            add_startspan(startspans, sp, (psImage *)img, PM_SSPAN_RESTART);
     618        }
     619        //
     620        // Now look for spans connected to the old span.  The first of these we'll
     621        // simply process, but others will have to be deferred for later consideration.
     622        //
     623        // In fact, if the span overhangs to the right we'll have to defer the overhang
     624        // until later too, as it too can grow in both directions
     625        //
     626        // Note that column numCols exists virtually, and always ends the last span; this
     627        // is why we claim below that sx1 is always set
     628        //
     629        bool first = false;             // is this the first new span detected?
     630        for (int j = nx1 + 1; j <= x1 + 1; j++) {
     631            double pixVal = (j >= numCols) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]);
     632            if (pixVal >= threshold) {
     633                int sx0 = j++;          // span that we're working on is sx0:sx1
     634                int sx1 = -1;           // We know that if we got here, we'll also set sx1
     635                for (; j <= numCols; j++) {
     636                    double pixVal = (j >= numCols) ? threshold - 100 : (F32 ? imgRowF32[j] : imgRowS32[j]);
     637                    if (pixVal < threshold) { // end of span
     638                        sx1 = j;
     639                        break;
     640                    }
     641                }
     642                assert (sx1 >= 0);
     643
     644                const pmSpan *sp;
     645                if (first) {
     646                    if (sx1 <= x1) {
     647                        sp = pmFootprintAddSpan(fp, i + row0, sx0 + col0, sx1 + col0 - 1);
     648                        add_startspan(startspans, sp, (psImage *)img, PM_SSPAN_DONE);
     649                    } else {            // overhangs to right
     650                        sp = pmFootprintAddSpan(fp, i + row0, sx0 + col0, x1 + col0);
     651                        add_startspan(startspans, sp, (psImage *)img, PM_SSPAN_DONE);
     652                        sp = pmFootprintAddSpan(fp, i + row0, x1 + 1 + col0, sx1 + col0 - 1);
     653                        add_startspan(startspans, sp, (psImage *)img, PM_SSPAN_RESTART);
     654                    }
     655                    first = false;
     656                } else {
     657                    sp = pmFootprintAddSpan(fp, i + row0, sx0 + col0, sx1 + col0 - 1);
     658                    add_startspan(startspans, sp, (psImage *)img, PM_SSPAN_RESTART);
     659                }
     660            }
     661        }
     662
     663        if (first == false) {           // we're done
     664            break;
     665        }
     666
     667        x0 = nx0; x1 = nx1;
     668    }
     669    /*
     670     * Cleanup
     671     */
     672
     673    sspan->direction = PM_SSPAN_DONE;
     674    return true;
     675}
     676
     677/*
     678 * Go through an image, starting at (row, col) and assembling all the pixels
     679 * that are connected to that point (in a chess kings-move sort of way) into
     680 * a pmFootprint.
     681 *
     682 * This is much slower than pmFindFootprints if you want to find lots of
     683 * footprints, but if you only want a small region about a given point it
     684 * can be much faster
     685 *
     686 * N.b. The returned pmFootprint is not in "normal form"; that is the pmSpans
     687 * are not sorted by increasing y, x0, x1.  If this matters to you, call
     688 * pmFootprintNormalize()
     689 */
     690pmFootprint *
     691pmFindFootprintAtPoint(const psImage *img,      // image to search
     692                       const float threshold,   // Threshold
     693                       int row, int col) { // starting position (in img's parent's coordinate system)
     694   assert(img != NULL);
     695
     696   bool F32 = false;                    // is this an F32 image?
     697   if (img->type.type == PS_TYPE_F32) {
     698       F32 = true;
     699   } else if (img->type.type == PS_TYPE_S32) {
     700       F32 = false;
     701   } else {                             // N.b. You can't trivially add more cases here; F32 is just a bool
     702       psError(PS_ERR_UNKNOWN, true, "Unsupported psImage type: %d", img->type.type);
     703       return NULL;
     704   }
     705   psF32 *imgRowF32 = NULL;             // row pointer if F32
     706   psS32 *imgRowS32 = NULL;             //  "   "   "  "  !F32
     707   
     708   const int row0 = img->row0;
     709   const int col0 = img->col0;
     710   const int numRows = img->numRows;
     711   const int numCols = img->numCols;
     712/*
     713 * Is point in image, and above threshold?
     714 */
     715   row -= row0; col -= col0;
     716   if (row < 0 || row >= numRows ||
     717       col < 0 || col >= numCols) {
     718        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     719                "row/col == (%d, %d) are out of bounds [%d--%d, %d--%d]",
     720                row + row0, col + col0, row0, row0 + numRows - 1, col0, col0 + numCols - 1);
     721       return NULL;
     722   }
     723
     724   double pixVal = F32 ? img->data.F32[row][col] : img->data.S32[row][col];
     725   if (pixVal < threshold) {
     726       return pmFootprintAlloc(0, img);
     727   }
     728   
     729   pmFootprint *fp = pmFootprintAlloc(1 + img->numRows/10, img);
     730/*
     731 * Find starting span passing through (row, col)
     732 */
     733   psArray *startspans = psArrayAllocEmpty(1); // spans where we have to restart the search
     734   
     735   imgRowF32 = img->data.F32[row];      // only one of
     736   imgRowS32 = img->data.S32[row];      //      these is valid!
     737   {
     738       int i;
     739       for (i = col; i >= 0; i--) {
     740           pixVal = F32 ? imgRowF32[i] : imgRowS32[i];
     741           if (pixVal < threshold) {
     742               break;
     743           }
     744       }
     745       int i0 = i;
     746       for (i = col; i < numCols; i++) {
     747           pixVal = F32 ? imgRowF32[i] : imgRowS32[i];
     748           if (pixVal < threshold) {
     749               break;
     750           }
     751       }
     752       int i1 = i;
     753       const pmSpan *sp = pmFootprintAddSpan(fp, row + row0, i0 + col0 + 1, i1 + col0 - 1);
     754
     755       add_startspan(startspans, sp, (psImage *)img, PM_SSPAN_RESTART);
     756   }
     757   /*
     758    * Now workout from those Startspans, searching for pixels above threshold
     759    */
     760   while (do_startspan(fp, img, threshold, startspans)) continue;
     761   /*
     762    * Cleanup
     763    */
     764   psFree(startspans);                  // restores the image pixel
     765
     766   return fp;                           // pmFootprint really
     767}
     768
     769/************************************************************************************************************/
     770/*
     771 * Worker routine for the pmSetFootprintArrayIDs/pmSetFootprintID (and pmMergeFootprintArrays)
     772 */
     773static void
     774set_footprint_id(psImage *idImage,      // the image to set
     775                 const pmFootprint *fp, // the footprint to insert
     776                 const int id) {        // the desired ID
     777   const int col0 = fp->region.x0;
     778   const int row0 = fp->region.y0;
     779
     780   for (int j = 0; j < fp->spans->n; j++) {
     781       const pmSpan *span = fp->spans->data[j];
     782       psS32 *imgRow = idImage->data.S32[span->y - row0];
     783       for(int k = span->x0 - col0; k <= span->x1 - col0; k++) {
     784           imgRow[k] += id;
     785       }
     786   }
     787}
     788
    399789static void
    400790set_footprint_array_ids(psImage *idImage,
    401791                        const psArray *footprints, // the footprints to insert
    402792                        const bool relativeIDs) { // show IDs starting at 0, not pmFootprint->id
    403    const pmFootprint *fp = footprints->data[0];
    404    const int col0 = fp->region.x0;
    405    const int row0 = fp->region.y0;
    406 
    407793   int id = 0;                          // first index will be 1
    408794   for (int i = 0; i < footprints->n; i++) {
    409       fp = footprints->data[i];
    410       if (relativeIDs) {
    411          id++;
    412       } else {
    413          id = fp->id;
    414       }
    415      
    416       for (int j = 0; j < fp->nspan; j++) {
    417          const pmSpan *span = fp->spans->data[j];
    418          psS32 *imgRow = idImage->data.S32[span->y - row0];
    419          for(int k = span->x0 - col0; k <= span->x1 - col0; k++) {
    420             imgRow[k] += id;
    421          }
    422       }
     795       const pmFootprint *fp = footprints->data[i];
     796       if (relativeIDs) {
     797           id++;
     798       } else {
     799           id = fp->id;
     800       }
     801       
     802       set_footprint_id(idImage, fp, id);
    423803   }
    424804}
     
    428808 */
    429809psImage *pmSetFootprintArrayIDs(const psArray *footprints, // the footprints to insert
    430                                 const bool relativeIDs) { // show IDs starting at 0, not pmFootprint->id
     810                                const bool relativeIDs) { // show IDs starting at 1, not pmFootprint->id
    431811   assert (footprints != NULL);
    432812
     
    456836}
    457837
     838/*
     839 * Set an image to the value of footprint's ID whever they may fall
     840 */
     841psImage *pmSetFootprintID(const pmFootprint *fp, // the footprint to insert
     842                          const int id) {       // the desired ID
     843   assert(fp != NULL && pmIsFootprint((const psPtr)fp));
     844   const int numCols = fp->region.x1 - fp->region.x0 + 1;
     845   const int numRows = fp->region.y1 - fp->region.y0 + 1;
     846   const int col0 = fp->region.x0;
     847   const int row0 = fp->region.y0;
     848   assert (numCols >= 0 && numRows >= 0);
     849   
     850   psImage *idImage = psImageAlloc(numCols, numRows, PS_TYPE_S32);
     851   P_PSIMAGE_SET_ROW0(idImage, row0);
     852   P_PSIMAGE_SET_COL0(idImage, col0);
     853   psImageInit(idImage, 0);
     854   /*
     855    * do the work
     856    */
     857   set_footprint_id(idImage, fp, id);
     858
     859   return idImage;
     860   
     861}
     862
    458863/************************************************************************************************************/
    459864/*
     
    575980    for (int i = 0; i < footprints->n; i++) {
    576981        pmFootprint *fp = footprints->data[i];
    577         fp->peaks = psArraySort (fp->peaks, pmPeakSortBySN);
     982        fp->peaks = psArraySort(fp->peaks, pmPeakSortBySN);
    578983    }
    579984
     
    6241029        float threshold = subImg->data.F32[y][x] - nsigma_delta*stdev;
    6251030        if (threshold < min_threshold) {
     1031#if 1                                   // min_threshold is assumed to be below the detection threshold,
     1032                                        // so all the peaks are pmFootprint, and this isn't the brightest
     1033            (void)psArrayRemoveIndex(fp->peaks, i);
     1034            i--;                        // we moved everything down one
     1035            continue;
     1036#else
     1037#error n.b. We will be running LOTS of checks at this threshold, so only find the footprint once
    6261038            threshold = min_threshold;
     1039#endif
    6271040        }
    6281041        if (threshold > subImg->data.F32[y][x]) {
     
    6301043        }
    6311044
    632         psArray *peakFootprints = pmFindFootprints(subImg, threshold, 1);
     1045#if 0
     1046        const in npixMin = 1;
     1047        psArray *peakFootprints = pmFindFootprints(subImg, threshold, npixMin);
    6331048        psImage *idImg = pmSetFootprintArrayIDs(peakFootprints, true);
    634 
     1049        psFree(peakFootprints);
    6351050        const int peak_id = idImg->data.S32[y][x]; // the ID for the peak of interest
    6361051        assert (peak_id != 0);
     1052#else
     1053        const int peak_id = 1; // the ID for the peak of interest
     1054        pmFootprint *peakFootprint = pmFindFootprintAtPoint(subImg, threshold, peak->y, peak->x);
     1055        psImage *idImg = pmSetFootprintID(peakFootprint, peak_id);
     1056        psFree(peakFootprint);
     1057#endif
    6371058
    6381059        int j;
     
    6541075        }
    6551076
    656         psFree(peakFootprints);
    6571077        psFree(idImg);
    6581078    }
  • trunk/psphot/src/pmFootprint.h

    r13007 r13236  
    11#if !defined(PM_FOOTPRINT_H)
    22#define PM_FOOTPRINT_H
    3 
     3//
     4// Describe a segment of an image
     5//
    46typedef struct {
    5     int y;
    6     int x0, x1;
     7    int y;                              //!< Row that span's in
     8    int x0;                             //!< Starting column (inclusive)
     9    int x1;                             //!< Ending column (inclusive)
    710} pmSpan;
    811
    912pmSpan *pmSpanAlloc(int y, int x1, int x2);
    1013bool pmIsSpan(const psPtr ptr);
     14int pmSpanSortByYX (const void **a, const void **b);
    1115
    1216typedef struct {
    13     const int id;                       // unique ID
    14     int npix;                           // number of pixels in this pmFootprint
    15     int nspan;                          // number of pmSpans in this pmFootprint
    16     psArray *spans;                     // the pmSpans
    17     psRegion bbox;                      // the pmFootprint's bounding box
    18     psArray *peaks;                     // the peaks lying in this footprint
    19     psRegion region;   // A region describing the psImage the footprints live in
     17    const int id;                       //!< unique ID
     18    int npix;                           //!< number of pixels in this pmFootprint
     19    psArray *spans;                     //!< the pmSpans
     20    psRegion bbox;                      //!< the pmFootprint's bounding box
     21    psArray *peaks;                     //!< the peaks lying in this footprint
     22    psRegion region;   //!< A region describing the psImage the footprints live in
     23    bool normalized;                    //!< Are the spans sorted?
    2024} pmFootprint;
    2125
     
    2327bool pmIsFootprint(const psPtr ptr);
    2428
     29pmFootprint *pmFootprintNormalize(pmFootprint *fp);
    2530int pmFootprintSetNpix(pmFootprint *fp);
    2631void pmFootprintSetBBox(pmFootprint *fp);
    2732psArray *pmFindFootprints(const psImage *img, const float threshold, const int npixMin);
     33pmFootprint *pmFindFootprintAtPoint(const psImage *img,
     34                                    const float threshold,
     35                                    int row, int col);
    2836
    2937psArray *pmMergeFootprintArrays(const psArray *footprints1, const psArray *footprints2);
    3038
    31 psImage *pmSetFootprintArrayIDs(const psArray *footprints,
    32                                 const bool relativeIDs);
     39psImage *pmSetFootprintArrayIDs(const psArray *footprints, const bool relativeIDs);
     40psImage *pmSetFootprintID(const pmFootprint *fp, const int id);
    3341
    3442psErrorCode pmPeaksAssignToFootprints(psArray *footprints, const psArray *peaks);
Note: See TracChangeset for help on using the changeset viewer.