IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 14, 2004, 1:22:49 PM (22 years ago)
Author:
desonia
Message:

Added psImageRebin functionality.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/image/psImageManip.c

    r1205 r1216  
    1010 *  @author Ross Harman, MHPCC
    1111 *
    12  *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-07-09 21:48:07 $
     12 *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2004-07-14 23:22:49 $
    1414 *
    1515 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    1717#include <math.h>                      // for isfinite(), etc.
    1818#include <stdlib.h>
     19#include <stdbool.h>
    1920
    2021#include "psError.h"
    2122#include "psImage.h"
    22 
    23 int psImageClip(psImage* input,float min,float vmin,float max,float vmax)
     23#include "psStats.h"
     24#include "psMemory.h"
     25
     26bool getSpecifiedStatValue(const psStats* stats, double* value);
     27
     28int psImageClip(psImage* input, psF64 min, psF64 vmin, psF64 max, psF64 vmax)
    2429{
    2530    int numClipped = 0;
     
    4146    switch (input->type.type) {
    4247
    43         #define psImageClipCase(type)\
     48        #define psImageClipCase(type,typename) \
    4449    case PS_TYPE_##type: { \
     50            if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \
     51                psError(__func__, "Specified vmin (%g) is outside of image's " \
     52                        typename " pixel range", \
     53                        vmin); \
     54            } \
     55            if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \
     56                psError(__func__, "Specified vmax (%g) is outside of image's " \
     57                        typename " pixel range", \
     58                        vmax); \
     59            } \
    4560            ps##type minimum = (ps##type) min; \
    4661            ps##type maximum = (ps##type) max; \
     
    5974        } \
    6075        break;
    61         #define psImageClipCaseComplex(type)\
     76
     77        #define psImageClipCaseComplex(type,typename,absfcn)\
    6278    case PS_TYPE_##type: { \
     79            if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \
     80                psError(__func__, "Specified vmin (%g) is outside of image's " \
     81                        typename " pixel range", \
     82                        vmin); \
     83            } \
     84            if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \
     85                psError(__func__, "Specified vmax (%g) is outside of image's " \
     86                        typename " pixel range", \
     87                        vmax); \
     88            } \
    6389            for (unsigned int row = 0;row<numRows;row++) { \
    6490                ps##type* inputRow = input->data.type[row]; \
    6591                for (unsigned int col = 0; col < numCols; col++) { \
    66                     if (cabsf(inputRow[col]) < min) { \
     92                    if (absfcn(inputRow[col]) < min) { \
    6793                        inputRow[col] = (ps##type)vmin; \
    6894                        numClipped++; \
    69                     } else if (cabsf(inputRow[col]) > max) { \
     95                    } else if (absfcn(inputRow[col]) > max) { \
    7096                        inputRow[col] = (ps##type)vmax; \
    7197                        numClipped++; \
     
    76102        break;
    77103
    78         psImageClipCase(S8)
    79         psImageClipCase(S16)
    80         psImageClipCase(S32)
    81         psImageClipCase(S64)
    82         psImageClipCase(U8)
    83         psImageClipCase(U16)
    84         psImageClipCase(U32)
    85         psImageClipCase(U64)
    86         psImageClipCase(F32)
    87         psImageClipCase(F64)
    88         psImageClipCaseComplex(C32)
    89         psImageClipCaseComplex(C64)
     104        psImageClipCase(S8,"psS8")
     105        psImageClipCase(S16,"psS16")
     106        psImageClipCase(S32,"psS32")
     107        psImageClipCase(S64,"psS64")
     108        psImageClipCase(U8,"psU8")
     109        psImageClipCase(U16,"psU16")
     110        psImageClipCase(U32,"psU32")
     111        psImageClipCase(U64,"psU64")
     112        psImageClipCase(F32,"psF32")
     113        psImageClipCase(F64,"psF64")
     114        psImageClipCaseComplex(C32,"psC32",cabsf)
     115        psImageClipCaseComplex(C64,"psC64",cabs)
    90116
    91117    default:
     
    97123}
    98124
    99 int psImageClipNaN(psImage* input,float value)
     125int psImageClipNaN(psImage* input,psF64 value)
    100126{
    101127    int numClipped = 0;
     
    240266    return 0;
    241267}
     268
     269int psImageClipComplexRegion(psImage* input, psC64 min, psC64 vmin, psC64 max, psC64 vmax)
     270{
     271    int numClipped = 0;
     272    unsigned int numRows;
     273    unsigned int numCols;
     274    psF64 realMin = creal(min);
     275    psF64 imagMin = cimag(min);
     276    psF64 realMax = creal(max);
     277    psF64 imagMax = cimag(max);
     278
     279    if (input == NULL) {
     280        return 0;
     281    }
     282
     283    if ( realMax < realMin ) {
     284        psError(__func__,"psImageClipComplexRegion can not be invoked with "
     285                "max < min in the real image space.");
     286        return 0;
     287    }
     288    if ( imagMax < imagMin ) {
     289        psError(__func__,"psImageClipComplexRegion can not be invoked with "
     290                "max < min in the imaginary image space.");
     291        return 0;
     292    }
     293
     294    numRows = input->numRows;
     295    numCols = input->numCols;
     296
     297    switch (input->type.type) {
     298
     299        #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \
     300    case PS_TYPE_##type: { \
     301            if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \
     302                    realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \
     303                psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \
     304                        typename " pixel range", \
     305                        realfcn(vmin),imagfcn(vmin)); \
     306            } \
     307            if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \
     308                    realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \
     309                psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \
     310                        typename " pixel range", \
     311                        realfcn(vmax),imagfcn(vmax)); \
     312            } \
     313            for (unsigned int row = 0;row<numRows;row++) { \
     314                ps##type* inputRow = input->data.type[row]; \
     315                for (unsigned int col = 0; col < numCols; col++) { \
     316                    if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \
     317                        inputRow[col] = (ps##type)vmin; \
     318                        numClipped++; \
     319                    } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMax) ){ \
     320                        inputRow[col] = (ps##type)vmax; \
     321                        numClipped++; \
     322                    } \
     323                } \
     324            } \
     325        } \
     326        break;
     327
     328        psImageClipComplexRegionCase(C32,"psC32",crealf,cimagf)
     329        psImageClipComplexRegionCase(C64,"psC64",creal,cimag)
     330
     331    default:
     332        psError(__func__,"psImageClip does not support the given datatype (%d)",
     333                input->type.type);
     334    }
     335
     336    return numClipped;
     337}
     338
     339bool getSpecifiedStatValue(const psStats* stats, double* value)
     340{
     341
     342    switch (stats->options &
     343            ! (PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE | PS_STAT_ROBUST_FOR_SAMPLE)) {
     344    case PS_STAT_SAMPLE_MEAN:
     345        *value = stats->sampleMean;
     346        return true;
     347
     348    case PS_STAT_SAMPLE_MEDIAN:
     349        *value = stats->sampleMedian;
     350        return true;
     351
     352    case PS_STAT_SAMPLE_STDEV:
     353        *value = stats->sampleStdev;
     354        return true;
     355
     356    case PS_STAT_ROBUST_MEAN:
     357        *value = stats->robustMean;
     358        return true;
     359
     360    case PS_STAT_ROBUST_MEDIAN:
     361        *value = stats->robustMedian;
     362        return true;
     363
     364    case PS_STAT_ROBUST_MODE:
     365        *value = stats->robustMode;
     366        return true;
     367
     368    case PS_STAT_ROBUST_STDEV:
     369        *value = stats->robustStdev;
     370        return true;
     371
     372    case PS_STAT_CLIPPED_MEAN:
     373        *value = stats->clippedMean;
     374        return true;
     375
     376    case PS_STAT_CLIPPED_STDEV:
     377        *value = stats->clippedStdev;
     378        return true;
     379
     380    case PS_STAT_MAX:
     381        *value = stats->max;
     382        return true;
     383
     384    case PS_STAT_MIN:
     385        *value = stats->min;
     386        return true;
     387
     388    default:
     389        return false;
     390    }
     391}
     392
     393
     394psImage* psImageRebin(psImage* out,const psImage* in,unsigned int scale,const psStats* stats)
     395{
     396    int inRows;
     397    int inCols;
     398    int outRows;
     399    int outCols;
     400    psVector* vec;            // vector to hold the values of a single bin.
     401    psStats* myStats;
     402    double statVal;
     403
     404    if (in == NULL) {
     405        psError(__func__,"Input image is NULL.");
     406        return NULL;
     407    }
     408
     409    if (scale < 1) {
     410        psError(__func__,"The scale must be positive.");
     411        return NULL;
     412    }
     413
     414    if (stats == NULL) {
     415        psError(__func__,"The stats input can not be NULL.");
     416        return NULL;
     417    }
     418
     419    if (getSpecifiedStatValue(stats,&statVal) == false) {
     420        psError(__func__,"The stat options didn't specify a single supported statistic type.");
     421        return NULL;
     422    }
     423
     424    myStats = psAlloc(sizeof(psStats));
     425    *myStats = *stats;
     426
     427    vec = psVectorAlloc(scale*scale,in->type.type);
     428
     429    // create output image.
     430    inRows = in->numRows;
     431    inCols = in->numCols;
     432    outRows = (inRows+scale-1) / scale;   // round-up for remainders
     433    outCols = (inCols+scale-1) / scale;   // round-up for remainders
     434    out = psImageRecycle(out,outCols,outRows,in->type.type);
     435
     436    #define PS_IMAGE_REBIN_CASE(type) \
     437case PS_TYPE_##type: { \
     438        ps##type* vecData = vec->data.type; \
     439        for (int row = 0; row < outRows; row++) { \
     440            ps##type* outRowData = out->data.type[row]; \
     441            int inCurrentRow = row*scale; \
     442            int inNextRow = (row+1)*scale; \
     443            for (int col = 0; col < outCols; col++) { \
     444                int inCurrentCol = col*scale; \
     445                int inNextCol = (col+1)*scale; \
     446                int n = 0; \
     447                for (int inRow = inCurrentRow; inRow < inNextRow && inRow < inRows; inRow++) { \
     448                    ps##type* inRowData = in->data.type[inRow]; \
     449                    for (int inCol = inCurrentCol; inCol < inNextCol && inCol < inCols; inCol++) { \
     450                        vecData[n++] = inRowData[inCol]; \
     451                    } \
     452                } \
     453                vec->n = n; \
     454                myStats = psVectorStats(myStats,vec,NULL,0); \
     455                getSpecifiedStatValue(myStats,&statVal); \
     456                outRowData[col] = (ps##type)statVal; \
     457            } \
     458        } \
     459    } \
     460    break;
     461
     462    switch (in->type.type) {
     463        PS_IMAGE_REBIN_CASE(U8);
     464        PS_IMAGE_REBIN_CASE(U16);
     465        PS_IMAGE_REBIN_CASE(U32);
     466        PS_IMAGE_REBIN_CASE(U64);
     467        PS_IMAGE_REBIN_CASE(S8);
     468        PS_IMAGE_REBIN_CASE(S16);
     469        PS_IMAGE_REBIN_CASE(S32);
     470        PS_IMAGE_REBIN_CASE(S64);
     471        PS_IMAGE_REBIN_CASE(F32);
     472        PS_IMAGE_REBIN_CASE(F64);
     473        PS_IMAGE_REBIN_CASE(C32);
     474        PS_IMAGE_REBIN_CASE(C64);
     475    default:
     476        psError(__func__,"Input image type not supported.");
     477        psFree(out);
     478        out = NULL;
     479    }
     480
     481    psFree(vec);
     482    psFree(myStats);
     483
     484    return out;
     485}
Note: See TracChangeset for help on using the changeset viewer.