IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 24, 2004, 4:06:12 PM (22 years ago)
Author:
desonia
Message:

added psImageRadialCut. Untested, but compiles.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/image/psImageExtraction.c

    r1864 r1897  
    1010*  @author Robert DeSonia, MHPCC
    1111*
    12 *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    13 *  @date $Date: 2004-09-23 18:31:49 $
     12*  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     13*  @date $Date: 2004-09-25 02:06:12 $
    1414*
    1515*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    609609
    610610psVector* psImageCut(psVector* out,
    611                      psVector* coords,
    612                      const psImage* input,
     611                     psVector* cutCols,
     612                     psVector* cutRows,
     613                     const psImage* in,
    613614                     const psImage* restrict mask,
    614615                     unsigned int maskVal,
     
    620621                     psImageInterpolateMode mode)
    621622{
    622 
    623     return NULL;
     623    if (in == NULL || in->data.V == NULL) {
     624        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
     625                   PS_ERR_BAD_PARAMETER_NULL, true,
     626                   PS_ERRORTEXT_psImage_IMAGE_NULL);
     627        psFree(out);
     628        return NULL;
     629    }
     630    int numCols = in->numCols;
     631    int numRows = in->numRows;
     632
     633    if (nSamples < 2) {
     634        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
     635                   PS_ERR_BAD_PARAMETER_VALUE, true,
     636                   PS_ERRORTEXT_psImage_nSamples_TOOSMALL,
     637                   nSamples);
     638        psFree(out);
     639        return NULL;
     640    }
     641
     642    if (startCol < 0 || startCol >= numCols ||
     643            startRow < 0 || startRow >= numRows ||
     644            endCol < 0 || endCol >= numCols ||
     645            endRow < 0 || endRow >= numRows) {
     646        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
     647                   PS_ERR_BAD_PARAMETER_VALUE, true,
     648                   PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE,
     649                   startCol,startRow,endCol,endRow,
     650                   numCols,numRows);
     651        psFree(out);
     652    }
     653
     654    if (mask != NULL) {
     655        if (numRows != mask->numRows || numCols != mask->numCols) {
     656            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
     657                       PS_ERR_BAD_PARAMETER_VALUE, true,
     658                       PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE,
     659                       mask->numCols,mask->numRows,
     660                       numCols, numRows);
     661            psFree(out);
     662        }
     663        if (mask->type.type != PS_TYPE_MASK) {
     664            char* typeStr;
     665            PS_TYPE_NAME(typeStr,mask->type.type);
     666            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
     667                       PS_ERR_BAD_PARAMETER_TYPE, true,
     668                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
     669                       typeStr, PS_TYPE_MASK_NAME);
     670            psFree(out);
     671        }
     672    }
     673
     674    //resize the vectors for the coordinate output
     675    psF32* cutColsData = NULL;
     676    psF32* cutRowsData = NULL;
     677    if (cutCols != NULL) {
     678        (void)psVectorRecycle(cutCols, nSamples, PS_TYPE_F32);
     679        cutColsData = cutCols->data.F32;
     680    }
     681    if (cutRows != NULL) {
     682        (void)psVectorRecycle(cutRows, nSamples, PS_TYPE_F32);
     683        cutRowsData = cutRows->data.F32;
     684    }
     685
     686    out = psVectorRecycle(out,nSamples,in->type.type);
     687
     688    float dX = (endCol - startCol) / (nSamples-1);
     689    float dY = (endRow - startRow) / (nSamples-1);
     690
     691    float x = startCol;
     692    float y = startRow;
     693
     694    #define LINEAR_CUT_CASE(TYPE) \
     695case PS_TYPE_##TYPE: { \
     696        ps##TYPE* outData = out->data.TYPE; \
     697        for (int i = 0; i < nSamples; i++) { \
     698            /* store off the location of the sample. */ \
     699            if (cutColsData != NULL) { \
     700                cutColsData[i] = x; \
     701            } \
     702            if (cutRowsData != NULL) { \
     703                cutRowsData[i] = y; \
     704            } \
     705            outData[i] = psImagePixelInterpolate(in,x,y,mask,maskVal,0,mode); \
     706            x += dX; \
     707            y += dY; \
     708        } \
     709    } \
     710    break;
     711
     712
     713    switch (in->type.type) {
     714        LINEAR_CUT_CASE(U8);
     715        LINEAR_CUT_CASE(U16);
     716        LINEAR_CUT_CASE(U32);
     717        LINEAR_CUT_CASE(U64);
     718        LINEAR_CUT_CASE(S8);
     719        LINEAR_CUT_CASE(S16);
     720        LINEAR_CUT_CASE(S32);
     721        LINEAR_CUT_CASE(S64);
     722        LINEAR_CUT_CASE(F32);
     723        LINEAR_CUT_CASE(F64);
     724        LINEAR_CUT_CASE(C32);
     725        LINEAR_CUT_CASE(C64);
     726
     727    default: {
     728            char* typeStr;
     729            PS_TYPE_NAME(typeStr,in->type.type);
     730            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
     731                       PS_ERR_BAD_PARAMETER_TYPE, true,
     732                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
     733                       typeStr);
     734            psFree(out);
     735            out = NULL;
     736        }
     737    }
     738
     739    return out;
    624740}
    625741
    626742psVector* psImageRadialCut(psVector* out,
    627                            const psImage* input,
     743                           const psImage* in,
    628744                           const psImage* restrict mask,
    629745                           unsigned int maskVal,
     
    633749                           const psStats* stats)
    634750{
    635 
    636     return NULL;
     751    double statVal;
     752
     753    /* check the parameters */
     754
     755    if (in == NULL || in->data.V == NULL) {
     756        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     757                   PS_ERR_BAD_PARAMETER_NULL, true,
     758                   PS_ERRORTEXT_psImage_IMAGE_NULL);
     759        psFree(out);
     760        return NULL;
     761    }
     762    int numCols = in->numCols;
     763    int numRows = in->numRows;
     764
     765    if (mask != NULL) {
     766        if (numRows != mask->numRows || numCols != mask->numCols) {
     767            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     768                       PS_ERR_BAD_PARAMETER_VALUE, true,
     769                       PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE,
     770                       mask->numCols,mask->numRows,
     771                       numCols, numRows);
     772            psFree(out);
     773        }
     774        if (mask->type.type != PS_TYPE_MASK) {
     775            char* typeStr;
     776            PS_TYPE_NAME(typeStr,mask->type.type);
     777            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     778                       PS_ERR_BAD_PARAMETER_TYPE, true,
     779                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
     780                       typeStr, PS_TYPE_MASK_NAME);
     781            psFree(out);
     782        }
     783    }
     784
     785    if (centerCol < 0 || centerCol >= numCols ||
     786            centerRow < 0 || centerRow >= numRows) {
     787        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     788                   PS_ERR_BAD_PARAMETER_VALUE, true,
     789                   PS_ERRORTEXT_psImage_CENTER_NOT_IN_IMAGE,
     790                   centerCol, centerRow,
     791                   numCols, numRows);
     792        psFree(out);
     793    }
     794
     795    if (radii == NULL) {
     796        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     797                   PS_ERR_BAD_PARAMETER_NULL, true,
     798                   PS_ERRORTEXT_psImage_RADII_VECTOR_NULL);
     799        psFree(out);
     800        return NULL;
     801    }
     802
     803    if (radii->n < 2) {
     804        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     805                   PS_ERR_BAD_PARAMETER_VALUE, true,
     806                   PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL,
     807                   radii->n);
     808        psFree(out);
     809        return NULL;
     810    }
     811
     812    if (stats == NULL) {
     813        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     814                   PS_ERR_BAD_PARAMETER_NULL, true,
     815                   PS_ERRORTEXT_psImage_STAT_NULL);
     816        psFree(out);
     817        return NULL;
     818    }
     819
     820    // verify that the stats struct specifies a
     821    // single stats operation
     822    if (p_psGetStatValue(stats, &statVal) == false) {
     823        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
     824                   PS_ERR_BAD_PARAMETER_VALUE, false,
     825                   PS_ERRORTEXT_psImage_BAD_STAT);
     826        psFree(out);
     827        return NULL;
     828    }
     829
     830    /* completed checking the parameters */
     831
     832    // size the output vector to proper size.
     833    int numOut = radii->n - 1;
     834    out = psVectorRecycle(out, numOut, PS_TYPE_F64);
     835    psF64* outData = out->data.F64;
     836
     837    // sort the radii by value
     838    psVector* rSqVec = psVectorCopy(NULL, radii, PS_TYPE_F32);
     839    psVectorSort(rSqVec,rSqVec);
     840    psF32* rSq = rSqVec->data.F32;
     841
     842    int startRow = centerRow - rSq[numOut];
     843    int endRow = centerRow + rSq[numOut];
     844    int startCol = centerCol - rSq[numOut];
     845    int endCol = centerCol + rSq[numOut];
     846
     847    if (startRow < 0) {
     848        startRow = 0;
     849    }
     850
     851    if (startCol < 0) {
     852        startCol = 0;
     853    }
     854
     855    if (endRow >= numRows) {
     856        endRow = numRows - 1;
     857    }
     858
     859    if (endCol >= numCols) {
     860        endCol = numCols - 1;
     861    }
     862
     863    // Square the data
     864    for (int d = 0; d <= numOut; d++) {
     865        rSq[d] *= rSq[d];
     866    }
     867
     868    // create temporary vectors for the data binning step
     869    psVector** buffer = psAlloc(sizeof(psVector*)*numOut);
     870    psVector** bufferMask = psAlloc(sizeof(psVector*)*numOut);
     871    for (int lcv = 0; lcv < numOut; lcv++) {
     872        // n.b. alloc enough for the data by making the vectors slightly larger
     873        // than the area of the region of interest.
     874        buffer[lcv] = psVectorAlloc(1+4*(rSq[lcv+1]-rSq[lcv]),
     875                                    in->type.type);
     876        buffer[lcv]->n = 0;
     877
     878        bufferMask[lcv] = NULL;
     879        if (mask != NULL) {
     880            bufferMask[lcv] = psVectorAlloc(1+4*(rSq[lcv+1]-rSq[lcv]),
     881                                            PS_TYPE_MASK);
     882            bufferMask[lcv]->n = 0;
     883        }
     884    }
     885
     886    float dX;
     887    float dY;
     888    float dist;
     889    for (int row=startRow; row <= endRow; row++) {
     890        psF32* inRow = in->data.F32[row];
     891        psMaskType* maskRow = NULL;
     892        if (mask != NULL) {
     893            maskRow = mask->data.PS_TYPE_MASK_DATA[row];
     894        }
     895        for (int col=startCol; col <= endCol; col++) {
     896            dX = centerCol - (float)col - 0.5f;
     897            dY = centerRow - (float)row - 0.5f;
     898            dist = dX*dX+dY*dY;
     899            for (int r = 0; r < numOut;) {
     900                if (rSq[r] < dist && dist < rSq[++r]) {
     901                    int n = buffer[r]->n;
     902                    if (n == buffer[r]->nalloc) { // in case buffers already full, expand
     903                        buffer[r] = psVectorRealloc(n*2, buffer[r]);
     904                        if (bufferMask[r] != NULL) {
     905                            bufferMask[r] = psVectorRealloc(n*2, bufferMask[r]);
     906                        }
     907                    }
     908
     909                    buffer[r]->data.F32[n] = inRow[col];
     910                    buffer[r]->n = n+1;
     911
     912                    if (maskRow != NULL) {
     913                        bufferMask[r]->data.PS_TYPE_MASK_DATA[n] = maskRow[col];
     914                        bufferMask[r]->n = n+1;
     915                    }
     916
     917                    break;
     918                }
     919            }
     920        }
     921    }
     922
     923    psStats* myStats = psAlloc(sizeof(psStats));
     924    *myStats = *stats;
     925
     926    for (int r = 0; r < numOut; r++) {
     927        myStats = psVectorStats(myStats,buffer[r], bufferMask[r],maskVal);
     928        (void)p_psGetStatValue(myStats,&statVal);
     929        outData[r] = statVal;
     930    }
     931
     932    psFree(myStats);
     933
     934    for (int lcv = 0; lcv < numOut; lcv++) {
     935        psFree(buffer[lcv]);
     936        psFree(bufferMask[lcv]);
     937    }
     938    psFree(buffer);
     939    psFree(bufferMask);
     940
     941    return out;
    637942}
Note: See TracChangeset for help on using the changeset viewer.