IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 36277


Ignore:
Timestamp:
Nov 10, 2013, 6:05:54 AM (13 years ago)
Author:
eugene
Message:

working on 2d convolve

Location:
branches/eam_branches/ipp-20130904
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20130904/psLib/src/imageops/psImageConvolve2dCache.c

    r36275 r36277  
    6565    psMemSetDeallocator(smdata, (psFreeFunc) psImageSmooth2dCacheDataFree);
    6666
    67     smdata->kernel = NULL;
    68 
    69     if (!image) {
    70         // relevant terms
    71         smdata->Nrange = sigma*Nsigma + 0.5;    // Number of pixels either side for convolution kernel
    72         smdata->Nx = 0;
    73         smdata->Ny = 0;
    74         smdata->resultX = NULL;
    75         smdata->resultY = NULL;
    76         return smdata;
    77     }
     67    smdata->radflux = NULL;
     68
     69    return smdata;
     70}
     71
     72// generate a 2D smoothing kernel for supplied sigma & kappa (PS1_V1 profile).  sigma here
     73// does not need to match that used to allocate the structure, but it is recommended
     74bool psImageSmooth2dCacheKernel_PS1_V1 (psImageSmooth2dCacheData *smdata, float sigma, float kappa) {
     75    // check for NULL structure elements?
     76
     77    int size = smdata->Nrange;
     78
     79    smdata->sigma = sigma;
     80
     81    smdata->Ns = (int)(smdata->Nsigma * sigma);
     82    smdata->Ns = MAX (3, MIN (smdata->Ns, 10));
     83
     84    int Ns2 = Ns * Ns;
     85
     86    // we are going to use a hard-wired radial profile
     87    smdata->radflux = psAlloc(sizeof(float)*NRAD_MAX);
     88
     89    float sum = 0.0;
     90    for (i = 0; i < NRAD_MAX; i++) {
     91      float z = radii2[i] / SQ(sigma);
     92      smdata->radflux[i] = 1.0 / (1.0 + kappa*z + pow(z,1.666));
     93      if (radii2[i] > Ns2) continue;
     94      sum += radiiN[i] * smdata->radflux[i];
     95    }
     96    for (i = 0; i < NRAD_MAX; i++) {
     97      smdata->radflux[i] = smdata->radflux[i] / sum;
     98    }
     99
     100    return true;
     101}
     102
     103// we can use the same DATA structure on multiple images of the same size
     104bool psImageSmooth2dCache_F32(psImage *image, psImageSmooth2dCacheData *smdata)
     105{
     106    PS_ASSERT_IMAGE_NON_NULL(image, false);
     107    PS_ASSERT_NON_NULL(smdata->radflux, false);
     108    // assert on data type
    78109
    79110    // relevant terms
    80     smdata->Nrange = sigma*Nsigma + 0.5;    // Number of pixels either side for convolution kernel
    81     smdata->Nx = image->numCols;            // Number of columns
    82     smdata->Ny = image->numRows;            // Number of rows
    83 
    84     // use a temp running buffer for X and Y directions.
    85     smdata->resultX = psAlloc(smdata->Nx * sizeof(psF32));
    86     memset (smdata->resultX, 0, smdata->Nx*sizeof(psF32));
    87 
    88     smdata->resultY = psAlloc(smdata->Ny * sizeof(psF32));
    89     memset (smdata->resultY, 0, smdata->Ny*sizeof(psF32));
    90 
    91     return smdata;
    92 }
     111    int Nrange = smdata->Nrange;    // Number of pixels either side for convolution kernel
     112    int Nx = smdata->Nx;            // Number of columns
     113    int Ny = smdata->Ny;            // Number of rows
     114
     115    psF32 *gauss = &smdata->kernel->data.F32[Nrange];
     116    psF32 *resultX = smdata->resultX;
     117    psF32 *resultY = smdata->resultY;
     118       
     119    /* Smooth in X direction */
     120    {
     121        for (int j = 0; j < Ny; j++) {
     122            psF32 *vi = image->data.F32[j];
     123            int xMax = PS_MIN(Nrange, Nx);
     124            /* Smooth first Nrange pixels, with renorm */
     125            for (int i = 0; i < xMax; i++, vi++) {
     126                int convRange = PS_MIN(Nrange + 1, Nx - i);
     127                psF32 *vr = vi - i;
     128                psF32 *vg = gauss - i;
     129                double g = 0.0;
     130                double s = 0.0;
     131                for (int n = -i; n < convRange; n++, vr++, vg++) {
     132                    s += *vg * *vr;
     133                    g += *vg;
     134                }
     135                resultX[i] = s / g;
     136            }
     137            /* If that's all the pixels we have, then we're done already */
     138            if (Nx > Nrange) {
     139                /* Smooth middle pixels; if Nx < 2*Nrange, this pass is skipped */
     140                for (int i = Nrange; i < Nx - Nrange; i++, vi++) {
     141                    psF32 *vr = vi - Nrange;
     142                    psF32 *vg = gauss - Nrange;
     143                    double s = 0;
     144                    for (int n = -Nrange; n < Nrange + 1; n++, vr++, vg++) {
     145                        s += *vg * *vr;
     146                    }
     147                    resultX[i] = s;
     148                }
     149                /* Smooth last Nrange pixels, with renorm */
     150                // if Nx < 2*Nrange, this pass starts at i == Nrange
     151                int xMin = PS_MAX(Nx - Nrange, Nrange);
     152                for (int i = xMin; i < Nx; i++, vi++) {
     153                    psF32 *vr = vi - Nrange;
     154                    psF32 *vg = gauss - Nrange;
     155                    double g = 0.0;
     156                    double s = 0.0;
     157                    for (int n = -Nrange; n < Nx - i; n++, vr++, vg++) {
     158                        s += *vg * *vr;
     159                        g += *vg;
     160                    }
     161                    resultX[i] = s / g;
     162                }
     163            }
     164            memcpy(image->data.F32[j], resultX, Nx*sizeof(psF32));
     165        }
     166    }
     167       
     168    // this section probably hits the cache poorly for large images, but is probably OK for small ones
     169    /* Smooth in Y direction */
     170    {
     171        for (int i = 0; i < Nx; i++) {
     172            int yMax = PS_MIN(Nrange, Ny);
     173            /* Smooth first Nrange pixels, with renorm */
     174            for (int j = 0; j < yMax; j++) {
     175                int convRange = PS_MIN(Nrange + 1, Ny - j);
     176                psF32 *vg = gauss - j;
     177                double g = 0.0;
     178                double s = 0.0;
     179                for (int n = -j; n < convRange; n++, vg++) {
     180                    psF32 vr = image->data.F32[j+n][i];
     181                    s += *vg * vr;
     182                    g += *vg;
     183                }
     184                resultY[j] = s / g;
     185            }
     186            /* If that's all the pixels we have, then we're done already */
     187            if (Ny > Nrange) {
     188                /* Smooth middle pixels */
     189                for (int j = Nrange; j < Ny - Nrange; j++) {
     190                    psF32 *vg = gauss - Nrange;
     191                    double s = 0;
     192                    for (int n = -Nrange; n < Nrange + 1; n++, vg++) {
     193                        psF32 vr = image->data.F32[j+n][i];
     194                        s += *vg * vr;
     195                    }
     196                    resultY[j] = s;
     197                }
     198                /* Smooth last Nrange pixels, with renorm */
     199                // if Ny < 2*Nrange, this pass starts at j == Nrange
     200                int yMin = PS_MAX(Ny - Nrange, Nrange);
     201                for (int j = yMin; j < Ny; j++) {
     202                    psF32 *vg = gauss - Nrange;
     203                    double g = 0.0;
     204                    double s = 0.0;
     205                    for (int n = -Nrange; n < Ny - j; n++, vg++) {
     206                        psF32 vr = image->data.F32[j+n][i];
     207                        s += *vg * vr;
     208                        g += *vg;
     209                    }
     210                    resultY[j] = s / g;
     211                }
     212            }
     213            // loop here
     214            for (int j = 0; j < Ny; j++) {
     215                image->data.F32[j][i] = resultY[j];
     216            }
     217        }
     218    }
     219    return true;
     220}
     221
  • branches/eam_branches/ipp-20130904/psModules/src/objects/pmPCMdata.c

    r36276 r36277  
    5959    psFree (pcm->constraint);
    6060
    61     psFree (pcm->smdata1); // pre-allocated data for psImageSmooth_PreAlloc
    62     psFree (pcm->smdata2); // pre-allocated data for psImageSmooth_PreAlloc
     61    psFree (pcm->smdata); // pre-allocated data for psImageSmooth_PreAlloc
     62    psFree (pcm->smdata2d); // pre-allocated data for psImageSmooth_PreAlloc
    6363    return;
    6464}
     
    9090    }
    9191
    92     pcm->smdata1 = NULL;
    93     pcm->smdata2 = NULL;
     92    pcm->smdata = NULL;
     93    pcm->smdata2d = NULL;
    9494
    9595    pcm->modelConv = NULL;
Note: See TracChangeset for help on using the changeset viewer.