Changeset 36277
- Timestamp:
- Nov 10, 2013, 6:05:54 AM (13 years ago)
- Location:
- branches/eam_branches/ipp-20130904
- Files:
-
- 2 edited
-
psLib/src/imageops/psImageConvolve2dCache.c (modified) (1 diff)
-
psModules/src/objects/pmPCMdata.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20130904/psLib/src/imageops/psImageConvolve2dCache.c
r36275 r36277 65 65 psMemSetDeallocator(smdata, (psFreeFunc) psImageSmooth2dCacheDataFree); 66 66 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 74 bool 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 104 bool 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 78 109 79 110 // 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 59 59 psFree (pcm->constraint); 60 60 61 psFree (pcm->smdata 1); // pre-allocated data for psImageSmooth_PreAlloc62 psFree (pcm->smdata2 ); // pre-allocated data for psImageSmooth_PreAlloc61 psFree (pcm->smdata); // pre-allocated data for psImageSmooth_PreAlloc 62 psFree (pcm->smdata2d); // pre-allocated data for psImageSmooth_PreAlloc 63 63 return; 64 64 } … … 90 90 } 91 91 92 pcm->smdata 1= NULL;93 pcm->smdata2 = NULL;92 pcm->smdata = NULL; 93 pcm->smdata2d = NULL; 94 94 95 95 pcm->modelConv = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.
