最近开始学习图像识别,第一步FFT
2007-09-04 10:14
603 查看
代码根据csdn论坛上一位达人的C++代码改编:
[/code]
创建FFT对象的时候指定层数ex,也就是点数N= pow(2,ex); 构造函数中会计算omega(0到N-1)节约时间。
public class FFT { /** Creates a new instance of FFT */ public FFT(int _ex) { ex = _ex; N = (int) Math.pow(2, ex); omegaRe = new double ; omegaIm = new double ; for (int k = 0; k < N; k++) { omegaRe[k] = Math.cos(2 * Math.PI / N * k); omegaIm[k] = Math.sin(-2 * Math.PI / N * k); } } double omegaRe[]; double omegaIm[]; int ex; int N; public int rev(int x) { int in = x; int ret = 0; for (int i = 0; i < ex; i++) { ret = ret | (in % 2 << ex - i - 1); in = in >> 1; } return ret; } public void fft(double[] inputRe, double[] inputIm, double[] outputRe, double[] outputIm) { assert (inputRe.length >= N); assert (inputRe.length == inputIm.length); assert (outputRe.length == outputIm.length); assert (inputRe.length == outputRe.length); int k; // 当前树的深度 int j; int nBtFlyLen = 0; if (inputIm == null) { inputIm = new double[inputRe.length]; } // 变换需要的工作空间 double[] work1Re = new double ; double[] work1Im = new double ; double[] work2Re = new double ; double[] work2Im = new double ; // 临时变量 double[] tmpRe; double[] tmpIm; // 初始化,写入数据 System.arraycopy(inputRe, 0, work1Re, 0, N); System.arraycopy(inputIm, 0, work1Im, 0, N); // 临时变量 int nInter = 0; // 蝶形算法进行快速傅立叶变换 for (k = 0; k < ex; k++) { for (j = 0; j < (1 << k); j++) { // 计算长度 nBtFlyLen = 1 << (ex - k); // 倒序重排,加权计算 for (int i = 0; i < nBtFlyLen / 2; i++) { nInter = j * nBtFlyLen; work2Re[i + nInter] = work1Re[i + nInter] + work1Re[i + nInter + nBtFlyLen / 2]; work2Im[i + nInter] = work1Im[i + nInter] + work1Im[i + nInter + nBtFlyLen / 2]; double a = work1Re[i + nInter] - work1Re[i + nInter + nBtFlyLen / 2]; double b = work1Im[i + nInter] - work1Im[i + nInter + nBtFlyLen / 2]; double c = omegaRe[i * (1 << k)]; double d = omegaIm[i * (1 << k)]; work2Re[i + nInter + nBtFlyLen / 2] = a * c - b * d; work2Im[i + nInter + nBtFlyLen / 2] = a * d + b * c; } } // 交换 work1和work2的数据 tmpRe = work1Re; tmpIm = work1Im; work1Re = work2Re; work1Im = work2Im; work2Re = tmpRe; work2Im = tmpIm; } // 重新排序 for (j = 0; j < N; j++) { nInter = 0; for (int i = 0; i < ex; i++) { if ((j & (1 << i)) != 0) { nInter += 1 << (ex - i - 1); } } outputRe[j] = work1Re[nInter]; outputIm[j] = work1Im[nInter]; } } public void ifft(double[] inputRe, double[] inputIm, double[] outputRe, double[] outputIm) { assert (inputRe.length >= N); assert (inputRe.length == inputIm.length); assert (outputRe.length == outputIm.length); assert (inputRe.length == outputRe.length); double[] transformRe = new double ; double[] transformIm = new double ; for (int i = 0; i < N; i++) { transformRe[i] = inputRe[i]; transformIm[i] = -inputIm[i]; } fft(transformRe, transformIm, outputRe, outputIm); for (int i = 0; i < N; i++) { outputRe[i] = outputRe[i] / N; outputIm[i] = -outputIm[i] / N; } } public void fft_2d(double[][] inputRe, double[][] inputIm, double[][] outputRe, double[][] outputIm) { // 检查不强, 没有循环检查二维数组的第二维 assert (inputRe.length >= N); assert (inputRe.length == inputIm.length); assert (outputRe.length == outputIm.length); assert (inputRe.length == outputRe.length); if (inputIm == null) inputIm = new double ; for (int i = 0; i < N; i++) { fft(inputRe[i], inputIm[i], outputRe[i], outputIm[i]); } // 重新为in分配一块空间 double[][] inRe = new double ; double[][] inIm = new double ; // 转置 for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { inRe[i][j] = outputRe[j][i]; inIm[i][j] = outputIm[j][i]; } } for (int i = 0; i < N; i++) { fft(inRe[i], inIm[i], outputRe[i], outputIm[i]); } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { inRe[i][j] = outputRe[j][i]; inIm[i][j] = outputIm[j][i]; } } for (int i = 0; i < N; i++) { System.arraycopy(inRe[i], 0, outputRe[i], 0, N); System.arraycopy(inIm[i], 0, outputIm[i], 0, N); } } public void ifft_2d(double[][] inputRe, double[][] inputIm, double[][] outputRe, double[][] outputIm) { double[][] workRe = new double ; double[][] workIm = new double ; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { workRe[i][j] = inputRe[i][j]; workIm[i][j] = -inputIm[i][j]; } } fft_2d(workRe, workIm, outputRe, outputIm); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { outputRe[i][j] = outputRe[i][j] / (N * N); outputIm[i][j] = -outputIm[i][j] / (N * N); } } } }
[/code]
创建FFT对象的时候指定层数ex,也就是点数N= pow(2,ex); 构造函数中会计算omega(0到N-1)节约时间。
相关文章推荐
- 资料网址大全 (数学,深度学习,机器学习,计算机视觉,人脸识别,图像处理等)
- 学习python图像识别
- 【王晓刚】深度学习在图像识别中的研究进展与展望
- 最近博客没怎么写,因为开始学习ios了,就此开篇
- 最近工作任务比较清闲,开始着手学习unity3d
- Matlab图像识别/检索系列(6)-10行代码完成深度学习网络之基于CNN的图像分类
- 图像处理与识别学习小结
- 深度学习、图像分类入门,从VGG16卷积神经网络开始
- TensorFlow:实战Google深度学习框架(五)图像识别与卷积神经网络
- [译]基于深度残差学习的图像识别
- 最近开始学习数据库,下了一点资料,分享一下
- Matlab图像处理学习笔记(三):基于匹配的目标识别
- [深度学习基础] 1. 图像识别问题的挑战及数据驱动过程
- 最近感冒发烧,今天好多了,开始学习...
- matlab 关于利用深度学习进行图像识别
- 【opencv学习】图像处理和图像识别中常用的OpenCV函数
- 量子学习及思考8-图像识别
- 深度学习-图像识别更多的理解
- 图像处理与识别学习小结
- 学习图像处理,从C++编程开始