IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 18, 2007, 6:30:33 PM (19 years ago)
Author:
magnier
Message:

added psImageSmoothMaskF32

File:
1 edited

Legend:

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

    r10999 r11153  
    55 *  @author Robert DeSonia, MHPCC
    66 *
    7  *  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
    8  *  @date $Date: 2007-01-09 22:38:52 $
     7 *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
     8 *  @date $Date: 2007-01-19 04:30:33 $
    99 *
    1010 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    671671    return true;
    672672}
     673
     674bool psImageSmoothMaskF32 (psImage *image,
     675                           psImage *mask,
     676                           psMaskType maskVal,
     677                           double  sigma,
     678                           double  Nsigma)
     679{
     680    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
     681    PS_ASSERT_IMAGE_NON_NULL(mask, NULL);
     682
     683    // relevant terms
     684    int Nrange = sigma*Nsigma + 0.5;    // Number of pixels either side for convolution kernel
     685    int Npixel = 2*Nrange + 1;          // Total number of pixels in convolution kernel
     686    int Nx = image->numCols;            // Number of columns
     687    int Ny = image->numRows;            // Number of rows
     688
     689    /* generate normalized gaussian */
     690    psVector *gaussnorm = psVectorAlloc(Npixel, PS_TYPE_F32);
     691    {
     692        double sum = 0.0;
     693        double factor = -0.5/(sigma*sigma);
     694        for (int i = -Nrange; i < Nrange + 1; i++) {
     695            gaussnorm->data.F32[i+Nrange] = exp(factor*i*i);
     696            sum += gaussnorm->data.F32[i+Nrange];
     697        }
     698        for (int i = -Nrange; i < Nrange + 1; i++) {
     699            gaussnorm->data.F32[i+Nrange] /= sum;
     700        }
     701    }
     702    psF32 *gauss = &gaussnorm->data.F32[Nrange];
     703
     704    /** Smooth in X direction **/
     705    psVector *calculation = psVectorAlloc(Nx, PS_TYPE_F32);
     706    for (int j = 0; j < Ny; j++) {
     707        psU8  *vm = mask->data.U8[j];
     708        psF32 *vi = image->data.F32[j];
     709        psF32 *vo = calculation->data.F32;
     710        // loop over all pixels in the row
     711        for (int i = 0; i < Nx; i++, vi++, vo++, vm++) {
     712            int offset = PS_MIN (i, Nrange);
     713            psU8  *sm = vm - offset;
     714            psF32 *si = vi - offset;
     715            psF32 *sg = gauss - offset;
     716            double g = 0.0;
     717            double s = 0.0;
     718            // loop over all valid pixels in the smoothing kernel
     719            int xMin = PS_MAX (i - Nrange, 0);
     720            int xMax = PS_MIN (i + Nrange + 1, Nx);
     721            for (int n = xMin; n < xMax; n++, sm++, si++, sg++) {
     722                if (*sm & maskVal)
     723                    continue;
     724                s += *sg * *si;
     725                g += *sg;
     726            }
     727            *vo = (g > 0) ? s / g : 0.0;
     728        }
     729        memcpy(image->data.F32[j], calculation->data.F32, Nx*sizeof(psF32));
     730    }
     731    psFree(calculation);
     732
     733    /** Smooth in Y direction  **/
     734    // allocate and save Nrange extra row vectors for storage. these will be
     735    // written over the output rows only after we are Nrange rows beyond them
     736    int Nsave = Nrange + 1;
     737    psArray *rows = psArrayAlloc(Nsave);
     738    for (int i = 0; i < Nsave; i++) {
     739        rows->data[i] = psVectorAlloc(Nx, PS_TYPE_F32);
     740    }
     741
     742    psVector *outsum = psVectorAlloc(Nx, PS_TYPE_F32);
     743    for (int j = 0; j < Ny; j++) {
     744        psVector *output = rows->data[j % Nsave];
     745        memset (output->data.F32, 0, Nx*sizeof(psF32));
     746        memset (outsum->data.F32, 0, Nx*sizeof(psF32));
     747        int yMin = PS_MAX (j - Nrange, 0);
     748        int yMax = PS_MIN (j + Nrange + 1, Ny);
     749        for (int n = yMin; n < yMax; n++) {
     750            psU8  *vm = mask->data.U8[n];
     751            psF32 *vi = image->data.F32[n];
     752            psF32 *vo = output->data.F32;
     753            psF32 *vs = outsum->data.F32;
     754            double g = gauss[n - j];
     755            for (int i = 0; i < Nx; i++, vi++, vo++, vm++, vs++) {
     756                if (*vm & maskVal)
     757                    continue;
     758                *vo += *vi * g;
     759                *vs += g;
     760            }
     761        }
     762        // renormalize the row
     763        psF32 *vo = output->data.F32;
     764        psF32 *vs = outsum->data.F32;
     765        for (int i = 0; i < Nx; i++, vo++, vs++) {
     766            *vo = (*vs > 0) ? *vo / *vs : 0.0;
     767        }
     768
     769        // Write the output row
     770        if (j - Nrange >= 0) {
     771            int Nout = (j - Nrange) % Nsave;
     772            psVector *save = rows->data[Nout];
     773            memcpy(image->data.F32[j-Nrange], save->data.F32, Nx*sizeof(psF32));
     774        }
     775    }
     776
     777    // Write the remaining output rows
     778    for (int j = PS_MAX(0, Ny - Nrange); j < Ny; j++) {
     779        psVector *save = rows->data[j % Nsave];
     780        memcpy(image->data.F32[j], save->data.F32, Nx*sizeof(psF32));
     781    }
     782    psFree(rows);
     783    psFree(outsum);
     784    psFree(gaussnorm);
     785    return true;
     786}
Note: See TracChangeset for help on using the changeset viewer.