318 lines
10 KiB
C
318 lines
10 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include "defines.h"
|
|
|
|
typedef struct {
|
|
int x,y;} Xpoint;
|
|
|
|
int ii[2][MAX_CRAB], jj[2][MAX_CRAB]; /* arrays for keeping locations of points for crabgrass */
|
|
int nn[2]; /* array containing lengths of the ping-pong lists */
|
|
int npu; /* number of points unwrapped */
|
|
Xpoint bridge[2]; /* bridge for phase unwrapping */
|
|
|
|
void crab_step(unsigned char **, float **, int, int, int) ;
|
|
void dmphsm(char*, char*, int*, int*, int*, int*);
|
|
|
|
unsigned char *fbf;
|
|
|
|
/**
|
|
* Phase unwrapping grass
|
|
*
|
|
* @param intFilename interferogram filename
|
|
* @param flagFilename phase unwrapping flag filename
|
|
* @param unwFilename unwrapped phase output filename
|
|
* @param width number of samples per row
|
|
* @param start starting line (default=1)
|
|
* @param xmin starting range pixel offset
|
|
* @param xmax last range pixel offset
|
|
* @param ymin starting azimuth row offset
|
|
* @param ymax last azimuth row offset
|
|
* @param xinit starting range pixel for unwrapping
|
|
* @param yinit starint row for unwrapping
|
|
*/
|
|
int
|
|
grass(char *intFilename, char *flagFilename, char *unwFilename, int width, int start, int xmin, int xmax, int ymin, int ymax, int xinit, int yinit)
|
|
{
|
|
double frac; /* fraction of image which was unwrapped */
|
|
double p_min,p_max; /* minimum and maximum phase values */
|
|
float *buf, *buf_out; /* single row complex data, output line */
|
|
float **phase, *ph; /* phase array for unwrapping */
|
|
int nlines; /* number of lines in the file */
|
|
int xw,yh; /* width, height of processed region */
|
|
int offs; /* offset number of lines to read from start of file*/
|
|
int i,j; /* loop counters */
|
|
int m; /* current ping-pong list */
|
|
int pp=0; /* ping-pong counter */
|
|
int ppd; /* ping-pong iteration for display */
|
|
int ww, wh, cv_width, cv_height;
|
|
unsigned char **gzw, *fbf; /* set of pointers to the rows of flag array */
|
|
FILE *int_file, *flag_file, *unw_file;
|
|
|
|
if (xmax <= 0) {
|
|
xmax=width-1; /* default value of xmax */
|
|
} else if (xmax > width-1) {
|
|
xmax=width-1; /* check that xmax within bounds */
|
|
}
|
|
|
|
|
|
int_file = fopen(intFilename,"r");
|
|
if (int_file == NULL){
|
|
fprintf(stderr, "interferogram file does not exist!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
flag_file = fopen(flagFilename,"r+");
|
|
if (flag_file == NULL){
|
|
fprintf(stderr, "flag file does not exist!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
unw_file = fopen(unwFilename,"w");
|
|
if (unw_file == NULL){
|
|
fprintf(stderr, "cannot create magnitude/upwrapped phase file!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
fseek(int_file, 0L, REL_EOF); /* determine # lines in the file */
|
|
nlines=(int)ftell(int_file)/(width*8);
|
|
fprintf(stderr,"# interferogram lines: %d\n",nlines);
|
|
rewind(int_file);
|
|
|
|
if (ymax <= 0) {
|
|
ymax=nlines-start; /* default value of ymax */
|
|
} else if (ymax > nlines-start) {
|
|
ymax = nlines-start;
|
|
fprintf(stderr,"insufficient #lines in the file, ymax: %d\n",ymax);
|
|
}
|
|
|
|
|
|
xw=xmax-xmin+1; /* width of each line to process */
|
|
yh=ymax-ymin+1; /* height of array */
|
|
offs=start+ymin-1; /* first line of file to start reading/writing */
|
|
fprintf(stderr,"array width,height (x,y), starting line: %6d %6d %6d \n",xw,yh,offs);
|
|
|
|
if (xinit < 0 ) {
|
|
xinit = xmin+xw/2; /* default position to start phase unwrapping */
|
|
}
|
|
if (yinit < 0) {
|
|
yinit = ymin+yh/2; /* default position to start phase unwrapping */
|
|
}
|
|
// Initialize seed location here if xinit and yinit were passed in
|
|
fprintf(stderr,"initial seed location (x,y): %6d %6d \n",xinit,yinit);
|
|
|
|
/******************* Allocate space *********************/
|
|
|
|
ph = (float *) malloc(sizeof(float)*width*yh);
|
|
if(ph == (float *) NULL) {
|
|
fprintf(stderr,"failure to allocate space for phase array\n");
|
|
exit(-1) ;
|
|
}
|
|
|
|
buf = (float *)malloc(2*sizeof(float)*width);
|
|
if(buf == (float *) NULL) {
|
|
fprintf(stderr,"failure to allocate space for input line buffer\n");
|
|
exit(-1) ;
|
|
}
|
|
|
|
buf_out = (float *) malloc(2*sizeof(float)*width);
|
|
if(buf_out == (float *) NULL) {
|
|
fprintf(stderr,"failure to allocate space output line buffer\n");
|
|
exit(-1) ;
|
|
}
|
|
|
|
fbf = (unsigned char *) malloc(sizeof(unsigned char)*width*yh);
|
|
if(fbf == (unsigned char *) NULL) {
|
|
fprintf(stderr,"failure to allocate space for flag array\n");
|
|
exit(-1) ;
|
|
}
|
|
|
|
gzw = (unsigned char **)malloc(sizeof(unsigned char *) * yh); /* allocate flag pointers */
|
|
phase = (float **)malloc(sizeof(float *) * yh); /* allocate phase pointers */
|
|
|
|
/**************** Read interferogram ******************/
|
|
|
|
fprintf(stderr,"initializing phase array values...\n");
|
|
|
|
for (i=0; i < yh; i++){ /* clear phase array */
|
|
for (j=0; j < width; j++){
|
|
ph[i*width+j]=0.;
|
|
}
|
|
}
|
|
|
|
fprintf(stdout,"reading interferogram...\n");
|
|
fseek(int_file, offs*width*2*sizeof(float), REL_BEGIN); /*seek starting line */
|
|
|
|
for(i=0; i < yh; i++) {
|
|
fread((char *)buf, sizeof(float), 2*width, int_file); /* read next line */
|
|
if(i%100 == 0){
|
|
fprintf(stdout,"\rinterferogram input line %d", i);
|
|
fflush(stdout);
|
|
}
|
|
for(j=0; j < width; j++){
|
|
if((buf[2*j]==0.) && (buf[2*j+1]==0.)) ph[i*width+j]=0.; /* phase undefined */
|
|
else ph[i*width+j] = atan2((double)buf[2*j+1],(double)buf[2*j]);
|
|
}
|
|
}
|
|
|
|
for (i=0; i < yh; i++){ /* set-up pointers for phase data */
|
|
phase[i] = (float *)(ph + i*width + xmin);
|
|
}
|
|
|
|
/**************** Read in flag data *******************/
|
|
|
|
|
|
fseek(flag_file, offs*width*sizeof(unsigned char), REL_BEGIN);
|
|
|
|
fprintf(stderr,"\nreading flag file...\n");
|
|
fread((char *)fbf, sizeof(unsigned char), width*yh, flag_file);
|
|
|
|
for (i=0; i< yh; i++){
|
|
gzw[i] = (unsigned char *)(fbf + i*width + xmin);
|
|
}
|
|
|
|
cv_height=yh;
|
|
cv_width=width;
|
|
ww=Min(WIN_WIDTH_MAX,cv_width+SCROLL_WIDTH);
|
|
wh=Min(WIN_HEIGHT_MAX,cv_height+SCROLL_WIDTH);
|
|
|
|
/**************** Initialize crabgrass *****************/
|
|
while((gzw[yinit][xinit]&CUT) != 0) { /*initial point cannot be on a cut */
|
|
xinit++;
|
|
yinit++;
|
|
}
|
|
|
|
fprintf(stderr,"actual seed location (x,y): %d %d\n",xinit,yinit);
|
|
|
|
ii[0][0]=yinit; /* initialize list with the seed */
|
|
jj[0][0]=xinit;
|
|
nn[0]=1; /* initial list length */
|
|
npu=0; /* number of pixels unwrapped */
|
|
m=0; /* current ping-pong list */
|
|
/*fprintf(stderr,"enter interation number for flag display: ");
|
|
scanf("%d",&ppd);*/
|
|
ppd = 10000;
|
|
/**************** Grow crabgrass ***********************/
|
|
|
|
while(nn[m] != 0) { /* continue as long as list not zero length */
|
|
crab_step(gzw, phase, yh,xw, m);
|
|
m=1-m; /* ping-pong */
|
|
if (pp%50 == 0){
|
|
fprintf(stderr,"\rping-pong interation, list size %d %d", pp, nn[m]);
|
|
}
|
|
if(pp == ppd){
|
|
/* dmphsm(argv[1], (char *)fbf, &cv_width, &cv_height, &ww, &wh);
|
|
fprintf(stderr,"\nenter next interation number for flag display: ");
|
|
scanf("%d",&ppd);*/
|
|
}
|
|
pp++; /* increment ping-pong step counter */
|
|
}
|
|
|
|
/* dmphsm(argv[1], (char *)fbf, &cv_width, &cv_height, &ww, &wh); */
|
|
fprintf(stderr,"\ntotal ping-pong interations %d\n", pp);
|
|
frac = npu/(float)(xw*yh);
|
|
fprintf(stderr,"fraction of the image unwrapped: %8.5f\n",frac);
|
|
p_min=p_max=0.0;
|
|
|
|
for(i=0; i < yh; i++){ /* determine min and max phase values */
|
|
for(j=0; j < xw; j++) {
|
|
if(phase[i][j] < p_min) p_min=phase[i][j];
|
|
if(phase[i][j] > p_max) p_max=phase[i][j];
|
|
}
|
|
}
|
|
|
|
printf("minimum phase, maximum phase: %12.3f %12.3f\n",p_min,p_max);
|
|
printf("phase difference: %12.3f \n",p_max-p_min);
|
|
|
|
/************** write out unwrapped phase **************/
|
|
for (i=0; i < width; i++) { /* generate NULL line */
|
|
buf[i]=0.;
|
|
buf[i+width]=0.;
|
|
}
|
|
|
|
fprintf(stderr,"writing output file...\n");
|
|
|
|
for (i=0; i< ymin; i++){ /* clear out ymin lines */
|
|
fwrite((char *)buf, sizeof(float), 2*width, unw_file);
|
|
}
|
|
|
|
fseek(int_file, offs*width*2*sizeof(float), REL_BEGIN); /*seek starting line */
|
|
|
|
for (i=0; i < yh; i++){
|
|
fread((char *)buf, sizeof(float), 2*width, int_file); /* read next line */
|
|
if (i%100 == 0) fprintf(stderr,"\routput line: %d", i);
|
|
|
|
|
|
for (j=0; j< width; j++){
|
|
if ((j >= xmin) && (j <= xmax) && ((gzw[i][j-xmin]&LAWN) != 0)){ /* check if on the LAWN too */
|
|
buf_out[j] = hypot((double)buf[2*j],(double)buf[2*j+1]);
|
|
buf_out[j+width] = phase[i][j-xmin]; /* take into account pointer offsets */
|
|
}
|
|
else {
|
|
buf_out[j]=0.;
|
|
buf_out[j+width]=0.;
|
|
}
|
|
}
|
|
fwrite((char *)buf_out,sizeof(float),2*width, unw_file);
|
|
|
|
|
|
}
|
|
fprintf(stdout,"\nwriting flag file...\n");
|
|
fseek(flag_file, offs*width*sizeof(unsigned char), REL_BEGIN); /*seek starting line */
|
|
fwrite((char *)fbf, sizeof(unsigned char), yh*width, flag_file);
|
|
|
|
fclose(int_file);
|
|
fclose(flag_file);
|
|
fclose(unw_file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void crab_step(unsigned char **gzw, float **phase, int data_w, int data_h, int m)
|
|
{
|
|
int i,j,k,l,i1,j1;
|
|
double u;
|
|
static int dir_x[]={ 0, 0,-1, 1};
|
|
static int dir_y[]={-1, 1, 0, 0};
|
|
|
|
if(nn[m]==0) return; /* if list zero length */
|
|
nn[1-m]=0; /* initialize new list length */
|
|
|
|
for(k=0; k < nn[m]; k++) { /* go through the list, growing around each pixel if possible */
|
|
i=ii[m][k];
|
|
j=jj[m][k];
|
|
|
|
/* if( (gzw[i][j] & (CUT)) == 0) { */ /* CUT?, don't grow cuts*/
|
|
|
|
if( (gzw[i][j] & (CUT | LSNR) ) == 0) { /*CUT or LSNR?, don't grow cuts, or LSNR regions */
|
|
|
|
u=(double)phase[i][j];
|
|
|
|
for(l=0; l< 4; l++) { /* check neighbors */
|
|
i1=i+dir_x[l];
|
|
j1=j+dir_y[l];
|
|
if((i1 < 0)||(i1 >= data_w) || (j1<0) || (j1 >= data_h)) continue; /* check boundries */
|
|
if((gzw[i1][j1] & LAWN) != 0) continue; /* check if already grown */
|
|
npu++; /* increment number of pixels grown */
|
|
phase[i1][j1] += TWO_PI*nint((u-(double)phase[i1][j1])/TWO_PI); /* unwrap the phase */
|
|
gzw[i1][j1] |=LAWN; /* set pixel flag as grown */
|
|
|
|
if(nn[1-m] < MAX_CRAB) {
|
|
ii[1-m][nn[1-m]]=i1; /* place this pixel onto the new list */
|
|
jj[1-m][nn[1-m]]=j1;
|
|
nn[1-m]++; /* increment the length counter of the new list */
|
|
}
|
|
else {
|
|
fprintf(stderr,"warning: subroutine crab_step, crab_grass table over flow\n");
|
|
return; /* grow the new list */
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|