Thread View: comp.dsp
2 messages
2 total messages
Started by Yongsup Kim
Wed, 27 Dec 1989 15:11
Correlation and FFT
Author: Yongsup Kim
Date: Wed, 27 Dec 1989 15:11
Date: Wed, 27 Dec 1989 15:11
309 lines
8162 bytes
8162 bytes
Hello World!, Signal/Image Proc. Programmers or Simply Hackers!
I ask your favor to solve a well-known problem in the signal/image
processing fields. I want to compute the correlation of two signals
using the Fourier Transform. The two discrete signals are as follows:
f(n) = {1,1,1,1,2,2,2,2,8,8,8,8,9,9,9,9}, n=0,1,....,15.
h(n) = {1,2} n=0,1.
The result should have the highest correlation coefficients at 1,2 and
8,9 transitions. In other words I want to do a pattern matching using FFT.
I was able to get the expected results in the spatial domain, but not in
the frequency domain. I haven't figured out the normalization steps to take
care of the scale changes when I used the FFT.
Note that the lengths of the two signals are not the same, but we can
assume that they are a power of two. I've never posted a news before.
You're more than welcome to call me if you have answers, questions and
problems.
Thanks in advance.
Name: Youngsup Kim
Phone: 1-800-633-7207, 1-205-772-1999 USA
mail: kimy@ingr.com
b15!ysk!youngsup@ingr.com
!!HappyNewYear!!HappyNewYear!!HappyNewYear!!HappyNewYear!!HappyNewYear!!Happy
!!HappyNewYear!!HappyNewYear!!HappyNewYear!!HappyNewYear!!HappyNewYear!!Happy
==========
BACKGROUND
==========
The discrete correlation function is defined as
In the spatial domain:
----------------------
M-1
f(x) o h(x) = SUM f(m) h(x+m) for x=0,1,..,M-1.
m=0
The normalization should be carried out to overcome the scaling
problem. Here is the formular to compute the correlation coefficients.
SUM [f(x) - f'(x)] [h(x-m) - h']
r(m) = ----------------------------------------------
sqrt{ SUM [f(x) - f'(x)] SUM [h(x-m) - h'] }
where m=0,1,...M-1, h' is the average value of the signal,
f'(x) is the average value of f(x) in the region coincident with h(x),
and the summations are taken over the coordinates common to both f and h.
The coefficient r(m) is scaled to the range from -1 to 1, independent of
scale changes in the amplitude of f(x) and h(x). This works great.
Once again I want to do the same thing in the frequency domain or using
the Fourier tranform.
In the freqency domain:
----------------------
-1 *
f(x) o h(x) = FFT [ F(n) H(n) ]
*
where H(n) is the complex conjugate of H(n). F(n) and H(n) are the
Fourier Transform of f(n) and h(n), respectively.
For your convenience, I include the forward/inverse FFT routines and
complex.h. The FFT routines are not optimized but working.
/*
* File: complex.h
*
* define the complex number structure and operations
*
* History:
* 11/01/89 YSK Creation
*
*/
#ifndef IM_CMPLX
#define IM_CMPLX
struct IM_sd_cmplx
{
float r; /* real part */
float i; /* imaginary part */
};
typedef struct IM_sd_cmplx IM_S_CMPLX;
typedef struct IM_sd_cmplx *IM_p_CMPLX;
/*
IDEA:
** Computing a complex product (A + iB) * (X + iY) can be done
** with only three real multiplications at a price of one additional
** addition and assignment.
** (A+B)(X-Y)+AY-BX + i(BX+AY)
** When you do the massive complex multiplications, you use the idea
** described above instead of using CMPLX_mul().
*/
#define CMPLX_cnj(a) (a.i = -a.i)
#define CMPLX_add(a,b,c) (a.r = b.r + c.r, a.i = b.i + c.i)
#define CMPLX_addto(a,b) (a.r += b.r, a.i += b.i)
#define CMPLX_mul(a,b,c) ((a.r = b.r * c.r - b.i * c.i), \
(a.i = b.r * c.i + b.i * c.r))
#define CMPLX_abs(a,b) (a = sqrt(b.r * b.r + b.i * b.i))
#endif
/***************************************************************************
*
* file: fft.c
*
* FFT() Forward Fast Fourier Transform
* FFT_inverse() Inverse Fast Fourier Transform
* is_pow_2 () Check if an integer is a power of 2.
*
* Author: Youngsup Kim
*
* History:
*
* 11/08/89 YSK Creation
*
****************************************************************************/
#include <stdio.h>
#include <math.h>
#include "complex.h"
#define Debug 0
extern double sin(), cos();
/*-----------------------------------------------------------------------*\
FFT
Abstract:
This routine performs 1-dimensional Fast Fourier Transform.
This implementation of the successive-doubling FFT algorithm
is adapted from Cooley and Tukey's paper.
1 M-1
F(u) = --- SUM f(x) exp(-j2 PI(ux/M))
N x=0
The size of the input array or the number of point to compute
should be a power of 2.
Also it assumes that n = 2**ln (NO checking will be done).
The output is overwritten on the input.
Bug:
History:
11/1/89: YSK Initial implementation
\*-----------------------------------------------------------------------*/
int FFT (f, n, ln)
IM_p_CMPLX f; /* input array */
int n; /* size of input array */
int ln; /* n = 2**ln */
{
IM_S_CMPLX u, w, t;
register int i, j;
int k, l, nv2, nm1, ip, le, le1;
float ay, bx;
/* for (i=1, n=2; i<ln; n*=2, i++); Since n is already known, just pass it */
nv2 = n / 2;
nm1 = n - 1;
j = 0;
for (i=0; i<nm1; i++)
{
if (i <= j)
{
t = f[j]; f[j] = f[i]; f[i] = t;
}
k = nv2;
while (k <= j)
{
j -= k;
k /= 2;
}
j += k;
}
for (l=0; l<ln; l++)
{
le = 2;
for (i=1; i<=l; le*=2, i++);
le1 = le / 2;
u.r = 1.0; u.i = 0.0;
w.r = cos(M_PI/le1); w.i = -sin(M_PI/le1);
for (j=0; j<le1; j++)
{
for (i=j; i<n; i+=le)
{
ip = i + le1;
CMPLX_mul (t, f[ip], u);
CMPLX_add (f[ip], f[i], -t);
CMPLX_addto (f[i], t);
}
CMPLX_mul (t, u, w);
u = t;
/**
** Computing a complex product (A + iB) * (X + iY) can be done
** with only three real multiplications at a price of one additional
** addition and assignment.
** (A+B)(X-Y)+AY-BX + i(BX+AY)
**/
#if 0
ay = u.r * w.i;
bx = u.i * w.r;
u.r = (u.i + u.r) * (w.r - w.i) + ay - bx;
u.i = ay + bx;
#endif
}
}
/* Normalize */
for (i=0; i<n; f[i].r /= (float) n, f[i++].i /= (float) n);
}
/*-----------------------------------------------------------------------*\
FFT_inverse
Abstract:
This routine performs 1-dimensional Inverse Fast Fourier
Transform in place.
This routine simply calls the one-dimensional forward FFT after
it conjugates and scales the input array.
The size of the input array or the number of point to compute
should be a power of 2.
The input is scaled down by n.
Also it assumes that n = 2**ln (NO checking will be done).
The output is overwritten on the input or this is in-place
operation.
Bug:
History:
11/1/89: YSK Initial implementation
\*-----------------------------------------------------------------------*/
int FFT_inverse (me, n, ln)
IM_p_CMPLX me; /* input one-dimensional array */
int n; /* size of "me" */
int ln; /* n = 2 ** ln */
{
int i;
IM_p_CMPLX ptr;
ptr=me;
for (i=0; i<n; i++, ptr++)
{
ptr->r = ptr->r * n;
ptr->i = -ptr->i * n;
}
return (FFT (me, n, ln));
}
/*
** is_pow_2: checks if the number is a power of 2 and returns the power,
** or a -1 if the number isn't
*/
int is_pow_2 (k)
unsigned int k; /* is this number a power of 2? */
{
int i, j, l;
for (i=1; i<sizeof(int) * 8; i++)
{
if (k == 0) break;
j = 1 << i;
if (j == k) break;
}
if (i == (sizeof (int) * 8)) i = -1;
return (i);
}
!HappyNewYear!!HappyNewYear!!HappyNewYear!!HappyNewYear!!HappyNewYear!
Re: Correlation and FFT
Author: Gerald Joseph Durand
Date: Fri, 29 Dec 1989 09:34
Date: Fri, 29 Dec 1989 09:34
60 lines
2409 bytes
2409 bytes
>Hello World!, Signal/Image Proc. Programmers or Simply Hackers!
>I ask your favor to solve a well-known problem in the signal/image
>processing fields. I want to compute the correlation of two signals
using the Fourier Transform. The two discrete signals are as follows:
>
> f(n) = {1,1,1,1,2,2,2,2,8,8,8,8,9,9,9,9}, n=0,1,....,15.
> h(n) = {1,2} n=0,1.
>
>The result should have the highest correlation coefficients at 1,2 and
>8,9 transitions. In other words I want to do a pattern matching using FFT.
>I was able to get the expected results in the spatial domain, but not in
>the frequency domain. I haven't figured out the normalization steps to take
>care of the scale changes when I used the FFT.
>Note that the lengths of the two signals are not the same, but we can
>assume that they are a power of two. I've never posted a news before.
>You're more than welcome to call me if you have answers, questions and
>problems.
>
>Thanks in advance.
>
>Name: Youngsup Kim
>Phone: 1-800-633-7207, 1-205-772-1999 USA
>mail: kimy@ingr.com
> b15!ysk!youngsup@ingr.com
Hi Kim
------
You may be helped by the following reference book
"Multidimensional Digital Signal Processing"
by DAN E. DUDGEON & RUSSEL M. MERSEREAU
PRENTICE-HALL 1984
thank you Jerry Durand.
This routine simply calls the one-dimensional forward FFT after
it conjugates and scales the input array.
The size of the input array or the number of point to compute
should be a power of 2.
The input is scaled down by n.
Also it assumes that n = 2**ln (NO checking will be done).
The output is overwritten on the input or this is in-place
operation.
Bug:
History:
11/1/89: YSK Initial implementation
\*-----------------------------------------------------------------------*/
int FFT_inverse (me, n, ln)
IM_p_CMPLX me; /* input one-dimensional array */
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads