Changeset 26892
- Timestamp:
- Feb 10, 2010, 7:27:29 PM (16 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 20 edited
-
imageops/psImageConvolve.c (modified) (1 diff)
-
imageops/psImageConvolve.h (modified) (1 diff)
-
imageops/psImageCovariance.c (modified) (6 diffs)
-
imageops/psImageCovariance.h (modified) (2 diffs)
-
imageops/psImageInterpolate.c (modified) (1 diff)
-
math/psBinaryOp.c (modified) (1 diff)
-
math/psBinaryOp.h (modified) (1 diff)
-
math/psHistogram.c (modified) (1 diff)
-
math/psMatrix.c (modified) (4 diffs)
-
math/psMatrix.h (modified) (1 diff)
-
math/psUnaryOp.c (modified) (1 diff)
-
math/psUnaryOp.h (modified) (1 diff)
-
mathtypes/psVector.c (modified) (1 diff)
-
sys/psErrorCodes.c.in (modified) (1 diff)
-
sys/psMemory.h (modified) (2 diffs)
-
sys/psTrace.c (modified) (1 diff)
-
types/psArray.c (modified) (1 diff)
-
types/psArray.h (modified) (1 diff)
-
types/psMetadata.c (modified) (3 diffs)
-
types/psMetadata.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageConvolve.c
r25383 r26892 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) -
trunk/psLib/src/imageops/psImageConvolve.h
r25383 r26892 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 /// -
trunk/psLib/src/imageops/psImageCovariance.c
r25994 r26892 14 14 #include "psTrace.h" 15 15 #include "psBinaryOp.h" 16 #include "psScalar.h" 17 #include "psThread.h" 16 18 17 19 #include "psImageCovariance.h" 20 21 static bool threaded = false; // Run threaded? 22 18 23 19 24 psKernel *psImageCovarianceNone(void) … … 24 29 } 25 30 26 27 psKernel *psImageCovarianceCalculate(const psKernel *kernel, const psKernel *covariance) 28 { 29 PS_ASSERT_KERNEL_NON_NULL(kernel, NULL); 30 31 // See http://en.wikipedia.org/wiki/Error_propagation 32 // 33 // If 34 // f_k = sum_i A_ik x_i 35 // is a set of functions, then the covariance matrix for f is given by: 36 // M^f_ij = sum_k sum_l A_ik M^x_kl A_lj 37 // where M^x is the covariance matrix for x. 38 // Note that the errors in f are correlated (covariance) even if the errors in x are not. 39 40 psKernel *covar; // Covariance matrix to use 41 if (covariance) { 42 covar = psMemIncrRefCounter((psKernel*)covariance); // Casting away const 43 } else { 44 covar = psImageCovarianceNone(); 45 } 46 47 // Check for non-finite elements 48 for (int y = kernel->yMin; y <= kernel->yMax; y++) { 49 for (int x = kernel->xMin; x <= kernel->xMax; x++) { 50 if (!isfinite(kernel->kernel[y][x])) { 51 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 52 "Non-finite covariance matrix element in kernel at %d,%d", x, y); 53 psFree(covar); 54 return NULL; 55 } 56 } 57 } 58 for (int y = covar->yMin; y <= covar->yMax; y++) { 59 for (int x = covar->xMin; x <= covar->xMax; x++) { 60 if (!isfinite(covar->kernel[y][x])) { 61 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 62 "Non-finite covariance matrix element in covariance matrix at %d,%d", x, y); 63 psFree(covar); 64 return NULL; 65 } 66 } 67 } 68 69 // The above (double) sum for the covariance matrix means that, for each point in the output covariance 70 // matrix, we need to work out all combinations of getting to the central point via a kernel, input 71 // covariance matrix and another kernel. This means that the resultant covariance matrix has twice the 72 // size of the kernel plus the size of the input covariance matrix. 73 int xMin = kernel->xMin - kernel->xMax + covar->xMin, xMax = kernel->xMax - kernel->xMin + covar->xMax; 74 int yMin = kernel->yMin - kernel->yMax + covar->yMin, yMax = kernel->yMax - kernel->yMin + covar->yMax; 75 psKernel *out = psKernelAlloc(xMin, xMax, yMin, yMax); // Covariance matrix for output 31 /// Calculation of covariance matrix element when convolving 32 static float imageCovarianceCalculate(const psKernel *covar, // Original covariance matrix 33 const psKernel *kernel, // Convolution kernel 34 int x, int y // Coordinates in output covariance matrix 35 ) 36 { 37 psAssert(covar, "Require covariance matrix"); 38 psAssert(kernel, "Require kernel"); 76 39 77 40 // Need to go: … … 89 52 // from the source coordinate), we take the smallest possible (because everything else is zero outside). 90 53 91 double total = 0.0; // Total covariance 54 // Range for v 55 int vMin = PS_MAX(kernel->yMin + covar->yMin, y + kernel->yMin); 56 int vMax = PS_MIN(kernel->yMax + covar->yMax, y + kernel->yMax); 57 // Range for u 58 int uMin = PS_MAX(kernel->xMin + covar->xMin, x + kernel->xMin); 59 int uMax = PS_MIN(kernel->xMax + covar->xMax, x + kernel->xMax); 60 61 double sum = 0.0; // Sum for value of covariance matrix at (x,y) 62 for (int v = vMin; v <= vMax; v++) { 63 // Range for q 64 int qMin = PS_MAX(v + covar->yMin, kernel->yMin); 65 int qMax = PS_MIN(v + covar->yMax, kernel->yMax); 66 for (int u = uMin; u <= uMax; u++) { 67 // Range for p 68 int pMin = PS_MAX(u + covar->xMin, kernel->xMin); 69 int pMax = PS_MIN(u + covar->xMax, kernel->xMax); 70 71 double xyuvValue = kernel->kernel[v-y][u-x]; // Value for (x,y) --> (u,v) 72 73 double uvpqValue = 0.0; // Value for (u,v) --> (p,q) --> (0,0) 74 for (int q = qMin; q <= qMax; q++) { 75 for (int p = pMin; p <= pMax; p++) { 76 uvpqValue += (double)covar->kernel[q-v][p-u] * (double)kernel->kernel[q][p]; 77 } 78 } 79 sum += xyuvValue * uvpqValue; 80 } 81 } 82 83 return sum; 84 } 85 86 /// Thread entry point for calculation of covariance matrix element when convolving 87 static bool imageCovarianceCalculateThread(psThreadJob *job) 88 { 89 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 90 psAssert(job->args, "No job arguments"); 91 psAssert(job->args->n == 5, "Wrong number of job arguments: %ld", job->args->n); 92 93 psKernel *out = job->args->data[0]; // Output covariance matrix 94 const psKernel *covar = job->args->data[1]; // Input covariance matrix 95 const psKernel *kernel = job->args->data[2]; // Convolution kernel 96 int x = PS_SCALAR_VALUE(job->args->data[3], S32); // x coordinate in output covariance matrix 97 int y = PS_SCALAR_VALUE(job->args->data[4], S32); // y coordinate in output covariance matrix 98 99 out->kernel[y][x] = imageCovarianceCalculate(covar, kernel, x, y); 100 101 return true; 102 } 103 104 105 106 psKernel *psImageCovarianceCalculate(const psKernel *kernel, const psKernel *covariance) 107 { 108 PS_ASSERT_KERNEL_NON_NULL(kernel, NULL); 109 110 // See http://en.wikipedia.org/wiki/Error_propagation 111 // 112 // If 113 // f_k = sum_i A_ik x_i 114 // is a set of functions, then the covariance matrix for f is given by: 115 // M^f_ij = sum_k sum_l A_ik M^x_kl A_lj 116 // where M^x is the covariance matrix for x. 117 // Note that the errors in f are correlated (covariance) even if the errors in x are not. 118 119 psKernel *covar; // Covariance matrix to use 120 if (covariance) { 121 covar = psMemIncrRefCounter((psKernel*)covariance); // Casting away const 122 } else { 123 covar = psImageCovarianceNone(); 124 } 125 126 // Check for non-finite elements 127 for (int y = kernel->yMin; y <= kernel->yMax; y++) { 128 for (int x = kernel->xMin; x <= kernel->xMax; x++) { 129 if (!isfinite(kernel->kernel[y][x])) { 130 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 131 "Non-finite covariance matrix element in kernel at %d,%d", x, y); 132 psFree(covar); 133 return NULL; 134 } 135 } 136 } 137 for (int y = covar->yMin; y <= covar->yMax; y++) { 138 for (int x = covar->xMin; x <= covar->xMax; x++) { 139 if (!isfinite(covar->kernel[y][x])) { 140 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 141 "Non-finite covariance matrix element in covariance matrix at %d,%d", x, y); 142 psFree(covar); 143 return NULL; 144 } 145 } 146 } 147 148 // The above (double) sum for the covariance matrix means that, for each point in the output covariance 149 // matrix, we need to work out all combinations of getting to the central point via a kernel, input 150 // covariance matrix and another kernel. This means that the resultant covariance matrix has twice the 151 // size of the kernel plus the size of the input covariance matrix. 152 int xMin = kernel->xMin - kernel->xMax + covar->xMin, xMax = kernel->xMax - kernel->xMin + covar->xMax; 153 int yMin = kernel->yMin - kernel->yMax + covar->yMin, yMax = kernel->yMax - kernel->yMin + covar->yMax; 154 psKernel *out = psKernelAlloc(xMin, xMax, yMin, yMax); // Covariance matrix for output 155 92 156 for (int y = yMin; y <= yMax; y++) { 93 // Range for v94 int vMin = PS_MAX(kernel->yMin + covar->yMin, y + kernel->yMin);95 int vMax = PS_MIN(kernel->yMax + covar->yMax, y + kernel->yMax);96 157 for (int x = xMin; x <= xMax; x++) { 97 // Range for u 98 int uMin = PS_MAX(kernel->xMin + covar->xMin, x + kernel->xMin); 99 int uMax = PS_MIN(kernel->xMax + covar->xMax, x + kernel->xMax); 100 101 double sum = 0.0; // Sum for value of covariance matrix at (x,y) 102 for (int v = vMin; v <= vMax; v++) { 103 // Range for q 104 int qMin = PS_MAX(v + covar->yMin, kernel->yMin); 105 int qMax = PS_MIN(v + covar->yMax, kernel->yMax); 106 for (int u = uMin; u <= uMax; u++) { 107 // Range for p 108 int pMin = PS_MAX(u + covar->xMin, kernel->xMin); 109 int pMax = PS_MIN(u + covar->xMax, kernel->xMax); 110 111 double xyuvValue = kernel->kernel[v-y][u-x]; // Value for (x,y) --> (u,v) 112 113 double uvpqValue = 0.0; // Value for (u,v) --> (p,q) --> (0,0) 114 for (int q = qMin; q <= qMax; q++) { 115 for (int p = pMin; p <= pMax; p++) { 116 uvpqValue += (double)covar->kernel[q-v][p-u] * (double)kernel->kernel[q][p]; 117 } 118 } 119 sum += xyuvValue * uvpqValue; 158 if (threaded) { 159 psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_COVARIANCE_CALCULATE"); 160 psArrayAdd(job->args, 1, out); 161 psArrayAdd(job->args, 1, covar); 162 psArrayAdd(job->args, 1, (psKernel*)kernel); // Casting away const 163 PS_ARRAY_ADD_SCALAR(job->args, x, PS_TYPE_S32); 164 PS_ARRAY_ADD_SCALAR(job->args, y, PS_TYPE_S32); 165 if (!psThreadJobAddPending(job)) { 166 psFree(covar); 167 return NULL; 120 168 } 121 } 122 out->kernel[y][x] = sum; 123 total += sum; 124 } 125 } 126 psTrace("psLib.imageops", 3, "Total covariance: %lf ; Central variance: %f\n", total, out->kernel[0][0]); 127 169 psFree(job); 170 } else { 171 out->kernel[y][x] = imageCovarianceCalculate(covar, kernel, x, y); 172 } 173 } 174 } 128 175 psFree(covar); 176 177 if (threaded && !psThreadPoolWait(true)) { 178 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 179 return false; 180 } 181 129 182 return out; 130 183 } 184 185 float psImageCovarianceCalculateFactor(const psKernel *kernel, const psKernel *covariance) 186 { 187 psKernel *covar; // Covariance matrix to use 188 if (covariance) { 189 covar = psMemIncrRefCounter((psKernel*)covariance); // Casting away const 190 } else { 191 covar = psImageCovarianceNone(); 192 } 193 194 // Check for non-finite elements 195 for (int y = kernel->yMin; y <= kernel->yMax; y++) { 196 for (int x = kernel->xMin; x <= kernel->xMax; x++) { 197 if (!isfinite(kernel->kernel[y][x])) { 198 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 199 "Non-finite covariance matrix element in kernel at %d,%d", x, y); 200 psFree(covar); 201 return NAN; 202 } 203 } 204 } 205 for (int y = covar->yMin; y <= covar->yMax; y++) { 206 for (int x = covar->xMin; x <= covar->xMax; x++) { 207 if (!isfinite(covar->kernel[y][x])) { 208 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 209 "Non-finite covariance matrix element in covariance matrix at %d,%d", x, y); 210 psFree(covar); 211 return NAN; 212 } 213 } 214 } 215 216 float factor = imageCovarianceCalculate(covar, kernel, 0, 0); // Covariance factor 217 psFree(covar); 218 return factor; 219 } 220 221 // Calculation of covariance matrix element when binning 222 static float imageCovarianceBin(const psKernel *covar, // Original covariance matrix 223 int bin, // Binning factor 224 float binVal, // Convolution kernel value for binning 225 int x, int y // Coordinates in output covariance matrix 226 ) 227 { 228 psAssert(covar, "Require covariance matrix"); 229 psAssert(bin > 0 && binVal > 0, "Require binning: %d %f", bin, binVal); 230 231 int binMin = -(bin - 1) / 2, binMax = bin / 2; // Range of "kernel" 232 233 // Range for v 234 int vMin = PS_MAX(binMin + covar->yMin, bin * y + binMin); 235 int vMax = PS_MIN(binMax + covar->yMax, bin * y + binMax); 236 // Range for u 237 int uMin = PS_MAX(binMin + covar->xMin, bin * x + binMin); 238 int uMax = PS_MIN(binMax + covar->xMax, bin * x + binMax); 239 240 double sum = 0.0; // Sum for value of covariance matrix at (x,y) 241 for (int v = vMin; v <= vMax; v++) { 242 // Range for q 243 int qMin = PS_MAX(v + covar->yMin, binMin); 244 int qMax = PS_MIN(v + covar->yMax, binMax); 245 for (int u = uMin; u <= uMax; u++) { 246 // Range for p 247 int pMin = PS_MAX(u + covar->xMin, binMin); 248 int pMax = PS_MIN(u + covar->xMax, binMax); 249 250 double xyuvValue = binVal; // Value for (x,y) --> (u,v) 251 252 double uvpqValue = 0.0; // Value for (u,v) --> (p,q) --> (0,0) 253 for (int q = qMin; q <= qMax; q++) { 254 for (int p = pMin; p <= pMax; p++) { 255 uvpqValue += (double)covar->kernel[q-v][p-u] * (double)binVal; 256 } 257 } 258 sum += xyuvValue * uvpqValue; 259 } 260 } 261 262 return sum; 263 } 264 265 /// Thread entry point for calculation of covariance matrix element when binning 266 static bool imageCovarianceBinThread(psThreadJob *job) 267 { 268 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 269 psAssert(job->args, "No job arguments"); 270 psAssert(job->args->n == 6, "Wrong number of job arguments: %ld", job->args->n); 271 272 psKernel *out = job->args->data[0]; // Output covariance matrix 273 const psKernel *covar = job->args->data[1]; // Input covariance matrix 274 int bin = PS_SCALAR_VALUE(job->args->data[2], S32); // Binning factor 275 float binVal = PS_SCALAR_VALUE(job->args->data[3], F32); // Convolution kernel value for binning 276 int x = PS_SCALAR_VALUE(job->args->data[4], S32); // x coordinate in output covariance matrix 277 int y = PS_SCALAR_VALUE(job->args->data[5], S32); // y coordinate in output covariance matrix 278 279 out->kernel[y][x] = imageCovarianceBin(covar, bin, binVal, x, y); 280 281 return true; 282 } 283 131 284 132 285 psKernel *psImageCovarianceBin(int bin, const psKernel *covariance, bool average) … … 165 318 psKernel *out = psKernelAlloc(xMin, xMax, yMin, yMax); // Covariance matrix for output 166 319 167 double total = 0.0; // Total covariance168 320 for (int y = yMin; y <= yMax; y++) { 169 // Range for v170 int vMin = PS_MAX(binMin + covar->yMin, bin * y + binMin);171 int vMax = PS_MIN(binMax + covar->yMax, bin * y + binMax);172 321 for (int x = xMin; x <= xMax; x++) { 173 // Range for u 174 int uMin = PS_MAX(binMin + covar->xMin, bin * x + binMin); 175 int uMax = PS_MIN(binMax + covar->xMax, bin * x + binMax); 176 177 double sum = 0.0; // Sum for value of covariance matrix at (x,y) 178 for (int v = vMin; v <= vMax; v++) { 179 // Range for q 180 int qMin = PS_MAX(v + covar->yMin, binMin); 181 int qMax = PS_MIN(v + covar->yMax, binMax); 182 for (int u = uMin; u <= uMax; u++) { 183 // Range for p 184 int pMin = PS_MAX(u + covar->xMin, binMin); 185 int pMax = PS_MIN(u + covar->xMax, binMax); 186 187 double xyuvValue = binVal; // Value for (x,y) --> (u,v) 188 189 double uvpqValue = 0.0; // Value for (u,v) --> (p,q) --> (0,0) 190 for (int q = qMin; q <= qMax; q++) { 191 for (int p = pMin; p <= pMax; p++) { 192 uvpqValue += (double)covar->kernel[q-v][p-u] * (double)binVal; 193 } 194 } 195 sum += xyuvValue * uvpqValue; 322 if (threaded) { 323 psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_COVARIANCE_BIN"); 324 psArrayAdd(job->args, 1, out); 325 psArrayAdd(job->args, 1, covar); 326 PS_ARRAY_ADD_SCALAR(job->args, bin, PS_TYPE_S32); 327 PS_ARRAY_ADD_SCALAR(job->args, binVal, PS_TYPE_F32); 328 PS_ARRAY_ADD_SCALAR(job->args, x, PS_TYPE_S32); 329 PS_ARRAY_ADD_SCALAR(job->args, y, PS_TYPE_S32); 330 if (!psThreadJobAddPending(job)) { 331 psFree(covar); 332 return NULL; 196 333 } 197 } 198 out->kernel[y][x] = sum; 199 total += sum; 200 } 201 } 202 psTrace("psLib.imageops", 3, "Total covariance: %lf ; Central variance: %f\n", total, out->kernel[0][0]); 203 334 psFree(job); 335 } else { 336 out->kernel[y][x] = imageCovarianceBin(covar, bin, binVal, x, y); 337 } 338 } 339 } 204 340 psFree(covar); 205 341 342 if (threaded && !psThreadPoolWait(true)) { 343 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 344 return false; 345 } 346 206 347 return out; 207 348 } … … 219 360 220 361 for (int y = covar->yMin; y <= covar->yMax; y++) { 221 if (y < -radius) continue;222 if (y > +radius) continue;223 for (int x = covar->xMin; x <= covar->xMax; x++) {224 if (x < -radius) continue;225 if (x > +radius) continue;226 227 if (hypot(x, y) > radius) continue;228 229 psAssert (isfinite(covar->kernel[y][x]), "invalid NAN in covariance matrix");230 Sum += covar->kernel[y][x];231 }362 if (y < -radius) continue; 363 if (y > +radius) continue; 364 for (int x = covar->xMin; x <= covar->xMax; x++) { 365 if (x < -radius) continue; 366 if (x > +radius) continue; 367 368 if (hypot(x, y) > radius) continue; 369 370 psAssert (isfinite(covar->kernel[y][x]), "invalid NAN in covariance matrix"); 371 Sum += covar->kernel[y][x]; 372 } 232 373 } 233 374 … … 428 569 return true; 429 570 } 571 572 573 bool psImageCovarianceSetThreads(bool set) 574 { 575 bool old = threaded; // Old value 576 if (set && !threaded) { 577 { 578 psThreadTask *task = psThreadTaskAlloc("PSLIB_IMAGE_COVARIANCE_CALCULATE", 5); 579 task->function = &imageCovarianceCalculateThread; 580 psThreadTaskAdd(task); 581 psFree(task); 582 } 583 { 584 psThreadTask *task = psThreadTaskAlloc("PSLIB_IMAGE_COVARIANCE_BIN", 6); 585 task->function = &imageCovarianceBinThread; 586 psThreadTaskAdd(task); 587 psFree(task); 588 } 589 } else if (!set && threaded) { 590 psThreadTaskRemove("PSLIB_IMAGE_COVARIANCE_CALCULATE"); 591 psThreadTaskRemove("PSLIB_IMAGE_COVARIANCE_BIN"); 592 } 593 threaded = set; 594 return old; 595 } 596 597 bool psImageCovarianceGetThreads(void) 598 { 599 return threaded; 600 } -
trunk/psLib/src/imageops/psImageCovariance.h
r25994 r26892 47 47 ); 48 48 49 /// Return the pixel-to-pixel covariance factor following calculation 50 /// 51 /// This doesn't require calculation of the entire covariance matrix, so is much faster. 52 float psImageCovarianceCalculateFactor( 53 const psKernel *kernel, ///< Convolution kernel 54 const psKernel *covariance ///< Current covariance pseudo-matrix 55 ); 56 57 49 58 /// Return the covariance factor for an aperture of a given radius 50 59 float psImageCovarianceFactorForAperture(const psKernel *covar, float radius); … … 81 90 ); 82 91 92 /// Control threading for image covariance functions 93 /// 94 /// Returns old threading status 95 bool psImageCovarianceSetThreads(bool threaded ///< Run image covariance functions threaded? 96 ); 97 98 /// Return whether image covariance functions are threaded 99 bool psImageCovarianceGetThreads(void); 83 100 84 101 /// @} -
trunk/psLib/src/imageops/psImageInterpolate.c
r23231 r26892 197 197 { 198 198 // Casting away const 199 psFree( (psImage*)interp->image);200 psFree( (psImage*)interp->mask);201 psFree( (psImage*)interp->variance);202 psFree( (psImage*)interp->kernel);203 psFree( (psImage*)interp->kernel2);204 psFree( (psVector*)interp->sumKernel2);199 psFree(interp->image); 200 psFree(interp->mask); 201 psFree(interp->variance); 202 psFree(interp->kernel); 203 psFree(interp->kernel2); 204 psFree(interp->sumKernel2); 205 205 } 206 206 -
trunk/psLib/src/math/psBinaryOp.c
r17050 r26892 379 379 } 380 380 381 psMathType* psBinaryOp(psPtr out, const psPtr in1, const char *op, constpsPtr in2)381 psMathType* psBinaryOp(psPtr out, psPtr in1, const char *op, psPtr in2) 382 382 { 383 383 -
trunk/psLib/src/math/psBinaryOp.h
r11248 r26892 55 55 psMathType* psBinaryOp( 56 56 psPtr out, ///< Output type, either psImage or psVector. 57 constpsPtr in1, ///< First input, either psImage or psVector.57 psPtr in1, ///< First input, either psImage or psVector. 58 58 const char *op, ///< Operator. 59 constpsPtr in2 ///< Second input, either psImage or psVector.59 psPtr in2 ///< Second input, either psImage or psVector. 60 60 ); 61 61 -
trunk/psLib/src/math/psHistogram.c
r21183 r26892 127 127 static void histogramFree(psHistogram* myHist) 128 128 { 129 psFree( (void *)myHist->bounds);129 psFree(myHist->bounds); 130 130 psFree(myHist->nums); 131 131 } -
trunk/psLib/src/math/psMatrix.c
r26001 r26892 1033 1033 } 1034 1034 1035 psVector *psMatrixSolveSVD(psVector *out, const psImage *matrix, const psVector *vector )1035 psVector *psMatrixSolveSVD(psVector *out, const psImage *matrix, const psVector *vector, float thresh) 1036 1036 { 1037 1037 #define psMatrixSolveSVD_EXIT {psFree(out); return NULL; } … … 1063 1063 gsl_vector_free(work); 1064 1064 1065 if (isfinite(thresh) && thresh > 0.0) { 1066 // Trim the singular values 1067 double total = 0.0; // Total of singular values 1068 for (int i = 0; i < numCols; i++) { 1069 total += gsl_vector_get(S, i); 1070 } 1071 thresh *= total; 1072 for (int i = 0; i < numCols; i++) { 1073 double value = gsl_vector_get(S, i); // Singular value 1074 if (value < thresh) { 1075 psTrace("psLib.math", 5, "Trimming singular value %d: %lg", i, value); 1076 gsl_vector_set(S, i, 0.0); 1077 #if 0 1078 for (int j = 0; j < numCols; j++) { 1079 // Being thorough; probably unnecessary 1080 gsl_matrix_set(V, j, i, 0.0); 1081 gsl_matrix_set(A, j, i, 0.0); 1082 } 1083 #endif 1084 } else { 1085 psTrace("psLib.math", 5, "Singular value %d: %lg", i, value); 1086 } 1087 } 1088 } 1089 1065 1090 // Solve system (or minimise least-squares if overconstrained): Ax = b 1066 1091 gsl_vector *b = gsl_vector_alloc(numCols); // Vector b … … 1093 1118 } 1094 1119 1095 1096 1097 1120 // This code supplied by Andy Becker (becker@astro.washington.edu) 1098 psImage *psMatrixSVD (psImage* evec, psVector* eval, const psImage* in)1121 psImage *psMatrixSVD_old(psImage* evec, psVector* eval, const psImage* in) 1099 1122 { 1100 1123 #define psMatrixSVD_EXIT {psFree(evec); psFree(eval); return NULL;} … … 1145 1168 return evec; 1146 1169 } 1170 1171 // this is basically a wrapper for the gsl function: gsl_linalg_SV_decomp() SVD decomposes 1172 // matrix A based on the following equation: A = U w V^T . This function (as usual for SVD 1173 // implementations) returns V not V^T. U and V are returned to images; w is returned to a 1174 // vector representing the diagonal of w. The input image A is not modified. U, V, and w may 1175 // be supplied as NULL or may be allocated; their lengths are set here to match the 1176 // dimensionality of A. XXX there is no error handling for the gsl functions (anywhere in 1177 // psMatrix.c) 1178 bool psMatrixSVD(psImage **U, psVector **w, psImage **V, const psImage *A) 1179 { 1180 // Error checks Missing one for eval 1181 PS_ASSERT_PTR_NON_NULL(U, false); 1182 PS_ASSERT_PTR_NON_NULL(w, false); 1183 PS_ASSERT_PTR_NON_NULL(V, false); 1184 PS_ASSERT_PTR_NON_NULL(A, false); 1185 1186 // A is provided with size Nx,Ny = numCols,numRows 1187 // U has size Nx,Ny 1188 // V has size Nx,Nx 1189 // w has size Nx 1190 1191 // Initialize data 1192 int numRows = A->numRows; 1193 int numCols = A->numCols; 1194 1195 *U = psImageRecycle(*U, numCols, numRows, A->type.type); 1196 *V = psImageRecycle(*V, numCols, numCols, A->type.type); 1197 *w = psVectorRecycle(*w, numCols, A->type.type); 1198 1199 gsl_matrix *Agsl = gsl_matrix_alloc(numRows, numCols); 1200 gsl_matrix *Vgsl = gsl_matrix_alloc(numCols, numCols); 1201 gsl_vector *Sgsl = gsl_vector_alloc(numCols); 1202 gsl_vector *work = gsl_vector_alloc(numCols); 1203 1204 // Copy psImage data into GSL matrix data 1205 matrixPStoGSL(Agsl, A); 1206 1207 // Calculate SVD decomposition 1208 gsl_linalg_SV_decomp(Agsl, Vgsl, Sgsl, work); 1209 1210 // Copy GSL matrix data to psImage data 1211 matrixGSLtoPS(*V, Vgsl); 1212 matrixGSLtoPS(*U, Agsl); // gsl_linalg_SV_decomp replaces A with U 1213 vectorGSLtoPS(*w, Sgsl); 1214 1215 // Free GSL data 1216 gsl_matrix_free(Agsl); 1217 gsl_matrix_free(Vgsl); 1218 gsl_vector_free(Sgsl); 1219 gsl_vector_free(work); 1220 1221 return true; 1222 } 1223 -
trunk/psLib/src/math/psMatrix.h
r26001 r26892 192 192 psVector *solution, ///< Solution to output, or NULL 193 193 const psImage *matrix, ///< Matrix to be solved 194 const psVector *vector ///< Vector of values 194 const psVector *vector, ///< Vector of values 195 float thresh ///< Threshold relative to maximum for trimming singular values 195 196 ); 196 197 197 198 /// Single value decomposition, provided by Andy Becker 199 psImage *psMatrixSVD(psImage* evec, psVector* eval, const psImage* in); 198 /// Single value decomposition (original by Andy Becker, updated by EAM) 199 bool psMatrixSVD(psImage **U, psVector **w, psImage **V, const psImage *A); 200 200 201 201 /// @} -
trunk/psLib/src/math/psUnaryOp.c
r17050 r26892 211 211 } 212 212 213 psMathType* psUnaryOp(psPtr out, constpsPtr in, const char *op)213 psMathType* psUnaryOp(psPtr out, psPtr in, const char *op) 214 214 { 215 215 #define psUnaryOp_EXIT { \ -
trunk/psLib/src/math/psUnaryOp.h
r11248 r26892 59 59 psMathType* psUnaryOp( 60 60 psPtr out, ///< Output type, either psImage or psVector. 61 const psPtr in,///< Input, either psImage or psVector.61 psPtr in, ///< Input, either psImage or psVector. 62 62 const char *op ///< Operator. 63 63 ); -
trunk/psLib/src/mathtypes/psVector.c
r24886 r26892 729 729 char line[1024]; 730 730 731 sprintf (line, " vector: %s\n", name);731 sprintf (line, "# vector: %s\n", name); 732 732 if (write(fd, line, strlen(line))) {;} //ignore return value 733 733 -
trunk/psLib/src/sys/psErrorCodes.c.in
r11675 r26892 67 67 static void freeErrorDescription(psErrorDescription* err) 68 68 { 69 psFree( (void *)err->description);69 psFree(err->description); 70 70 } 71 71 -
trunk/psLib/src/sys/psMemory.h
r23305 r26892 326 326 327 327 /** Free memory. This operates much like free(). 328 * 328 * 329 329 * @see psAlloc, psRealloc 330 * note: we cast ptr to (void *) in case we are supplied a const pointer. 330 331 */ 331 332 #ifdef DOXYGEN … … 336 337 #ifndef SWIG 337 338 #define psFree(ptr) \ 338 psMemDecrRefCounter(ptr)339 ptr = psMemDecrRefCounter((void *)ptr); 339 340 #endif // ifndef SWIG 340 341 #endif // ifdef DOXYGEN -
trunk/psLib/src/sys/psTrace.c
r20546 r26892 119 119 120 120 psMemSetPersistent((psPtr)comp->name,false); 121 psFree( (void *)comp->name);121 psFree(comp->name); 122 122 } 123 123 -
trunk/psLib/src/types/psArray.c
r15714 r26892 166 166 // drop an item from the array and free it 167 167 bool psArrayRemoveData(psArray* array, 168 constpsPtr data)168 psPtr data) 169 169 { 170 170 PS_ASSERT_ARRAY_NON_NULL(array, false); -
trunk/psLib/src/types/psArray.h
r19056 r26892 186 186 bool psArrayRemoveData( 187 187 psArray* array, ///< array to operate on 188 const psPtr data///< the data pointer to remove from psArray188 psPtr data ///< the data pointer to remove from psArray 189 189 ); 190 190 -
trunk/psLib/src/types/psMetadata.c
r25383 r26892 622 622 623 623 // may need to extend this to change the keyname in the copy 624 bool psMetadataItemSupplement(psMetadata *out, 624 bool psMetadataItemSupplement(bool *status, 625 psMetadata *out, 625 626 const psMetadata *in, 626 627 const char *key) … … 632 633 psMetadataItem *item = psMetadataLookup(in, key); 633 634 if (!item) { 634 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Could not find '%s' in metadata.\n", key); 635 if (status) { 636 *status = false; 637 } else { 638 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Could not find '%s' in metadata.\n", key); 639 } 635 640 return false; 636 641 } … … 968 973 } 969 974 970 psMetadataItem* psMetadataLookup(const psMetadata *md, 975 // Get entry by index 976 psMetadataItem *psMetadataGetIndex(psMetadata *md, long location) 977 { 978 PS_ASSERT_METADATA_NON_NULL(md, false); 979 return psListGet(md->list, location); 980 } 981 982 psMetadataItem *psMetadataLookup(const psMetadata *md, 971 983 const char *key) 972 984 { -
trunk/psLib/src/types/psMetadata.h
r25383 r26892 545 545 */ 546 546 bool psMetadataItemSupplement( 547 bool *status, ///< if supplied, returns true/false if key is found (suppresses the error) 547 548 psMetadata *out, ///< output Metadata container for copying. 548 549 const psMetadata *in, ///< Metadata collection from which to copy.
Note:
See TracChangeset
for help on using the changeset viewer.
