home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vis-ftp.cs.umass.edu
/
vis-ftp.cs.umass.edu.tar
/
vis-ftp.cs.umass.edu
/
pub
/
Software
/
ASCENDER
/
ascendMar8.tar
/
UMass
/
BoldtNew
/
LLVS
/
signal2D.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-31
|
9KB
|
368 lines
/***********************************************************************
* Signal2D.c - convolution with a 2d template
* Author: Xiao-Guang Wang
* Modifications:
* 2/20/95 - Bob Collins, added new convolution functions for
* different input and output types.
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "signal2D.h"
void free_signal_2D(Signal_2D * psignal)
{
if((psignal->xwidth > 0) && (psignal->xwidth > 0)) free(psignal->value);
psignal->xwidth = 0;
psignal->ywidth = 0;
psignal->xbase = 0;
psignal->ybase = 0;
}
Bool read_signal_2D(char * filename, Signal_2D * psignal)
/*
Read the 2D signal from a file.
*/
{
int j, i;
FILE * fp;
double * dpvalue;
fp = fopen(filename, "r");
if(! fp)
{
printf("template file open error.\n");
return(FALSE);
}
fscanf(fp, "%d %d", (& psignal->xwidth), (& psignal->ywidth));
psignal->xbase = psignal->xwidth / 2;
psignal->ybase = psignal->ywidth / 2;
psignal->value = (double *)malloc( psignal->xwidth * psignal->ywidth
* sizeof(double));
dpvalue = psignal->value;
for(i = 0; i < psignal->ywidth; i ++)
{
for(j = 0; j < psignal->xwidth; j ++)
{
fscanf(fp, "%lf", dpvalue);
dpvalue ++;
}
}
fclose(fp);
return(TRUE);
}
Bool write_signal_2D(char * filename, Signal_2D * psignal)
/*
Write the 2D signal into a file.
*/
{
int j, i;
FILE * fp;
double * dpvalue;
fp = fopen(filename, "w");
if(! fp)
{
printf("template file open error.\n");
return(FALSE);
}
dpvalue = psignal->value;
for(i = 0; i < psignal->ywidth; i ++)
{
for(j = 0; j < psignal->xwidth; j ++)
{
dpvalue ++;
}
fprintf(fp, "\n");
}
fclose(fp);
return(TRUE);
}
#define Signal_value_significance 0.1
/*
void get_signal_2D_gaussian(double sd, Signal_2D * pgaussian)
{
int i;
double * list;
int list_length = 0;
double numerator, denominator;
double next_value;
double sum;
/the middle value/
append_list((char **) & list, & list_length, sizeof(double));
list[0] = 1.0;
/if sd is too small, the gaussian becomes an impulse/
if(sd > Small_double)
{
denominator = 2.0 * sd * sd;
numerator = (double)list_length * list_length;
next_value = exp(- (numerator / denominator));
/other values/
while(next_value > (list[0] * Signal_value_significance))
{
append_list((char **) & list, & list_length, sizeof(double));
list[list_length - 1] = next_value;
numerator = (double)list_length * list_length;
next_value = exp(- (numerator / denominator));
}
}
/write to the template/
pgaussian->width = (2 * list_length) - 1;
pgaussian->base = list_length - 1;
pgaussian->value = (double *)malloc(pgaussian->width * sizeof(double));
pgaussian->value[(pgaussian->width - 1) / 2] = list[0];
for(i = 1; i < (pgaussian->width + 1) / 2; i ++)
{
pgaussian->value[((pgaussian->width - 1) / 2) - i] = list[i];
pgaussian->value[((pgaussian->width - 1) / 2) + i] = list[i];
}
free_list((char **) & list, & list_length);
/normalize/
sum = 0;
for(i = 0; i < pgaussian->width; i ++)
{
sum += pgaussian->value[i];
}
for(i = 0; i < pgaussian->width; i ++)
{
pgaussian->value[i] /= sum;
}
}
*/
Bool signal_2D_convolve_edgecut(short * psignal, int xsize, int ysize,
Signal_2D * ptemplate, short ** ppresult)
/*
This function convolve the psignal with the ptemplate, and write the
result to presult. For image borders, this function cuts the edge. That is,
only part of the template (the part that is in the signal) are multiplied
with the signal. presult has the same size as psignal, and is allocated in
this function. Note: the template is not inverted in this convolution.
*/
{
int l, k, j, i;
int n, m;
double sum;
short * dpsignal;
double * dptempvalue;
short * presult;
short * dpresult;
presult = (short *)malloc(xsize * ysize * sizeof(short));
if(presult == NULL)
{
printf("presult allocation error in convolution.\n");
return(FALSE);
}
dpresult = presult;
for(i = 0; i < ysize; i ++)
{
for(j = 0; j < xsize; j ++)
{
sum = 0;
for(k = 0; k < ptemplate->ywidth; k ++)
{
m = i + (k - ptemplate->ybase);
if((m >= 0) && (m < ysize))
{
dpsignal = psignal + (m * xsize);
dptempvalue = ptemplate->value + (k * ptemplate->xwidth);
for(l = 0; l < ptemplate->xwidth; l ++)
{
n = j + (l - ptemplate->xbase);
if((n >= 0) && (n < xsize))
{
sum += ((* (dptempvalue + l)) * (* (dpsignal + n)));
}
} /*l*/
}
} /*k*/
(* dpresult) = (short)sum;
dpresult ++;
} /*j*/
} /*i*/
(* ppresult) = presult;
return(TRUE);
}
Bool shortIn_floatOut_signal_2D_convolve_edgecut(short * psignal,
int xsize, int ysize, Signal_2D * ptemplate, float * ppresult)
/*
Same as signal_2D_convolve_edgecut, but produces floating point output.
*/
{
int l, k, j, i;
int n, m;
double sum;
short * dpsignal;
double * dptempvalue;
float * dpresult;
/* Memory allocation for result is done prior to this function --BobC
presult = (float *)malloc(xsize * ysize * sizeof(float));
if(presult == NULL)
{
printf("presult allocation error in convolution.\n");
return(FALSE);
}
*/
dpresult = ppresult;
for(i = 0; i < ysize; i ++)
{
for(j = 0; j < xsize; j ++)
{
sum = 0;
for(k = 0; k < ptemplate->ywidth; k ++)
{
m = i + (k - ptemplate->ybase);
if((m >= 0) && (m < ysize))
{
dpsignal = psignal + (m * xsize);
dptempvalue = ptemplate->value + (k * ptemplate->xwidth);
for(l = 0; l < ptemplate->xwidth; l ++)
{
n = j + (l - ptemplate->xbase);
if((n >= 0) && (n < xsize))
{
sum += ((* (dptempvalue + l)) * (* (dpsignal + n)));
}
} /*l*/
}
} /*k*/
(* dpresult) = (float)sum;
dpresult ++;
} /*j*/
} /*i*/
return(TRUE);
}
Bool byteIn_floatOut_signal_2D_convolve_edgecut(Byte * psignal,
int xsize, int ysize, Signal_2D * ptemplate, float * ppresult)
/*
Same as signal_2D_convolve_edgecut, but byte input and floating point output
*/
{
int l, k, j, i;
int n, m;
double sum;
Byte * dpsignal;
double * dptempvalue;
float * dpresult;
/* Memory allocation for result is done prior to this function --BobC
presult = (float *)malloc(xsize * ysize * sizeof(float));
if(presult == NULL)
{
printf("presult allocation error in convolution.\n");
return(FALSE);
}
*/
dpresult = ppresult;
for(i = 0; i < ysize; i ++)
{
for(j = 0; j < xsize; j ++)
{
sum = 0;
for(k = 0; k < ptemplate->ywidth; k ++)
{
m = i + (k - ptemplate->ybase);
if((m >= 0) && (m < ysize))
{
dpsignal = psignal + (m * xsize);
dptempvalue = ptemplate->value + (k * ptemplate->xwidth);
for(l = 0; l < ptemplate->xwidth; l ++)
{
n = j + (l - ptemplate->xbase);
if((n >= 0) && (n < xsize))
{
sum += ((* (dptempvalue + l)) * (* (dpsignal + n)));
}
} /*l*/
}
} /*k*/
(* dpresult) = (float)sum;
dpresult ++;
} /*j*/
} /*i*/
return(TRUE);
}
Bool signal_2D_convolve_rotation(short * psignal, int xsize, int ysize,
Signal_2D * ptemplate, short ** ppresult)
/*
This function convolve the psignal with the ptemplate, and write the
result to presult. For the two ends, this function uses the rotation
method. psignal must have a length not shorter than ptemplate.
presult has the same width as psignal, and is allocated in this function.
Note: the template is not inverted in this convolution.
*/
{
/*
int j, i;
presult->width = psignal->width;
presult->base = psignal->base;
presult->value = (double *)malloc(presult->width * sizeof(double));
for(i = 0; i < presult->width; i ++)
{
presult->value[i] = 0;
for(j = 0; j < ptemplate->width; j ++)
{
presult->value[i]
+= ( ptemplate->value[j]
* psignal->value[mod((i + (j - ptemplate->base)), psignal->width)]
);
}
}
*/
return(TRUE);
}
void signal_2D_difference(Signal_2D * psignal, Signal_2D * presult)
/*
In this function psignal is differenced and the result is written
into presult. psignal must have a width longer than 1.
presult->value[0] is meaningless.
*/
{
/*
int i;
presult->width = psignal->width;
presult->base = psignal->base;
presult->value = (double *)malloc(presult->width * sizeof(double));
presult->value[0] = 0;
for(i = 1; i < presult->width; i ++)
{
presult->value[i] = psignal->value[i] - psignal->value[i - 1];
}
*/
}