IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 9315


Ignore:
Timestamp:
Oct 5, 2006, 1:36:26 PM (20 years ago)
Author:
Paul Price
Message:

Adding pmShutterCorrectionMeasure to measure the shutter correction given an array of images.

Location:
trunk/psModules/src/detrend
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/detrend/pmShutterCorrection.c

    r9298 r9315  
    121121        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    122122                "Not enough good values to guess shutter correction.\n");
    123         goto ERROR;
     123        goto GUESS_ERROR;
    124124    }
    125125    tmpX->data.F32[0] = exptime->data.F32[index];
     
    133133        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    134134                "Exposure times are all identical --- cannot guess shutter correction.\n");
    135         goto ERROR;
     135        goto GUESS_ERROR;
    136136    }
    137137    tmpY->data.F32[1] = counts->data.F32[index];
     
    141141    if (!psVectorFitPolynomial1D(line, NULL, 0, tmpY, NULL, tmpX)) {
    142142        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to fit for the time offset.\n");
    143         goto ERROR;
     143        goto GUESS_ERROR;
    144144    }
    145145    float ratio = psPolynomial1DEval(line, 0.0) / corr->scale;
     
    170170    if (!psVectorFitPolynomial1D (line, NULL, 0, tmpY, NULL, tmpX)) {
    171171        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to fit for the reference offset.\n");
    172         goto ERROR;
     172        goto GUESS_ERROR;
    173173    }
    174174    corr->offref = psPolynomial1DEval(line, value);
     
    181181    return corr;
    182182
    183 ERROR:
     183GUESS_ERROR:
    184184    psFree(tmpX);
    185185    psFree(tmpY);
     
    344344    return corr;
    345345}
     346
     347//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     348
     349#define MEASURE_SAMPLES 4
     350
     351psImage *pmShutterCorrectionMeasure(const psVector *exptimes, // Exposure times
     352                                    const psArray *images, // Input images
     353                                    const psArray *masks, // Mask images
     354                                    unsigned int size, // Size of samples
     355                                    psStatsOptions meanStat, // Statistic to use for mean
     356                                    psStatsOptions stdevStat, // Statistic to use for stdev
     357                                    psMaskType maskVal // Mask value
     358                                   )
     359{
     360    PS_ASSERT_VECTOR_NON_NULL(exptimes, NULL);
     361    PS_ASSERT_VECTOR_TYPE(exptimes, PS_TYPE_F32, NULL);
     362    PS_ASSERT_ARRAY_NON_NULL(images, NULL);
     363    if (masks) {
     364        PS_ASSERT_ARRAYS_SIZE_EQUAL(images, masks, NULL);
     365    }
     366    long num = images->n;               // Number of images
     367    PS_ASSERT_VECTOR_SIZE(exptimes, num, NULL);
     368
     369    // Check input sizes, generate first-pass statistics
     370    psRegion refRegion;                 // Reference region
     371    psVector *refs = psVectorAlloc(num, PS_TYPE_F32); // Reference measurements
     372    refs->n = num;
     373    psVectorInit(refs, 0);
     374    psArray *regions = psArrayAlloc(MEASURE_SAMPLES); // Array of sample regions, made on each image
     375    regions->n = MEASURE_SAMPLES;
     376    psImage *samplesMean = psImageAlloc(num, MEASURE_SAMPLES, PS_TYPE_F32); // Measurements for each file
     377    psImage *samplesStdev = psImageAlloc(num, MEASURE_SAMPLES, PS_TYPE_F32); // Errors for each file
     378    psStats *stats = psStatsAlloc(meanStat | stdevStat);
     379    int numRows = 0, numCols = 0; // Size of images
     380    for (long i = 0; i < images->n; i++) {
     381        psImage *image = images->data[i]; // Image of interest
     382        if (!image) {
     383            continue;
     384        }
     385        if (numRows == 0 || numCols == 0) {
     386            numRows = image->numRows;
     387            numCols = image->numCols;
     388            // Set up the sample regions
     389            refRegion = psRegionForSquare(0.5 * numCols, 0.5 * numRows, size);
     390            for (int j = 0; j < MEASURE_SAMPLES; j++) {
     391                int x = (j % 2) ? size : image->numCols - size;
     392                int y = (j > 1) ? size : image->numRows - size;
     393                psRegion region = psRegionForSquare(x, y, size);
     394                region = psRegionForImage(image, region);
     395                regions->data[j] = psRegionAlloc(region.x0, region.x1, region.y0, region.y1);
     396            }
     397        } else if (numRows != image->numRows || numCols != image->numCols) {
     398            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
     399                    "Image sizes don't match: %dx%d vs %dx%d\n", image->numCols, image->numRows,
     400                    numCols, numRows);
     401            goto MEASURE_ERROR;
     402        }
     403
     404        // Measure statistics
     405        if (!psImageStats(stats, image, masks->data[i], maskVal)) {
     406            psWarning("Unable to measure reference statistics.\n");
     407        }
     408        refs->data.F32[i] = psStatsGetValue(stats, meanStat);
     409        if (refs->data.F32[i] <= 0.0) {
     410            psError(PS_ERR_UNKNOWN, true, "Measured non-positive reference value.\n");
     411            goto MEASURE_ERROR;
     412        }
     413        refs->data.F32[i] = 1.0 / refs->data.F32[i];
     414        for (int j = 0; j < MEASURE_SAMPLES; j++) {
     415            psRegion *region = regions->data[j]; // Region of interest
     416            psImage *subImage = psImageSubset(image, *region); // Sub-image
     417            if (!psImageStats(stats, subImage, masks->data[i], maskVal)) {
     418                psString regionString = psRegionToString(*region);
     419                psWarning("Unable to measure sample statistics at %s in image %ld.\n",
     420                          regionString, i);
     421                psFree(regionString);
     422            }
     423            psFree(subImage);
     424            samplesMean->data.F32[j][i] = psStatsGetValue(stats, meanStat) * refs->data.F32[i];
     425            samplesStdev->data.F32[j][i] = psStatsGetValue(stats, stdevStat) * refs->data.F32[i];
     426        }
     427    }
     428    psFree(regions);
     429    psFree(stats);
     430
     431    float meanRef = 0.0;                // Mean reference offset
     432    int numGood = 0;                    // Number of good measurements
     433    psVector *counts = psVectorAlloc(num, PS_TYPE_F32); // Mean for each image
     434    psVector *errors = psVectorAlloc(num, PS_TYPE_F32); // Stdev for each image
     435    for (int i = 0; i < MEASURE_SAMPLES; i++) {
     436        counts = psImageRow(counts, samplesMean, i);
     437        errors = psImageRow(errors, samplesStdev, i);
     438        pmShutterCorrection *guess = pmShutterCorrectionGuess(exptimes, counts); // Guess at correction
     439        pmShutterCorrection *params = pmShutterCorrectionFullFit(exptimes, counts, errors, guess); // Correc'n
     440        if (isfinite(params->offref)) {
     441            meanRef += params->offref;
     442            numGood++;
     443        }
     444        psFree(params);
     445        psFree(guess);
     446    }
     447    psFree(samplesMean);
     448    psFree(samplesStdev);
     449
     450    if (numGood == 0) {
     451        psError(PS_ERR_UNKNOWN, true, "Unable to measure mean reference offset.\n");
     452        psFree(counts);
     453        psFree(errors);
     454        goto MEASURE_ERROR;
     455    }
     456    meanRef /= (float)numGood;
     457
     458    psImage *shutter = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Shutter correction image
     459    //psImage *pattern = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Illumination pattern
     460    for (int y = 0; y < numRows; y++) {
     461        for (int x = 0; x < numCols; x++) {
     462            for (int i = 0; i < num; i++) {
     463                psImage *image = images->data[i]; // Image of interest
     464                counts->data.F32[i] = image->data.F32[y][x] * refs->data.F32[i];
     465                errors->data.F32[i] = sqrtf(image->data.F32[y][x]) * refs->data.F32[i];
     466            }
     467
     468            pmShutterCorrection *corr = pmShutterCorrectionLinFit(exptimes, counts, errors, meanRef);
     469            shutter->data.F32[y][x] = corr->offset;
     470            //pattern->data.F32[y][x] = corr->scale;
     471            psFree(corr);
     472        }
     473    }
     474    psFree(counts);
     475    psFree(errors);
     476    psFree(refs);
     477
     478    return shutter;
     479
     480
     481MEASURE_ERROR:
     482    // Clean up after error
     483    psFree(refs);
     484    psFree(regions);
     485    psFree(stats);
     486    psFree(samplesMean);
     487    psFree(samplesStdev);
     488    return NULL;
     489}
  • trunk/psModules/src/detrend/pmShutterCorrection.h

    r9298 r9315  
    4848 *  @author Eugene Magnier, IfA
    4949 *
    50  *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
    51  *  @date $Date: 2006-10-05 20:48:56 $
     50 *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
     51 *  @date $Date: 2006-10-05 23:36:26 $
    5252 *
    5353 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    5454 */
     55
     56#ifndef PM_SHUTTER_CORRECTION_H
     57#define PM_SHUTTER_CORRECTION_H
    5558
    5659#include "pslib.h"
     
    8891        const pmShutterCorrection *guess // Initial guess
    8992                                               );
     93
     94// Measure a shutter correction image from an array of images
     95psImage *pmShutterCorrectionMeasure(const psVector *exptimes, // Exposure times
     96                                    const psArray *images, // Input images
     97                                    const psArray *masks, // Mask images
     98                                    unsigned int size, // Size of samples
     99                                    psStatsOptions meanStat, // Statistic to use for mean
     100                                    psStatsOptions stdevStat, // Statistic to use for stdev
     101                                    psMaskType maskVal // Mask value
     102                                   );
     103
     104#endif
Note: See TracChangeset for help on using the changeset viewer.