402 lines
11 KiB
C
402 lines
11 KiB
C
//////////////////////////////////////
|
|
// Cunren Liang, NASA JPL/Caltech
|
|
// Copyright 2017
|
|
//////////////////////////////////////
|
|
//update: add default value azpos_off = 0.0; 12-DEC-2019
|
|
//update: normalization of resampling kernals. 12-DEC-2019
|
|
|
|
|
|
#include "resamp.h"
|
|
|
|
#define SWAP4(a) (*(unsigned int *)&(a) = (((*(unsigned int *)&(a) & 0x000000ff) << 24) | ((*(unsigned int *)&(a) & 0x0000ff00) << 8) | ((*(unsigned int *)&(a) >> 8) & 0x0000ff00) | ((*(unsigned int *)&(a) >> 24) & 0x000000ff)))
|
|
|
|
void normalize_kernel(float *kernel, long start_index, long end_index);
|
|
|
|
int resamp(char *slc2, char *rslc2, char *rgoff_file, char *azoff_file, int nrg1, int naz1, int nrg2, int naz2, float prf, float *dopcoeff, float *rgcoef, float *azcoef, float azpos_off, int byteorder, long imageoffset, long lineoffset, int verbose){
|
|
/*
|
|
mandatory:
|
|
slc2: secondary image
|
|
rslc2: resampled secondary image
|
|
rgoff_file: range offset file. if no range offset file, specify fake
|
|
azoff_file: azimuth offset file. if no azimuth offset file, specify fake
|
|
nrg1: number of columns in reference image
|
|
naz1: number of lines in reference image
|
|
nrg2: number of columns in secondary image
|
|
naz2: number of lines in secondary image
|
|
prf: PRF of secondary image
|
|
dopcoeff[0]-[3]: Doppler centroid frequency coefficents
|
|
optional:
|
|
rgcoef[0]-[9]: range offset polynomial coefficents. First of two fit results of resamp_roi
|
|
azcoef[0]-[9]: azimuth offset polynomial coefficents. First of two fit results of resamp_roi
|
|
azpos_off: azimuth position offset. Azimuth line number (column 3) of first offset in culled offset file
|
|
|
|
byteorder: (0) LSB, little endian; (1) MSB, big endian of intput file
|
|
imageoffset: offset from start of the image of input file
|
|
lineoffset: length of each line of input file
|
|
*/
|
|
|
|
FILE *slc2fp;
|
|
FILE *rslc2fp;
|
|
FILE *rgoffp;
|
|
FILE *azoffp;
|
|
int rgflag;
|
|
int azflag;
|
|
//int nrg1;
|
|
//int naz1;
|
|
//int nrg2;
|
|
//int naz2;
|
|
//float prf;
|
|
//float dopcoeff[4];
|
|
//float rgcoef[10];
|
|
//float azcoef[10];
|
|
//float azpos_off;
|
|
float beta;
|
|
int n;
|
|
int m;
|
|
int interp_method;
|
|
int edge_method;
|
|
float rgpos;
|
|
float azpos;
|
|
float rgoff;
|
|
float azoff;
|
|
float rgoff1;
|
|
float azoff1;
|
|
float *rgoff2;
|
|
float *azoff2;
|
|
float rg2;
|
|
float az2;
|
|
int rgi2;
|
|
int azi2;
|
|
float rgf;
|
|
float azf;
|
|
int rgfn;
|
|
int azfn;
|
|
int hnm;
|
|
int hn;
|
|
float *sincc;
|
|
float *kaiserc;
|
|
float *kernel;
|
|
float *rgkernel;
|
|
float *azkernel;
|
|
fcomplex *azkernel_fc;
|
|
fcomplex *rgrs;
|
|
fcomplex *azca;
|
|
fcomplex *rgrsb;
|
|
fcomplex *azrs;
|
|
float *dop;
|
|
float dopx;
|
|
fcomplex **inb;
|
|
int i, j, k, k1, k2;
|
|
int tmp1, tmp2;
|
|
int zero_flag;
|
|
float ftmp1, ftmp2;
|
|
fcomplex fctmp1, fctmp2;
|
|
beta = 2.5;
|
|
n = 9;
|
|
m = 10000;
|
|
interp_method = 0;
|
|
edge_method = 0;
|
|
|
|
|
|
slc2fp = openfile(slc2, "rb");
|
|
rslc2fp = openfile(rslc2, "wb");
|
|
rgflag = 0;
|
|
azflag = 0;
|
|
if (strcmp(rgoff_file, "fake") == 0){
|
|
rgflag = 0;
|
|
printf("range offset file not provided\n");
|
|
}
|
|
else{
|
|
rgflag = 1;
|
|
rgoffp = openfile(rgoff_file, "rb");
|
|
}
|
|
if (strcmp(azoff_file, "fake") == 0){
|
|
azflag = 0;
|
|
printf("azimuth offset file not provided\n");
|
|
}
|
|
else{
|
|
azflag = 1;
|
|
azoffp = openfile(azoff_file, "rb");
|
|
}
|
|
//nrg1 = atoi(argv[5]);
|
|
//naz1 = atoi(argv[6]);
|
|
//nrg2 = atoi(argv[7]);
|
|
//naz2 = atoi(argv[8]);
|
|
//prf = atof(argv[9]);
|
|
//for(i = 0; i < 4; i++){
|
|
// dopcoeff[i] = atof(argv[10+i]);
|
|
//}
|
|
//for(i = 0; i < 10; i++){
|
|
// if(argc > 14 + i)
|
|
// rgcoef[i] = atof(argv[14+i]);
|
|
// else
|
|
// rgcoef[i] = 0.0;
|
|
//}
|
|
//for(i = 0; i < 10; i++){
|
|
// if(argc > 24 + i)
|
|
// azcoef[i] = atof(argv[24+i]);
|
|
// else
|
|
// azcoef[i] = 0.0;
|
|
//}
|
|
//if(argc > 34)
|
|
// azpos_off = atof(argv[34]);
|
|
//else
|
|
// azpos_off = 0.0;
|
|
if(verbose != 0){
|
|
printf("\n\ninput parameters:\n");
|
|
printf("slc2: %s\n", slc2);
|
|
printf("rslc2: %s\n", rslc2);
|
|
printf("rgoff_file: %s\n", rgoff_file);
|
|
printf("azoff_file: %s\n\n", azoff_file);
|
|
printf("nrg1: %d\n", nrg1);
|
|
printf("naz1: %d\n", naz1);
|
|
printf("nrg2: %d\n", nrg2);
|
|
printf("naz2: %d\n\n", naz2);
|
|
printf("prf: %f\n\n", prf);
|
|
for(i = 0; i < 4; i++){
|
|
printf("dopcoeff[%d]: %e\n", i, dopcoeff[i]);
|
|
}
|
|
printf("\n");
|
|
for(i = 0; i < 10; i++){
|
|
printf("rgcoef[%d]: %e\n", i, rgcoef[i]);
|
|
}
|
|
printf("\n");
|
|
for(i = 0; i < 10; i++){
|
|
printf("azcoef[%d]: %e\n", i, azcoef[i]);
|
|
}
|
|
printf("\n");
|
|
printf("azpos_off: %f\n\n", azpos_off);
|
|
|
|
if(byteorder == 0){
|
|
printf("inputfile byte order: little endian\n");
|
|
}
|
|
else{
|
|
printf("inputfile byte order: big endian\n");
|
|
}
|
|
printf("input file image offset [byte]: %ld\n", imageoffset);
|
|
printf("input file line offset [byte]: %ld\n", lineoffset);
|
|
}
|
|
|
|
if(imageoffset < 0){
|
|
fprintf(stderr, "image offset must be >= 0\n");
|
|
exit(1);
|
|
}
|
|
if(lineoffset < 0){
|
|
fprintf(stderr, "lineoffset offset must be >= 0\n");
|
|
exit(1);
|
|
}
|
|
|
|
hn = n / 2;
|
|
hnm = n * m / 2;
|
|
rgoff2 = array1d_float(nrg1);
|
|
azoff2 = array1d_float(nrg1);
|
|
sincc = vector_float(-hnm, hnm);
|
|
kaiserc = vector_float(-hnm, hnm);
|
|
kernel = vector_float(-hnm, hnm);
|
|
rgkernel = vector_float(-hn, hn);
|
|
azkernel = vector_float(-hn, hn);
|
|
azkernel_fc = vector_fcomplex(-hn, hn);
|
|
rgrs = vector_fcomplex(-hn, hn);
|
|
azca = vector_fcomplex(-hn, hn);
|
|
rgrsb = vector_fcomplex(-hn, hn);
|
|
azrs = array1d_fcomplex(nrg1);
|
|
dop = array1d_float(nrg2);
|
|
inb = array2d_fcomplex(naz2, nrg2);
|
|
sinc(n, m, sincc);
|
|
kaiser(n, m, kaiserc, beta);
|
|
for(i = -hnm; i <= hnm; i++)
|
|
kernel[i] = kaiserc[i] * sincc[i];
|
|
if(verbose != 0)
|
|
printf("\n");
|
|
for(i = 0; i < nrg2; i++){
|
|
dop[i] = dopcoeff[0] + dopcoeff[1] * i + dopcoeff[2] * i * i + dopcoeff[3] * i * i * i;
|
|
//get rid of this bad convention from roi_pac
|
|
//dop[i] *= prf;
|
|
if(verbose != 0)
|
|
if(i % 500 == 0)
|
|
printf("range sample: %5d, doppler centroid frequency: %8.2f Hz\n", i, dop[i]);
|
|
}
|
|
if(verbose != 0)
|
|
printf("\n");
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
//skip image header
|
|
fseek(slc2fp, imageoffset, SEEK_SET);
|
|
|
|
for(i = 0; i < naz2; i++){
|
|
if(i!=0)
|
|
fseek(slc2fp, lineoffset - (size_t)nrg2 * sizeof(fcomplex), SEEK_CUR);
|
|
readdata((fcomplex *)inb[i], (size_t)nrg2 * sizeof(fcomplex), slc2fp);
|
|
}
|
|
|
|
//read image data
|
|
//if(lineoffset == 0){
|
|
// readdata((fcomplex *)inb[0], (size_t)naz2 * (size_t)nrg2 * sizeof(fcomplex), slc2fp);
|
|
//}
|
|
//else{
|
|
// for(i = 0; i < naz2; i++){
|
|
// fseek(slc2fp, lineoffset, SEEK_CUR);
|
|
// readdata((fcomplex *)inb[i], (size_t)nrg2 * sizeof(fcomplex), slc2fp);
|
|
// }
|
|
//}
|
|
//swap bytes
|
|
if(byteorder!=0){
|
|
printf("swapping bytes...\n");
|
|
for(i = 0; i < naz2; i++)
|
|
for(j = 0; j < nrg2; j++){
|
|
SWAP4(inb[i][j].re);
|
|
SWAP4(inb[i][j].im);
|
|
}
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
for(i = 0; i < naz1; i++){
|
|
if((i + 1) % 100 == 0)
|
|
fprintf(stderr,"processing line: %6d of %6d\r", i+1, naz1);
|
|
if (rgflag == 1){
|
|
readdata((float *)rgoff2, nrg1 * sizeof(float), rgoffp);
|
|
}
|
|
if (azflag == 1){
|
|
readdata((float *)azoff2, nrg1 * sizeof(float), azoffp);
|
|
}
|
|
for(j = 0; j < nrg1; j++){
|
|
azrs[j].re = 0.0;
|
|
azrs[j].im = 0.0;
|
|
}
|
|
for(j = 0; j < nrg1; j++){
|
|
rgpos = j;
|
|
azpos = i - azpos_off;
|
|
rgoff1 = rgcoef[0] + azpos*(rgcoef[2] + \
|
|
azpos*(rgcoef[5] + azpos*rgcoef[9])) + \
|
|
rgpos*(rgcoef[1] + rgpos*(rgcoef[4] + \
|
|
rgpos*rgcoef[8])) + \
|
|
rgpos*azpos*(rgcoef[3] + azpos*rgcoef[6] + \
|
|
rgpos*rgcoef[7]);
|
|
azoff1 = azcoef[0] + azpos*(azcoef[2] + \
|
|
azpos*(azcoef[5] + azpos*azcoef[9])) + \
|
|
rgpos*(azcoef[1] + rgpos*(azcoef[4] + \
|
|
rgpos*azcoef[8])) + \
|
|
rgpos*azpos*(azcoef[3] + azpos*azcoef[6] + \
|
|
rgpos*azcoef[7]);
|
|
if (rgflag == 1){
|
|
rgoff = rgoff1 + rgoff2[j];
|
|
}
|
|
else{
|
|
rgoff = rgoff1;
|
|
}
|
|
if (azflag == 1){
|
|
azoff = azoff1 + azoff2[j];
|
|
}
|
|
else{
|
|
azoff = azoff1;
|
|
}
|
|
rg2 = j + rgoff;
|
|
az2 = i + azoff;
|
|
rgi2 = roundfi(rg2);
|
|
azi2 = roundfi(az2);
|
|
rgf = rg2 - rgi2;
|
|
azf = az2 - azi2;
|
|
rgfn = roundfi(rgf * m);
|
|
azfn = roundfi(azf * m);
|
|
for(k = -hn; k <= hn; k++){
|
|
tmp1 = k * m - rgfn;
|
|
tmp2 = k * m - azfn;
|
|
if(tmp1 > hnm) tmp1 = hnm;
|
|
if(tmp2 > hnm) tmp2 = hnm;
|
|
if(tmp1 < -hnm) tmp1 = -hnm;
|
|
if(tmp2 < -hnm) tmp2 = -hnm;
|
|
rgkernel[k] = kernel[tmp1];
|
|
azkernel[k] = kernel[tmp2];
|
|
}
|
|
normalize_kernel(rgkernel, -hn, hn);
|
|
normalize_kernel(azkernel, -hn, hn);
|
|
for(k1 = -hn; k1 <= hn; k1++){
|
|
rgrs[k1].re = 0.0;
|
|
rgrs[k1].im = 0.0;
|
|
if(edge_method == 0){
|
|
if(azi2 < hn || azi2 > naz2 - 1 - hn || rgi2 < hn || rgi2 > nrg2 - 1 - hn){
|
|
continue;
|
|
}
|
|
}
|
|
else if(edge_method == 1){
|
|
if(azi2 < 0 || azi2 > naz2 - 1 || rgi2 < 0 || rgi2 > nrg2 - 1){
|
|
continue;
|
|
}
|
|
}
|
|
else{
|
|
if(azi2 < -hn || azi2 > naz2 - 1 + hn || rgi2 < -hn || rgi2 > nrg2 - 1 + hn){
|
|
continue;
|
|
}
|
|
}
|
|
for(k2 = -hn; k2 <= hn; k2++){
|
|
if(azi2 + k1 < 0 || azi2 + k1 > naz2 - 1 || rgi2 + k2 < 0 || rgi2 + k2 > nrg2 - 1)
|
|
continue;
|
|
rgrs[k1].re += inb[azi2 + k1][rgi2 + k2].re * rgkernel[k2];
|
|
rgrs[k1].im += inb[azi2 + k1][rgi2 + k2].im * rgkernel[k2];
|
|
}
|
|
}
|
|
for(k = -hn; k <= hn; k++){
|
|
if(rgrs[k].re == 0.0 && rgrs[k].im == 0.0)
|
|
continue;
|
|
dopx = dopcoeff[0] + dopcoeff[1] * rg2 + dopcoeff[2] * rg2 * rg2 + dopcoeff[3] * rg2 * rg2 * rg2;
|
|
//get rid of this bad convention from roi_pac
|
|
//dopx *= prf;
|
|
ftmp1 = 2.0 * PI * dopx * k / prf;
|
|
azca[k].re = cos(ftmp1);
|
|
azca[k].im = sin(ftmp1);
|
|
if(interp_method == 0){
|
|
rgrsb[k] = cmul(rgrs[k], cconj(azca[k]));
|
|
azrs[j].re += rgrsb[k].re * azkernel[k];
|
|
azrs[j].im += rgrsb[k].im * azkernel[k];
|
|
}
|
|
else{
|
|
azkernel_fc[k].re = azca[k].re * azkernel[k];
|
|
azkernel_fc[k].im = azca[k].im * azkernel[k];
|
|
azrs[j] = cadd(azrs[j], cmul(rgrs[k], azkernel_fc[k]));
|
|
}
|
|
}
|
|
if(interp_method == 0){
|
|
ftmp1 = 2.0 * PI * dopx * azf / prf;
|
|
fctmp1.re = cos(ftmp1);
|
|
fctmp1.im = sin(ftmp1);
|
|
azrs[j] = cmul(azrs[j], fctmp1);
|
|
}
|
|
}
|
|
writedata((fcomplex *)azrs, nrg1 * sizeof(fcomplex), rslc2fp);
|
|
}
|
|
fprintf(stderr,"processing line: %6d of %6d\n", naz1, naz1);
|
|
free_array1d_float(rgoff2);
|
|
free_array1d_float(azoff2);
|
|
free_vector_float(sincc, -hnm, hnm);
|
|
free_vector_float(kaiserc, -hnm, hnm);
|
|
free_vector_float(kernel, -hnm, hnm);
|
|
free_vector_float(rgkernel, -hn, hn);
|
|
free_vector_float(azkernel, -hn, hn);
|
|
free_vector_fcomplex(azkernel_fc, -hn, hn);
|
|
free_vector_fcomplex(rgrs, -hn, hn);
|
|
free_vector_fcomplex(azca, -hn, hn);
|
|
free_vector_fcomplex(rgrsb, -hn, hn);
|
|
free_array1d_fcomplex(azrs);
|
|
free_array1d_float(dop);
|
|
free_array2d_fcomplex(inb);
|
|
fclose(slc2fp);
|
|
fclose(rslc2fp);
|
|
if (rgflag == 1){
|
|
fclose(rgoffp);
|
|
}
|
|
if (azflag == 1){
|
|
fclose(azoffp);
|
|
}
|
|
return 0;
|
|
}
|
|
void normalize_kernel(float *kernel, long start_index, long end_index){
|
|
double sum;
|
|
long i;
|
|
sum = 0.0;
|
|
for(i = start_index; i <= end_index; i++)
|
|
sum += kernel[i];
|
|
if(sum!=0)
|
|
for(i = start_index; i <= end_index; i++)
|
|
kernel[i] /= sum;
|
|
}
|