📄 cxdxt.cpp
字号:
}
}
// 2. all the other transforms
for( f_idx = (factors[0]&1) ? 0 : 1; f_idx < nf; f_idx++ )
{
int factor = factors[f_idx];
nx = n;
n *= factor;
dw0 /= factor;
if( factor == 3 )
{
// radix-3
for( i = 0; i < n0; i += n )
{
CvComplex64f* v = dst + i;
double r1 = v[nx].re + v[nx*2].re;
double i1 = v[nx].im + v[nx*2].im;
double r0 = v[0].re;
double i0 = v[0].im;
double r2 = icv_sin_120*(v[nx].im - v[nx*2].im);
double i2 = icv_sin_120*(v[nx*2].re - v[nx].re);
v[0].re = r0 + r1; v[0].im = i0 + i1;
r0 -= 0.5*r1; i0 -= 0.5*i1;
v[nx].re = r0 + r2; v[nx].im = i0 + i2;
v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
{
v = dst + i + j;
r0 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im;
i0 = v[nx].re*wave[dw].im + v[nx].im*wave[dw].re;
i2 = v[nx*2].re*wave[dw*2].re - v[nx*2].im*wave[dw*2].im;
r2 = v[nx*2].re*wave[dw*2].im + v[nx*2].im*wave[dw*2].re;
r1 = r0 + i2; i1 = i0 + r2;
r2 = icv_sin_120*(i0 - r2); i2 = icv_sin_120*(i2 - r0);
r0 = v[0].re; i0 = v[0].im;
v[0].re = r0 + r1; v[0].im = i0 + i1;
r0 -= 0.5*r1; i0 -= 0.5*i1;
v[nx].re = r0 + r2; v[nx].im = i0 + i2;
v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
}
}
}
else if( factor == 5 )
{
// radix-5
for( i = 0; i < n0; i += n )
{
for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
{
CvComplex64f* v0 = dst + i + j;
CvComplex64f* v1 = v0 + nx*2;
CvComplex64f* v2 = v1 + nx*2;
double r0, i0, r1, i1, r2, i2, r3, i3, r4, i4, r5, i5;
r3 = v0[nx].re*wave[dw].re - v0[nx].im*wave[dw].im;
i3 = v0[nx].re*wave[dw].im + v0[nx].im*wave[dw].re;
r2 = v2[0].re*wave[dw*4].re - v2[0].im*wave[dw*4].im;
i2 = v2[0].re*wave[dw*4].im + v2[0].im*wave[dw*4].re;
r1 = r3 + r2; i1 = i3 + i2;
r3 -= r2; i3 -= i2;
r4 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im;
i4 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re;
r0 = v1[0].re*wave[dw*2].re - v1[0].im*wave[dw*2].im;
i0 = v1[0].re*wave[dw*2].im + v1[0].im*wave[dw*2].re;
r2 = r4 + r0; i2 = i4 + i0;
r4 -= r0; i4 -= i0;
r0 = v0[0].re; i0 = v0[0].im;
r5 = r1 + r2; i5 = i1 + i2;
v0[0].re = r0 + r5; v0[0].im = i0 + i5;
r0 -= 0.25*r5; i0 -= 0.25*i5;
r1 = icv_fft5_2*(r1 - r2); i1 = icv_fft5_2*(i1 - i2);
r2 = -icv_fft5_3*(i3 + i4); i2 = icv_fft5_3*(r3 + r4);
i3 *= -icv_fft5_5; r3 *= icv_fft5_5;
i4 *= -icv_fft5_4; r4 *= icv_fft5_4;
r5 = r2 + i3; i5 = i2 + r3;
r2 -= i4; i2 -= r4;
r3 = r0 + r1; i3 = i0 + i1;
r0 -= r1; i0 -= i1;
v0[nx].re = r3 + r2; v0[nx].im = i3 + i2;
v2[0].re = r3 - r2; v2[0].im = i3 - i2;
v1[0].re = r0 + r5; v1[0].im = i0 + i5;
v1[nx].re = r0 - r5; v1[nx].im = i0 - i5;
}
}
}
else
{
// radix-"factor" - an odd number
int p, q, factor2 = (factor - 1)/2;
int d, dd, dw_f = tab_size/factor;
CvComplex64f* a = buf;
CvComplex64f* b = buf + factor2;
for( i = 0; i < n0; i += n )
{
for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
{
CvComplex64f* v = dst + i + j;
CvComplex64f v_0 = v[0];
CvComplex64f vn_0 = v_0;
if( j == 0 )
{
for( p = 1, k = nx; p <= factor2; p++, k += nx )
{
double r0 = v[k].re + v[n-k].re;
double i0 = v[k].im - v[n-k].im;
double r1 = v[k].re - v[n-k].re;
double i1 = v[k].im + v[n-k].im;
vn_0.re += r0; vn_0.im += i1;
a[p-1].re = r0; a[p-1].im = i0;
b[p-1].re = r1; b[p-1].im = i1;
}
}
else
{
const CvComplex64f* wave_ = wave + dw*factor;
d = dw;
for( p = 1, k = nx; p <= factor2; p++, k += nx, d += dw )
{
double r2 = v[k].re*wave[d].re - v[k].im*wave[d].im;
double i2 = v[k].re*wave[d].im + v[k].im*wave[d].re;
double r1 = v[n-k].re*wave_[-d].re - v[n-k].im*wave_[-d].im;
double i1 = v[n-k].re*wave_[-d].im + v[n-k].im*wave_[-d].re;
double r0 = r2 + r1;
double i0 = i2 - i1;
r1 = r2 - r1;
i1 = i2 + i1;
vn_0.re += r0; vn_0.im += i1;
a[p-1].re = r0; a[p-1].im = i0;
b[p-1].re = r1; b[p-1].im = i1;
}
}
v[0] = vn_0;
for( p = 1, k = nx; p <= factor2; p++, k += nx )
{
CvComplex64f s0 = v_0, s1 = v_0;
d = dd = dw_f*p;
for( q = 0; q < factor2; q++ )
{
double r0 = wave[d].re * a[q].re;
double i0 = wave[d].im * a[q].im;
double r1 = wave[d].re * b[q].im;
double i1 = wave[d].im * b[q].re;
s1.re += r0 + i0; s0.re += r0 - i0;
s1.im += r1 - i1; s0.im += r1 + i1;
d += dd;
d -= -(d >= tab_size) & tab_size;
}
v[k] = s0;
v[n-k] = s1;
}
}
}
}
}
if( fabs(scale - 1.) > DBL_EPSILON )
{
double re_scale = scale, im_scale = scale;
if( inv )
im_scale = -im_scale;
for( i = 0; i < n0; i++ )
{
double t0 = dst[i].re*re_scale;
double t1 = dst[i].im*im_scale;
dst[i].re = t0;
dst[i].im = t1;
}
}
else if( inv )
{
for( i = 0; i <= n0 - 2; i += 2 )
{
double t0 = -dst[i].im;
double t1 = -dst[i+1].im;
dst[i].im = t0;
dst[i+1].im = t1;
}
if( i < n0 )
dst[n0-1].im = -dst[n0-1].im;
}
return CV_OK;
}
// mixed-radix complex discrete Fourier transform: single-precision version
static CvStatus CV_STDCALL
icvDFT_32fc( const CvComplex32f* src, CvComplex32f* dst, int n,
int nf, int* factors, const int* itab,
const CvComplex32f* wave, int tab_size,
const void* spec, CvComplex32f* buf,
int flags, double scale )
{
int n0 = n, f_idx, nx;
int inv = flags & CV_DXT_INVERSE;
int dw0 = tab_size, dw;
int i, j, k;
CvComplex32f t;
int tab_step = tab_size == n ? 1 : tab_size == n*2 ? 2 : tab_size/n;
if( spec )
{
assert( icvDFTFwd_CToC_32fc_p != 0 && icvDFTInv_CToC_32fc_p != 0 );
return !inv ?
icvDFTFwd_CToC_32fc_p( src, dst, spec, buf ):
icvDFTInv_CToC_32fc_p( src, dst, spec, buf );
}
// 0. shuffle data
if( dst != src )
{
assert( (flags & ICV_DFT_NO_PERMUTE) == 0 );
if( !inv )
{
for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
{
int k0 = itab[0], k1 = itab[tab_step];
assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
dst[i] = src[k0]; dst[i+1] = src[k1];
}
if( i < n )
dst[n-1] = src[n-1];
}
else
{
for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
{
int k0 = itab[0], k1 = itab[tab_step];
assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
t.re = src[k0].re; t.im = -src[k0].im;
dst[i] = t;
t.re = src[k1].re; t.im = -src[k1].im;
dst[i+1] = t;
}
if( i < n )
{
t.re = src[n-1].re; t.im = -src[n-1].im;
dst[i] = t;
}
}
}
else
{
if( (flags & ICV_DFT_NO_PERMUTE) == 0 )
{
if( factors[0] != factors[nf-1] )
return CV_INPLACE_NOT_SUPPORTED_ERR;
if( nf == 1 )
{
if( (n & 3) == 0 )
{
int n2 = n/2;
CvComplex32f* dsth = dst + n2;
for( i = 0; i < n2; i += 2, itab += tab_step*2 )
{
j = itab[0];
assert( (unsigned)j < (unsigned)n2 );
CV_SWAP(dst[i+1], dsth[j], t);
if( j > i )
{
CV_SWAP(dst[i], dst[j], t);
CV_SWAP(dsth[i+1], dsth[j+1], t);
}
}
}
// else do nothing
}
else
{
for( i = 0; i < n; i++, itab += tab_step )
{
j = itab[0];
assert( (unsigned)j < (unsigned)n );
if( j > i )
CV_SWAP(dst[i], dst[j], t);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -