IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 20, 2005, 1:21:05 PM (21 years ago)
Author:
gusciora
Message:

The code is in better shape than the release version. CalculateEquation
generates a resonably looking image kernel (to me) for POIS. However, for
ISIS kernels, we are generating NANs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/pmImageSubtract.c

    r4223 r4322  
    11/** @file  ImageSubtract.c
    2  *
    3  *  This file will ...
    4  *
    5  *  @author Paul Price, IfA (original prototype)
    6  *  @author GLG, MHPCC
    7  *
    8  *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2005-06-13 20:09:53 $
    10  *
    11  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    12  *
    13  *   XXX: sync with iFa on this:
    14  *   The (x, y) (row, col) issue is becoming a problem.  In this file, and I
    15  *   think, the rest of psLib and psModules, the following conventions are used:
    16  *
    17  * 1) x will correspond to the column, and y will correspond to the row.
    18  * 2) When used in function prototypes, the column (and hence x) appears
    19  *    first.
    20  * 3) When used to index 2-D arrays, obviously, the row (and hence, y)
    21  *    appears first. (2 and 3 are the source of confusion).
    22  * 4) When (u, v) are used in certain structures.
    23  *  u corresponds to x
    24  *  v corresponds to y
    25  * 5) When element (a, b) is casually referred to in comments, or
    26  *    documentation it is unclear where a is the row, or the column.
    27  * 6) A convention on loop index variables (i, j) would be convenient.
    28  *    Currently, sometimes i corresponds to the column (x),
    29  *    usually it corresponds to the row (y).
    30  *
    31  */
     2*
     3*  This file will ...
     4*
     5*  @author Paul Price, IfA (original prototype)
     6*  @author GLG, MHPCC
     7*
     8*  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
     9*  @date $Date: 2005-06-20 23:21:05 $
     10*
     11*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     12*
     13*   XXX: sync with iFa on this:
     14*   The (x, y) (row, col) issue is becoming a problem.  In this file, and I
     15*   think, the rest of psLib and psModules, the following conventions are used:
     16*
     17* 1) x will correspond to the column, and y will correspond to the row.
     18* 2) When used in function prototypes, the column (and hence x) appears
     19*    first.
     20* 3) When used to index 2-D arrays, obviously, the row (and hence, y)
     21*    appears first. (2 and 3 are the source of confusion).
     22* 4) When (u, v) are used in certain structures.
     23*  u corresponds to x
     24*  v corresponds to y
     25* 5) When element (a, b) is casually referred to in comments, or
     26*    documentation it is unclear where a is the row, or the column.
     27* 6) A convention on loop index variables (i, j) would be convenient.
     28*    Currently, sometimes i corresponds to the column (x),
     29*    usually it corresponds to the row (y).
     30*
     31*  XXX: The following variables are used an interpreted this way:
     32* kernelSize: Means that the actual kernel is a square (1 + 2 * kernelSize) per side.
     33* border: When accessing an image, a swath of pixels this wide is ignored.
     34* footprint: When accessing a stample, a square of pixels, footprint pixels per side,
     35*  are looked at.  We must ensure that (footprint+kernelSize) pixels exist
     36*  around the center.
     37*/
    3238
    3339#include<stdio.h>
     
    6066    pmStamp *stamp = (pmStamp*)psAlloc(sizeof(pmStamp));
    6167    stamp->x = 0;
     68    stamp->p_xSize = 0;
    6269    stamp->y = 0;
     70    stamp->p_ySize = 0;
    6371    stamp->matrix = NULL;
    6472    stamp->vector = NULL;
     
    311319                                 psS32 xNum,             ///< Number of stamps in x
    312320                                 psS32 yNum,             ///< Number of stamps in y
    313                                  psS32 border            ///< Border around image to ignore (should be size of kernel)
     321                                 psS32 border            ///< Border around image to ignore (should be size of kernel or larger)
    314322                                )
    315323{
     
    351359    // Iterate over the image sections
    352360    //
     361    // XXX: Must handle cases where image size is not an even multiple of xNum or yNum
     362    //
    353363    psS32 num = 0;
    354364    for (psS32 j = 0; j < yNum; j++) {
    355365        for (psS32 i = 0; i < xNum; i++) {
    356366            pmStamp *stamp = (pmStamp *) stamps->data[num];
    357 
    358367            //
    359368            // Only find a new stamp if we need to
     
    376385                psS32 numX = xNum;
    377386                psS32 numY = yNum;
    378                 for (psS32 y = border + j * (numCols - 2.0 * border) / numY;
    379                         y < border + (j + 1) * (numCols - 2.0 * border) / numY; y++) {
    380                     for (psS32 x = border + i * (numRows - 2.0 * border) / numX;
    381                             x < border + (i + 1) * (numRows - 2.0 * border) / numX; x++) {
    382 
    383                         // Determine if this pixel is larger than the max, and unmasked.
    384                         if (image->data.F32[y][x] > max) {
    385                             if ((mask == NULL) || !((mask->data.U8[y][x]) & maskVal)) {
    386                                 max = image->data.F32[y][x];
    387                                 bestx = x;
    388                                 besty = y;
     387                psS32 yMin = border + j * (numCols - 2.0 * border) / numY;
     388                psS32 yMax = (border + (j + 1) * (numCols - 2.0 * border) / numY) - 1;
     389                psS32 xMin = border + i * (numRows - 2.0 * border) / numX;
     390                psS32 xMax = (border + (i + 1) * (numRows - 2.0 * border) / numX) - 1;
     391
     392                if ((yMax >= image->numRows) ||
     393                        (xMax >= image->numCols) ||
     394                        (yMin < 0) ||
     395                        (xMin < 0)) {
     396                    // XXX: We skip this stamp since its borders extends beyond the image.
     397                    // XXX: This is here mainly as a safeguard.  We need to redefine the above
     398                    // min/max pixels calculation to ensure that all stamps are legitimate.
     399
     400                    stamp->x = -1;
     401                    stamp->y = -1;
     402                    stamp->status = PM_STAMP_NONE;
     403                } else {
     404                    stamp->p_xSize = 1 + (xMax - xMin);
     405                    stamp->p_ySize = 1 + (yMax - yMin);
     406                    stamp->p_xMin = xMin;
     407                    stamp->p_xMax = xMax;
     408                    stamp->p_yMin = yMin;
     409                    stamp->p_yMax = yMax;
     410
     411                    for (psS32 y = yMin; y <= yMax ; y++) {
     412                        for (psS32 x = xMin; x <= xMax ; x++) {
     413                            // Determine if this pixel is larger than the max, and unmasked.
     414                            if (image->data.F32[y][x] > max) {
     415                                if ((mask == NULL) || !((mask->data.U8[y][x]) & maskVal)) {
     416                                    max = image->data.F32[y][x];
     417                                    bestx = x;
     418                                    besty = y;
     419                                }
    389420                            }
    390421                        }
    391422                    }
    392                 }
    393 
    394                 //
    395                 // If the max pixel is larger than the threshold, we keep this stamp.
    396                 // Otherwise, mark the stamp as PM_STAMP_NONE
    397                 //
    398                 if (image->data.F32[besty][bestx] >= threshold) {
    399                     stamp->x = bestx;
    400                     stamp->y = besty;
    401                     stamp->status = PM_STAMP_RECALC;
    402                 } else {
    403                     stamp->x = bestx;
    404                     stamp->y = besty;
    405                     stamp->status = PM_STAMP_NONE;
     423
     424                    //
     425                    // If the max pixel is larger than the threshold, we keep this stamp.
     426                    // Otherwise, mark the stamp as PM_STAMP_NONE
     427                    //
     428                    if (image->data.F32[besty][bestx] >= threshold) {
     429                        stamp->x = bestx;
     430                        stamp->y = besty;
     431                        stamp->status = PM_STAMP_RECALC;
     432                    } else {
     433                        stamp->x = bestx;
     434                        stamp->y = besty;
     435                        stamp->status = PM_STAMP_NONE;
     436                    }
    406437                }
    407438            }
     
    472503    for (psS32 yy = -kernelSize ; yy < kernelSize ; yy++) {
    473504        for (psS32 xx = -kernelSize ; xx < kernelSize ; xx++) {
    474             //printf("HERE: (%d, %d)\n", yy, xx);
    475             //printf("HERE: (%d, %d)\n", yy+row, xx+col);
    476             //printf("HERE: (%d, %d)\n", yy-kernelSize, xx-kernelSize);
    477             //printf("KERNEL SIZE is %d\n", kernelSize);
    478505            conv += input->data.F32[yy+row][xx+col] *
    479506                    preCalc->data.F32[yy+kernelSize][xx+kernelSize] *
     
    513540        PS_ASSERT_VECTORS_SIZE_EQUAL(kernels->u, kernels->preCalc, false);
    514541    }
     542    psS32 kernelSize = kernels->p_size;
    515543    PS_ASSERT_INT_NONNEGATIVE(footprint, false);
     544    //
     545    // For each legitimate stamp, ensure that the footprint is small enough to perform
     546    // the full calculation.
     547    //
     548    // XXX: Verify with IfA that this is a reasonable action.
     549    //
     550    for (psS32 s = 0; s < stamps->n; s++) {
     551        pmStamp *stamp = (pmStamp *) stamps->data[s];
     552        if (stamp->status == PM_STAMP_RECALC) {
     553            // XXX: trace message
     554            // printf("stamp %d (x, y) is (%d, %d).  Footprint is %d.  kernelSize is %d.\n", s, stamp->x, stamp->y, footprint, kernelSize);
     555            if (((stamp->y - (footprint + kernelSize)) < 0) ||
     556                    ((stamp->x - (footprint + kernelSize)) < 0) ||
     557                    ((stamp->y + footprint + kernelSize) >= input->numRows) ||
     558                    ((stamp->x + footprint + kernelSize) >= input->numCols)) {
     559                stamp->status = PM_STAMP_NONE;
     560                psLogMsg(__func__, PS_LOG_WARN,
     561                         "WARNING: stamp %d will be ignored.  It exceeds image size: access columns (%d to %d) and rows (%d to %d)\n",
     562                         s,
     563                         stamp->x - (footprint + kernelSize),
     564                         (stamp->x + footprint + kernelSize) - 1,
     565                         stamp->y - (footprint + kernelSize),
     566                         (stamp->y + footprint + kernelSize) - 1);
     567            }
     568        }
     569    }
     570
    516571    psS32 numHalfRows = reference->numRows;
    517572    psS32 numHalfCols = reference->numCols;
     
    567622
    568623            psTrace("pmSubtractionCalculateEquation", 5, "subCalcEqn(): stamp %d: generated spatial order terms.\n", s);
     624
    569625            //
    570626            // Iterate over all pixels surrounding this stamp.
     
    572628            for (psS32 y = stamp->y - footprint; y < stamp->y + footprint; y++) {
    573629                for (psS32 x = stamp->x - footprint; x < stamp->x + footprint; x++) {
     630
    574631                    psF32 invNoise2 = 1.0/reference->data.F32[y][x]; // The inverse of the noise, squared.
    575632
     
    617674                                // testing, depending on kernel size and footprint.
    618675                                //
    619                                 //printf("footprint is %d\n", footprint);
    620                                 //printf("Stamp (%d, %d).\n", stamp->y, stamp->x);
    621                                 //printf("HERE (y, x) is (%d, %d).  (v2, u2) is (%d, %d).\n", y, x, v2, u2);
    622                                 //printf("HERE 00 (%d %d) (%d %d)\n", j2, i2, y-v2, x-u2);
    623                                 //
    624676                                // Second convolution
    625677                                //
    626678                                psF32 conv2 = polyValues->data.F64[j2][i2] *
    627679                                              reference->data.F32[y-v2][x-u2];
    628 
    629680                                //
    630681                                // Assuming that the first kernel component is 0 order in x and y, and 0 offset
     
    656707
    657708                    } else if (kernels->type == PM_SUBTRACTION_KERNEL_ISIS) {
    658                         //                        printf("XXX: put some warning message here (ISIS kernels not implemented).\n");
    659                         //                        return(false);
    660                         // XXX: HEY: code this
    661709                        for (psS32 k1 = 0; k1 < numKernels; k1++) {
    662710                            psF32 conv1 = GeneralKernelConvolve(reference, kernels, k1, x, y);
    663711
    664712                            for (psS32 k2 = k1; k2 < numKernels; k2++) {
     713                                //printf("(k1, k2) is (%d, %d)\n", k1, k2);
    665714                                psF32 conv2 = GeneralKernelConvolve(reference, kernels, k2, x, y);
    666 
    667715                                stampMatrix->data.F64[k1][k2] += conv1 * conv2 * invNoise2;
    668 
    669716                            }
    670717                            stampVector->data.F64[k1] += input->data.F32[y][x] * conv1 * invNoise2;
     
    705752            }
    706753            stamp->status = PM_STAMP_USED;
     754        } else {
     755            // Stamp is ignored since it's not PM_STAMP_RECALC
    707756        }
    708757    }
     
    721770{
    722771    PS_ASSERT_PTR_NON_NULL(stamps, NULL);
    723     PS_ASSERT_IMAGE_NON_NULL(((pmStamp *) stamps->data[0])->matrix, NULL);
    724     PS_ASSERT_VECTOR_NON_NULL(((pmStamp *) stamps->data[0])->vector, NULL);
    725     psS32 size = ((pmStamp *) stamps->data[0])->vector->n;
     772    psS32 size = -1;
     773    psS32 s = 0;
     774
     775    //
     776    // Determine the size of the stamp vectors and matrix.
     777    // We iterate until we find the first acceptable stamp.
     778    //
     779    while ((size == -1) && (s < stamps->n)) {
     780        pmStamp *stamp = (pmStamp *) stamps->data[s];
     781        PS_ASSERT_PTR_NON_NULL(stamp, NULL);
     782        if (stamp->status == PM_STAMP_USED) {
     783            size = ((pmStamp *) stamps->data[s])->vector->n;
     784            PS_ASSERT_INT_POSITIVE(size, NULL);
     785        }
     786        s++;
     787    }
     788    if (size == -1) {
     789        psLogMsg(__func__, PS_LOG_WARN, "WARNING: no acceptable stamps.  Returning NULL\n");
     790        return(NULL);
     791    }
    726792
    727793    if (solution != NULL) {
     
    732798    }
    733799
     800    //
     801    // Create the solution matrix and vector.
     802    //
     803    // XXX: Test these functions with size=-1.  This caused seg faults during test.
     804    //
    734805    psImage *sumMatrix = psImageAlloc(size, size, PS_TYPE_F64);
    735806    psVector *sumVector = psVectorAlloc(size, PS_TYPE_F64);
     
    737808    PS_IMAGE_SET_F64(sumMatrix, 0.0);
    738809
     810    //
     811    // Verify that all stamps have similar sizes.
     812    // Compute the sum matrix and vector.
     813    //
    739814    for (psS32 s = 0; s < stamps->n; s++) {
    740815        pmStamp *stamp = (pmStamp *) stamps->data[s];
    741         psImage *stampMatrix = stamp->matrix;
    742         psVector *stampVector = stamp->vector;
    743 
    744         PS_ASSERT_VECTOR_TYPE(stampVector, PS_TYPE_F64, NULL);
    745         PS_ASSERT_VECTOR_SIZE(stampVector, size, NULL);
    746         PS_ASSERT_IMAGE_TYPE(stampMatrix, PS_TYPE_F64, NULL);
    747         PS_ASSERT_IMAGE_SIZE(stampMatrix, size, size, NULL);
    748816
    749817        if (stamp->status == PM_STAMP_USED) {
     818            PS_ASSERT_INT_EQUAL(((pmStamp *) stamps->data[s])->vector->n, size, NULL);
     819
     820            psImage *stampMatrix = stamp->matrix;
     821            psVector *stampVector = stamp->vector;
     822            PS_ASSERT_VECTOR_TYPE(stampVector, PS_TYPE_F64, NULL);
     823            PS_ASSERT_VECTOR_SIZE(stampVector, size, NULL);
     824            PS_ASSERT_IMAGE_TYPE(stampMatrix, PS_TYPE_F64, NULL);
     825            PS_ASSERT_IMAGE_SIZE(stampMatrix, size, size, NULL);
     826
    750827            (void)psBinaryOp(sumMatrix, sumMatrix, "+", stampMatrix);
    751828            (void)psBinaryOp(sumVector, sumVector, "+", stampVector);
     
    753830    }
    754831
     832    // XXX: Check output from these routines.
    755833    psVector *permutation = NULL;
    756834    psImage *luMatrix = psMatrixLUD(NULL, &permutation, sumMatrix);
     
    9301008                                            solution, kernels, x, y);
    9311009            } else {
    932                 printf("XXX: Generate WARNING: unknown kernel type\n");
     1010                psLogMsg(__func__, PS_LOG_WARN, "WARNING: unknown kernel type.  Returning NULL\n");
    9331011                return(NULL);
    9341012            }
     
    10221100        psS32 y = stamp->y;               // Stamp y coord
    10231101        if (stamp->status == PM_STAMP_USED) {
     1102
    10241103            psRegion myReg = psRegionSet(x - xSize, x + xSize, y - ySize, y + ySize);
    10251104            psImage *refStamp = psImageSubset((psImage *) refImage, myReg);
     
    11821261    if (out != NULL) {
    11831262        if ((out->numCols < (1+2*kernelSize)) || (out->numRows < (1+2*kernelSize))) {
    1184             printf("XXX: generate WARNING: out image is not large enough.\n");
     1263            psLogMsg(__func__, PS_LOG_WARN, "WARNING: out image is not large enough.\n");
    11851264            return(out);
    11861265        }
     
    12221301            psS32 xOrder = (psS32) kernels->xOrder->data.F32[k];
    12231302            psS32 yOrder = (psS32) kernels->yOrder->data.F32[k];
    1224             psF32 polyVal = polyValues->data.F32[yOrder][xOrder];
    12251303            // XXX: Verify that this is correct.
    12261304
    12271305            out->data.F32[kernelSize - v][kernelSize - u]+=
    1228                 solution->data.F64[k] *
    1229                 polyValues->data.F64[yOrder][xOrder] *
    1230                 polyVal;
    1231             polyVal = polyVal;
     1306                solution->data.F64[k] * polyValues->data.F32[yOrder][xOrder];
    12321307        }
    12331308    }
Note: See TracChangeset for help on using the changeset viewer.