IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 20, 2011, 2:24:57 PM (14 years ago)
Author:
eugene
Message:

creating psImageSmooth_PreAlloc_F32 to avoid excessive allocs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/imageops/psImageConvolve.c

    r32714 r32724  
    765765}
    766766
     767// XXX NOTE : work to do : figure out the actual containers needed in there, pre-allocate them
     768bool psImageSmooth_PreAlloc_F32(psImage *image, double sigma, double Nsigma)
     769{
     770    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
     771    // assert on data type
     772
     773    // relevant terms
     774    int Nrange = sigma*Nsigma + 0.5;    // Number of pixels either side for convolution kernel
     775    int Nx = image->numCols;            // Number of columns
     776    int Ny = image->numRows;            // Number of rows
     777
     778    IMAGE_SMOOTH_GAUSS(gaussnorm, Nrange, sigma, F32);
     779    psF32 *gauss = &gaussnorm->data.F32[Nrange];
     780       
     781    // use a temp running buffer for X and Y directions.
     782    psF32 *resultX = (psF32 *) psAlloc(Nx * sizeof(psF32));
     783    memset (resultX, 0, Nx*sizeof(psF32));
     784    psF32 *resultY = (psF32 *) psAlloc(Ny * sizeof(psF32));
     785    memset (resultY, 0, Ny*sizeof(psF32));
     786
     787    /* Smooth in X direction */
     788    {
     789        for (int j = 0; j < Ny; j++) {
     790            psF32 *vi = image->data.F32[j];
     791            int xMax = PS_MIN(Nrange, Nx);
     792            int convRange = PS_MIN(Nrange + 1, Nx);
     793            /* Smooth first Nrange pixels, with renorm */
     794            for (int i = 0; i < xMax; i++, vi++) {
     795                psF32 *vr = vi - i;
     796                psF32 *vg = gauss - i;
     797                double g = 0.0;
     798                double s = 0.0;
     799                for (int n = -i; n < convRange; n++, vr++, vg++) {
     800                    s += *vg * *vr;
     801                    g += *vg;
     802                }
     803                resultX[i] = s / g;
     804            }
     805            /* If that's all the pixels we have, then we're done already */
     806            if (Nx > Nrange) {
     807                /* Smooth middle pixels */
     808                for (int i = Nrange; i < Nx - Nrange; i++, vi++) {
     809                    psF32 *vr = vi - Nrange;
     810                    psF32 *vg = gauss - Nrange;
     811                    double s = 0;
     812                    for (int n = -Nrange; n < Nrange + 1; n++, vr++, vg++) {
     813                        s += *vg * *vr;
     814                    }
     815                    resultX[i] = s;
     816                }
     817                /* Smooth last Nrange pixels, with renorm */
     818                for (int i = Nx - Nrange; i < Nx; i++, vi++) {
     819                    psF32 *vr = vi - Nrange;
     820                    psF32 *vg = gauss - Nrange;
     821                    double g = 0.0;
     822                    double s = 0.0;
     823                    for (int n = -Nrange; n < Nx - i; n++, vr++, vg++) {
     824                        s += *vg * *vr;
     825                        g += *vg;
     826                    }
     827                    resultX[i] = s / g;
     828                }
     829            }
     830            memcpy(image->data.F32[j], resultX, Nx*sizeof(psF32));
     831        }
     832    }
     833       
     834    // this section probably hits the cache poorly for large images, but is probably OK for small ones
     835    /* Smooth in Y direction */
     836    {
     837        for (int i = 0; i < Nx; i++) {
     838            int yMax = PS_MIN(Nrange, Ny);
     839            int convRange = PS_MIN(Nrange + 1, Ny);
     840            /* Smooth first Nrange pixels, with renorm */
     841            for (int j = 0; j < yMax; j++) {
     842                psF32 *vg = gauss - j;
     843                double g = 0.0;
     844                double s = 0.0;
     845                for (int n = -j; n < convRange; n++, vg++) {
     846                    psF32 vr = image->data.F32[j+n][i];
     847                    s += *vg * vr;
     848                    g += *vg;
     849                }
     850                resultY[j] = s / g;
     851            }
     852            /* If that's all the pixels we have, then we're done already */
     853            if (Ny > Nrange) {
     854                /* Smooth middle pixels */
     855                for (int j = Nrange; j < Ny - Nrange; j++) {
     856                    psF32 *vg = gauss - Nrange;
     857                    double s = 0;
     858                    for (int n = -Nrange; n < Nrange + 1; n++, vg++) {
     859                        psF32 vr = image->data.F32[j+n][i];
     860                        s += *vg * vr;
     861                    }
     862                    resultY[j] = s;
     863                }
     864                /* Smooth last Nrange pixels, with renorm */
     865                for (int j = Ny - Nrange; j < Ny; j++) {
     866                    psF32 *vg = gauss - Nrange;
     867                    double g = 0.0;
     868                    double s = 0.0;
     869                    for (int n = -Nrange; n < Ny - j; n++, vg++) {
     870                        psF32 vr = image->data.F32[j+n][i];
     871                        s += *vg * vr;
     872                        g += *vg;
     873                    }
     874                    resultY[j] = s / g;
     875                }
     876            }
     877            // loop here
     878            for (int j = 0; j < Ny; j++) {
     879                image->data.F32[j][i] = resultY[j];
     880            }
     881        }
     882    }
     883       
     884    psFree(resultX);
     885    psFree(resultY);
     886    psFree(gaussnorm);
     887
     888    return true;
     889}
     890
    767891static bool imageSmoothMaskPixels(psVector *out, const psImage *image, const psImage *mask,
    768892                                  psImageMaskType maskVal, const psVector *x, const psVector *y,
Note: See TracChangeset for help on using the changeset viewer.