IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 26, 2007, 4:44:42 PM (19 years ago)
Author:
magnier
Message:

converted binning operations to use the common pmImageBinning methods

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/camera/pmFPAMosaic.c

    r11786 r12589  
    382382}
    383383
    384 // Mosaic multiple images, with flips, binning and offsets
    385 static psImage *imageMosaic(const psArray *source, // Images to splice in
    386                             const psVector *xFlip, const psVector *yFlip, // Need to flip x and y?
    387                             const psVector *xBinSource, // Binning in x of source images
    388                             const psVector *yBinSource, // Binning in y of source images
    389                             int xBinTarget, int yBinTarget, // Binning in x and y of target images
    390                             const psVector *x0, const psVector *y0 // Offsets for source images on target
    391                            )
    392 {
    393     assert(source);
    394     assert(xFlip && xFlip->type.type == PS_TYPE_U8);
    395     assert(yFlip && yFlip->type.type == PS_TYPE_U8);
    396     assert(xBinSource && xBinSource->type.type == PS_TYPE_S32);
    397     assert(yBinSource && yBinSource->type.type == PS_TYPE_S32);
    398     assert(x0 && x0->type.type == PS_TYPE_S32);
    399     assert(y0 && y0->type.type == PS_TYPE_S32);
    400     assert(xFlip->n == source->n);
    401     assert(yFlip->n == source->n);
    402     assert(xBinSource->n == source->n);
    403     assert(yBinSource->n == source->n);
    404     assert(x0->n == source->n);
    405     assert(y0->n == source->n);
    406 
    407     if (source->n == 0) {
    408         return NULL;
    409     }
    410 
    411     // Get the maximum extent of the mosaic image
    412     int xMin = INT_MAX;
    413     int xMax = - INT_MAX;
    414     int yMin = INT_MAX;
    415     int yMax = - INT_MAX;
    416     psElemType type = 0;
    417     int numImages = 0;                  // Number of images
    418     psTrace("psModules.camera", 3, "Mosaicking %ld cells.\n", source->n);
    419     for (int i = 0; i < source->n; i++) {
    420         psImage *image = source->data[i]; // The image of interest
    421         if (!image) {
    422             continue;
    423         }
    424         numImages++;
    425 
    426         // Only implemented for F32 and U8 images so far.
    427         assert(image->type.type == PS_TYPE_F32 || image->type.type == PS_TYPE_U8);
    428         // All input types must be the same
    429         if (type == 0) {
    430             type = image->type.type;
    431         }
    432         assert(type == image->type.type);
    433 
    434         // Size of cell in x and y
    435         int xParity = xFlip->data.U8[i] ? -1 : 1;
    436         int yParity = yFlip->data.U8[i] ? -1 : 1;
    437         psTrace("psModules.camera", 5, "Extent of cell %d: %d -> %d , %d -> %d\n", i, x0->data.S32[i],
    438                 x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols, y0->data.S32[i],
    439                 y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows);
    440 
    441         COMPARE(x0->data.S32[i], xMin, xMax);
    442         COMPARE(y0->data.S32[i], yMin, yMax);
    443         // Subtract the parity to get the inclusive limit (not exclusive)
    444         COMPARE(x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols - xParity, xMin, xMax);
    445         COMPARE(y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows - yParity, yMin, yMax);
    446     }
    447     if (numImages == 0) {
    448         return NULL;
    449     }
    450 
    451     // Set up the image
    452     // Since both upper and lower values are inclusive, we need to add one to the size
    453     float xSize = (float)(xMax - xMin + 1) / (float)xBinTarget;
    454     if (xSize - (int)xSize > 0) {
    455         xSize += 1;
    456     }
    457     float ySize = (float)(yMax - yMin + 1) / (float)yBinTarget;
    458     if (ySize - (int)ySize > 0) {
    459         ySize += 1;
    460     }
    461 
    462     psTrace("psModules.camera", 3, "Spliced image will be %dx%d\n", (int)xSize, (int)ySize);
    463     psImage *mosaic = psImageAlloc((int)xSize, (int)ySize, type); // The mosaic image
    464     psImageInit(mosaic, 0);
    465 
    466     // Next pass through the images to do the mosaicking
    467     for (int i = 0; i < source->n; i++) {
    468         psImage *image = source->data[i]; // The image of interest
    469         if (!image) {
    470             continue;
    471         }
    472         int xParity = xFlip->data.U8[i] ? -1 : 1; // Parity difference, in x
    473         int yParity = yFlip->data.U8[i] ? -1 : 1; // Parity difference, in y
    474         int xTargetBase = (x0->data.S32[i] - xMin) / xBinTarget; // The base x position in the target frame
    475         int yTargetBase = (y0->data.S32[i] - yMin) / yBinTarget; // The base y position in the target frame
    476         if (xBinSource->data.S32[i] == xBinTarget && yBinSource->data.S32[i] == yBinTarget &&
    477                 xFlip->data.U8[i] == 0 && yFlip->data.U8[i] == 0) {
    478             // Let someone else do the hard work
    479             psImageOverlaySection(mosaic, image, xTargetBase, yTargetBase, "+");
    480         } else if (xBinSource->data.S32[i] == xBinTarget && yBinSource->data.S32[i] == yBinTarget) {
    481             // There's a difference with the parities, but we don't have to worry about binning
    482 
    483             #define COPY_WITH_PARITY_DIFFERENCE(TYPE) \
     384// supporting macros used by imageMosaic()
     385// copy pixels without binning
     386#define COPY_WITH_PARITY_DIFFERENCE(TYPE) \
    484387        case PS_TYPE_##TYPE: { \
    485388                for (int y = 0; y < image->numRows; y++) { \
     
    493396            break;
    494397
    495             switch (type) {
    496                 COPY_WITH_PARITY_DIFFERENCE(F32);
    497                 COPY_WITH_PARITY_DIFFERENCE(U8);
    498             default:
    499                 psAbort("Should never get here.\n");
    500             }
    501 
    502         } else {
    503             // We have to do all of the hard work ourself
    504 
    505             // In case the original image is binned but the mosaic is not, we need to fill in the
    506             // values in the mosaic.
    507             #define FILL_IN(TYPE) \
     398// In case the original image is binned but the mosaic is not, we need to fill in the values in
     399// the mosaic.  this operation should be replaced with a call to one of the functions defined
     400// in psImageBinning
     401#define FILL_IN(TYPE) \
    508402        case PS_TYPE_##TYPE: \
    509403            for (int y = 0; y < image->numRows; y++) { \
     
    522416            break;
    523417
     418// Mosaic multiple images, with flips, binning and offsets
     419static psImage *imageMosaic(const psArray *source, // Images to splice in
     420                            const psVector *xFlip, const psVector *yFlip, // Need to flip x and y?
     421                            const psVector *xBinSource, // Binning in x of source images
     422                            const psVector *yBinSource, // Binning in y of source images
     423                            int xBinTarget, int yBinTarget, // Binning in x and y of target images
     424                            const psVector *x0, const psVector *y0 // Offsets for source images on target
     425                           )
     426{
     427    assert(source);
     428    assert(xFlip && xFlip->type.type == PS_TYPE_U8);
     429    assert(yFlip && yFlip->type.type == PS_TYPE_U8);
     430    assert(xBinSource && xBinSource->type.type == PS_TYPE_S32);
     431    assert(yBinSource && yBinSource->type.type == PS_TYPE_S32);
     432    assert(x0 && x0->type.type == PS_TYPE_S32);
     433    assert(y0 && y0->type.type == PS_TYPE_S32);
     434    assert(xFlip->n == source->n);
     435    assert(yFlip->n == source->n);
     436    assert(xBinSource->n == source->n);
     437    assert(yBinSource->n == source->n);
     438    assert(x0->n == source->n);
     439    assert(y0->n == source->n);
     440
     441    if (source->n == 0) {
     442        return NULL;
     443    }
     444
     445    // Get the maximum extent of the mosaic image
     446    int xMin = INT_MAX;
     447    int xMax = - INT_MAX;
     448    int yMin = INT_MAX;
     449    int yMax = - INT_MAX;
     450    psElemType type = 0;
     451    int numImages = 0;                  // Number of images
     452    psTrace("psModules.camera", 3, "Mosaicking %ld cells.\n", source->n);
     453    for (int i = 0; i < source->n; i++) {
     454        psImage *image = source->data[i]; // The image of interest
     455        if (!image) {
     456            continue;
     457        }
     458        numImages++;
     459
     460        // Only implemented for F32 and U8 images so far.
     461        assert(image->type.type == PS_TYPE_F32 || image->type.type == PS_TYPE_U8);
     462        // All input types must be the same
     463        if (type == 0) {
     464            type = image->type.type;
     465        }
     466        assert(type == image->type.type);
     467
     468        // Size of cell in x and y
     469        int xParity = xFlip->data.U8[i] ? -1 : 1;
     470        int yParity = yFlip->data.U8[i] ? -1 : 1;
     471        psTrace("psModules.camera", 5, "Extent of cell %d: %d -> %d , %d -> %d\n", i, x0->data.S32[i],
     472                x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols, y0->data.S32[i],
     473                y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows);
     474
     475        COMPARE(x0->data.S32[i], xMin, xMax);
     476        COMPARE(y0->data.S32[i], yMin, yMax);
     477        // Subtract the parity to get the inclusive limit (not exclusive)
     478        COMPARE(x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols - xParity, xMin, xMax);
     479        COMPARE(y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows - yParity, yMin, yMax);
     480    }
     481    if (numImages == 0) {
     482        return NULL;
     483    }
     484
     485    // Set up the image
     486    // Since both upper and lower values are inclusive, we need to add one to the size
     487    float xSize = (float)(xMax - xMin + 1) / (float)xBinTarget;
     488    if (xSize - (int)xSize > 0) {
     489        xSize += 1;
     490    }
     491    float ySize = (float)(yMax - yMin + 1) / (float)yBinTarget;
     492    if (ySize - (int)ySize > 0) {
     493        ySize += 1;
     494    }
     495
     496    psTrace("psModules.camera", 3, "Spliced image will be %dx%d\n", (int)xSize, (int)ySize);
     497    psImage *mosaic = psImageAlloc((int)xSize, (int)ySize, type); // The mosaic image
     498    psImageInit(mosaic, 0);
     499
     500    // Next pass through the images to do the mosaicking
     501    // XXX this function uses summing for the output: is this the right choice?
     502    for (int i = 0; i < source->n; i++) {
     503        psImage *image = source->data[i]; // The image of interest
     504        if (!image) {
     505            continue;
     506        }
     507        int xParity = xFlip->data.U8[i] ? -1 : 1; // Parity difference, in x
     508        int yParity = yFlip->data.U8[i] ? -1 : 1; // Parity difference, in y
     509        int xTargetBase = (x0->data.S32[i] - xMin) / xBinTarget; // The base x position in the target frame
     510        int yTargetBase = (y0->data.S32[i] - yMin) / yBinTarget; // The base y position in the target frame
     511
     512        // in the first case, we are just copy a section pixel-by-pixel
     513        if ((xBinSource->data.S32[i] == xBinTarget) &&
     514            (yBinSource->data.S32[i] == yBinTarget) &&
     515            (xFlip->data.U8[i] == 0) &&
     516            (yFlip->data.U8[i] == 0)) {
     517            // Let someone else do the hard work
     518            psImageOverlaySection(mosaic, image, xTargetBase, yTargetBase, "+");
     519            continue;
     520        }
     521       
     522        // in the second case, there's a difference with the parities, but we don't have to
     523        // worry about binning
     524        if (xBinSource->data.S32[i] == xBinTarget && yBinSource->data.S32[i] == yBinTarget) {
    524525            switch (type) {
    525                 FILL_IN(F32);
    526                 FILL_IN(U8);
    527             default:
     526                COPY_WITH_PARITY_DIFFERENCE(F32);
     527                COPY_WITH_PARITY_DIFFERENCE(U8);
     528              default:
    528529                psAbort("Should never get here.\n");
    529530            }
    530 
    531         } // Various difficulty levels
     531            continue;
     532        }
     533       
     534        // In the third case, the images are flipped and have different binnnig.
     535        // We have to do all of the hard work ourselves
     536        switch (type) {
     537            FILL_IN(F32);
     538            FILL_IN(U8);
     539          default:
     540            psAbort("Should never get here.\n");
     541        }
    532542    } // Iterating over images
    533543
    534544    return mosaic;
    535545}
    536 
    537546
    538547// Add a cell and its various properties to the arrays
Note: See TracChangeset for help on using the changeset viewer.