Changeset 26762
- Timestamp:
- Feb 2, 2010, 11:45:40 AM (16 years ago)
- Location:
- branches/eam_branches/20091201/psLib/src/imageops
- Files:
-
- 2 edited
-
psImageConvolve.c (modified) (1 diff)
-
psImageConvolve.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20091201/psLib/src/imageops/psImageConvolve.c
r25383 r26762 246 246 return kernel; 247 247 } 248 249 bool psKernelTruncate(psKernel *kernel, float frac) 250 { 251 PS_ASSERT_KERNEL_NON_NULL(kernel, false); 252 PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(frac, 0.0, false); 253 PS_ASSERT_FLOAT_LESS_THAN(frac, 1.0, false); 254 255 if (frac == 0.0) { 256 // Nothing to do 257 return true; 258 } 259 260 int xMin = kernel->xMin, xMax = kernel->xMax, yMin = kernel->yMin, yMax = kernel->yMax; // Bounds 261 int maxSize = PS_MAX(PS_MAX(PS_MAX(-xMin, xMax), -yMin), yMax); // Maximum size 262 263 // Determine the threshold 264 // Summing absolute values because large negative deviations have power as well 265 double sumKernel = 0.0; // Sum of the kernel 266 for (int y = yMin; y <= yMax; y++) { 267 for (int x = xMin; x <= xMax; x++) { 268 sumKernel += fabsf(kernel->kernel[y][x]); 269 } 270 } 271 272 float threshold = sumKernel * (1.0 - frac); // Threshold for truncation 273 274 // Find truncation size 275 int truncate = 0; // Truncation radius 276 for (int radius = 1; truncate == 0 && radius < maxSize; radius++) { 277 int uMin = PS_MAX(-radius, xMin); 278 int uMax = PS_MIN(radius, xMax); 279 int vMin = PS_MAX(-radius, yMin); 280 int vMax = PS_MIN(radius, yMax); 281 int r2 = PS_SQR(radius); 282 double sum = 0.0; 283 for (int v = vMin; v <= vMax; v++) { 284 int v2 = PS_SQR(v); 285 for (int u = uMin; u <= uMax; u++) { 286 int u2 = PS_SQR(u); 287 if (u2 + v2 <= r2) { 288 sum += fabsf(kernel->kernel[v][u]); 289 } 290 } 291 } 292 if (sum > threshold) { 293 // This is the truncation radius 294 truncate = radius; 295 } 296 } 297 if (truncate == maxSize) { 298 // No truncation possible 299 return true; 300 } 301 302 // Truncate the kernel 303 { 304 int uMin = PS_MAX(-truncate, xMin); 305 int uMax = PS_MIN(truncate, xMax); 306 int vMin = PS_MAX(-truncate, yMin); 307 int vMax = PS_MIN(truncate, yMax); 308 int r2 = PS_SQR(truncate); 309 for (int v = vMin; v <= vMax; v++) { 310 int v2 = PS_SQR(v); 311 for (int u = uMin; u <= uMax; u++) { 312 int u2 = PS_SQR(u); 313 if (u2 + v2 > r2) { 314 kernel->kernel[v][u] = 0.0; 315 } 316 } 317 } 318 } 319 kernel->xMin = PS_MAX(-truncate, kernel->xMin); 320 kernel->xMax = PS_MIN(truncate, kernel->xMax); 321 kernel->yMin = PS_MAX(-truncate, kernel->yMin); 322 kernel->yMax = PS_MIN(truncate, kernel->yMax); 323 324 return true; 325 } 326 327 248 328 249 329 psImage *psImageConvolveDirect(psImage *out, const psImage *in, const psKernel *kernel) -
branches/eam_branches/20091201/psLib/src/imageops/psImageConvolve.h
r25383 r26762 138 138 ); 139 139 140 /// Truncate a kernel 141 /// 142 /// Truncates the outer parts of the kernel where the contribution is below the nominated fraction of the 143 /// total kernel. 144 bool psKernelTruncate( 145 psKernel *in, ///< Kernel to be truncated 146 float frac ///< Fraction for truncation threshold 147 ); 148 149 140 150 /// Convolve an image with a kernel, using a direct convolution 141 151 ///
Note:
See TracChangeset
for help on using the changeset viewer.
