Changeset 14504
- Timestamp:
- Aug 15, 2007, 10:10:01 AM (19 years ago)
- Location:
- branches/ipp-2-2/psModules/src
- Files:
-
- 2 added
- 4 edited
-
detrend/Makefile.am (modified) (2 diffs)
-
detrend/pmBias.c (modified) (7 diffs)
-
detrend/pmBias.h (modified) (2 diffs)
-
detrend/pmOverscan.c (added)
-
detrend/pmOverscan.h (added)
-
psmodules.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/ipp-2-2/psModules/src/detrend/Makefile.am
r12098 r14504 10 10 pmNonLinear.c \ 11 11 pmBias.c \ 12 pmOverscan.c \ 12 13 pmDetrendDB.c \ 13 14 pmShutterCorrection.c \ … … 23 24 pmNonLinear.h \ 24 25 pmBias.h \ 26 pmOverscan.h \ 25 27 pmDetrendDB.h \ 26 28 pmShutterCorrection.h \ -
branches/ipp-2-2/psModules/src/detrend/pmBias.c
r14385 r14504 15 15 #include "pmFPACalibration.h" 16 16 17 #include "pmOverscan.h" 17 18 #include "pmBias.h" 18 19 19 #define SMOOTH_NSIGMA 4.0 // Number of Gaussian sigma the smoothing kernel extends 20 21 22 static void overscanOptionsFree(pmOverscanOptions *options) 23 { 24 psFree(options->stat); 25 psFree(options->poly); 26 psFree(options->spline); 27 } 28 29 pmOverscanOptions *pmOverscanOptionsAlloc(bool single, pmFit fitType, unsigned int order, psStats *stat, 30 int boxcar, float gauss) 31 { 32 pmOverscanOptions *opts = psAlloc(sizeof(pmOverscanOptions)); 33 psMemSetDeallocator(opts, (psFreeFunc)overscanOptionsFree); 34 35 // Inputs 36 opts->single = single; 37 opts->fitType = fitType; 38 opts->order = order; 39 opts->stat = psMemIncrRefCounter(stat); 40 41 // Smoothing 42 opts->boxcar = boxcar; 43 opts->gauss = gauss; 44 45 // Outputs 46 opts->poly = NULL; 47 opts->spline = NULL; 48 49 return opts; 50 } 51 52 53 // subtractFrame(): this routine will take as input a readout for the input image and a readout for the bias 20 // pmBiasSubtractFrame(): this routine will take as input a readout for the input image and a readout for the bias 54 21 // image. The bias image is subtracted in place from the input image. 55 static bool subtractFrame(pmReadout *in, // Input readout22 bool pmBiasSubtractFrame(pmReadout *in, // Input readout 56 23 const pmReadout *sub, // Readout to be subtracted from input 57 24 float scale // Scale to apply before subtracting … … 125 92 } 126 93 127 // Produce an overscan vector from an array of pixels 128 static psVector *overscanVector(float *chi2, // chi^2 from fit 129 pmOverscanOptions *overscanOpts, // Overscan options 130 const psArray *pixels, // Array of vectors containing the pixel values 131 psStats *myStats // Statistic to use in reducing the overscan 132 ) 133 { 134 assert(overscanOpts); 135 assert(pixels); 136 assert(myStats); 137 138 psStatsOptions statistic = psStatsSingleOption(myStats->options); // Statistic to use 139 assert(statistic != 0); 140 141 // Reduce the overscans 142 psVector *reduced = psVectorAlloc(pixels->n, PS_TYPE_F32); // Overscan for each row 143 psVector *ordinate = psVectorAlloc(pixels->n, PS_TYPE_F32); // Ordinate 144 psVector *mask = psVectorAlloc(pixels->n, PS_TYPE_U8); // Mask for fitting 145 146 for (int i = 0; i < pixels->n; i++) { 147 psVector *values = pixels->data[i]; // Vector with overscan values 148 if (values->n > 0) { 149 mask->data.U8[i] = 0; 150 ordinate->data.F32[i] = 2.0*(float)i/(float)pixels->n - 1.0; // Scale to [-1,1] 151 psVectorStats(myStats, values, NULL, NULL, 0); 152 reduced->data.F32[i] = psStatsGetValue(myStats, statistic); 153 } else if (overscanOpts->fitType == PM_FIT_NONE) { 154 psError(PS_ERR_UNKNOWN, true, "The overscan is not supplied for all points on the " 155 "image, and no fit is requested.\n"); 156 return NULL; 157 } else { 158 // We'll fit this one out 159 mask->data.U8[i] = 1; 160 } 161 } 162 163 // Smooth the reduced vector 164 if (overscanOpts->boxcar > 0) { 165 psVector *smoothed = psVectorBoxcar(NULL, reduced, overscanOpts->boxcar); // Smoothed vector 166 psFree(reduced); 167 reduced = smoothed; 168 } 169 if (isfinite(overscanOpts->gauss) && overscanOpts->gauss > 0) { 170 if (overscanOpts->boxcar > 0) { 171 psWarning("Gaussian smoothing the boxcar smoothed overscan --- you asked for it."); 172 } 173 psVector *smoothed = psVectorSmooth(NULL, reduced, overscanOpts->gauss, SMOOTH_NSIGMA); 174 psFree(reduced); 175 reduced = smoothed; 176 } 177 178 // Fit the overscan, if required 179 psVector *fitted; // Fitted overscan values 180 switch (overscanOpts->fitType) { 181 case PM_FIT_NONE: 182 // No fitting --- that's easy. 183 fitted = psMemIncrRefCounter(reduced); 184 break; 185 case PM_FIT_POLY_ORD: 186 if (overscanOpts->poly && (overscanOpts->poly->nX != overscanOpts->order || 187 overscanOpts->poly->type != PS_POLYNOMIAL_ORD)) { 188 psFree(overscanOpts->poly); 189 overscanOpts->poly = NULL; 190 } 191 if (! overscanOpts->poly) { 192 overscanOpts->poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, overscanOpts->order); 193 } 194 psVectorFitPolynomial1D(overscanOpts->poly, mask, 1, reduced, NULL, ordinate); 195 fitted = psPolynomial1DEvalVector(overscanOpts->poly, ordinate); 196 break; 197 case PM_FIT_POLY_CHEBY: 198 if (overscanOpts->poly && (overscanOpts->poly->nX != overscanOpts->order || 199 overscanOpts->poly->type != PS_POLYNOMIAL_CHEB)) { 200 psFree(overscanOpts->poly); 201 overscanOpts->poly = NULL; 202 } 203 if (! overscanOpts->poly) { 204 overscanOpts->poly = psPolynomial1DAlloc(PS_POLYNOMIAL_CHEB, overscanOpts->order); 205 } 206 psVectorFitPolynomial1D(overscanOpts->poly, mask, 1, reduced, NULL, ordinate); 207 fitted = psPolynomial1DEvalVector(overscanOpts->poly, ordinate); 208 break; 209 case PM_FIT_SPLINE: 210 // XXX I don't think psSpline1D is up to scratch yet --- it has no mask, and requires an 211 // input spline 212 overscanOpts->spline = psVectorFitSpline1D(reduced, ordinate); 213 fitted = psSpline1DEvalVector(overscanOpts->spline, ordinate); 214 break; 215 default: 216 psError(PS_ERR_UNKNOWN, true, "Unknown value for the fitting type: %d\n", overscanOpts->fitType); 217 return NULL; 218 break; 219 } 220 221 if (chi2) { 222 *chi2 = 0.0; // chi^2 (sort of) 223 for (int i = 0; i < reduced->n; i++) { 224 *chi2 += PS_SQR(fitted->data.F32[i] - reduced->data.F32[i]); 225 } 226 } 227 228 psFree(reduced); 229 psFree(ordinate); 230 psFree(mask); 231 232 return fitted; 233 } 234 235 bool pmBiasSubtract(pmReadout *inRO, pmOverscanOptions *overscanOpts, 236 const pmReadout *biasRO, const pmReadout *darkRO, const pmFPAview *view) 94 bool pmBiasSubtract(pmReadout *in, pmOverscanOptions *overscanOpts, 95 const pmReadout *bias, const pmReadout *dark, const pmFPAview *view) 237 96 { 238 97 psTrace("psModules.detrend", 4, 239 98 "---- pmBiasSubtract() begin ----\n"); 240 99 241 PS_ASSERT_PTR_NON_NULL(in RO, false);242 PS_ASSERT_IMAGE_NON_NULL(in RO->image, false);243 PS_ASSERT_IMAGE_TYPE(in RO->image, PS_TYPE_F32, false);244 if (bias RO) {245 PS_ASSERT_IMAGE_NON_NULL(bias RO->image, false);246 PS_ASSERT_IMAGE_TYPE(bias RO->image, PS_TYPE_F32, false);100 PS_ASSERT_PTR_NON_NULL(in, false); 101 PS_ASSERT_IMAGE_NON_NULL(in->image, false); 102 PS_ASSERT_IMAGE_TYPE(in->image, PS_TYPE_F32, false); 103 if (bias) { 104 PS_ASSERT_IMAGE_NON_NULL(bias->image, false); 105 PS_ASSERT_IMAGE_TYPE(bias->image, PS_TYPE_F32, false); 247 106 } 248 if (dark RO) {107 if (dark) { 249 108 PS_ASSERT_PTR_NON_NULL(view, false); 250 PS_ASSERT_IMAGE_NON_NULL(dark RO->image, false);251 PS_ASSERT_IMAGE_TYPE(dark RO->image, PS_TYPE_F32, false);109 PS_ASSERT_IMAGE_NON_NULL(dark->image, false); 110 PS_ASSERT_IMAGE_TYPE(dark->image, PS_TYPE_F32, false); 252 111 } 253 112 254 pmHDU *hdu = pmHDUFromReadout(inRO); // HDU of interest 255 psImage *image = inRO->image; // The input image 113 pmHDU *hdu = pmHDUFromReadout(in); // HDU of interest 256 114 257 // Overscan processing 258 if (overscanOpts) { 259 // Check for an unallowable pmFit. 260 if (overscanOpts->fitType != PM_FIT_NONE && overscanOpts->fitType != PM_FIT_POLY_ORD && 261 overscanOpts->fitType != PM_FIT_POLY_CHEBY && overscanOpts->fitType != PM_FIT_SPLINE) { 262 psError(PS_ERR_UNKNOWN, true, "Invalid fit type (%d). Returning original image.\n", 263 overscanOpts->fitType); 264 return false; 265 } 266 267 psList *overscans = inRO->bias; // List of the overscan images 268 269 psStatsOptions statistic = psStatsSingleOption(overscanOpts->stat->options); // Statistic to use 270 if (statistic == 0) { 271 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Multiple or no statistics options set: %p\n", 272 overscanOpts->stat); 273 return false; 274 } 275 psStats *stats = psStatsAlloc(statistic); // A new psStats, to avoid clobbering original 276 277 psString comment = NULL; // Comment to add 278 psStringAppend(&comment, "Subtracting overscan (stat %x; type %x; order %d)", 279 statistic, overscanOpts->fitType, overscanOpts->order); 280 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, 281 comment, ""); 282 psFree(comment); 283 284 // Reduce all overscan pixels to a single value 285 if (overscanOpts->single) { 286 psVector *pixels = psVectorAlloc(0, PS_TYPE_F32); 287 psListIterator *iter = psListIteratorAlloc(overscans, PS_LIST_HEAD, false); // Iterator 288 psImage *overscan = NULL; // Overscan image from iterator 289 while ((overscan = psListGetAndIncrement(iter))) { 290 int index = pixels->n; // Index 291 pixels = psVectorRealloc(pixels, pixels->n + overscan->numRows * overscan->numCols); 292 pixels->n += overscan->numRows * overscan->numCols; 293 for (int i = 0; i < overscan->numRows; i++) { 294 memcpy(&pixels->data.F32[index], overscan->data.F32[i], 295 overscan->numCols * sizeof(psF32)); 296 index += overscan->numCols; 297 } 298 } 299 psFree(iter); 300 301 (void)psVectorStats(stats, pixels, NULL, NULL, 0); 302 psFree(pixels); 303 double reduced = psStatsGetValue(stats, statistic); // Result of statistics 304 305 psString comment = NULL; // Comment to add 306 psStringAppend(&comment, "Overscan value: %f", reduced); 307 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, ""); 308 psFree(comment); 309 310 // write metadata header value 311 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan value", 312 reduced); 313 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", NAN); 314 315 (void)psBinaryOp(image, image, "-", psScalarAlloc((float)reduced, PS_TYPE_F32)); 316 } else { 317 // We do the regular overscan subtraction 318 bool readRows = psMetadataLookupBool(NULL, inRO->parent->concepts, 319 "CELL.READDIR"); // Read direction 320 float chi2 = NAN; // chi^2 from fit 321 322 if (readRows) { 323 // The read direction is rows 324 psArray *pixels = psArrayAlloc(image->numRows); // Array of vectors containing pixels 325 for (int i = 0; i < pixels->n; i++) { 326 pixels->data[i] = psVectorAlloc(0, PS_TYPE_F32); 327 } 328 329 // Pull the pixels out into the vectors 330 psListIterator *iter = psListIteratorAlloc(overscans, PS_LIST_HEAD, false); // Iterator 331 psImage *overscan = NULL; // Overscan image from iterator 332 while ((overscan = psListGetAndIncrement(iter))) { 333 // the overscan and image might not be aligned. pixels->data represents 334 // the image row pixels. 335 int diff = overscan->row0 - image->row0; // Offset between the two regions 336 for (int i = PS_MAX(0,diff); i < PS_MIN(image->numRows, overscan->numRows + diff); i++) { 337 int j = i - diff; 338 // i is row on image 339 // j is row on overscan 340 psVector *values = pixels->data[i]; 341 int index = values->n; // Index in the vector 342 values = psVectorRealloc(values, values->n + overscan->numCols); 343 values->n += overscan->numCols; 344 memcpy(&values->data.F32[index], overscan->data.F32[j], 345 overscan->numCols * PSELEMTYPE_SIZEOF(PS_TYPE_F32)); 346 index += overscan->numCols; 347 pixels->data[i] = values; // Update the pointer in case it's moved 348 } 349 } 350 psFree(iter); 351 352 // Reduce the overscans 353 psVector *reduced = overscanVector(&chi2, overscanOpts, pixels, stats); 354 psFree(pixels); 355 if (! reduced) { 356 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate overscan vector.\n"); 357 return false; 358 } 359 360 // Subtract row by row 361 for (int i = 0; i < image->numRows; i++) { 362 for (int j = 0; j < image->numCols; j++) { 363 image->data.F32[i][j] -= reduced->data.F32[i]; 364 } 365 } 366 psFree(reduced); 367 368 } else { 369 // The read direction is columns 370 psArray *pixels = psArrayAlloc(image->numCols); // Array of vectors containing pixels 371 for (int i = 0; i < pixels->n; i++) { 372 psVector *values = psVectorAlloc(0, PS_TYPE_F32); 373 pixels->data[i] = values; 374 } 375 376 // Pull the pixels out into the vectors 377 psListIterator *iter = psListIteratorAlloc(overscans, PS_LIST_HEAD, false); // Iterator 378 psImage *overscan = NULL; // Overscan image from iterator 379 while ((overscan = psListGetAndIncrement(iter))) { 380 // the overscan and image might not be aligned. pixels->data represents 381 // the image row pixels. 382 int diff = overscan->col0 - image->col0; // Offset between the two regions 383 for (int i = PS_MAX(0,diff); i < PS_MIN(image->numCols, overscan->numCols + diff); i++) { 384 int iFixed = i - diff; 385 // i is column on image 386 // iFixed is column on overscan 387 psVector *values = pixels->data[i]; 388 int index = values->n; // Index in the vector 389 values = psVectorRealloc(values, values->n + overscan->numRows); 390 for (int j = 0; j < overscan->numRows; j++) { 391 values->data.F32[index++] = overscan->data.F32[j][iFixed]; 392 } 393 values->n += overscan->numRows; 394 pixels->data[i] = values; // Update the pointer in case it's moved 395 } 396 } 397 psFree(iter); 398 399 // Reduce the overscans 400 psVector *reduced = overscanVector(&chi2, overscanOpts, pixels, stats); 401 psFree(pixels); 402 if (! reduced) { 403 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate overscan vector.\n"); 404 return false; 405 } 406 407 // Subtract column by column 408 for (int i = 0; i < image->numCols; i++) { 409 for (int j = 0; j < image->numRows; j++) { 410 image->data.F32[j][i] -= reduced->data.F32[i]; 411 } 412 } 413 psFree(reduced); 414 } 415 416 switch (overscanOpts->fitType) { 417 case PM_FIT_POLY_ORD: 418 case PM_FIT_POLY_CHEBY: { 419 psString comment = NULL; // Comment to add 420 psStringAppend(&comment, "Overscan fit (chi2: %.2f): ", chi2); 421 psPolynomial1D *poly = overscanOpts->poly; // The polynomial 422 for (int i = 0; i < poly->nX; i++) { 423 psStringAppend(&comment, "%.1f ", poly->coeff[i]); 424 } 425 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, ""); 426 psFree(comment); 427 428 // write metadata header value 429 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, 430 "Overscan value", poly->coeff[0]); 431 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, 432 "Overscan stdev", poly->coeffErr[0]); 433 break; 434 } 435 case PM_FIT_SPLINE: { 436 psSpline1D *spline = overscanOpts->spline; // The spline 437 for (int i = 0; i < spline->n; i++) { 438 psStringAppend(&comment, "Overscan fit (chi2: %.2f) %d:", chi2, i); 439 psPolynomial1D *poly = spline->spline[i]; // i-th polynomial 440 for (int j = 0; j < poly->nX; j++) { 441 psStringAppend(&comment, "%.1f ", poly->coeff[i]); 442 } 443 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, 444 comment, ""); 445 psFree(comment); 446 } 447 // write metadata header value 448 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, 449 "Overscan value", NAN); 450 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, 451 "Overscan stdev", NAN); 452 break; 453 } 454 case PM_FIT_NONE: 455 break; 456 default: 457 psAbort("Should never get here!!!\n"); 458 } 459 460 461 } 462 psFree(stats); 463 } // End of overscan subtraction 115 if (!pmOverscanSubtract (in, overscanOpts)) { 116 return false; 117 } 464 118 465 119 // Bias frame subtraction 466 if (bias RO) {467 psVector *md5 = psImageMD5(bias RO->image); // md5 hash120 if (bias) { 121 psVector *md5 = psImageMD5(bias->image); // md5 hash 468 122 psString md5string = psMD5toString(md5); // String 469 123 psFree(md5); … … 473 127 psFree(md5string); 474 128 475 if (! subtractFrame(inRO, biasRO, 1.0)) {129 if (!pmBiasSubtractFrame(in, bias, 1.0)) { 476 130 return false; 477 131 } 478 132 } 479 133 480 if (dark RO) {134 if (dark) { 481 135 // Get the scaling 482 float inTime = psMetadataLookupF32(NULL, in RO->parent->concepts, "CELL.DARKTIME");483 float darkTime = psMetadataLookupF32(NULL, dark RO->parent->concepts, "CELL.DARKTIME");136 float inTime = psMetadataLookupF32(NULL, in->parent->concepts, "CELL.DARKTIME"); 137 float darkTime = psMetadataLookupF32(NULL, dark->parent->concepts, "CELL.DARKTIME"); 484 138 if (isnan(inTime) || isnan(darkTime)) { 485 139 psError(PS_ERR_UNKNOWN, false, "Unable to determine dark scaling."); … … 488 142 489 143 float darkNorm = 1.0; 490 float inNorm = pmFPADarkNorm(in RO->parent->parent->parent, view, inTime);144 float inNorm = pmFPADarkNorm(in->parent->parent->parent, view, inTime); 491 145 492 146 // if we have a normalized dark exposure, we simply multiply the master by inNorm. if … … 495 149 496 150 if (darkTime != 1.0) { 497 darkNorm = pmFPADarkNorm(dark RO->parent->parent->parent, view, darkTime);151 darkNorm = pmFPADarkNorm(dark->parent->parent->parent, view, darkTime); 498 152 } 499 153 … … 505 159 float scale = inNorm / darkNorm;// Scaling to apply to dark exposure 506 160 507 psVector *md5 = psImageMD5(dark RO->image); // md5 hash161 psVector *md5 = psImageMD5(dark->image); // md5 hash 508 162 psString md5string = psMD5toString(md5); // String 509 163 psFree(md5); … … 513 167 psFree(md5string); 514 168 515 if (! subtractFrame(inRO, darkRO, scale)) {169 if (!pmBiasSubtractFrame(in, dark, scale)) { 516 170 return false; 517 171 } -
branches/ipp-2-2/psModules/src/detrend/pmBias.h
r14385 r14504 5 5 * @author Paul Price, IfA 6 6 * 7 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $8 * @date $Date: 2007-0 6-20 20:45:00$7 * @version $Revision: 1.6.2.1 $ $Name: not supported by cvs2svn $ 8 * @date $Date: 2007-08-15 20:10:01 $ 9 9 * Copyright 2004--2006 Institute for Astronomy, University of Hawaii 10 10 */ 11 11 12 #ifndef PM_ _BIAS_H13 #define PM_ _BIAS_H12 #ifndef PM_BIAS_H 13 #define PM_BIAS_H 14 14 15 15 /// @addtogroup detrend Detrend Creation and Application 16 16 /// @{ 17 18 /// Type of fit to perform19 typedef enum {20 PM_FIT_NONE, ///< No fit21 PM_FIT_POLY_ORD, ///< Fit ordinary polynomial22 PM_FIT_POLY_CHEBY, ///< Fit Chebyshev polynomial23 PM_FIT_SPLINE ///< Fit cubic splines24 } pmFit;25 26 /// Options for overscan subtraction27 ///28 /// The overscan subtraction may be performed by reducing all overscan regions to a single value (e.g., if29 /// there is no structure); or the overscan may be fit perpendicular to the read direction (usually the30 /// columns) with a particular functional form; or a single value may be subtracted for each read/scan without31 /// fitting (if the structure defies characterisation). In any case, statistics are required to reduce32 /// multiple values to a single value (either for the scan, or for the entire overscan regions).33 typedef struct34 {35 // Inputs36 bool single; ///< Reduce all overscan regions to a single value?37 pmFit fitType; ///< Type of fit to overscan38 unsigned int order; ///< Order of polynomial, or number of spline pieces39 psStats *stat; ///< Statistic to use when reducing the minor direction40 int boxcar; ///< Boxcar smoothing radius41 float gauss; ///< Gaussian smoothing sigma42 // Outputs43 psPolynomial1D *poly; ///< Result of polynomial fit44 psSpline1D *spline; ///< Result of spline fit45 }46 pmOverscanOptions;47 48 /// Allocator for overscan options49 pmOverscanOptions *pmOverscanOptionsAlloc(bool single, ///< Reduce all overscan regions to a single value?50 pmFit fitType, ///< Type of fit to overscan51 unsigned int order, ///< Order of polynomial, or number of splines52 psStats *stat, ///< Statistic to use53 int boxcar, ///< Boxcar smoothing radius54 float gauss ///< Gaussian smoothing sigma55 );56 17 57 18 /// Subtract the overscan, bias and/or dark … … 66 27 ); 67 28 29 // pmBiasSubtractFrame(): this routine will take as input a readout for the input image and a readout for the bias 30 // image. The bias image is subtracted in place from the input image. 31 bool pmBiasSubtractFrame(pmReadout *in, // Input readout 32 const pmReadout *sub, // Readout to be subtracted from input 33 float scale // Scale to apply before subtracting 34 ); 35 68 36 /// @} 69 37 #endif -
branches/ipp-2-2/psModules/src/psmodules.h
r13898 r14504 61 61 #include <pmMaskBadPixels.h> 62 62 #include <pmNonLinear.h> 63 #include <pmOverscan.h> 63 64 #include <pmBias.h> 64 65 #include <pmShutterCorrection.h>
Note:
See TracChangeset
for help on using the changeset viewer.
