can be set to true to do the inverse calculations instead. Again *gRe and *gIm are the input arrays, and*GRe and *GIm the output arrays. In this 2D version, the values are divided through m for the normalDFT and through n for the inverse DFT. There are also definitions where you should divide throughm*n in one direction and through 1 in the other, or though sqrt(m*n) in both, but it doesn't really matterwhich one you pick, as long as the forward FT and the inverse together give the original image back.The version here gives the nicest results to draw.void DFT2D(int n, int m, bool inverse, double *gRe, double *gIm, double *GRe, double *GIm){std::vector Gr2(m * n * 3);std::vector Gi2(m * n * 3); //temporary buffers//calculate the fourier transform of the columnsfor(int x = 0; x < n; x++)for(int c = 0; c < 3; c++){print(" % done",8, 0, RGB_White, 1);print(50 * x / n, 0, 0, RGB_White, 1);if(done()) end();redraw();//This is the 1D DFT:for(int w = 0; w < m; w++){Gr2[m * 3 * x + 3 * w + c] = Gi2[m * 3 * x + 3 * w + c] = 0;for(int y = 0; y < m; y++){double a= 2 * pi * w * y / float(m);if(!inverse)a = -a;double ca = cos(a);double sa = sin(a);Gr2[m * 3 * x + 3 * w + c] += gRe[m * 3 * x + 3 * y + c] * ca - gIm[m * 3 * x + 3 * y + c] * sa;Gi2[m * 3 * x + 3 * w + c] += gRe[m * 3 * x + 3 * y + c] * sa + gIm[m * 3 * x + 3 * y + c] * ca;}}}//calculate the fourier transform of the rowsfor(int y = 0; y < m; y++)for(int c = 0; c < 3; c++){print(" % done",8, 0, RGB_White, 1);print(50 + 50 * y / m, 0, 0, RGB_White, 1);if(done()) end();redraw();//This is the 1D DFT:for(int w = 0; w < n; w++){GRe[m * 3 * w + 3 * y + c] = GIm[m * 3 * w + 3 * y + c] = 0;for(int x = 0; x < n; x++){double a = 2 * pi * w * x / float(n);if(!inverse)a = -a;double ca = cos(a);double sa = sin(a);GRe[m * 3 * w + 3 * y + c] += Gr2[m * 3 * x + 3 * y + c] * ca - Gi2[m * 3 * x + 3 * y + c] * sa;GIm[m * 3 * w + 3 * y + c] += Gr2[m * 3 * x + 3 * y + c] * sa + Gi2[m * 3 * x + 3 * y + c] * ca;}if(inverse){GRe[m * 3 * w + 3 * y + c] /= n;GIm[m * 3 * w + 3 * y + c] /= n;}else{GRe[m * 3 * w + 3 * y + c] /= m;GIm[m * 3 * w + 3 * y + c] /= m;}}}}
And here's the Fast <strong>Fourier</strong> <strong>Transform</strong> again, in 2D this time. The same can be said about this functionas for the DFT2D function. The explanation of the FFT was already done in an earlier section.void FFT2D(int n, int m, bool inverse, double *gRe, double *gIm, double *GRe, double *GIm){int l2n = 0, p = 1; //l2n will become log_2(n)while(p < n) {p *= 2; l2n++;}int l2m = 0; p = 1; //l2m will become log_2(m)while(p < m) {p *= 2; l2m++;}m = 1
- Page 1 and 2: Lode's Computer Graphics TutorialFo
- Page 3 and 4: would have a single peak. A spectru
- Page 5 and 6: The spectrum is positive everywhere
- Page 7 and 8: This looks already much more progra
- Page 9 and 10: that remains at fixed position, whi
- Page 11 and 12: It takes 4 arrays as parameters: *g
- Page 13 and 14: FFT, which uses only O(n*logn) oper
- Page 15 and 16: FiltersIn the Fourier Domain, it's
- Page 17 and 18: Now the keys all change the spectru
- Page 19 and 20: A HP FilterHere, the same is done w
- Page 21: The main function first loads an im
- Page 25 and 26: left corner at xpos,yPos. The shift
- Page 27 and 28: would have only 2 color channels, o
- Page 29 and 30: The sloped lines in the spectrum he
- Page 31 and 32: shown here, the code for all keys i
- Page 33 and 34: }calculateAmp(N, M, fAmp[0][0], fRe
- Page 35 and 36: component back.This is the original
- Page 37 and 38: In the above images, a circular sec
- Page 39 and 40: It looks pretty ugly, because there
- Page 41 and 42: And here's the result of a much thi