IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 4, 2007, 12:42:02 PM (19 years ago)
Author:
Paul Price
Message:

Reworking image interpolation to work on mask and variance image
simultaneously with the proper image. Working in the idea of having
"good", "bad" and "poor" output mask pixels (taken from Andy Becker),
where "poor" pixels have at least one bad input pixel contributing to
the flux, but the contribution is small (where 'small' is defined by a
user option). To handle all the options, created a
psImageInterpolateOptions structure, which contains all the things
which are constant while looping over an image (including the input
image, variance and mask). Changed function name, and split code out
of psImage.[ch] into its own file. Function returns boolean error
status; output values for image, variance and mask come from pointers
to double. Added interpolation types (GAUSS, LANCZOS2, LANCZOS3,
LANCZOS4). Using a fairly general framework so that additional
interpolation methods might be easily added. Updated tests and other
dependent code. Tests pass (but only test BILINEAR and BICUBE), and
pswarp works (but currently only uses BILINEAR).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/imageops/psImageGeomManip.c

    r12431 r12741  
    1010 *  @author Ross Harman, MHPCC
    1111 *
    12  *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2007-03-14 00:39:50 $
     12 *  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2007-04-04 22:42:02 $
    1414 *
    1515 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    3333#include "psMemory.h"
    3434#include "psAssert.h"
    35 
     35#include "psImageInterpolate.h"
    3636#include "psCoord.h"
    3737
     
    200200    }
    201201
    202     if (mode > PS_INTERPOLATE_LANCZOS4_VARIANCE ) {
    203         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    204                 _("Specified interpolation mode, %d, is unsupported."),
    205                 mode);
    206         psFree(out);
    207         return NULL;
    208     }
    209 
    210202    // create an output image of the same size
    211203    // and type
     
    213205    outCols = in->numCols * scale;
    214206    invScale = 1.0f / (float)scale;
     207
     208    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, in, NULL, NULL, 0,
     209                                                                       NAN, NAN, 0, 0, 0);
    215210
    216211    #define PSIMAGE_RESAMPLE_CASE(TYPE) \
     
    221216            float inRow = (float)row * invScale; \
    222217            for (psS32 col=0;col<outCols;col++) { \
    223                 rowData[col] = psImagePixelInterpolate(in,(float)col*invScale,inRow,NULL,0,0,mode); \
     218                double value; \
     219                if (!psImageInterpolate(&value, NULL, NULL, (float)col*invScale, inRow, interp)) { \
     220                    psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     221                    psFree(interp); \
     222                    psFree(out); \
     223                    return NULL; \
     224                } \
     225                rowData[col] = value; \
    224226            } \
    225227        }  \
     
    249251    }
    250252
     253    psFree(interp);
     254
    251255    return out;
    252256}
     
    492496        float CenterYMinusminXTimesSinT = centerY - minX * sinT;
    493497
    494         #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \
     498        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, input, NULL, NULL, 0,
     499                                                                           exposed, NAN, 0, 0, 0.0);
     500
     501        #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE)  \
     502          case PS_TYPE_##TYPE: { \
    495503            if (exposed < PS_MIN_##TYPE || \
    496504                    exposed > PS_MAX_##TYPE || \
     
    515523                outRow = out->data.TYPE[y]; \
    516524                for (psS32 x = 0; x < outCols; x++) { \
    517                     outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(input,inX,inY,NULL,0,exposed); \
     525                    double value; \
     526                    if (!psImageInterpolate(&value, NULL, NULL, inX, inY, interp)) { \
     527                        psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     528                        psFree(out); \
     529                        psFree(interp); \
     530                        return NULL; \
     531                    } \
     532                    outRow[x] = value; \
    518533                    inX += cosT; \
    519534                    inY -= sinT; \
    520535                } \
    521536            } \
    522         }
    523 
    524         #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \
    525     case PS_INTERPOLATE_##MODE: \
    526         switch (type) { \
    527         case PS_TYPE_U8: \
    528             PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \
    529537            break; \
    530         case PS_TYPE_U16: \
    531             PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \
    532             break; \
    533         case PS_TYPE_U32:   /* Not a requirement */ \
    534             PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \
    535             break; \
    536         case PS_TYPE_U64:   /* Not a requirement */ \
    537             PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \
    538             break;  \
    539         case PS_TYPE_S8: \
    540             PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \
    541             break; \
    542         case PS_TYPE_S16: \
    543             PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \
    544             break; \
    545         case PS_TYPE_S32:   /* Not a requirement */ \
    546             PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \
    547             break; \
    548         case PS_TYPE_S64:   /* Not a requirement */ \
    549             PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \
    550             break; \
    551         case PS_TYPE_F32: \
    552             PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \
    553             break; \
    554         case PS_TYPE_F64: \
    555             PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \
    556             break; \
    557         default: { \
    558                 char* typeStr; \
    559                 PS_TYPE_NAME(typeStr,type); \
    560                 psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    561                         _("Specified psImage type, %s, is not supported."), \
    562                         typeStr); \
    563                 psFree(out); \
    564                 out = NULL; \
    565             } \
    566         } \
    567         break;
    568 
    569         switch (mode) {
    570             PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT);
    571             PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR);
    572             PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR_VARIANCE);
    573         default:
    574             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    575                     _("Specified interpolation mode, %d, is unsupported."),
    576                     mode);
    577             psFree(out);
    578             out = NULL;
    579         }
     538        }
     539
     540        switch (type) {
     541            PSIMAGE_ROTATE_ARBITRARY_LOOP(U8);
     542            PSIMAGE_ROTATE_ARBITRARY_LOOP(U16);
     543            PSIMAGE_ROTATE_ARBITRARY_LOOP(U32);
     544            PSIMAGE_ROTATE_ARBITRARY_LOOP(U64);
     545            PSIMAGE_ROTATE_ARBITRARY_LOOP(S8);
     546            PSIMAGE_ROTATE_ARBITRARY_LOOP(S16);
     547            PSIMAGE_ROTATE_ARBITRARY_LOOP(S32);
     548            PSIMAGE_ROTATE_ARBITRARY_LOOP(S64);
     549            PSIMAGE_ROTATE_ARBITRARY_LOOP(F32);
     550            PSIMAGE_ROTATE_ARBITRARY_LOOP(F64);
     551          default: {
     552              char* typeStr;
     553              PS_TYPE_NAME(typeStr,type);
     554              psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     555                      _("Specified psImage type, %s, is not supported."),
     556                      typeStr);
     557              psFree(out);
     558              psFree(interp);
     559              out = NULL;
     560          }
     561        }
     562
     563        psFree(interp);
     564
    580565    }
    581566
     
    695680    out = psImageRecycle(out, outCols, outRows, type);
    696681
    697     #define PSIMAGE_SHIFT_CASE(MODE,TYPE) \
     682    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, input, NULL, NULL, 0,
     683                                                                       exposed, NAN, 0, 0, 0.0);
     684
     685    #define PSIMAGE_SHIFT_CASE(TYPE) \
    698686case PS_TYPE_##TYPE: \
    699687    if (exposed < PS_MIN_##TYPE || \
     
    719707        for (psS32 col=0;col<outCols;col++) { \
    720708            float x = col + 0.5 - dx; \
    721             outRow[col] = p_psImagePixelInterpolate##MODE##_##TYPE( \
    722                           input,x,y,NULL,0,exposed); \
     709            double value; \
     710            if (!psImageInterpolate(&value, NULL, NULL, x, y, interp)) { \
     711                psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     712                psFree(interp); \
     713                psFree(out); \
     714                return NULL; \
     715            } \
     716            outRow[col] = value; \
    723717        } \
    724718    } \
    725719    break;
    726720
    727     #define PSIMAGE_SHIFT_ARBITRARY_CASE(MODE) \
    728 case PS_INTERPOLATE_##MODE: \
    729     switch (input->type.type) { \
    730         PSIMAGE_SHIFT_CASE(MODE,U8);  \
    731         PSIMAGE_SHIFT_CASE(MODE,U16); \
    732         PSIMAGE_SHIFT_CASE(MODE,U32);     /* Not a requirement */ \
    733         PSIMAGE_SHIFT_CASE(MODE,U64);     /* Not a requirement */ \
    734         PSIMAGE_SHIFT_CASE(MODE,S8);  \
    735         PSIMAGE_SHIFT_CASE(MODE,S16); \
    736         PSIMAGE_SHIFT_CASE(MODE,S32);    /* Not a requirement */ \
    737         PSIMAGE_SHIFT_CASE(MODE,S64);    /* Not a requirement */ \
    738         PSIMAGE_SHIFT_CASE(MODE,F32); \
    739         PSIMAGE_SHIFT_CASE(MODE,F64); \
    740        \
    741     default: { \
    742             char* typeStr; \
    743             PS_TYPE_NAME(typeStr,type); \
    744             psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    745                     _("Specified psImage type, %s, is not supported."), \
    746                     typeStr); \
    747             psFree(out); \
    748             out = NULL; \
    749         } \
    750     } \
    751     break;
    752 
    753     // EAM: added BICUBE
    754     switch (mode) {
    755         PSIMAGE_SHIFT_ARBITRARY_CASE(FLAT);
    756         PSIMAGE_SHIFT_ARBITRARY_CASE(BILINEAR);
    757         PSIMAGE_SHIFT_ARBITRARY_CASE(BILINEAR_VARIANCE);
    758         PSIMAGE_SHIFT_ARBITRARY_CASE(BICUBE);
    759     default:
    760         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    761                 _("Specified interpolation mode, %d, is unsupported."),
    762                 mode);
    763         psFree(out);
    764         out = NULL;
    765     }
    766 
     721    switch (input->type.type) {
     722        PSIMAGE_SHIFT_CASE(U8);
     723        PSIMAGE_SHIFT_CASE(U16);
     724        PSIMAGE_SHIFT_CASE(U32);
     725        PSIMAGE_SHIFT_CASE(U64);
     726        PSIMAGE_SHIFT_CASE(S8);
     727        PSIMAGE_SHIFT_CASE(S16);
     728        PSIMAGE_SHIFT_CASE(S32);
     729        PSIMAGE_SHIFT_CASE(S64);
     730        PSIMAGE_SHIFT_CASE(F32);
     731        PSIMAGE_SHIFT_CASE(F64);
     732      default: {
     733          char* typeStr;
     734          PS_TYPE_NAME(typeStr,type);
     735          psError(PS_ERR_BAD_PARAMETER_TYPE, true, _("Specified psImage type, %s, is not supported."),
     736                  typeStr);
     737          psFree(out);
     738          psFree(interp);
     739          return NULL;
     740        }
     741    }
     742
     743    psFree(interp);
    767744    return out;
    768745}
     
    866843
    867844    // loop through the output image using the domain above and transform
    868     // each output pixel to input coordinates and use psImagePixelInterpolate
     845    // each output pixel to input coordinates and use psImageInterpolate
    869846    // to determine the pixel value.
    870847    psPlane outPosition;
    871848    psPlane* inPosition = NULL;
    872849
    873     #define PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
     850    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, input, NULL, inputMask,
     851                                                                       inputMaskVal, NAN, NAN, 0, 0, 0.0);
     852
     853
     854    #define PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE) \
    874855    /* apply the transform to get the position in the input image */ \
    875856    inPosition = psPlaneTransformApply(inPosition, outToIn, &outPosition); \
     
    882863    } \
    883864    /* interpolate the cooresponding input pixel to get the output pixel value. */ \
    884     ps##TYPE value = p_psImagePixelInterpolate##MODE##_##TYPE(input, \
    885                      inPosition->x, inPosition->y, \
    886                      inputMask, inputMaskVal, NAN); \
     865    double value; \
     866    if (!psImageInterpolate(&value, NULL, NULL, inPosition->x, inPosition->y, interp)) { \
     867        psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     868        psFree(output); \
     869        psFree(interp); \
     870        return NULL; \
     871    } \
    887872    /*    psFree(inPosition); */\
    888873    if (isnan(value)) { \
     
    893878    } \
    894879
    895     #define PSIMAGE_TRANSFORM_LOOP(TYPE, MODE) { \
     880    #define PSIMAGE_TRANSFORM_CASE(TYPE) \
     881      case PS_TYPE_##TYPE: { \
    896882        for (int row = 0; row < numRows; row++) { \
    897883            outPosition.y = row+row0; \
     
    899885            for (int col = 0; col < numCols; col++) { \
    900886                outPosition.x = col+col0; \
    901                 PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
     887                PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE) \
    902888                outputData[col] = value; \
    903889            } \
    904890        } \
    905     }
    906 
    907     #define PSIMAGE_TRANSFORM_FROMLIST(TYPE, MODE) { \
    908         int n = pixels->n; \
    909         for (int i= 0; i < n; i++) { \
    910             int x = pixels->data[i].x; \
    911             int y = pixels->data[i].y; \
    912             if (x >= col0 && x < col1 && y >= row0 && y < row1) { \
    913                 outPosition.x = x; \
    914                 outPosition.y = y; \
    915                 PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
    916                 output->data.TYPE[y][x] = value; \
    917             } \
    918         } \
    919     }
    920 
    921     #define PSIMAGE_TRANSFORM_CASE(MODE) \
    922 case PS_INTERPOLATE_##MODE: \
    923     switch (type) { \
    924     case PS_TYPE_F32: \
    925         PSIMAGE_TRANSFORM_LOOP(F32,MODE); \
    926891        break; \
    927     case PS_TYPE_F64: \
    928         PSIMAGE_TRANSFORM_LOOP(F64,MODE); \
    929         break; \
    930     default: { \
    931             char* typeStr; \
    932             PS_TYPE_NAME(typeStr,type); \
    933             psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    934                     _("Specified psImage type, %s, is not supported."), \
    935                     typeStr); \
    936             psFree(output); \
    937             return NULL; \
    938         } \
    939     } \
    940     break;
    941 
    942     switch (mode) {
    943         PSIMAGE_TRANSFORM_CASE(FLAT);
    944         PSIMAGE_TRANSFORM_CASE(BILINEAR);
    945         PSIMAGE_TRANSFORM_CASE(BILINEAR_VARIANCE);
    946     default:
    947         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    948                 _("Specified interpolation mode, %d, is unsupported."),
    949                 mode);
    950         psFree(output);
    951         return NULL;
     892    }
     893
     894    switch (type) {
     895        PSIMAGE_TRANSFORM_CASE(F32);
     896        PSIMAGE_TRANSFORM_CASE(F64);
     897      default: {
     898          char* typeStr;
     899          PS_TYPE_NAME(typeStr,type);
     900          psError(PS_ERR_BAD_PARAMETER_TYPE, true, _("Specified psImage type, %s, is not supported."),
     901                  typeStr);
     902          psFree(output);
     903          psFree(inPosition);
     904          return NULL;
     905      }
    952906    }
    953907
Note: See TracChangeset for help on using the changeset viewer.