⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snaphu_util.c

📁 phase unwrapping algorithm for SAR interferometry
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************  snaphu utility function source file  Written by Curtis W. Chen  Copyright 2002 Board of Trustees, Leland Stanford Jr. University  Please see the supporting documentation for terms of use.  No warranty.*************************************************************************/#include <stdio.h>#include <stdlib.h>#include <math.h>#include <signal.h>#include <limits.h>#include <float.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include "snaphu.h"/* function: IsTrue() * ------------------ * Returns TRUE if the string input is any of TRUE, True, true, 1,  * y, Y, yes, YES */int IsTrue(char *str){  if(!strcmp(str,"TRUE") || !strcmp(str,"true") || !strcmp(str,"True")     || !strcmp(str,"1") || !strcmp(str,"y") || !strcmp(str,"Y")     || !strcmp(str,"yes") || !strcmp(str,"YES") || !strcmp(str,"Yes")){    return(TRUE);  }else{    return(FALSE);  }}/* function: IsFalse() * ------------------ * Returns FALSE if the string input is any of FALSE, False, false,  * 0, n, N, no, NO */int IsFalse(char *str){  if(!strcmp(str,"FALSE") || !strcmp(str,"false") || !strcmp(str,"False")     || !strcmp(str,"0") || !strcmp(str,"n") || !strcmp(str,"N")     || !strcmp(str,"no") || !strcmp(str,"NO") || !strcmp(str,"No")){    return(TRUE);  }else{    return(FALSE);  }}/* function: SetBoolenaSignedChar() * -------------------------------- * Sets the value of a signed character based on the string argument passed. * Returns TRUE if the string was not a valid value, FALSE otherwise. */signed char SetBooleanSignedChar(signed char *boolptr, char *str){  if(IsTrue(str)){    (*boolptr)=TRUE;    return(FALSE);  }else if(IsFalse(str)){    (*boolptr)=FALSE;    return(FALSE);  }  return(TRUE);}/* function: ModDiff() * ------------------- * Computes floating point difference between two numbers. * f1 and f2 should be between [0,2pi).  The result is the  * modulo difference between (-pi,pi].  Assumes that * PI and TWOPI have been defined.   */  double ModDiff(double f1, double f2){  double f3;  f3=f1-f2;  if(f3>PI){    f3-=TWOPI;  }else if(f3<=-PI){    f3+=TWOPI;  }  return(f3);}/* function: WrapPhase() * --------------------- * Makes sure the passed float array is properly wrapped into the [0,2pi) * interval. */void WrapPhase(float **wrappedphase, long nrow, long ncol){  long row, col;  for(row=0;row<nrow;row++){    for(col=0;col<ncol;col++){      wrappedphase[row][col]-=TWOPI*floor(wrappedphase[row][col]/TWOPI);    }  }}/* function: CalcWrappedRangeDiffs() * --------------------------------- * Computes an array of wrapped phase differences in range (across rows). * Input wrapped phase array should be in radians.  Output is in cycles. */void CalcWrappedRangeDiffs(float **dpsi, float **avgdpsi, float **wrappedphase,			   long kperpdpsi, long kpardpsi,			   long nrow, long ncol){  long row, col;  float **paddpsi;  for(row=0;row<nrow;row++){    for(col=0;col<ncol-1;col++){      dpsi[row][col]=(wrappedphase[row][col+1]-wrappedphase[row][col])/TWOPI;      if(dpsi[row][col]>=0.5){	dpsi[row][col]-=1.0;      }else if(dpsi[row][col]<-0.5){	dpsi[row][col]+=1.0;      }    }  }  paddpsi=MirrorPad(dpsi,nrow,ncol-1,(kperpdpsi-1)/2,(kpardpsi-1)/2);  if(paddpsi==dpsi){    fprintf(sp0,"Wrapped-gradient averaging box too large "	    "for input array size\nAbort\n");    exit(ABNORMAL_EXIT);  }  BoxCarAvg(avgdpsi,paddpsi,nrow,ncol-1,kperpdpsi,kpardpsi);  Free2DArray((void **)paddpsi,nrow+kperpdpsi-1);}/* function: CalcWrappedAzDiffs() * --------------------------------- * Computes an array of wrapped phase differences in range (across rows). * Input wrapped phase array should be in radians.  Output is in cycles. */void CalcWrappedAzDiffs(float **dpsi, float **avgdpsi, float **wrappedphase,			long kperpdpsi, long kpardpsi, long nrow, long ncol){  long row, col;  float **paddpsi;  for(row=0;row<nrow-1;row++){    for(col=0;col<ncol;col++){      dpsi[row][col]=(wrappedphase[row][col]-wrappedphase[row+1][col])/TWOPI;      if(dpsi[row][col]>=0.5){	dpsi[row][col]-=1.0;      }else if(dpsi[row][col]<-0.5){	dpsi[row][col]+=1.0;      }    }  }  paddpsi=MirrorPad(dpsi,nrow-1,ncol,(kpardpsi-1)/2,(kperpdpsi-1)/2);  if(paddpsi==dpsi){    fprintf(sp0,"Wrapped-gradient averaging box too large "	    "for input array size\nAbort\n");    exit(ABNORMAL_EXIT);  }  BoxCarAvg(avgdpsi,paddpsi,nrow-1,ncol,kpardpsi,kperpdpsi);  Free2DArray((void **)paddpsi,nrow-1+kpardpsi-1);}/* function: CycleResidue() * ------------------------ * Computes the cycle array of a phase 2D phase array. Input arrays  * should be type float ** and signed char ** with memory pre-allocated.   * Numbers of rows and columns in phase array should be passed.   * Residue array will then have size nrow-1 x ncol-1.  Residues will * always be -1, 0, or 1 if wrapped phase is passed in. */void CycleResidue(float **phase, signed char **residue, 		  int nrow, int ncol){  int row, col;  float **rowdiff, **coldiff;  rowdiff=(float **)Get2DMem(nrow-1,ncol,sizeof(float *),sizeof(float));  coldiff=(float **)Get2DMem(nrow,ncol-1,sizeof(float *),sizeof(float));  for(row=0;row<nrow-1;row++){    for(col=0;col<ncol;col++){      rowdiff[row][col]=ModDiff(phase[row+1][col],phase[row][col]);    }  }  for(row=0;row<nrow;row++){    for(col=0;col<ncol-1;col++){      coldiff[row][col]=ModDiff(phase[row][col+1],phase[row][col]);    }  }  for(row=0;row<nrow-1;row++){    for(col=0;col<ncol-1;col++){      residue[row][col]=(signed char)LRound((coldiff[row][col]					     +rowdiff[row][col+1]					     -coldiff[row+1][col]					     -rowdiff[row][col])/TWOPI);    }  }  Free2DArray((void **)rowdiff,nrow-1);  Free2DArray((void **)coldiff,nrow);}/* function: CalcFlow() * -------------------- * Calculates flow based on unwrapped phase data in a 2D array.   * Allocates memory for row and column flow arrays. */void CalcFlow(float **phase, short ***flowsptr, long nrow, long ncol){  long row, col;  /* get memory for flow arrays */  if((*flowsptr)==NULL){    (*flowsptr)=(short **)Get2DRowColMem(nrow,ncol,					 sizeof(short *),sizeof(short));  }  /* get row flows (vertical phase differences) */  for(row=0;row<nrow-1;row++){    for(col=0;col<ncol;col++){      (*flowsptr)[row][col]=(short)LRound((phase[row][col]-phase[row+1][col])					 /TWOPI);    }  }    /* get col flows (horizontal phase differences) */  for(row=0;row<nrow;row++){    for(col=0;col<ncol-1;col++){      (*flowsptr)[nrow-1+row][col]=(short)LRound((phase[row][col+1]						  -phase[row][col])						 /TWOPI);    }  }}/* function: IntegratePhase() * -------------------------- * This function takes row and column flow information and integrates * wrapped phase to create an unwrapped phase field.  The unwrapped * phase field will be the same size as the wrapped field.  The array * rowflow should have size N-1xM and colflow size NxM-1 where the  * phase fields are NxM.  Output is saved to a file. */void IntegratePhase(float **psi, float **phi, short **flows,		    long nrow, long ncol){  long row, col;  short **rowflow, **colflow;  rowflow=flows;  colflow=&(flows[nrow-1]);   /* set first element as seed */  phi[0][0]=psi[0][0];  /* integrate over first row */  for(col=1;col<ncol;col++){    phi[0][col]=phi[0][col-1]+(ModDiff(psi[0][col],psi[0][col-1])      +colflow[0][col-1]*TWOPI);  }  /* integrate over columns */  for(row=1;row<nrow;row++){    for(col=0;col<ncol;col++){      phi[row][col]=phi[row-1][col]+(ModDiff(psi[row][col],psi[row-1][col])	-rowflow[row-1][col]*TWOPI);    }  }}/* end IntegratePhase() *//* function: ExtractFlow() * ----------------------- * Given an unwrapped phase array, parse the data and find the flows. * Assumes only integer numbers of cycles have been added to get the  * unwrapped phase from the wrapped pase.  Gets memory and writes  * wrapped phase to passed pointer.  Assumes flows fit into short ints. */float **ExtractFlow(float **unwrappedphase, short ***flowsptr, 		    long nrow, long ncol){      long row, col;  float **wrappedphase;    /* get memory for wrapped phase array */  wrappedphase=(float **)Get2DMem(nrow,ncol,sizeof(float *),sizeof(float));  /* calculate wrapped phase */  for(row=0;row<nrow;row++){    for(col=0;col<ncol;col++){      /* fmod() gives wrong results here (maybe because of float argument?) */      /* wrappedphase[row][col]=fmod(unwrappedphase[row][col],TWOPI); */      wrappedphase[row][col]=unwrappedphase[row][col]	-TWOPI*floor(unwrappedphase[row][col]/TWOPI);    }  }  /* calculate flows */  CalcFlow(unwrappedphase,flowsptr,nrow,ncol);  /* return pointer to wrapped phase array */  return(wrappedphase);}/* function: FlipPhaseArraySign() * ------------------------------ * Flips the sign of all values in a passed array if the flip flag is set. * Otherwise, does nothing. */void FlipPhaseArraySign(float **arr, paramT *params, long nrow, long ncol){  long row, col;  if(params->flipphasesign){    for(row=0;row<nrow;row++){      for(col=0;col<ncol;col++){	arr[row][col]*=-1;      }    }  }}/* function: FlipFlowArraySign() * ------------------------------ * Flips the sign of all values in a row-by-column array if the flip * flip flag is set.  Otherwise, does nothing. */void FlipFlowArraySign(short **arr, paramT *params, long nrow, long ncol){  long row, col, maxcol;  if(params->flipphasesign){    for(row=0;row<2*nrow-1;row++){      if(row<nrow-1){	maxcol=ncol;      }else{	maxcol=ncol-1;      }      for(col=0;col<maxcol;col++){	arr[row][col]=-arr[row][col];      }    }  }}/* function: Get2DMem() * -------------------- * Allocates memory for 2D array. * Dynamically allocates memory and returns pointer of * type void ** for an array of size nrow x ncol.   * First index is row number: array[row][col] * size is size of array element, psize is size of pointer * to array element (eg sizeof(float *)). */void **Get2DMem(int nrow, int ncol, int psize, size_t size){  int row;  void **array;  if((array=malloc(nrow*psize))==NULL){    fprintf(sp0,"Out of memory\n");     exit(ABNORMAL_EXIT);  }  for(row=0; row<nrow; row++){    if((array[row]=malloc(ncol*size))==NULL){      fprintf(sp0,"Out of memory\n");      exit(ABNORMAL_EXIT);    }  }  return(array);}/* function: Get2DRowColMem() * -------------------------- * Allocates memory for 2D array.  The array will have 2*nrow-1 rows. * The first nrow-1 rows will have ncol columns, and the rest will * have ncol-1 columns. */void **Get2DRowColMem(long nrow, long ncol, int psize, size_t size){  long row;  void **array;  if((array=malloc((2*nrow-1)*psize))==NULL){    fprintf(sp0,"Out of memory\n");     exit(ABNORMAL_EXIT);  }  for(row=0; row<nrow-1; row++){    if((array[row]=malloc(ncol*size))==NULL){      fprintf(sp0,"Out of memory\n");      exit(ABNORMAL_EXIT);    }  }  for(row=nrow-1; row<2*nrow-1; row++){    if((array[row]=malloc((ncol-1)*size))==NULL){      fprintf(sp0,"Out of memory\n");      exit(ABNORMAL_EXIT);    }  }  return(array);}/* function: Get2DRowColZeroMem() * ------------------------------ * Allocates memory for 2D array.  The array will have 2*nrow-1 rows. * The first nrow-1 rows will have ncol columns, and the rest will * have ncol-1 columns.  Memory is initialized to zero. */void **Get2DRowColZeroMem(long nrow, long ncol, int psize, size_t size){  long row;  void **array;  if((array=malloc((2*nrow-1)*psize))==NULL){    fprintf(sp0,"Out of memory\n");     exit(ABNORMAL_EXIT);  }  for(row=0; row<nrow-1; row++){    if((array[row]=calloc(ncol,size))==NULL){      fprintf(sp0,"Out of memory\n");      exit(ABNORMAL_EXIT);    }  }  for(row=nrow-1; row<2*nrow-1; row++){    if((array[row]=calloc((ncol-1),size))==NULL){      fprintf(sp0,"Out of memory\n");      exit(ABNORMAL_EXIT);    }  }  return(array);}/* function: MAlloc() * -------------------- * Has same functionality as malloc(), but exits if out of memory. */void *MAlloc(size_t size){  void *ptr;  if((ptr=malloc(size))==NULL){    fprintf(sp0,"Out of memory\n");    exit(ABNORMAL_EXIT);  }  return(ptr);}/* function: CAlloc() * ------------------ * Has same functionality as calloc(), but exits if out of memory. */void *CAlloc(size_t nitems, size_t size){    void *ptr;    if((ptr=calloc(nitems,size))==NULL){    fprintf(sp0,"Out of memory\n");    exit(ABNORMAL_EXIT);  }  return(ptr);}/* function: ReAlloc() * ------------------- * Has same functionality as realloc(), but exits if out of memory. */void *ReAlloc(void *ptr, size_t size){    void *ptr2;    if((ptr2=realloc(ptr,size))==NULL){    fprintf(sp0,"Out of memory\n");    exit(ABNORMAL_EXIT);  }  return(ptr2);}/* function: Free2DArray() * ----------------------- * This function frees the dynamically allocated memory for a 2D * array.  Pass in a pointer to a pointer cast to a void **. * The function assumes the array is of the form arr[rows][cols] * so that nrow is the number of elements in the pointer array. */void Free2DArray(void **array, unsigned int nrow){  int row;  for(row=0; row<nrow; row++){    free(array[row]);  }  free(array);}/* function: Set2DShortArray() * ------------------------- * Sets all entries of a 2D array of shorts to the given value.  Assumes * that memory is already allocated. */void Set2DShortArray(short **arr, long nrow, long ncol, long value){  long row, col;  for(row=0;row<nrow;row++){    for(col=0;col<ncol;col++){      arr[row][col]=value;    }  }}/* function: ValidDataArray() * -------------------------- * Given a 2D floating point array, returns FALSE if any elements are NaN * or infinite, and TRUE otherwise (uses math library finite() function). */signed char ValidDataArray(float **arr, long nrow, long ncol){  long row, col;  for(row=0;row<nrow;row++){    for(col=0;col<ncol;col++){      if(!IsFinite(arr[row][col])){	return(FALSE);      }    }  }  return(TRUE);}/* function: IsFinite() * -------------------- * This function takes a double and returns a nonzero value if  * the arguemnt is finite (not NaN and not infinite), and zero otherwise. * Different implementations are given here since not all machines have * these functions available.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -